Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   AutoIt (http://forum.oszone.net/forumdisplay.php?f=103)
-   -   [решено] Режимы MessageLoop и OnEvent Mode (http://forum.oszone.net/showthread.php?t=183227)

saavaage 18-08-2010 01:24 1476019

Режимы MessageLoop и OnEvent Mode
 
Вопрос в различии между этими 2-мя режимами и их применением в ситуации, когда форма содержит Tab с вкладками и кнопками на каждой из них, а также общие кнопки для всей формы.

Изучил справку по этим 2-м режимам (rus). Но остался ряд вопросов:

1. OnEvent Mode прерывает выполнение скрипта на время выполнения события. В справке нет ответа как действует в этом случае MessageLoop?

2. Не совсем понятна фраза справки: "Обработка сообщений в режиме опроса требует обеспечения высокой скорости чтения вызовом GUIGetMsg и последующей обработки полученных сообщений. Иначе не все события будут обработаны." Что означает "высокой скорости чтения вызовом GUIGetMsg"? Значит ли это, что машина со старым процессором может отработать скрипт неполностью (особенно если в цикле много case)?

3. В справке указано, что MessageLoop, не смотря на цикл, не грузит процессор. Насколько я понял, OnEvent Mode, не является циклическим процессом и срабатывает только при активации пользователем. Логично предположить, что он также не грузит процессор. Я прав?

4. Для меня осталось не совсем понятно, в чем принципиальное отличие этих 2-х режимов? Они выполняют одну и туже функцию, без особой нагрузки на процессор... Какой режим когда лучше, в таком случае, применять? Какой из них менее ресурсоемкий и более надежный?

5. Если брать мой частный случай, то меня конкретно интересует следующее: если гуи-форма содержит много кнопок на разных вкладках + общие кнопки, то как будет лучше действовать:

- использовать вариант MessageLoop - для общих кнопок, а вариант OnEvent Mode - для кнопок на конкретной вкладке
- лучше использовать только вариант MessageLoop
- лучше использовать только вариант OnEvent Mode
- все равно

Если можно, прокомментируйте свои ответы (особенно на вопрос #5).

Заранее благодарю за помощь.

Creat0R 18-08-2010 02:55 1476042

Немного по теме: http://autoit-script.ru/index.php/topic,459.0.html
Цитата:

Цитата saavaage
как действует в этом случае MessageLoop? »

Смотря что в нём происходит, если дополнительный цикл, тогда будет также останавливать.

Цитата:

Цитата saavaage
Значит ли это, что машина со старым процессором может отработать скрипт неполностью »

Не сталкивался с подобным, не должно оно влиять. В любом случае GUIGetMsg содержит в себе паузу примерно в 10 мс, поэтому добавлять паузы в цикл больше не нужно.

Цитата:

Цитата saavaage
В справке указано, что MessageLoop, не смотря на цикл, не грузит процессор »

Ну если в цикле нет паузы (Sleep) и не опрашивается с GUIGetMsg, то нагрузка будет).

Цитата:

Цитата saavaage
Логично предположить, что он также не грузит процессор. Я прав? »

Логично, событие вызывается при неком действий, а цикл проверяет всегда (если скрипт не блокируется функцией).

Цитата:

Цитата saavaage
Какой из них менее ресурсоемкий и более надежный? »

Вместе не получится, нужно разделить два этих критерия :) MessageLoop надёжнее в плане удобства и доступности, но в то же время он может быть ресурсоёмким. А режим OnEvent он более сложный для работы с многими окнами и элементами, однако ресурсов в большинстве случаев потребляет меньше... хотя это всё поддаётся сравнению, прочитайте тему по ссылке что я привёл в начале, там это расписано.

Цитата:

Цитата saavaage
использовать вариант MessageLoop - для общих кнопок, а вариант OnEvent Mode - для кнопок на конкретной вкладке »

Это как? :) совмещать режимы для одного GUI не получится.

Цитата:

Цитата saavaage
лучше использовать только вариант MessageLoop »

Если нет дочерних окон, то да.

Цитата:

Цитата saavaage
лучше использовать только вариант OnEvent Mode »

Если есть дочерние окна которые создаются по запросу (по кнопке, в функций к примеру).

Цитата:

Цитата saavaage
все равно »

Можно и так :unsure:

saavaage 18-08-2010 11:20 1476231

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

Creat0R 18-08-2010 17:32 1476475

Цитата:

Цитата saavaage
Есть еще один вопрос по форме с вкладками »

Этот вопрос заслуживает отдельной темы (где не помешало бы выложить пример этой самой формы).

saavaage 18-08-2010 20:27 1476583

Creat0R, так и сделаю

Creat0R 18-08-2010 20:30 1476585

Цитата:

Цитата saavaage
так и сделаю »

Эта тема решена?

saavaage 18-08-2010 20:34 1476587

Creat0R, так точно, сэр :-). Закрываю.

saavaage 21-08-2010 01:16 1478403

Creat0R, извините, но обнаружил на русском форуме Autoit Ваше высказывание на тему MessageLoop vs OnEvent Mode:
пост http://autoit-script.ru/index.php/topic,459.0.html
цитата: "Это всё зависит от поставленной задачи. Иногда лучше использовать MessageLoop (например если некие элементы вызывают дочернее окно которое также требует обработку событий), а иногда лучше OnEvent. "

Оно противоречит Вашему ответу в текущем посте:
Цитата:

Цитата Creat0R
лучше использовать только вариант MessageLoop »
Если нет дочерних окон, то да. »

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

Спасибо

Creat0R 21-08-2010 04:36 1478430

Цитата:

Цитата saavaage
Оно противоречит Вашему ответу в этом посте »

И в чём же противоречие? и там и там я пишу про то что в неких ситуациях лучше использовать «MessageLoop».

Цитата:

Цитата saavaage
я планирую делать подчиненное окно с настройками утилиты »

Вариант с MessageLoop:
Код:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

#Region Main GUI
$hMain_GUI = GUICreate("My Program", 500, 300)
$nMain_Exit_Button = GUICtrlCreateButton("Exit", 20, 270, 60, 20)
$nMain_Settings_Button = GUICtrlCreateButton("Settings", 90, 270, 60, 20)
GUISetState(@SW_SHOW, $hMain_GUI)
#EndRegion Main GUI

#Region Settings GUI
$hSettings_GUI = GUICreate("Settings", 400, 250, -1, -1, -1, -1, $hMain_GUI)
$nStngs_Close_Button = GUICtrlCreateButton("Close", 20, 220, 60, 20)
$nStngs_Save_Button = GUICtrlCreateButton("Save", 90, 220, 60, 20)
#EndRegion Settings GUI

While 1
    $nMsg = GUIGetMsg(1)

    Switch $nMsg[0]
        Case $GUI_EVENT_CLOSE, $nStngs_Close_Button, $nMain_Exit_Button
            If $nMsg[1] = $hSettings_GUI Then
                GUISetState(@SW_ENABLE, $hMain_GUI)
                GUISetState(@SW_HIDE, $hSettings_GUI)
            Else
                Exit
            EndIf
        Case $nMain_Settings_Button
            GUISetState(@SW_DISABLE, $hMain_GUI)
            GUISetState(@SW_SHOW, $hSettings_GUI)
        Case $nStngs_Save_Button
            MsgBox(64, 'Title', 'Settings saved!', 0, $hSettings_GUI)
    EndSwitch
WEnd

Вариант с OnEvent:
Код:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Opt("GUIOnEventMode", 1)

#Region Main GUI
$hMain_GUI = GUICreate("My Program", 500, 300)
$nMain_Exit_Button = GUICtrlCreateButton("Exit", 20, 270, 60, 20)
$nMain_Settings_Button = GUICtrlCreateButton("Settings", 90, 270, 60, 20)

GUICtrlSetOnEvent($nMain_Exit_Button, "_MainGUI_Events")
GUICtrlSetOnEvent($nMain_Settings_Button, "_MainGUI_Events")
GUISetOnEvent($GUI_EVENT_CLOSE, "_MainGUI_Events", $hMain_GUI)

GUISetState(@SW_SHOW, $hMain_GUI)
#EndRegion Main GUI

#Region Settings GUI
$hSettings_GUI = GUICreate("Settings", 400, 250, -1, -1, -1, -1, $hMain_GUI)
$nStngs_Close_Button = GUICtrlCreateButton("Close", 20, 220, 60, 20)
$nStngs_Save_Button = GUICtrlCreateButton("Save", 90, 220, 60, 20)

GUICtrlSetOnEvent($nStngs_Close_Button, "_SettingsGUI_Events")
GUICtrlSetOnEvent($nStngs_Save_Button, "_SettingsGUI_Events")
GUISetOnEvent($GUI_EVENT_CLOSE, "_SettingsGUI_Events", $hSettings_GUI)
#EndRegion Settings GUI

While 1
    Sleep(100)
WEnd

Func _MainGUI_Events()
    Switch @GUI_CtrlId
        Case $GUI_EVENT_CLOSE, $nMain_Exit_Button
            Exit
        Case $nMain_Settings_Button
            GUISetState(@SW_DISABLE, $hMain_GUI)
            GUISetState(@SW_SHOW, $hSettings_GUI)
    EndSwitch
EndFunc

Func _SettingsGUI_Events()
    Switch @GUI_CtrlId
        Case $GUI_EVENT_CLOSE, $nStngs_Close_Button
            GUISetState(@SW_ENABLE, $hMain_GUI)
            GUISetState(@SW_HIDE, $hSettings_GUI)
        Case $nStngs_Save_Button
            MsgBox(64, 'Title', 'Settings saved!', 0, $hSettings_GUI)
    EndSwitch
EndFunc

Хотя я лично предпочитаю в таком случае создавать GUI в функций, и временно изменить с OnEvent на MessageLoop, так мне кажется удобнее, тем более что так меньше ресурсов потребляет:
Подробнее
Код:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Opt("GUIOnEventMode", 1)

#Region Main GUI

$hMain_GUI = GUICreate("My Program", 500, 300)
$nExit_Button = GUICtrlCreateButton("Exit", 20, 270, 60, 20)
$nSettings_Button = GUICtrlCreateButton("Settings", 90, 270, 60, 20)

GUICtrlSetOnEvent($nExit_Button, "_MainGUI_Events")
GUICtrlSetOnEvent($nSettings_Button, "_MainGUI_Events")
GUISetOnEvent($GUI_EVENT_CLOSE, "_MainGUI_Events", $hMain_GUI)
GUISetState(@SW_SHOW, $hMain_GUI)

#EndRegion Main GUI

While 1
    Sleep(100)
WEnd

Func _MainGUI_Events()
    Switch @GUI_CtrlId
        Case $GUI_EVENT_CLOSE, $nExit_Button
            Exit
        Case $nSettings_Button
            _Settings_GUI($hMain_GUI)
    EndSwitch
EndFunc

Func _Settings_GUI($hParent)
    Local $iOpt_GOEM, $hSettings_GUI, $nStngs_Close_Button, $nStngs_Save_Button

    $iOpt_GOEM = Opt("GUIOnEventMode", 0)

    $hSettings_GUI = GUICreate("Settings", 400, 250, -1, -1, -1, -1, $hParent)
    $nStngs_Close_Button = GUICtrlCreateButton("Close", 20, 220, 60, 20)
    $nStngs_Save_Button = GUICtrlCreateButton("Save", 90, 220, 60, 20)

    GUISetState(@SW_DISABLE, $hParent)
    GUISetState(@SW_SHOW, $hSettings_GUI)

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE, $nStngs_Close_Button
                ExitLoop
            Case $nStngs_Save_Button
                MsgBox(64, 'Title', 'Settings saved!', 0, $hSettings_GUI)
        EndSwitch
    WEnd

    GUISetState(@SW_ENABLE, $hParent)
    GUISetState(@SW_HIDE, $hSettings_GUI)

    Opt("GUIOnEventMode", $iOpt_GOEM)
EndFunc



Выбирай :)

saavaage 21-08-2010 04:47 1478432

Creat0R, большое спасибо (особенно за 3 вариант)

PS противоречие было в том, что в первой цитате Вы рекомендовали использовать MessageLoop с дочерними окнами, а во-второй, наоборот, если нет дочерних окон.

Не заглянете в тему http://forum.oszone.net/thread-182740.html ? Там у нас небольшая проблема возникла с ограничением вывода инфо в ListViewItem

Creat0R 21-08-2010 05:58 1478434

Цитата:

Цитата saavaage
противоречие было в том, что в первой цитате Вы рекомендовали использовать MessageLoop с дочерними окнами, а во-второй, наоборот, если нет дочерних окон. »

Там речь шла про события, это именно тот случай когда «всё зависит от поставленной задачи» ;).

Цитата:

Цитата saavaage
Не заглянете в тем »

Заглянул :)


Время: 07:41.

Время: 07:41.
© OSzone.net 2001-