Jump to content

Determining the "current" GUI


Recommended Posts

  • Moderators

Hi all,

GUISwitch returns the handle of the previously "current" window. Is there any way of determining the "current" window without using GUISwitch?

Why do I want to know? In order to work, my StringSize UDF requires the creation, and then destruction, of a GUI within the function. This has not posed a problem until yesterday when another member found that he needed to GUISwitch back to his GUI when calling the function AFTER an initial GUICreate command or the controls would not get created in that GUI (or any other).

Testing (see below) has shown that this is because in destroying its own GUI, the UDF also seems to empty the "current" GUI location - GUISwitch returns 0x00000000. If you have only the one GUI in your script, AutoIt appears to adopt this by default when asked to create any new controls - the problem only came to light because the script in question had multiple GUIs, and AutoIt (quite reasonably) declined to choose between them when creating new controls.

Now it is not onerous for the user to GUISwitch back in the specific circumstances of having multiple GUIs and using the UDF after having used GUICreate, but it would be preferable and neater to save the handle of the "current" GUI as the UDF starts so that it can GUISwitch back to this GUI as it ends. However I cannot find a way to get this information other than as a return from GUISwitch - and within the UDF there is nothing available to GUISwitch to! If I wait the UDF creates its own GUI, then that of course becomes the "current" one and the previous handle is lost.

I could ask the user to pass a handle into the UDF, but that means yet another parameter to deal with a single specific set of circumstances. My hope is that the value is not stored in an internal AutoIt register and so can be obtained via the API, but my Googling has so far come up blank.

Any ideas - or suggestions of another way to deal with the problem?

M23

If you would like to see the behaviour described above, here is a short example script:

#include <GUIConstantsEx.au3>

; Create a GUI so that there are multiple GUIs in the script
$hGUI_2 = GUICreate("Test 2", 200, 100, 10, 10) ; <<<<<<<<<<<<<<<<<<<<
ConsoleWrite("GUI_2 = " & $hGUI_2 & @CRLF) ; <<<<<<<<<<<<<<<<<<<<
GUISetState(@SW_SHOW, $hGUI_2) ; <<<<<<<<<<<<<<<<<<<<

; Create the main GUI
$hGUI_1 = GUICreate("Test 1", 200, 100, 300, 10)
ConsoleWrite("GUI_1 = " & $hGUI_1 & @CRLF)

; Create first control
$hButton_1 = GUICtrlCreateButton("Test 1", 10, 10, 80, 30)

; Simulate the StringSize UDF
_Sim_StringSize()

; Switch to the dummy GUI
ConsoleWrite("Switch [?] - 2 (last was GUI_3): " & GUISwitch($hGUI_2) & @CRLF) ; xxxxxxxxxxxxxxxxxxx

; Switch back to the main GUI
ConsoleWrite("Switch 2 - 1 (should be GUI_2): " & GUISwitch($hGUI_1) & @CRLF) ; xxxxxxxxxxxxxxxxxxx

; Create second control in the main GUI
$hButton_2 = GUICtrlCreateButton("Test 2", 10, 50, 80, 30)

GUISetState(@SW_SHOW, $hGUI_1)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

Func _Sim_StringSize()
    $hGUI_3 = GUICreate("Test 3", 200, 100, 600, 10)
    ConsoleWrite("GUI_3 = " & $hGUI_3 & @CRLF)
    GUISetState(@SW_SHOW, $hGUI_3)
    GUIDelete($hGUI_3)
EndFunc

Run it as posted and you should see that you get 0x00000000 returned whan you switch to $hGUI_2.

Now, comment out the 2 Switch lines (marked with xxxxxxxxxxx) - and look, no second button! AutoIt cannot decide which of the 2 GUIs is "current".

Finally, comment out the 3 lines which create the additional GUI (marked with <<<<<<<<<<<<<<) - and hey presto, the second button reappears! AutoIt has only one GUI in the script and has obviously decided it must be "current".

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Interesting issue Melba23 

using WinGetHandle ( "[ACTIVE]" ) returns the the correct handle for the active window, $hGUI_1 when I run it, if inserted as below. However the second button is still not drawn. It seems as thought GUIDelete() destroys AutoIts internal handle to the currently active window and Autoit is not internally picking up the handle of the window that the operating system made active when the active window ($hGUI_3) was destroyed.   

; Switch to the dummy GUI
ConsoleWrite("Switch [?] - 2 (last was GUI_3): " & WinGetHandle ( "[ACTIVE]" ) & @CRLF) ; xxxxxxxxxxxxxxxxxxx
;~ ConsoleWrite("Switch [?] - 2 (last was GUI_3): " & GUISwitch($hGUI_2) & @CRLF) ; xxxxxxxxxxxxxxxxxxx

; Switch back to the main GUI
;~ ConsoleWrite("Switch 2 - 1 (should be GUI_2): " & GUISwitch($hGUI_1) & @CRLF) ; xxxxxxxxxxxxxxxxxxx

"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to build bigger and better idiots. So far, the universe is winning."- Rick Cook

Link to comment
Share on other sites

  • Moderators

Bowmore,

Thanks for that suggestion. I have continued experimenting and found that using WinActivate on the newly created GUI (even before you use GUISetState) will allow you to use your WinGetHandle("[ACTIVE]") idea successfully, but that you must do this every time you call the function. Try this script and see what happens if you comment out either of the WinActivate lines (marked with ~~~~~~~~~~~~~):

#include <GUIConstantsEx.au3>

; Create a GUI so that there are multiple GUIs in the script
$hGUI_2 = GUICreate("Test 2", 200, 130, 10, 10)
ConsoleWrite("GUI_2 = " & $hGUI_2 & @CRLF)
GUISetState(@SW_SHOW, $hGUI_2)

; Create the main GUI
$hGUI_1 = GUICreate("Test 1", 200, 130, 300, 10)
ConsoleWrite("GUI_1 = " & $hGUI_1 & @CRLF)

;GUISetState(@SW_SHOW, $hGUI_1) ; ############################

; Create first control
$hButton_1 = GUICtrlCreateButton("Test 1", 10, 10, 80, 30)

WinActivate($hGUI_1) ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Simulate the StringSize UDF
_Sim_StringSize()

; Create second control in the main GUI
$hButton_2 = GUICtrlCreateButton("Test 2", 10, 50, 80, 30)

WinActivate($hGUI_1) ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Simulate the StringSize UDF
_Sim_StringSize()

; Create third control in the main GUI
$hButton_3 = GUICtrlCreateButton("Test 3", 10, 90, 80, 30)

GUISetState(@SW_SHOW, $hGUI_1)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

Func _Sim_StringSize()

    $hPrev = WinGetHandle("[ACTIVE]") ; +++++++++++++++++++++++++++

    $hGUI_3 = GUICreate("Test 3", 200, 100, 600, 10)
    ConsoleWrite("GUI_3 = " & $hGUI_3 & @CRLF)
    GUISetState(@SW_SHOW, $hGUI_3)
    GUIDelete($hGUI_3)

    GUISwitch($hPrev) ; +++++++++++++++++++++++++++

EndFunc

It looks as if AutoIt picks up the fully formed GUI as the "active" one. So your suggestion still requires the user to add a line to his code - to activate the GUI before the UDF call rather then to switch back to it when the UDF returns.

However, when I used GUISetState on $hGUI_1 before calling the simulated UDF, I had more success. Try uncommenting the first GUISetState line (########) and recommenting the WinActivate ones (~~~~~~~~). You now get all controls on $hGUI_1 which is what I would expect as Windows would default to that GUI as the last activated when the UDF GUI is destroyed.

Thanks again for the suggestion - activating the GUI might well be the way to do it.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

I wasn't really proposing my suggestion as a solution. My intention was to try and help narrow down where the problem was occurring. Like yourself I've been trying different things to try an understand what is happening. The code below offers a sort of workaround by forcing the GUI to be shown. This seems OK on the small test GUI which is drawn quickly, but it may not be acceptable on a larger GUI.  

#include <GUIConstantsEx.au3>

; Create a GUI so that there are multiple GUIs in the script
$hGUI_2 = GUICreate("Test 2", 200, 130, 10, 10)
ConsoleWrite("GUI_2 = " & $hGUI_2 & @CRLF)
GUISetState(@SW_SHOW, $hGUI_2)

; Create the main GUI
$hGUI_1 = GUICreate("Test 1", 200, 130, 300, 10)
ConsoleWrite("GUI_1 = " & $hGUI_1 & @CRLF)

; Create first control
$hButton_1 = GUICtrlCreateButton("Test 1", 10, 10, 80, 30)

; Simulate the StringSize UDF
_Sim_StringSize()

; Create second control in the main GUI
$hButton_2 = GUICtrlCreateButton("Test 2", 10, 50, 80, 30)

; Simulate the StringSize UDF
_Sim_StringSize()

; Create third control in the main GUI
$hButton_3 = GUICtrlCreateButton("Test 3", 10, 90, 80, 30)

GUISetState(@SW_SHOW, $hGUI_1)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

Func _Sim_StringSize()
        GUISetState(@SW_SHOW) ; ############################
    $hPrev = WinGetHandle("[ACTIVE]") ; +++++++++++++++++++++++++++
    $hGUI_3 = GUICreate("Test 3", 200, 100, -1000, -1000)
    ConsoleWrite("GUI_3 = " & $hGUI_3 & @CRLF)
    GUISetState(@SW_SHOW, $hGUI_3)
    GUIDelete($hGUI_3)
    GUISwitch($hPrev) ; +++++++++++++++++++++++++++
EndFunc

 

"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to build bigger and better idiots. So far, the universe is winning."- Rick Cook

Link to comment
Share on other sites

  • Moderators

Bowmore,

Thanks for that. An interesting little conundrum which does not seem easy to solve.

I am now trying to get the UDF to work without needing to create/destroy a GUI which I hope will make the whole question somewhat moot. trancexx has posted some code which looks promising - fingers crossed!

Thanks again for taking the time to try and work out what was going on in the example I posted - I appreciate it. :idea:

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...