Modified version of majkinetor's A_DefaultGui()

Post your working scripts, libraries and tools
User avatar
SKAN
Posts: 360
Joined: 29 Sep 2013, 16:58

Modified version of majkinetor's A_DefaultGui()

31 Aug 2014, 10:28

Code: Select all

A_DefaultGui() {   ; Original version by majkinetor goo.gl/oQoKaI  
  Static GUI := "", ADM := 0x800 ; Modified by SKAN goo.gl/qgxzhx
  Local hWnd := 0
	IfNotEqual, A_Gui,, Return 0, GUI := A_Gui
	Gui +LastFound
	hWnd := WinExist(),  OnMessage( ADM, A_ThisFunc )
  DllCall( "SendMessage", "Ptr",hWnd, "UInt",ADM, "Ptr",0, "Ptr",0 )
Return GUI, OnMessage( ADM, "" ), ErrorLevel := hwnd 	
}
Note: For Application Defined Messages, refer MSDN : http://goo.gl/ofXHOR

Test:

Code: Select all

Gui, MyGui:New
Msgbox % A_DefaultGui() "`n" ErrorLevel

Gui 15:Default
Msgbox % A_DefaultGui() "`n" ErrorLevel

Gui, New
Msgbox % A_DefaultGui() "`n" ErrorLevel
User avatar
SKAN
Posts: 360
Joined: 29 Sep 2013, 16:58

GuiList() - List all Gui names

31 Aug 2014, 11:15

Based on the above code, GuiList() will return all Gui names.

Code: Select all

GuiList() { ;           List all Gui names, by SKAN http://goo.gl/qgxzhx | Created: 31-Aug-2014
  Static TList := "", ADM := 0x801 
  Local  Instance := 0, List := "" 

  IfNotEqual, A_Gui,, Return 0, TList .= A_Gui "`n"

  DetectHiddenWindows, % SubStr( ( ADHW := A_DetectHiddenWindows ) . "On", -1 )
  WinGet, Instance, List, % "ahk_class AutoHotkeyGUI ahk_pid " DllCall( "GetCurrentProcessId" )
  DetectHiddenWindows, %ADHW%
  IfEqual, Instance, 0, Return "", ErrorLevel := 0

  OnMessage( ADM, A_ThisFunc )
  Loop %Instance%
    DllCall( "SendMessage", "Ptr",Instance%A_Index%, "UInt",ADM, "Ptr",0, "Ptr",0 )
  OnMessage( ADM, "" )    

  StringTrimRight, List, TList, 1  
Return List,  TList := "",  ErrorLevel := Instance
}
Test:

Code: Select all

#NoEnv
#Warn
#SingleInstance, Force

Gui, MyGui:New
Gui 15:Default 
Gui Add, Button ; creates a window
Gui, New
MsgbOx % GuiList() "`n`nCount = " ErrorLevel
Gui, 15:Destroy
MsgbOx % GuiList() "`n`nCount = " ErrorLevel
guest3456
Posts: 2477
Joined: 09 Oct 2013, 10:31

Re: Modified version of majkinetor's A_DefaultGui()

31 Aug 2014, 13:44

nice, but i still hate your preference of code size over clarity and readability

User avatar
trismarck
Posts: 506
Joined: 30 Sep 2013, 01:48
Location: Poland

Re: Modified version of majkinetor's A_DefaultGui()

31 Aug 2014, 16:01

Note also that A_DefaultGui() will only return the [name of] the default gui window if that window exists.
User avatar
SKAN
Posts: 360
Joined: 29 Sep 2013, 16:58

Re: Modified version of majkinetor's A_DefaultGui()

31 Aug 2014, 16:15

trismarck wrote:Note also that A_DefaultGui() will only return the [name of] the default gui window if that window exists.

Code: Select all

Gui 15:Default
Gui 15:Add, Button
Gui 15:Destroy
MsgBox % A_DefaultGui()
There is Gui +LastFound inside the function which will recreate the window!
User avatar
trismarck
Posts: 506
Joined: 30 Sep 2013, 01:48
Location: Poland

Re: Modified version of majkinetor's A_DefaultGui()

31 Aug 2014, 17:02

Sorry about that SKAN. I've overlooked Gui, +LastFound for Gui, +LastFoundExist and just posted the note because remembered that that was somewhat important. So the function has two 'side-effects':
  • creates default gui window if window doesn't exist
  • doesn't restore last found window (perhaps this could be patched)

Code: Select all

Gui, 3:+LastFound +hwndhwnd3	; last found
Gui, 1:+hwndhwnd1
;MsgBox % A_DefaultGui()
MsgBox % hwnd1 "`n" hwnd3 "`n" WinExist() ; hwnd1 == WinExist()
User avatar
SKAN
Posts: 360
Joined: 29 Sep 2013, 16:58

Re: Modified version of majkinetor's A_DefaultGui()

31 Aug 2014, 17:34

trismarck wrote:
  • creates default gui window if window doesn't exist
  • doesn't restore last found window (perhaps this could be patched)
Thanks for testing this function trismarck. :)

The first one in inevitable, I guess.
I think last found window can be saved & restored. I will try.
just me
Posts: 5707
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Modified version of majkinetor's A_DefaultGui()

01 Sep 2014, 05:39

This is a mix of majkinetor's A_DefaultGui() (old forum -> /board/topic/24532-function-a-defaultgui/) and Lexikos' GetDefaultGui() (old forum -> board/topic/84414-ahk-l-get-the-current-default-gui-name/).

If (hopefully) should work without unwanted side-effects now.

Code: Select all

A_DefaultGui(wParam := "") {
   ; majkinetor : A_DefaultGui()  -> www.autohotkey.com/board/topic/24532-function-a-defaultgui/
   ; Lexikos    : GetDefaultGui() -> www.autohotkey.com/board/topic/84414-ahk-l-get-the-current-default-gui-name/
   Static Msg := DllCall("User32.dll\RegisterWindowMessage", "Str", "AHKGetDefaultGui", "UInt")
   Static DefaultGui
   If (wParam = Msg) {                       ; called by OnMessage
      DefaultGui := A_Gui
      Return 0
   }
   If (Msg = 0)                              ; if RegisterWindowMessage failed, fall back to Lexikos' 0x8888
      Msg := 0x8888
   DetectHidden := A_DetectHiddenWindows     ; save current settings
   DetectHiddenWindows, On                   ; in case that the LastFoundWindow is currently hidden
   LastFoundWindow := WinExist()             ; save the Last Found Window, if any
   Gui, +LastFoundExist                      ; check if the default Gui exists; if not, it has to be created
   If !WinExist()
      Gui, +LastFound +hwndHDESTROY
   PH := OnMessage(Msg, "A_DefaultGui")      ; get the current default Gui
   DllCall("User32.dll\SendMessage", "Ptr", WinExist(), "UInt", Msg, "Ptr", Msg, "Ptr", 0)
   OnMessage(Msg, PH = A_ThisFunc ? "" : PH) ; restore previous handler, if any
   If (HDESTROY)                             ; if the Gui has been created, destroy it
      Gui, %HDESTROY%: Destroy
   If (LastFoundWindow)                      ; if the Last Found Window had been set, restore it ...
      WinExist("ahk_id " . LastFoundWindow)
   Else                                      ; ... otherwise clear it
      Gui, %A_ThisFunc%_NonexistentGui: +LastFoundExist
   DetectHiddenWindows, %DetectHidden%       ; restore the settings
   Return DefaultGui
}
*Updated*

I wonder what would happen if A_Gui would use g->GuiDefaultWindow->... (if present) instead of
'\0' for non-GUI threads:

Code: Select all

VarSizeType BIV_Gui(LPTSTR aBuf, LPTSTR aVarName)
// We're returning the length of the var's contents, not the size.
{
	TCHAR buf[MAX_INTEGER_SIZE];
	LPTSTR target_buf = aBuf ? aBuf : buf;
	GuiType* gui = g->GuiWindow; // For performance.

	if (!gui) // The current thread was not launched as a result of GUI action.
	{
		*target_buf = '\0';
		return 0;
	}
Last edited by just me on 01 Sep 2014, 09:08, edited 1 time in total.
User avatar
SKAN
Posts: 360
Joined: 29 Sep 2013, 16:58

Re: Modified version of majkinetor's A_DefaultGui()

01 Sep 2014, 06:00

just me wrote:Lexikos' GetDefaultGui()
I had missed it. Thanks just me.
User avatar
trismarck
Posts: 506
Joined: 30 Sep 2013, 01:48
Location: Poland

Re: Modified version of majkinetor's A_DefaultGui()

01 Sep 2014, 07:37

Just Me, perfect. A couple more fixes:

Code: Select all

A_DefaultGui(wParam := "") {
   ; majkinetor : A_DefaultGui()  -> www.autohotkey.com/board/topic/24532-function-a-defaultgui/
   ; Lexikos    : GetDefaultGui() -> www.autohotkey.com/board/topic/84414-ahk-l-get-the-current-default-gui-name/
   
   Static Msg := 0				             ; has to be 0, otherwise If (wParam = Msg) is true
   Static DefaultGui
   static first_call := true
   
   If (wParam = Msg) {                       ; called by OnMessage
      DefaultGui := A_Gui
      Return 0
   }
   
   if(first_call) {       
	 first_call := false                     
	 if(OnMessage(msg) != "")                ; safety check that the script doesn't already
	    return, "", ErrorLevel := 1          ; monitor the msg through some other function
	 try DllCall("User32.dll\RegisterWindowMessage", "Str", "GetDefaultGui", "UInt")
	 catch
		return, "", ErrorLevel := 2          ; and that RegisterWindowMessage worked
   }
   
   LastFoundWindow := WinExist()             ; save the Last Found Window, if any
   
   Gui, +LastFoundExist                      ; check if the default Gui exists,
   If !WinExist()							 ; if not, it has to be created
      ;Gui, New, +LastFound +hwndHDESTROY
		; sets the new default gui window, we don't want that
		; 
      Gui, +LastFound +hwndHDESTROY
   
   OnMessage(Msg, A_ThisFunc)            	; get the current default Gui
   try DllCall("User32.dll\SendMessage", "Ptr", WinExist(), "UInt", Msg, "Ptr", Msg, "Ptr", 0)
   catch
	   return, "", ErrorLevel := 3
   
   OnMessage(Msg, "")
   
   If (HDESTROY)                             ; if the dummy Gui has been created, destroy it
      Gui, %HDESTROY%: Destroy
   
   If (LastFoundWindow) {                    ; if the Last Found Window had been set, restore it ...
	  A_DetectHiddenWindowsOld := A_DetectHiddenWindows
      DetectHiddenWindows, On                ; precaution: window to be restored can be hidden
      WinExist("ahk_id" LastFoundWindow)
	  DetectHiddenWindows, % A_DetectHiddenWindowsOld
   }
   Else                                      ; ... otherwise clear it
      Gui, %A_ThisFunc%_NonexistentGui: +LastFoundExist
   Return DefaultGui, ErrorLevel := 0
}
So the function returns the name of the gui if the gui window has a name or the handle of the gui window if the gui window doesn't have a name.
just me
Posts: 5707
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Modified version of majkinetor's A_DefaultGui()

01 Sep 2014, 09:10

hi trismarck,

if(OnMessage(msg) != "") ; safety check that the script doesn't already
Msg is 0 on first call.

try DllCall("User32.dll\SendMessage", "Ptr", WinExist(), "UInt", Msg, "Ptr", Msg, "Ptr", 0)
I really don't think that this is necessary.

DetectHiddenWindows, On ; precaution: window to be restored can be hidden
Good point, but too late. This has already failed, if so:
LastFoundWindow := WinExist() ; save the Last Found Window, if any

THX, I've updated my post.
User avatar
trismarck
Posts: 506
Joined: 30 Sep 2013, 01:48
Location: Poland

Re: Modified version of majkinetor's A_DefaultGui()

01 Sep 2014, 18:16

Greetings Just Me.
Just Me wrote:if(OnMessage(msg) != "") ; safety check that the script doesn't already
Msg is 0 on first call.
Thanks. I was moving parts of the code around and here we see the result of that.
Just Me wrote: try DllCall("User32.dll\SendMessage", "Ptr", WinExist(), "UInt", Msg, "Ptr", Msg, "Ptr", 0)
I really don't think that this is necessary.
I agree. The purpose of try was to suppress throwing an exception if DllCall was enclosed with a try block somewhere down the call graph. Suppress as the function used Errorlevel variables instead of exception handling.
Just Me wrote: DetectHiddenWindows, On ; precaution: window to be restored can be hidden
Good point, but too late. This has already failed, if so:
LastFoundWindow := WinExist() ; save the Last Found Window, if any
Thanks.
Source wrote:// If the last found window is one of the script's own GUI windows, it is considered valid even if
// DetectHiddenWindows is ON.
(I think this comment should have said OFF (vs ON))
So the function in my previous post has passed this test:

Code: Select all

Gui, 3:+LastFound +hwndhwnd3    ; last found
Gui, 1:+hwndhwnd1
;MsgBox % A_DefaultGui()
MsgBox % hwnd1 "`n" hwnd3 "`n" WinExist() ; hwnd1 == WinExist()
only because it was the _gui_ window that was set as the last found window (vs some non-gui window).

Return to “Scripts and Functions”

Who is online

Users browsing this forum: arcticir, DuyMinh, Google [Bot] and 67 guests