Съобщенията в диалоговия прозорец не се обработват при отваряне на диалогов прозорец от запис в системната област

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

От друга страна, при директно отваряне на диалоговия прозорец (както е посочено в кода по-долу, който можете лесно да тествате, като премахнете коментарите от това извикване и коментирате извикването за записа в системната област), тогава съобщенията се обработват успешно.

Ето моят сценарий. Когато извиквате SettingsDialog директно (без да преминавате през менюто на системната лента), бутоните OK и Отказ работят, но иначе не.

#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
Аз съм голям човек на autoit и обичам, така че ще призная, че е най-добре първо да попитате там. Ще получите много по-бърз отговор и обикновено отговор, който решава проблема ви. В тези форуми съм от години.   -  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 след цикъла.

Когато стартирам този скрипт, диалоговият прозорец за настройки се затваря правилно чрез щракване върху „Ok“ или „Отказ“.

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