Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

ListVars


  • Please log in to reply
33 replies to this topic

Poll: What do you think about this wsh (25 member(s) have cast votes)

What do you think about this wsh

  1. Cmon Chris, add this FFS ! (23 votes [88.46%])

    Percentage of vote: 88.46%

  2. No Chris, don't listen to them ! (3 votes [11.54%])

    Percentage of vote: 11.54%

Vote Guests cannot vote
majkinetor
  • Moderators
  • 4512 posts
  • Last active: Jul 29 2016 12:40 AM
  • Joined: 24 May 2006
Is it possible to change this command so it returns the string that we can see in Edit, without opening GUI.

In absence of debuging in AHK it can at least help me about some things.

I imagine:
ListVars,result ,local|global, filter]

We can for instance use this to findout about and iterate trough all variables user created with some prefix or to create custom interface for ListVars (for instance to hide global variables used by modules)

I guess this is trivial code change.

EDIT:
This can be replaced somwhat with minor wish
Alternative is presented here
Why is alternative bad, is presented here.
Posted Image

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
I seem to remember someone (Laszlo?) made a function that silently captures the contents of ListVars, perhaps without having to show the window.

majkinetor
  • Moderators
  • 4512 posts
  • Last active: Jul 29 2016 12:40 AM
  • Joined: 24 May 2006
I think its not possible to do it correctly, without showing a window for a short amount of time.

I tried even to use WinEvent hooks to intercept window creation in early phase, but window is always flashing.

Perhaps there is something I didn't do. I also searchd for Laszlo's thing and found out some examples, but those were also showing window for short amount of time.

Anyway, its trivial code detail. Why not adding it internaly in absence of more serious debug functions. It can be also very well used for loging of internal variables in case script encounters some unusualy scenario.
Posted Image

corrupt
  • Members
  • 2558 posts
  • Last active: Nov 01 2014 03:23 PM
  • Joined: 29 Dec 2004
It is possible to do without displaying the window but not an ideal solution compared to built-in. Here's a link to the topic that you might have been thinking of: <!-- m -->http://www.autohotke...pic.php?t=10182<!-- m -->

corrupt
  • Members
  • 2558 posts
  • Last active: Nov 01 2014 03:23 PM
  • Joined: 29 Dec 2004
MsgBox,,Lines,     % GetAhkStats("lines") 

MsgBox,,Variables, % GetAhkStats("variables") 

MsgBox,,Hotkeys,   % GetAhkStats("hotkeys") 

MsgBox,,KeyHistory,% GetAhkStats("Key history") 

Return 



a::a 



GetAhkStats(Section="") {

 

   DetectHiddenWindows, On 

   IfEqual Section,, SetEnv Section, Key 

   HidWin := WinExist(A_ScriptFullPath " - AutoHotkey v") 

   OldPar := DllCall("GetParent", UInt,HidWin) 

   GUI +LastFound 

   DllCall("SetParent", UInt,HidWin, UInt,WinExist("ahk_class Shell_TrayWnd")) 

   WinMenuSelectItem ahk_id %HidWin%,,View, %Section%

   Sleep 0 

   ControlGetText Out1, Edit1, ahk_id %HidWin%

   WinHide ahk_id %HidWin% 

   DllCall("SetParent", UInt,HidWin, UInt,OldPar) 

   Return Out1 

}


majkinetor
  • Moderators
  • 4512 posts
  • Last active: Jul 29 2016 12:40 AM
  • Joined: 24 May 2006
Amazing workaround !!!


This is definitely good enough replacement, but internal support would be much better, especialy as SetParent may produce unwanted effects one day, and generaly shouldn't be used in such manner.
Posted Image

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
Excellent trick!

If you set the parent to "int", -3 (HWND_MESSAGE) instead of UInt,WinExist("ahk_class Shell_TrayWnd"), AutoHotkey becomes a message-only window. This prevents it from stealing the focus, so getting variables,etc. doesn't interrupt the user. :D (HWND_MESSAGE requires Windows 2000 or later.)

It does still cause the active window to flicker, though...

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
Contrary to my previous post, it seems HWND_MESSAGE only allows it to "recover quicker" - the function still interferes with the active window.

That being the case, I thought I'd make another attempt at preventing it from stealing focus. My attempts at catching window messages, using LockSetForegroundWindow, etc. all failed, so I went all out, and temporarily replaced ShowWindow/SetForegroundWindow:
Loop {
    tick := A_TickCount
    ToolTip % ListGlobalVars()
}

ListGlobalVars()
{
    static hwndEdit, pSFW, pSW, bkpSFW, bkpSW
    
    if !hwndEdit
    {
        dhw := A_DetectHiddenWindows
        DetectHiddenWindows, On
        Process, Exist
        ControlGet, hwndEdit, Hwnd,, Edit1, ahk_class AutoHotkey ahk_pid %ErrorLevel%
        DetectHiddenWindows, %dhw%
        
        astr := A_IsUnicode ? "astr":"str"
        ptr := A_PtrSize=8 ? "ptr":"uint"
        hmod := DllCall("GetModuleHandle", "str", "user32.dll", ptr)
        pSFW := DllCall("GetProcAddress", ptr, hmod, astr, "SetForegroundWindow", ptr)
        pSW := DllCall("GetProcAddress", ptr, hmod, astr, "ShowWindow", ptr)
        DllCall("VirtualProtect", ptr, pSFW, ptr, 8, "uint", 0x40, "uint*", 0)
        DllCall("VirtualProtect", ptr, pSW, ptr, 8, "uint", 0x40, "uint*", 0)
        bkpSFW := NumGet(pSFW+0, 0, "int64")
        bkpSW := NumGet(pSW+0, 0, "int64")
    }

    if (A_PtrSize=8) {
        NumPut(0x0000C300000001B8, pSFW+0, 0, "int64")  ; return TRUE
        NumPut(0x0000C300000001B8, pSW+0, 0, "int64")   ; return TRUE
    } else {
        NumPut(0x0004C200000001B8, pSFW+0, 0, "int64")  ; return TRUE
        NumPut(0x0008C200000001B8, pSW+0, 0, "int64")   ; return TRUE
    }
    
    ListVars
    
    NumPut(bkpSFW, pSFW+0, 0, "int64")
    NumPut(bkpSW, pSW+0, 0, "int64")
    
    ControlGetText, text,, ahk_id %hwndEdit%

    RegExMatch(text, "sm)(?<=^Global Variables \(alphabetical\)`r`n-{50}`r`n).*", text)
    return text
}
ListGlobalVars() neither shows nor activates the AutoHotkey main window. It is also considerably faster: on my system, 2ms vs 128ms (40ms with SetWinDelay, -1.)

It also doesn't hide the main window if it was already visible, though it does of course overwrite its contents.

---
Edit @ 2010-10-21 - Unicode builds of AutoHotkey_L require Astr vs str (optional for the ANSI build):
pSFW := DllCall("GetProcAddress", "uint", hmod, "Astr", "SetForegroundWindow")
pSW := DllCall("GetProcAddress", "uint", hmod, "Astr", "ShowWindow")
Edit @ 2010-11-12 - Updated code and tested with AutoHotkey v1.0.48.05, AutoHotkey_L ANSI, Unicode and Unicode x64.
Edit @ 2015-09-28 - Fixed x64 bugs.

Sean
  • Members
  • 2462 posts
  • Last active: Feb 07 2012 04:00 AM
  • Joined: 12 Feb 2007

and temporarily replaced ShowWindow/SetForegroundWindow:

What's next? ApiHook? Well, this is what I don't want to see in the forum, but I guess it's unstoppable. Anyway, nice trick.

SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005
@Lexikos, RE: ListGlobalVars()

Many thanks for the fantastic code! :D. I am able to save/restore global variables.

Posted Image

haichen
  • Members
  • 200 posts
  • Last active: Oct 20 2013 01:14 PM
  • Joined: 05 Feb 2007
Yes, its very impressive! and far away from my possibilities. :D

I would like to see also a ListAllIncludedFuncs() for listing the called library functions. This may be a useful debugging feature.

I've done the following two functions to start outputdebug with the script,
but to show the included functions DbgHelper_func(A_ThisFunc) must be inserted in all functions.

I put my functions in the Libfolder and with one line of code I can start debugview with my script
DbgHelper_RunDebugView()
;or DbgHelper_RunDebugView(0) for not showing included functions


DbgHelper_func(func){
    static  AllFuncs:=""
    global dbg91938514, ListAllUsedFunctions
    IfNotInString, AllFuncs, %func%
    {
      If (allfuncs<>"") 
			  AllFuncs := Func . ", " . AllFuncs
			else
			  AllFuncs := Func
      If (dbg91938514)
      ListAllUsedFunctions := AllFuncs
      OutputDebug, included Function=  %AllFuncs%	 ; %Func%
  	}
   
  }

DbgHelper_RunDebugView(funcOn="TRUE"){
    global dbg91938514
    dbg91938514 := funcOn ? 1:0
    debuggerpath .= "c:\programme\autoHotkey\DebugView\Dbgview.exe"
    debuggerTitel := "DebugView on \\" . A_ComputerName . " (local)"
    IfExist, %debuggerpath%
      IfWinNotExist, %debuggerTitel% 
				Run, %debuggerpath%
		WinWait, %debuggerTitel%, ,3
    FileGetTime, Created, %A_ScriptFullPath%, C
    FormatTime, Created, Created, dd.MM.yyyy HH:mm
    OutputDebug, Script= ---- %A_ScriptName% ----
    OutputDebug, Created= --- %Created% ---`n`n
  }


Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

I would like to see also a ListAllIncludedFuncs() for listing the called library functions. This may be a useful debugging feature.

If you mean what I think you mean, that can be done fairly easily:
RunWait, "%A_AhkPath%" /iLib "temp-file.ahk" "my-script-file.ahk"
temp-file.ahk would then either be empty (no library functions) or contain a list of #includes in the form:

#Include library-folder
#IncludeAgain full-path-of-first-library-script.ahk
#Include library-folder
#IncludeAgain full-path-of-second-library-script.ahk
etc.

I believe this feature is used by Ahk2Exe.

I've posted a method of avoid the temporary file on page 2 of this thread (keyword: iLib.)

haichen
  • Members
  • 200 posts
  • Last active: Oct 20 2013 01:14 PM
  • Joined: 05 Feb 2007
Wow!
One Line to get all included files and three to show them in debugview.

RunWait, "%A_AhkPath%" /iLib "%A_AppData%/temp-file.txt" "%a_scriptname%"
Fileread, includedFiles, %A_AppData%/temp-file.txt
outputdebug, Included Files:`n%includedFiles%
I also like your pipe-version!

And as third I (re)found fdeps from corrupt.
:D
Ah I forgot to ask. Are there more of such interresting switches?

majkinetor
  • Moderators
  • 4512 posts
  • Last active: Jul 29 2016 12:40 AM
  • Joined: 24 May 2006
Unfortunately, ListGlobalVars can not be used with certanity for now, and probably never will be, until there are some changes in AHK itself. See this.

So we need to restate the wish, if Chris decides not to add this the way it is originaly told:

Variables in ListVars window should never exceed one line, i.e. \r\n & \n have to be replaced. Its probably the best to escape them regulary, i.e. replace \n with `n and \r\n with `r`n.

This can't break scripts, and will make ListGlobalVars function reliable up to the point where number of variables is very big.

Ofcourse, update to ListVars itself would be much much cleaner option.

Honestly, I don't know why so much talk about this ? We have 0 debuging options in AHK and ListVars can't be worse. Why so much talk when requested thing is even more simple to implement then current solution, i.e. it just has to return the data before showing the window. I am sure this is one of those "10 minutes" updates...
Posted Image

SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005
Dear majkinetor, :)

I voted yes, but, er.. was the poll here before or was just introduced ? :roll:

ListGlobalVars function reliable up to the point where number of variables is very big.


How big ?

:)