在OnEvent模式下, 腳本并不需要頻繁地要求 GUI 檢查是否有任何事件發(fā)生(并根據(jù)返回信息處理事件),
而是僅當(dāng)某個事件發(fā)生時, GUI 才臨時性暫停腳本, 并調(diào)用一個用戶預(yù)定義的函數(shù)來處理該事件.
例如, 假定用戶點擊了按鈕1, 則 GUI 將暫停主腳本并調(diào)用某個預(yù)定義的用戶函數(shù)來處理按鈕1事件.
當(dāng)該函數(shù)完成處理操作后才回到主腳本繼續(xù)執(zhí)行.這個模式比較類似 Visual Basic 的窗體方法.
當(dāng)GUI被執(zhí)行時, 主腳本還可以做其它一般性工作,
但為了演示方便, 我們只是讓主腳本“閑置”在一個無限 While 循環(huán)里.
因為消息循環(huán)是默認(rèn)的模式,所以在應(yīng)用 OnEvent 模式之前我們應(yīng)該先使用 Opt("GUIOnEventMode", 1) 語句切換默認(rèn)模式
OnEvent 代碼的常規(guī)格結(jié)構(gòu):
While 1
Sleep(1000) ; 閑置,不做任何事
WEnd
Func Event1()
; 這里放置事件 1 的處理代碼
EndFunc
Func Event2()
; 這里放置事件 2 的處理代碼
EndFunc
在 OnEvent 模態(tài)中, GUI 將會產(chǎn)生下列"事件":
這兩種類型事件發(fā)生時, 都將調(diào)用用戶預(yù)先定義的函數(shù).
這些函數(shù)可以是為 GUI 定義的 (GUISetOnEvent); 也可以是為控件定義的 (GUICtrlSetOnEvent).
如果某事件沒有預(yù)先定義相應(yīng)的處理函數(shù), 則該事件被忽略. 這些被調(diào)用的函數(shù)內(nèi)部可使用各種宏以幫助處理事件.
宏指令 | 描述 |
@GUI_CTRLID | 發(fā)送消息的控件 ID 或系統(tǒng)事件 ID. |
@GUI_WINHANDLE | 發(fā)送消息的 GUI 句柄. |
@GUI_CTRLHANDLE | 發(fā)送消息的控件句柄(如果適用). |
注意: 使用同一函數(shù)響應(yīng)多種事件是完全合法的,記住要靈活使用 @GUI_CTRLID 這個宏.
例如您可以注冊所有系統(tǒng)事件到同一個用戶處理函數(shù).
控件事件
當(dāng)控件被點擊或該控件有其它變化時將發(fā)送控件事件. 該事件將被發(fā)送到 GUICtrlSetOnEvent 定義的函數(shù)中.
在用戶自定義函數(shù)內(nèi)部, @GUI_CTRLID 為設(shè)定為返回控件 ID 值.
也就是使用 GUICtrlCreate... 函數(shù)創(chuàng)建該控件時的返回值.
系統(tǒng)事件
包括 GUI 關(guān)閉等的系統(tǒng)事件, 以類似控件事件的方式發(fā)送,但事件類型則由 @GUI_CTRLID 定義.
系統(tǒng)事件發(fā)送到 GUISetOnEvent 定義的函數(shù)中. 系統(tǒng)事件的可能值如下所示(與消息模式完全相同):
$GUI_EVENT_CLOSE ---------- 窗口關(guān)閉
$GUI_EVENT_MINIMIZE ------- 窗口最小化
$GUI_EVENT_RESTORE -------- 窗口還原
$GUI_EVENT_MAXIMIZE ------- 窗口最大化
$GUI_EVENT_PRIMARYDOWN ---- 鼠標(biāo)左鍵按下
$GUI_EVENT_PRIMARYUP ------ 鼠標(biāo)左鍵釋放
$GUI_EVENT_SECONDARYDOWN -- 鼠標(biāo)右鍵按下
$GUI_EVENT_SECONDARYUP ---- 鼠標(biāo)右鍵釋放
$GUI_EVENT_MOUSEMOVE ------ 鼠標(biāo)移動
$GUI_EVENT_RESIZED -------- 調(diào)整大小
$GUI_EVENT_DROPPED -------- 拖動操作
在 GUI 概論 頁面上我們曾編寫過一個簡單的窗口:
#include <GUIConstantsEx.au3>
GUICreate("您好,世界", 200, 100)
GUICtrlCreateLabel("您好,世界! 你過得怎么樣?", 30, 10)
GUICtrlCreateButton("確定", 70, 50, 60)
GUISetState(@SW_SHOW)
Sleep(2000)
現(xiàn)在我們來嘗試使用 OnEvent 以及上面描述的事件來完成全部代碼.
#include <GUIConstantsEx.au3>
Opt("GUIOnEventMode", 1) ; 切換到 OnEvent 模式
$mainwindow = GUICreate("您好,世界", 200, 100)
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")
GUICtrlCreateLabel("您好,世界! 你過得怎么樣?", 30, 10)
$okbutton = GUICtrlCreateButton("確定", 70, 50, 60)
GUICtrlSetOnEvent($okbutton, "OKButton")
GUISetState(@SW_SHOW)
While 1
Sleep(1000) ; 閑置,不做任何事
WEnd
Func OKButton()
;注意: 此時 @GUI_CTRLID 的值等于 $okbutton,
;而 @GUI_WINHANDLE 則等于 $mainwindow
MsgBox(0, "GUI 事件", "你點擊了 '確定'!")
EndFunc
Func CLOSEClicked()
;注意: 此時 @GUI_CTRLID 等于 $GUI_EVENT_CLOSE,
;而 @GUI_WINHANDLE 等于 $mainwindow
MsgBox(0, "GUI 事件", "您選擇了關(guān)閉窗口!正在退出...")
Exit
EndFunc
就這么簡單. 很明顯的, 創(chuàng)建的窗口及控件越多則腳本越復(fù)雜, 但基本結(jié)構(gòu)都是類似上面的這個示例.
即使有很多窗口存在, 控件 ID 也是唯一的. 但是我們?nèi)绾翁幚矶啻翱谀?
下面這個示例腳本和上面的很像, 但多出了一個"dummy"(虛擬)窗口.
#include <GUIConstantsEx.au3>
Opt("GUIOnEventMode", 1) ; 切換到 OnEvent 模式
$mainwindow = GUICreate("您好,世界", 200, 100)
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")
GUICtrlCreateLabel("您好,世界! 你過得怎么樣?", 30, 10)
$okbutton = GUICtrlCreateButton("確定", 70, 50, 60)
GUICtrlSetOnEvent($okbutton, "OKButton")
$dummywindow = GUICreate("用于測試的虛擬窗口,不會顯示 ", 200, 100)
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")
GUISwitch($mainwindow)
GUISetState(@SW_SHOW)
While 1
Sleep(1000) ; 閑置,不做任何事
WEnd
Func OKButton()
;注意: 此時 @GUI_CTRLID 等于 $okbutton
MsgBox(0, "GUI 事件", "你點擊了 '確定'!")
EndFunc
Func CLOSEClicked()
;注意: 此時 @GUI_CTRLID 等于 $GUI_EVENT_CLOSE,
;@GUI_WINHANDLE 則可能等于 $mainwindow, 也可能等于 $dummywindow
If @GUI_WINHANDLE = $mainwindow Then
MsgBox(0, "GUI 事件", "您選擇了關(guān)閉主窗口!正在退出...")
Exit
EndIf
EndFunc
第一個主要變化是 GUISwitch 函數(shù)的調(diào)用.
當(dāng)新的窗口被創(chuàng)建之后, 該窗口即成為后面所有 GUI 操作(包括創(chuàng)建控件)的“默認(rèn)”工作窗口,
也就是說這些 GUI 操作的對象都會是這個默認(rèn)窗口.
現(xiàn)在要處理的是"您好,世界"的窗口, 而不是那個虛擬測試窗口, 這時就要使用 GUISwitch 函數(shù)來切換操作對象.
某些 GUI 函數(shù)允許調(diào)用時使用窗口句柄指定操作目標(biāo), 同時也將自動切換該目標(biāo)窗口為"默認(rèn)窗口".
所以在這個示例中, 我們可以改用這樣的語句:
GUISetState(@SW_SHOW, $mainwindow)
另外要注意, 我們使用了同一個 OnEvent 函數(shù)來處理兩個窗口的 "close" 關(guān)閉事件,
然后使用 @GUI_WINHANDLE 來檢查發(fā)送消息的窗口句柄.
這樣處理之后, 可以確保窗口關(guān)閉事件是主窗口發(fā)送的時候才退出 GUI.
當(dāng)然, 您也可以為每個窗口指定不同的事件處理函數(shù).
provider with jb51.net (unicode) |