Question

I have an AutoIt script in which I open a settings dialog from a system tray menu entry. When opening the dialog this way, messages via button clicks are not handled.

On the other hand, when opening the dialog directly (as indicated in the code below, which you can easily test by uncommenting this call and commenting out the call for the system tray entry), then the messages are handled successfully.

Here is my script. When calling SettingsDialog directly (without going via the systray menu), the OK and Cancel buttons work, but otherwise not.

#include <GUIConstantsEx.au3>
#include <ButtonConstants.au3>

;; Start program in system tray
SetupSystemTrayEntry()

;; When calling settings dialog directly, messages are handled properly
;;SettingsDialog()


Func SetupSystemTrayEntry()
    Opt("TrayMenuMode", 1)

    $settingsitem = TrayCreateItem("Settings")
    TrayCreateItem("")
    $exititem = TrayCreateItem("Exit")

    TraySetState()

    While 1
        Local $traymsg = TrayGetMsg()
        Select
            Case $traymsg = 0
                ContinueLoop
            Case $traymsg = $settingsitem
                SettingsDialog() ;; Bring up settings dialog
            Case $traymsg = $exititem
                Exit ;; Exit program
        EndSelect
    WEnd
EndFunc

Func SettingsDialog()
    GUICreate("Settings", 400, 150, @DesktopWidth / 2 - 200, @DesktopHeight / 2 - 75)
    $ok_button = GUICtrlCreateButton("OK", 100, 100, 80, 25, $BS_DEFPUSHBUTTON)
    $cancel_button = GUICtrlCreateButton("Cancel", 200, 100, 80, 25)

    GUISetState()

    Do
        ;; These messages are never handled when the dialog is brought up from
        ;; the system tray menu entry above, but when calling this function
        ;; directly, it works
        Local $settmsg = GUIGetMsg()
        Select
            Case $settmsg = $ok_button
                ExitLoop
            Case $settmsg = $cancel_button
                ExitLoop
        EndSelect
    Until $settmsg = $GUI_EVENT_CLOSE

EndFunc
Was it helpful?

Solution 2

As per solution provided on the AutoIt forum, here is a version of the script that hides and shows the dialog on each usage. There is a big caveat (read the forum thread for details) in that on creation of the dialog, it must be explicitly hidden!

#include <GUIConstantsEx.au3>
#include <ButtonConstants.au3>

; Do not declare Global variables in a function <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Global $settings_window_handle, $ok_button, $cancel_button

;; Set up settings dialog
InitSettingsDialog();

;; Start program in system tray
SetupSystemTrayEntry()

Func SetupSystemTrayEntry()
    Opt("TrayMenuMode", 1)

    $settingsitem = TrayCreateItem("Settings")
    TrayCreateItem("")
    $exititem = TrayCreateItem("Exit")

    TraySetState()

    While 1
        Switch TrayGetMsg()
            Case $settingsitem
                ShowSettingsDialog() ;; Bring up settings dialog
            Case $exititem
                Exit ;; Exit program
        EndSwitch
    WEnd
EndFunc   ;==>SetupSystemTrayEntry

Func InitSettingsDialog()
    ; Create
    $settings_window_handle = GUICreate("Settings", 400, 150, @DesktopWidth / 2 - 200, @DesktopHeight / 2 - 75)
    $ok_button = GUICtrlCreateButton("OK", 100, 100, 80, 25, $BS_DEFPUSHBUTTON)
    $cancel_button = GUICtrlCreateButton("Cancel", 200, 100, 80, 25)
    GUISetState(@SW_HIDE, $settings_window_handle)
EndFunc   ;==>SettingsDialog

Func ShowSettingsDialog()
    GUISetState(@SW_SHOW, $settings_window_handle)
    While 1
        Switch GUIGetMsg()
            Case $ok_button
                MsgBox(0, "test", "test")
                ExitLoop
            Case $cancel_button
                ExitLoop
        EndSwitch
    WEnd
    GUISetState(@SW_HIDE, $settings_window_handle)
EndFunc

OTHER TIPS

Seems all fine, except you should do something after you left the Do/Until loop.

Func SettingsDialog()
    GUICreate("Settings", 400, 150, @DesktopWidth / 2 - 200, @DesktopHeight / 2 - 75)
    $ok_button = GUICtrlCreateButton("OK", 100, 100, 80, 25, $BS_DEFPUSHBUTTON)
    $cancel_button = GUICtrlCreateButton("Cancel", 200, 100, 80, 25)

    GUISetState()

    Do
        ;; These messages are never handled when the dialog is brought up from
        ;; the system tray menu entry above, but when calling this function
        ;; directly, it works
        Local $settmsg = GUIGetMsg()
        ConsoleWrite(@HOUR & ":" & @MIN & ":" & @SEC & "," & @MSEC & "msg = " & $settmsg & @CRLF)

        Select
            Case $settmsg = $ok_button
                ExitLoop
            Case $settmsg = $cancel_button
                ExitLoop
        EndSelect
    Until $settmsg = $GUI_EVENT_CLOSE
    Return GUIDelete()
Endfunc

I added 2 lines, the ConsoleWrite after calling GUIGetMessage and the Return after the loop.

When I run this script the Settings Dialog is properly closed by either clicking 'Ok' or 'Cancel'.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top