在 OnEvent(事件驅(qū)動(dòng))模式下,腳本并不需要頻繁地要求GUI檢查是否有任何事件發(fā)生(并根據(jù)返回信息處理事件),而是僅當(dāng)某個(gè)事件發(fā)生時(shí)GUI才臨時(shí)性暫停腳本并調(diào)用一個(gè)用戶預(yù)定義的函數(shù)來(lái)處理該事件。例如,假定用戶點(diǎn)擊了按鈕1則GUI將暫停主腳本并調(diào)用某個(gè)預(yù)定義的用戶函數(shù)來(lái)處理按鈕1事件。當(dāng)該函數(shù)完成處理操作后才回到主腳本繼續(xù)執(zhí)行。這個(gè)模式比較類似 Visual Basic 的窗體方法。
當(dāng)GUI被執(zhí)行時(shí),主腳本還可以做其它一般性工作,但為了演示方便我們只是讓主腳本在一個(gè)無(wú)限While循環(huán)里“睡眠”一下。
因?yàn)橄⒀h(huán)是默認(rèn)的模式,所以在應(yīng)用 OnEvent 模式之前我們應(yīng)該先使用 Opt("GUIOnEventMode", 1) 語(yǔ)句。
下面是 OnEvent 的基本結(jié)構(gòu):
While 1
Sleep(1000) ; 閑置工作,不做任何事
WEnd
Func Event1()
; 處理事件的代碼放在這里
EndFunc
Func Event2()
; 處理事件的代碼放在這里
EndFunc
在 OnEvent 模式下會(huì)產(chǎn)生兩種“事件”:
這兩種事件類型發(fā)生時(shí)都將調(diào)用用戶預(yù)先定義的函數(shù),這些函數(shù)可以是為GUI(窗口)設(shè)置的(GUISetOnEvent)或者為控件設(shè)置的(GUICtrlSetOnEvent)。如果某事件并沒有預(yù)先定義相應(yīng)的處理函數(shù)則該事件將被忽略。在這些被調(diào)用的函數(shù)內(nèi)部可使用各種 宏 以助處理事件:
宏 |
說(shuō)明 |
@GUI_CTRLID | 發(fā)送消息的控件ID 或者 系統(tǒng)事件ID |
@GUI_WINHANDLE | 發(fā)送消息的GUI(窗口)句柄 |
@GUI_CTRLHANDLE | 發(fā)送消息的控件句柄(如果適用) |
注意:使用同一個(gè)函數(shù)來(lái)響應(yīng)多種事件是完全合法的,記住要靈活使用 @GUI_CTRLID 這個(gè)宏。比如說(shuō),您可以注冊(cè)所有系統(tǒng)事件到同一個(gè)函數(shù)。
控件
當(dāng)某個(gè)控件被點(diǎn)擊或該控件有其它變化時(shí)將發(fā)送控件事件。該事件將被傳遞到由 GUICtrlSetOnEvent 定義的函數(shù)中。在這個(gè)函數(shù)里,@GUI_CTRLID 的值是發(fā)送消息的 控件ID(也即使用 GUICtrlCreate... 函數(shù)創(chuàng)建該控件時(shí)的返回值)。
系統(tǒng)事件
系統(tǒng)事件包括GUI(窗口)被關(guān)閉等在內(nèi),它們以類似于控件事件的方式被發(fā)送出去,而事件類型(ID)則由 @GUI_CTRLID 指示。系統(tǒng)事件將被傳遞到由 GUISetOnEvent 定義的函數(shù)中。可能的系統(tǒng)事件包括:
$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 相關(guān) 的頁(yè)面上我們?cè)帉戇^(guò)一個(gè)簡(jiǎn)單的窗口:
#include <GUIConstants.au3>
GUICreate("您好", 200, 100)
GUICtrlCreateLabel("最近過(guò)得怎樣?", 30, 10)
GUICtrlCreateButton("還OK吧", 70, 50, 60)
GUISetState(@SW_SHOW)
Sleep(2000)
現(xiàn)在我們來(lái)嘗試使用 OnEvent 以及上面描述的事件消息來(lái)完成全部代碼:
#include <GUIConstants.au3>
Opt("GUIOnEventMode", 1) ; 切換為 OnEvent 模式
$mainwindow = GUICreate("您好", 200, 100) ; 創(chuàng)建窗口并返回窗口句柄
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked") ; 設(shè)置窗口關(guān)閉事件
GUICtrlCreateLabel("最近過(guò)得怎樣?", 30, 10)
$okbutton = GUICtrlCreateButton("還OK吧", 70, 50, 60)
GUICtrlSetOnEvent($okbutton, "OKButton")
GUISetState(@SW_SHOW)
While 1
Sleep(1000) ; 不做任何事
WEnd
Func OKButton()
;注意:此時(shí) @GUI_CTRLID 的值將等價(jià)于 $okbutton,
;而 @GUI_WINHANDLE 則等價(jià)于 $mainwindow
MsgBox(0, "GUI 事件", "您按下了“還OK吧”按鈕!")
EndFunc
Func CLOSEClicked()
;注意:此時(shí) @GUI_CTRLID 的值將等價(jià)于 $GUI_EVENT_CLOSE,
;而 @GUI_WINHANDLE 則等價(jià)于 $mainwindow
MsgBox(0, "GUI 事件", "您選擇了關(guān)閉!正在退出...")
Exit
EndFunc
很簡(jiǎn)單,對(duì)吧?很明顯創(chuàng)建的窗口及控件越多則腳本越復(fù)雜,但基本結(jié)構(gòu)都是類似上面的這個(gè)示例。
即使有很多窗口存在,控件 ID 也是唯一的,但是我們?nèi)绾翁幚矶啻翱谀兀?/p>
下面這個(gè)示例腳本和上面的很像,但多出了一個(gè)“dummy(虛設(shè)的)”窗口。
#include <GUIConstants.au3>
Opt("GUIOnEventMode", 1) ; 切換為 OnEvent 模式
$mainwindow = GUICreate("您好", 200, 100)
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")
GUICtrlCreateLabel("最近過(guò)得怎樣?", 30, 10)
$okbutton = GUICtrlCreateButton("還OK吧", 70, 50, 60)
GUICtrlSetOnEvent($okbutton, "OKButton")
$dummywindow = GUICreate(" 這只是測(cè)試用的虛設(shè)窗口,并不會(huì)被顯示 ", 200, 100)
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")
GUISwitch($mainwindow)
GUISetState(@SW_SHOW)
While 1
Sleep(1000) ; 不做任何事
WEnd
Func OKButton()
;注意:此時(shí) @GUI_CTRLID 的值將等價(jià)于 $okbutton
MsgBox(0, "GUI 事件", "您按下了“還OK吧”按鈕!")
EndFunc
Func CLOSEClicked()
;注意:此時(shí) @GUI_CTRLID 的值將等價(jià)于 $GUI_EVENT_CLOSE,
;而 @GUI_WINHANDLE 則等價(jià)于 $mainwindow 或 $dummywindow
If @GUI_WINHANDLE = $mainwindow Then
MsgBox(0, "GUI 事件", "您選擇了關(guān)閉主窗口!正在退出...")
Exit
EndIf
EndFunc
第一個(gè)需要注意的變動(dòng)是上面的腳本增加了一個(gè) GUISwitch 函數(shù)的調(diào)用,當(dāng)新的窗口被創(chuàng)建之后該窗口即變成后面所有GUI操作(包括創(chuàng)建控件在內(nèi))的“默認(rèn)”窗口,也就是說(shuō)這些GUI操作的對(duì)象都會(huì)是這個(gè)默認(rèn)窗口。但我們希望顯示的是主窗口(首先被創(chuàng)建的窗口)而不是那個(gè)測(cè)試窗口,這時(shí)就要使用 GUISwitch 函數(shù)來(lái)切換操作對(duì)象。某些GUI函數(shù)允許您在調(diào)用它們時(shí)使用窗口句柄(參數(shù))來(lái)指定操作目標(biāo),同時(shí)也將自動(dòng)切換該目標(biāo)窗口為“默認(rèn)窗口”。所以在這個(gè)示例中,我們還可以改用這樣的語(yǔ)句:
GUISetState(@SW_SHOW, $mainwindow)
另外要注意的就是我們使用了同一個(gè) OnEvent 函數(shù)來(lái)處理兩個(gè)窗口的“關(guān)閉”事件,為了識(shí)別被關(guān)閉的窗口究竟是哪一個(gè)我們還使用了 @GUI_WINHANDLE 來(lái)檢查發(fā)送消息的窗口句柄。這樣處理之后我們就可以確保在窗口的關(guān)閉按鈕被點(diǎn)擊 而且 消息是從主窗口發(fā)送的時(shí)候才退出GUI了。當(dāng)然了,您也可以為每個(gè)窗口指定不同的事件處理函數(shù)。