WildByDesign Posted Sunday at 01:10 PM Posted Sunday at 01:10 PM I came across this issue in one of my projects and decided to recreate a smaller script to reproduce the issue and see if anyone knows how I can get around this issue. The main GUI script has the ability to hide to it's system tray icon Clicking on the tray icon will show the GUI again In this case, the menu items (Help > About) and controls still work I have a situation where I use another script to show the GUI again since it is normally hidden in the system tray. GUI is already hidden in system tray This second script runs to show the GUI GUI does show and everything appears visually correct In this case, the menu items (Help > About) and controls do NOT work Yet if I hide the GUI again during the same run, and show itself again from the tray icon, everything works again. Therefore, it only seems to happen when showing the GUI from another process. Script1: expandcollapse popup#NoTrayIcon #include <AutoItConstants.au3> #include <TrayConstants.au3> #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include <StaticConstants.au3> Global $hGUI Opt("TrayMenuMode", 3) Opt("TrayAutoPause", 0) Opt("TrayOnEventMode", 1) TraySetOnEvent($TRAY_EVENT_PRIMARYDOWN, 'idGUI') TraySetClick(16) $idGUI = TrayCreateItem("Show GUI") TrayItemSetOnEvent($idGUI, "idGUI") TrayCreateItem("") $idExit = TrayCreateItem('Exit') TrayItemSetOnEvent($idExit, "_Exit") TraySetIcon(@AutoItExe, 1) TraySetToolTip("Show GUI") Example() Func Example() Local $sDefaultstatus = "Ready" $hGUI = GUICreate("My GUI menu", 300, 200) Local $idMnu_File = GUICtrlCreateMenu("&File") Local $idMnu_Help = GUICtrlCreateMenu("Help") Local $idMni_Info = GUICtrlCreateMenuItem("About", $idMnu_Help) Local $idMnu_View = GUICtrlCreateMenu("View", -1, 1) Local $idBtn_Hide = GUICtrlCreateButton("Hide GUI", 50, 130, 70, 20) GUICtrlSetState(-1, $GUI_FOCUS) Local $idBtn_Cancel = GUICtrlCreateButton("Exit", 180, 130, 70, 20) Local $idLbl_Status = GUICtrlCreateLabel($sDefaultstatus, 0, 165, 300, 16, BitOR($SS_SIMPLE, $SS_SUNKEN)) GUISetState(@SW_SHOW) ; Loop until the user exits. While 1 Switch GUIGetMsg() Case $idBtn_Hide GUISetState(@SW_HIDE, $hGUI) Case $idBtn_Cancel, $GUI_EVENT_CLOSE ExitLoop Case $idMni_Info MsgBox($MB_SYSTEMMODAL, "Info", "Only a test...") EndSwitch WEnd GUIDelete() EndFunc ;==>Example Func _Exit() Exit EndFunc Func idGUI() ; get GUI window state Local $iState = WinGetState($hGUI) If $iState <> $WIN_STATE_VISIBLE Then GUISetState(@SW_SHOW, $hGUI) EndFunc Script2: #include <WinAPISysWin.au3> ; show and activate the GUI window $hWnd = WinGetHandle("My GUI menu") _WinAPI_ShowWindow($hWnd, @SW_SHOW) _WinAPI_SetForegroundWindow($hWnd) By the way, I have tried all of the other functions such as WinActivate and various WinAPI to show and give focus to the GUI window. They all still work to show the GUI but also still have controls and menu items that fail. Does anyone know why this issue occurs or what I can do to fix it? Thank you for your time. Parsix and pixelsearch 2
WildByDesign Posted Sunday at 01:13 PM Author Posted Sunday at 01:13 PM Also, I realize that I am using OnEvent for tray stuff and GUIGetMsg for GUI stuff. In my main project, I use OnEvent for everything. The issue occurs either way and therefore this mix of OnEvent and GUIGetMsg in this example was just for the purpose of making a quick smaller example.
Solution argumentum Posted Sunday at 01:52 PM Solution Posted Sunday at 01:52 PM expandcollapse popup#NoTrayIcon #include <AutoItConstants.au3> #include <TrayConstants.au3> #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include <StaticConstants.au3> Global $hGUI Opt("TrayMenuMode", 3) Opt("TrayAutoPause", 0) Opt("TrayOnEventMode", 1) TraySetOnEvent($TRAY_EVENT_PRIMARYDOWN, 'idGUI') TraySetClick(16) Global $idGUI = TrayCreateItem("Show GUI") TrayItemSetOnEvent($idGUI, "idGUI") TrayCreateItem("") Global $idExit = TrayCreateItem('Exit') TrayItemSetOnEvent($idExit, "_Exit") TraySetIcon(@AutoItExe, 1) TraySetToolTip("Show GUI") Example() Func Example() Local $sDefaultstatus = "Ready" $hGUI = GUICreate("My GUI menu", 300, 200) Local $idMnu_File = GUICtrlCreateMenu("&File") Local $idMnu_Help = GUICtrlCreateMenu("Help") Local $idMni_Info = GUICtrlCreateMenuItem("About", $idMnu_Help) Local $idMnu_View = GUICtrlCreateMenu("View", -1, 1) Local $idBtn_Hide = GUICtrlCreateButton("Hide GUI", 50, 130, 70, 20) GUICtrlSetState(-1, $GUI_FOCUS) Local $idBtn_Cancel = GUICtrlCreateButton("Exit", 180, 130, 70, 20) Local $idLbl_Status = GUICtrlCreateLabel($sDefaultstatus, 0, 165, 300, 16, BitOR($SS_SIMPLE, $SS_SUNKEN)) GUISetState(@SW_SHOW) ; Loop until the user exits. While 1 Switch GUIGetMsg() Case $idBtn_Hide ;~ GUISetState(@SW_HIDE, $hGUI) WinSetState($hGUI, "", @SW_HIDE) Case $idBtn_Cancel, $GUI_EVENT_CLOSE ExitLoop Case $idMni_Info MsgBox($MB_SYSTEMMODAL, "Info", "Only a test...") EndSwitch WEnd GUIDelete() EndFunc ;==>Example Func _Exit() Exit EndFunc Func idGUI() If Not BitAND(WinGetState($hGUI), $WIN_STATE_VISIBLE) Then WinSetState($hGUI, "", @SW_SHOW) ;~ ; get GUI window state ;~ Local $iState = WinGetState($hGUI) ;~ If $iState <> $WIN_STATE_VISIBLE Then GUISetState(@SW_SHOW, $hGUI) EndFunc yes, is an old bug, and the way it is. Fortunately you can get around it. ioa747 and pixelsearch 2 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
WildByDesign Posted Sunday at 02:12 PM Author Posted Sunday at 02:12 PM 15 minutes ago, argumentum said: yes, is an old bug, and the way it is. Fortunately you can get around it. You literally just saved the rest of my weekend, Sir. Thank you! 🍷 So the trick was to essentially use WinSetState instead of GUISetState. I really needed this to work, one way or another. I feel very lucky for the fact that there was a simple workaround for this issue and thankful that you were able to help me solve this issue. Now I can relax. argumentum 1
WildByDesign Posted Monday at 10:03 AM Author Posted Monday at 10:03 AM 20 hours ago, argumentum said: Func idGUI() If Not BitAND(WinGetState($hGUI), $WIN_STATE_VISIBLE) Then WinSetState($hGUI, "", @SW_SHOW) ;~ ; get GUI window state ;~ Local $iState = WinGetState($hGUI) ;~ If $iState <> $WIN_STATE_VISIBLE Then GUISetState(@SW_SHOW, $hGUI) EndFunc So while this part worked and fixed the problem, it had an unexpected side effect of causing the controls on the GUI to have a delay in showing them. Even with the tiny example with only two buttons. Same with my project. The GUI shows immediately and the controls have a delayed load which is unusual. But I found another method that shows the GUI and controls instantly. Func idGUI() ; get GUI window state If Not BitAND(WinGetState($hGUI), $WIN_STATE_VISIBLE) Then _WinAPI_ShowWindow($hGUI, @SW_SHOW) EndFunc I have no idea why WinSetState has such a delay with showing the controls while _WinAPI_ShowWindow does not have the delay. But that is what I love about having so many options; so many different methods to achieve the same thing. argumentum 1
pixelsearch Posted Monday at 02:37 PM Posted Monday at 02:37 PM Interesting thread indeed. Based on WildByDesign and argumentum scripts, I just kept the minimum code in the following script, to reproduce the issue (no trayitem) 1) First script : we run it and click the Hide button => the gui is hidden ; expandcollapse popup; 1st script : click button to hide the gui #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> Example() Func Example() Local $hGUI = GUICreate("My GUI menu", 300, 200) Local $idMnu_File = GUICtrlCreateMenu("&File") Local $idMnu_Help = GUICtrlCreateMenu("Help") Local $idMni_Info = GUICtrlCreateMenuItem("About", $idMnu_Help) Local $idMnu_View = GUICtrlCreateMenu("View", -1, 1) Local $idBtn_Hide = GUICtrlCreateButton("Hide GUI", 50, 130, 70, 20) GUICtrlSetState(-1, $GUI_FOCUS) Local $idBtn_Cancel = GUICtrlCreateButton("Exit", 180, 130, 70, 20) GUISetState(@SW_SHOW) While 1 Switch GUIGetMsg() Case $idBtn_Hide ; watch out, another script won't be able to activate correctly the hidden GUI if GUISetState is used here. GUISetState(@SW_HIDE, $hGUI) ; <=============================== ; another script will be able to activate correctly the hidden GUI if WinSetState is used here. ; WinSetState($hGUI, "", @SW_HIDE) ; <========================= Case $idBtn_Cancel, $GUI_EVENT_CLOSE ExitLoop Case $idMni_Info MsgBox($MB_TOPMOST, "Info", "Only a test...") EndSwitch WEnd GUIDelete() EndFunc ;==>Example 2) Second script : we run it and the gui reappears, but its controls/menu don't respond : ; 2nd script : show & activate the hidden GUI #include <WinAPISysWin.au3> ; show and activate the GUI window . Watch out: controls won't react if the GUI was hidden using GUISetState in the 1st script Local $hWnd = WinGetHandle("My GUI menu") _WinAPI_ShowWindow($hWnd, @SW_SHOW) _WinAPI_SetForegroundWindow($hWnd) As argumentum suggested (thanks !) everything works fine if we use in the 1st script WinSetState (instead of GuiSetState) to hide the GUI @Melba23 wrote comments about it in this post. Dear Melba, in case you have some free time, could you please share your opinion about this, e.g. the fact that we need to use WinSetState in the 1st script (which isn't recommended when working with GUI's) because the hidden GUI needs to be shown/activated by an external script ? Thanks WildByDesign 1 "I think you are searching a bug where there is no bug... don't listen to bad advice."
argumentum Posted Monday at 02:44 PM Posted Monday at 02:44 PM ...there is also IPC. The code could ask the other code to show itself. WildByDesign 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
ioa747 Posted Monday at 04:41 PM Posted Monday at 04:41 PM (edited) playing with the idea a little Script1.au3 Spoiler expandcollapse popup; Script1.au3 #NoTrayIcon #include <AutoItConstants.au3> #include <TrayConstants.au3> #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include <StaticConstants.au3> Global $hGUI, $idLbl_Status Opt("TrayMenuMode", 3) Opt("TrayAutoPause", 0) Opt("TrayOnEventMode", 1) $idGUI = TrayCreateItem("Show GUI") TrayItemSetOnEvent($idGUI, "idGUI") TrayCreateItem("") $idExit = TrayCreateItem('Exit') TrayItemSetOnEvent($idExit, "_Exit") TraySetOnEvent($TRAY_EVENT_PRIMARYDOWN, 'idGUI') TraySetClick(16) TraySetIcon(@AutoItExe, 1) TraySetToolTip("Show GUI") Example() Func Example() $hGUI = GUICreate("My GUI menu", 300, 200) Local $idBtn_Hide = GUICtrlCreateButton("Hide GUI", 50, 130, 70, 20) Local $idBtn_Cancel = GUICtrlCreateButton("Exit", 180, 130, 70, 20) $idLbl_Status = GUICtrlCreateLabel("Ready", 0, 184, 300, 16, BitOR($SS_SIMPLE, $SS_SUNKEN)) GUISetState(@SW_SHOW) While 1 Switch GUIGetMsg() Case $idBtn_Hide GUISetState(@SW_HIDE, $hGUI) Case $idBtn_Cancel, $GUI_EVENT_CLOSE ExitLoop EndSwitch _ExtMsg() WEnd GUIDelete() EndFunc ;==>Example Func _ExtMsg($sTitle = StringTrimRight(@ScriptName, 4)) Local Static $hWnd = 0 If $hWnd = 0 Then $hWnd = WinGetHandle(AutoItWinGetTitle()) Local $sCurTitle = AutoItWinGetTitle() If $sCurTitle <> $sTitle Then Switch $sCurTitle Case "Show GUI" idGUI() Case "Hide GUI" GUICtrlSetData($idLbl_Status, "Hiden & Standby") GUISetState(@SW_HIDE) Case "Get Status" ControlSetText($hWnd, "", "Edit1", GUICtrlRead($idLbl_Status)) Case Else If StringLeft($sCurTitle, 8) = "Execute:" Then ConsoleWrite("Execute: " & StringTrimLeft($sCurTitle, 8) & @CRLF) ; *** info Execute(StringTrimLeft($sCurTitle, 8)) EndIf EndSwitch AutoItWinSetTitle($sTitle) EndIf EndFunc ;==>_ExtMsg Func _Exit() Exit EndFunc ;==>_Exit Func idGUI() Local $iState = WinGetState($hGUI) If Not BitAND($iState, $WIN_STATE_VISIBLE) Then GUISetState(@SW_SHOW, $hGUI) GUICtrlSetData($idLbl_Status, "Visible & Ready") EndFunc Script2.au3 Spoiler expandcollapse popup; Script2.au3 #include <GUIConstantsEx.au3> Test() Func Test() Local $hWnd = WinGetHandle("Script1") If Not IsHWnd($hWnd) Then Return MsgBox(16, "Error", "'Script1' not found") ConsoleWrite("$hWnd=" & $hWnd & @CRLF) ;~ ; for debuging ;~ WinMove($hWnd, "", (@DesktopWidth / 2) - 250, (@DesktopHeight / 2) - 250, 500, 500) ; Move the AutoIt Hidden Window and re-size for a better view. ;~ WinSetState($hWnd, "", @SW_SHOW) ; Show the AutoIt Hidden Window, normally this is hidden, but in the interest of this example I"m displaying it. ;~ ControlSetText($hWnd, "", "Edit1", "Show the AutoIt Hidden Window") Local $hGui = GUICreate(@ScriptName, 250, 170, -1, -1) Local $idBtn1 = GUICtrlCreateButton("Show GUI", 10, 10, 100, 25) Local $idBtn2 = GUICtrlCreateButton("Hide GUI", 10, 40, 100, 25) Local $idBtn3 = GUICtrlCreateButton("SetData", 10, 70, 100, 25) Local $idBtn4 = GUICtrlCreateButton("GetData", 10, 100, 100, 25) Local $idBtn5 = GUICtrlCreateButton("_Exit()", 10, 130, 100, 25) GUISetState(@SW_SHOW, $hGui) Local $sResult = "" While WinExists($hWnd) Local $aWPos = WinGetPos($hGui) Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $idBtn1 WinSetTitle($hWnd, "", "Show GUI") Case $idBtn2 WinSetTitle($hWnd, "", "Hide GUI") Case $idBtn3 WinSetTitle($hWnd, "", 'Execute:GUICtrlSetData($idLbl_Status, "Hello from the other side")') Case $idBtn4 $sResult = _GetResult($hWnd, "Get Status") ConsoleWrite("$sResult=" & $sResult & @CRLF) Case $idBtn5 WinSetTitle($hWnd, "", "Execute:_Exit()") EndSwitch WEnd GUIDelete($hGui) EndFunc ;==>Test Func _GetResult($hWnd, $sCmd, $iTimeout = 1000) Local $iStartTime = TimerInit() ControlSetText($hWnd, "", "Edit1", "") ; first we clear Edit1 WinSetTitle($hWnd, "", $sCmd) ; then we send Cmd Local $sIncomeText = "" While TimerDiff($iStartTime) < $iTimeout $sIncomeText = ControlGetText($hWnd, "", "Edit1") If $sIncomeText <> "" Then ; Check if new content arrived ExitLoop EndIf Sleep(40) WEnd ConsoleWrite(" processed in: " & Round(TimerDiff($iStartTime) / 1000, 3) & " seconds " & @LF) Return $sIncomeText EndFunc ;==>_GetResult Edited Tuesday at 09:16 AM by ioa747 update WildByDesign 1 I know that I know nothing
WildByDesign Posted Monday at 05:28 PM Author Posted Monday at 05:28 PM 45 minutes ago, ioa747 said: playing with the idea a little This is really creative. Thanks for sharing. I like how ideas turn into ideas and those ideas turn into more ideas. And now, I think I have some ideas for this technique. ioa747 1
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now