Диалоговые сообщения не обрабатываются при открытии диалога из панели задач

У меня есть сценарий AutoIt, в котором я открываю диалоговое окно настроек из пункта меню панели задач. При открытии диалога таким образом сообщения через нажатия кнопок не обрабатываются.

С другой стороны, при непосредственном открытии диалогового окна (как показано в приведенном ниже коде, который можно легко проверить, раскомментировав этот вызов и закомментировав вызов для входа в системный трей), сообщения обрабатываются успешно.

Вот мой сценарий. При прямом вызове SettingsDialog (без входа в системное меню) кнопки OK и Cancel работают, а в остальных случаях нет.

#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

person mydoghasworms    schedule 28.01.2014    source источник
comment
Я обсуждаю эту же проблему в ветке здесь: autoitscript.com/forum/topic/ . Если я разберусь с этим, я опубликую ответ здесь.   -  person mydoghasworms    schedule 28.01.2014
comment
Я большой автолюбитель и люблю SO, однако я признаю, что лучше сначала спросить там. Вы получите намного более быстрый ответ и, как правило, ответ, который решит вашу проблему. Я был на тех форумах в течение многих лет.   -  person Panama Jack    schedule 29.01.2014


Ответы (2)


Кажется, все в порядке, за исключением того, что вы должны что-то сделать после выхода из цикла Do/Until.

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

Я добавил 2 строки: ConsoleWrite после вызова GUIGetMessage и Return после цикла.

Когда я запускаю этот скрипт, диалоговое окно настроек закрывается правильно, нажав «ОК» или «Отмена».

person Andreas    schedule 29.01.2014
comment
Спасибо, это хорошее решение, так что +1. На форуме AutoIt я нашел другое решение, которое заключается в том, чтобы не удалять диалоговое окно каждый раз, а просто показывать и скрывать его, и это кажется предпочтительным. Большое спасибо за вашу помощь. - person mydoghasworms; 29.01.2014

Согласно решение предоставлено на форуме AutoIt, вот версия скрипта, которая скрывает и показывает диалоговое окно при каждом использовании. Есть большая оговорка (подробности читайте в ветке форума) в том, что при создании диалога он должен быть явно скрыт!

#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
person mydoghasworms    schedule 29.01.2014