注意:窗口標(biāo)題和窗口文本參數(shù)總是對大小寫敏感的。 1、等待窗口系列命令/函數(shù) AHK和AU3都提供了用法類似的一組窗口等待命令/函數(shù):WinWait/WinWaitActive/WinWaitClose。 它們分別用于等待窗口出現(xiàn)、等待窗口被激活、等待窗口被關(guān)閉。由于這些命令/函數(shù)的參數(shù)類似,現(xiàn)僅以WinWait為例說明。 AHK: WinWait [, 窗口標(biāo)題, 窗口文本, 超時(shí)時(shí)間, 排除標(biāo)題, 排除文本] AU3: WinWait ( "窗口標(biāo)題" [, "窗口文本" [, 超時(shí)時(shí)間]] ) WinWait 的作用是在目標(biāo)窗口出現(xiàn)之前不再執(zhí)行后面的所有語句。 假設(shè)我們要運(yùn)行記事本程序,并在其窗口出現(xiàn)時(shí)提示用戶: 【示例 3.1.1 】
AHK: Run Notepad WinWait, 無標(biāo)題 - 記事本 MsgBox 記事本窗口已被打開! AU3: Run("Notepad") WinWait("無標(biāo)題 - 記事本") MsgBox(0, "", "記事本窗口已被打開!")
2、激活窗口相關(guān)命令/函數(shù) 讓目標(biāo)窗口成為活動(dòng)窗口的辦法就是激活它,可用的命令/函數(shù)是WinActivate: AHK: WinActivate [,窗口標(biāo)題, 窗口文本, 排除標(biāo)題, 排除文本] AU3: WinActivate ( "窗口標(biāo)題" [, "窗口文本"] )
3、關(guān)閉窗口 關(guān)閉窗口有兩種方式,一種是正常的關(guān)閉窗口(WinClose),另一種則是強(qiáng)行關(guān)閉窗口(WinKill): AHK: WinClose/WinKill [,窗口標(biāo)題, 窗口文本, 超時(shí)時(shí)間,, 排除標(biāo)題, 排除文本] AU3: WinClose/WinKill ( "窗口標(biāo)題" [, "窗口文本"] )
現(xiàn)在我們已經(jīng)可以實(shí)現(xiàn)一個(gè)比較簡單的功能了,比如我們可以打開系統(tǒng)屬性窗口并等待其出現(xiàn),窗口出現(xiàn)后激活它,接著等待3秒再關(guān)閉它: 【示例 3.1.2 】
AHK: Run, Sysdm.cpl WinWait, 系統(tǒng)屬性 WinActivate, 系統(tǒng)屬性 WinWaitActive, 系統(tǒng)屬性 Sleep, 3000 WinClose, 系統(tǒng)屬性 WinWaitClose, 系統(tǒng)屬性 AU3: Run("Control Sysdm.cpl") WinWait("系統(tǒng)屬性") WinActivate("系統(tǒng)屬性") WinWaitActive("系統(tǒng)屬性") Sleep(3000) WinClose("系統(tǒng)屬性") WinWaitClose("系統(tǒng)屬性")
建議:如果程序中頻繁地出現(xiàn)要用到這些窗口標(biāo)題的地方,會(huì)帶來一個(gè)問題:腳本的可讀性,也許你會(huì)想,這不是很直觀嗎?可問題是如果這個(gè)重復(fù)出現(xiàn)的窗口標(biāo)題是個(gè)很長的字符串呢?這將嚴(yán)重影響整個(gè)代碼的排版美觀。而且我們也無從了解這些窗口標(biāo)題的“來頭”,不知道這個(gè)窗口標(biāo)題究竟是怎么來的。而如果我們定義一個(gè)變量(假設(shè)變量名是“AppWindow1”)保存這個(gè)窗口標(biāo)題,我們就能在命令/函數(shù)中用變量來表示它,這樣就達(dá)到了讓代碼用意更清晰一點(diǎn)的目的。另外,就算目標(biāo)軟件因某些原因(比如升級(jí))而改變了它的窗口標(biāo)題,我們也能很方便地作出修改。
4、更準(zhǔn)確的標(biāo)識(shí)窗口的方法(主要針對AHK腳本) 程序在運(yùn)行時(shí)起碼會(huì)有一個(gè)進(jìn)程,如果能獲得這個(gè)進(jìn)程ID就能在一定程度上保證對窗口的準(zhǔn)確標(biāo)識(shí)。另外,每個(gè)窗口都有定義窗口類名(Class,比如說記事本窗口的類名就是Notepad),所以我們可以以此排除與目標(biāo)窗口不同的其它窗口類。其實(shí),我們還有一個(gè)更準(zhǔn)確的方法: 每個(gè)窗口(包括控件在內(nèi))都被Windows指派了一個(gè)可區(qū)別于其它窗口的唯一的標(biāo)識(shí)符(ID),我們稱之為窗口句柄(HWND)。 直接給定窗口標(biāo)題來表示窗口的一個(gè)缺點(diǎn)就是無法保證在腳本運(yùn)行的過程中始終以該窗口為操作目標(biāo),因?yàn)樵谶@個(gè)過程中很有可能會(huì)有其它“同名”窗口(或者說滿足匹配條件的窗口)出現(xiàn),而如果我們使用這個(gè)標(biāo)識(shí)符來表示窗口自然就能保證命令/函數(shù)的操作窗口總是同一個(gè)窗口了。 我們先來了解一下獲得窗口句柄的命令/函數(shù): AHK: WinGet[, 輸出變量, ID, 窗口標(biāo)題, 窗口文本, 排除標(biāo)題, 排除文本] AU3: WinGetHandle ( "窗口標(biāo)題" [, "窗口文本"] ) 其中WinGet獲得的窗口ID將通過“輸出變量”返回,而WinGetHandle的返回值就是獲得的窗口ID。
我們在進(jìn)行自動(dòng)化操作時(shí)是要先運(yùn)行某個(gè)程序,如何獲得這個(gè)程序成功運(yùn)行后顯示的窗口句柄?一個(gè)比較保險(xiǎn)的辦法是先獲得這個(gè)程序的進(jìn)程ID,然后根據(jù)這個(gè)進(jìn)程ID獲得它的窗口句柄,AHK支持使用進(jìn)程ID作為窗口標(biāo)題使用;但AU3不支持這樣使用,只能先獲得該窗口的類名再根據(jù)該類名來獲得窗口句柄(不夠保險(xiǎn)): 【示例 3.1.3 】 AHK: Run, NotePad, , , ThisPID WinWait, ahk_pid %ThisPID%
;這里的ahk_pid表明跟在后面的變量是進(jìn)程ID WinGet, ThisID, ID, ahk_pid %ThisPID%
;ThisID將保存獲得的窗口句柄 AU3:
Opt("WinTitleMatchMode", 4) Run("Notepad") $handle = WinGetHandle("classname=Notepad") 現(xiàn)在暫且先忘記了AU3吧,因?yàn)樗拇翱诤瘮?shù)一般都不支持使用窗口句柄作為(窗口標(biāo)題)參數(shù)。 至于如何在AHK中使用窗口句柄,簡單的說,凡是有“窗口標(biāo)題”參數(shù)的命令就可以用窗口句柄來代替,比如: 【示例 3.1.4 】 AHK: Run, Notepad, , , ThisPID
;先獲得運(yùn)行的記事本程序的進(jìn)程ID WinWait, 無標(biāo)題 - 記事本 ahk_pid %ThisPID%
;等待該進(jìn)程窗口的出現(xiàn) WinGet, ThisHWND, ID, 無標(biāo)題 - 記事本 ahk_pid %ThisPID%
;獲得窗口句柄 WinActivate, ahk_id %ThisHWND% ;這里的ahk_id表明跟在后面的變量是窗口句柄 WinWaitActive, ahk_id %ThisHWND% Sleep, 3000 WinClose, ahk_id %ThisHWND% WinWaitClose, ahk_id %ThisHWND%
|