В режиме MessageLoop (цикла опроса GUI) ваш скрипт большую часть своего времени будет тратить в цикле. Этот цикл просто опрашивает GUI используя функцию GUIGetMsg. Когда произошло событие, функция GUIGetMsg возвращает значение (нажатие кнопки, закрытие GUI, и т.д.).
По умолчанию используется режим MessageLoop (цикл опроса GUI), другой возможный режим - OnEvent (по событию).
В режиме MessageLoop (цикла опроса GUI) вы получаете сообщения только в случае активного опроса элементов управления функцией GUIGetMsg, таким образом вы должны убедится, что вызываете функцию довольно часто (более 20-ти раз в секунду), иначе ваш GUI не будет откликаться на взаимодействие с элементами управления.
Основной формат MessageLoop (цикла опроса GUI) выглядит так:
While 1
$msg = GUIGetMsg()
...
...
WEnd
Обычно выполнение цикла приводит к загруженности процессора (CPU) до 100%, к счастью функция GUIGetMsg приводит процессор (CPU) в бездействие, при отсутствии ожидаемых событий. Не нужно самостоятельно вставлять функцию Sleep в цикл из-за страха перегрузить CPU, это только приведёт к тому, что GUI перестанет откликаться на взаимодействие с элементами управления.
Существует три типа сообщения при событии, возвращаемых функцией GUIGetMsg:
Нет событий
Если нет ожидаемых для обработки событий, то GUIGetMsg возвращает 0. Обычно в GUI это наиболее частый случай.
Событие от элементов управления
При клике на элементах управления или при их изменении, высылается сообщение, и оно является положительным числом, соответствующим идентификатору элемента управления controlID, возвращаемым функцией GUICtrlCreate... при создании элементов.
Системное событие
Системное событие - такое, как закрытие GUI - являются отрицательным числом. Разные события такого вида показаны ниже и их значения определены в GUIConstantsEx.au3:
$GUI_EVENT_CLOSE
$GUI_EVENT_MINIMIZE
$GUI_EVENT_RESTORE
$GUI_EVENT_MAXIMIZE
$GUI_EVENT_PRIMARYDOWN
$GUI_EVENT_PRIMARYUP
$GUI_EVENT_SECONDARYDOWN
$GUI_EVENT_SECONDARYUP
$GUI_EVENT_MOUSEMOVE
$GUI_EVENT_RESIZED
$GUI_EVENT_DROPPED
На главной странице Описание GUI мы начали делать простой пример "Привет Мир", который выглядел следующим образом:
#include <GUIConstantsEx.au3>
GUICreate("Привет Мир", 200, 100)
GUICtrlCreateLabel("Привет Мир! Как дела?", 30, 10)
GUICtrlCreateButton("OK", 70, 50, 60)
GUISetState(@SW_SHOW)
Sleep(2000)
Теперь мы завершим код, используя режим MessageLoop (цикл опроса GUI) и некоторые сообщения от событий, описанных выше. Используем оператор Switch для удобочитаемости, это обычно из-за большого количества возможных сообщений.
#include <GUIConstantsEx.au3>
Local $hGUI = GUICreate("Привет Мир", 200, 100)
GUICtrlCreateLabel("Привет Мир! Как дела?", 30, 10)
Local $iOKButton = GUICtrlCreateButton("OK", 70, 50, 60)
GUISetState(@SW_SHOW, $hGUI)
Local $iMsg
While 1
$iMsg = GUIGetMsg()
Switch $iMsg
Case $iOKButton
MsgBox(0, "Событие GUI", "Вы нажали OK!")
Case $GUI_EVENT_CLOSE
MsgBox(0, "Событие GUI", "Вы нажали ЗАКРЫТЬ ! Завершаем...")
ExitLoop
EndSwitch
WEnd
GUIDelete($hGUI)
Это очень простой пример. Очевидно, что чем больше окон и элементов управления вы используете, тем сложнее он становится, но выше указанное показывает вам основу.
Идентификатор элементов управления (ID) являются уникальным, даже если у вас есть несколько окон, поэтому вышеприведенный код прекрасно работает с элементами управления и с несколькими окнами. Тем не менее, при обработке событий таких как $GUI_EVENT_CLOSE или $GUI_MOUSEMOVE вы должны знать, какое GUI-окно вызвало событие. Для этого вы должны вызвать GUIGetMsg таким образом:
При вызове с параметром 1 вместо возвращаемого события возвращается массив, который содержит событие (в $aMsg[0]), а также дополнительную информацию, например, дескриптор окна (в $aMsg[1]). Если бы два окна были созданы в предыдущем примере, то правильный способ написания кода будет выглядеть так:
#include <GUIConstantsEx.au3>
Local $hMainGUI = GUICreate("Привет Мир", 200, 100)
GUICtrlCreateLabel("Привет Мир! Как дела?", 30, 10)
Local $iOKButton = GUICtrlCreateButton("OK", 70, 50, 60)
Local $hDummyGUI = GUICreate("Окно для теста", 200, 100)
GUISwitch($hMainGUI)
GUISetState(@SW_SHOW)
Local $aMsg
While 1
$aMsg = GUIGetMsg(1)
Select
Case $aMsg[0] = $iOKButton
MsgBox(0, "Событие GUI", "Вы нажали OK!")
Case $aMsg[0] = $GUI_EVENT_CLOSE And $aMsg[1] = $hMainGUI
MsgBox(0, "Событие GUI", "Вы нажали ЗАКРЫТЬ в главном окне! Завершаем...")
ExitLoop
EndSelect
WEnd
Первым заметным изменением является вызов функции GUISwitch - когда создается новое окно, оно становится "по умолчанию" для будущих операций с GUI (в том числе создание элементов управления). В нашем случае мы хотим работать с главным окном "Привет Мир", а не в тестовом окне, таким образом мы "переключаем". Некоторые функции GUI позволяют использовать дескриптор окна в своих параметрах - эти функции переключают автоматически. В нашем примере мы можем сделать это с помощью:
GUISetState(@SW_SHOW, $mainwindow)
Следующим различием является способ вызова GUIGetMsg для проверки событий - заметьте использование $aMsg[0] и $aMsg[1] - теперь у нас единственный способ завершить скрипт, если произойдёт событие выхода и это событие вызвано из нашего основного окна скрипта.