程序是用AutoHotkey語言寫的,
說明:
以自己使用頻率的順序在ExeList自定義的程序間切換
切換可以以所有窗口切換,也可以按程序組切換(比如在word窗口間切換)
程序組可以分別定義排除的窗口(比如想激活QQ聊天界面,但是想排除QQ主窗口)
切換順序:
如果當前激活程序在列表內,並有多個同類程序,則優先切換到同類窗口(比如打開多個word)
否則切換到ExeList里按順序第一個找到的窗口
使用方法:
按熱鍵后繼續按Tab鍵則在所有匹配的窗口間切換,按應用熱鍵則切換到程序窗口,按其他任意虛擬按鍵則腳本退出
各程序可以分別設置熱鍵,比如Word設置為W,Excel設置為E,按W就可以切換到Word組,繼續按W,會在Word窗口間切換
要求:
在應用程序名后面增加\加標題名,增加排除的標題名,比如QQ.exe排除標題為abc的窗口,則寫QQ.exe\abc
在應用程序名后面增加&字母,則為給該類應用增加熱鍵,否則默認為程序名第一個字母
示例:每個應用程序格式QQ.exe\QQ&Q,因為QQ.exe第一個字母為Q,最后的&Q可省略,各應用之間用|隔開
下載:http://files.cnblogs.com/files/hyaray/WinTab.7z
#Tab:: ;特定窗口間切換 ExeList := "excel.exe|WINWORD.EXE|PotPlayerMini64.exe|Xmind.exe|Foxit_Reader.exe" ;前面的窗口優先,別忘了.exe后綴 ;看當前窗口是否在列表里,如果在,則標記InList = 1,並移動到列表第一項 WinGet, pn, ProcessName, A ;獲取當前窗口應用名,如notepad.exe InList := InStr(ExeList, pn) ? 1 : 0 ;當前窗口在列表里,記錄變量InList If (InStr(ExeList, pn) > 2) ;當前窗口移到ExeList最前面 { List_Tmp := "" Loop, Parse, ExeList, | List_Tmp := (InStr(A_LoopField, pn)) ? A_LoopField . "|" . List_Tmp : List_Tmp . A_LoopField . "|" ExeList := Trim(List_Tmp, "|") ;去除兩邊的|符,防止A_LoopField出來空值 } ;通過ExeList獲取窗口信息並存入ObjTotal和ObjKeyAndNum ;下面的變量說明:i為每個應用找到的有效窗口數 ObjTotal := {} ;把所有匹配窗口信息寫入此對象 ObjKeyAndNum := {} ;以熱鍵分組,把匹配的窗口信息寫入此對象 total := 0 ;記錄所有匹配窗口總數,ObjTotal用 Loop, Parse, ExeList, | { ;獲取應用程序名name Loop, Parse, A_LoopField, &\| { name := A_LoopField Break } ;獲取快捷鍵k(后面找到的窗口都放在k對應的對象里) If InStr(A_LoopField, "&") ;自定義了快捷鍵 k := SubStr(A_LoopField, InStr(A_LoopField, "&") + 1) ;&后一位為快捷鍵 Else { StringLeft, k, A_LoopField, 1 ;默認首字母當快捷鍵 StringUpper, k, k } ;獲取排除窗口標題數組ms p2 := InStr(A_LoopField, "\") If p2 ;有排除窗口內容 ms := hyf_gREP_Match(A_LoopField, "(?<=\\).*?(?=\\|&|$)") ;獲取當前應用所有有效窗口列表 WinGet, idList, List, Ahk_exe %name% ;獲取當前應用所有窗口ID i := 0 ;記錄當前應用提取窗口數 Loop,% idList ;遍歷窗口ID,提取想要的窗口 { tt := hyf_winGet("title", "Ahk_id " . idList%A_Index%) ;過濾空標題(有些隱藏程序,比如hh.exe)2015-08-02 19:22:26 If (tt = "") Continue ;過濾自定義標題(若有) If p2 { For k, m In ms { If (tt = m.value(0)) Continue 2 ;跳到Loop,% ID的下個循環(找下個窗口) } } ;記錄匹配窗口的各類信息(關鍵)★★★★★★★★★★★★★★★★★★★★★★★★★★★★ ;心得:如果以應用程序為出發點,記錄多個窗口的數據,理解上就需要3維數組,這結構更像是樹狀的,不是數組的標准結構 ;但是以窗口為出發點,還是簡單的2維數組,好理解多了。。。 i++ total++ ;把ID值寫入兩個對象,因為索引有兩種方式 ObjTotal[total] := {"hwnd":IDList%A_Index%, "key": k, "exe": name, "title":tt} ObjKeyAndNum[k, i] := {"hwnd":IDList%A_Index%, "key": k, "exe": name, "title":tt} } } ;該If判斷匹配窗口為0或1個時,特殊處理后,提示信息並退出腳本 If (total = 0) hyf_tooltip("沒有找到窗口,腳本退出", , 1) Else If (total = 1) { If InList hyf_tooltip("當前已是唯一目標窗口,腳本退出", , 1) Else { hyf_winActivate(ObjTotal[1].hwnd, "ID") hyf_tooltip("已激活唯一窗口,腳本退出", , 1) } } Else If (total = 2) && InList ;有2個窗口,且當前已在其中1個窗口 { Num_InTotal := Mod(hyf_getKeyOfValueInObj1(ObjTotal, hyf_winGet("ID"), "hwnd"), total) + 1 hyf_winActivate(ObjTotal[Num_InTotal].hwnd, "ID") hyf_tooltip("共2個窗口,已激活另一個窗口,腳本退出", , 1) } ;有2個及2個以上匹配窗口時按熱鍵后的操作 Num_InTotal := InList ? 2 : 1 ;在列表則直接切換到第2個窗口,否則切換第1個找到的窗口 hyf_winActivate(ObjTotal[Num_InTotal].hwnd, "ID") ;列出熱鍵列表和窗口列表 Key_All := "" Win_All := "" Num_Tmp := 0 For k1, v1 In ObjKeyAndNum For k2, v2 In v1 { If !InStr(key_All, k1) Key_All .= v1[1].exe "熱鍵為" . k1 . "`n" } For k1, v1 In ObjTotal Win_All .= A_Index . ": " . v1.title . "`n" ;這里開始自定義按鍵並跳轉到相應的程序,腳本主要功能。 ToolTip,% "等待按鍵(Tab或數字或字母鍵)`n按其他鍵則腳本退出。`n`n窗口列表:`n" . Win_All Loop ;等待按鍵繼續切換 { kp := hyf_waitKeyAndReturn() If (kp = "Tab") ;按Tab則依次切換到下個窗口 { Num_InTotal := Mod(hyf_getKeyOfValueInObj1(ObjTotal, hyf_winGet("ID"), "hwnd"), total) + 1 hyf_winActivate(ObjTotal[Num_InTotal].hwnd, "ID") hyf_tooltip("您按下了" . kp . "鍵,窗口位置為" . Num_InTotal . "/" . total . "`n`nPS:按窗口熱鍵會在熱鍵窗口內切換。`n您識別到的應用名和熱鍵分別為:`n" . key_All, 2) Continue } Else If hyf_isWord(kp) ;是字母,則判斷是否存在該熱鍵窗口 { If ObjKeyAndNum[kp,1].hwnd ;存在該熱鍵窗口 { If (hyf_winGet("ProcessName") = ObjKeyAndNum[kp,1].exe) ;如果按的熱鍵和當前窗口一樣,則跳到該類的下一個窗口 { kn := ObjKeyAndNum[kp].MaxIndex() i := Mod(hyf_getKeyOfValueInObj2(ObjKeyAndNum, hyf_winGet("ID"), "hwnd")[2], kn) + 1 hyf_winActivate(ObjKeyAndNum[kp, i].hwnd, "ID") hyf_tooltip("您按下了" . kp . "鍵,已激活熱鍵內第" . i . "/" . kn . "個窗口`n`nPS:按Tab會按總窗口順序切換") } Else { hyf_winActivate(ObjKeyAndNum[kp, 1].hwnd, "ID") hyf_tooltip("您按下了" . kp . "鍵`n之前窗口和該窗口不同類,已激活熱鍵第1個窗口", 2) } Continue } Else ;不存在該快捷鍵窗口 hyf_tooltip("按鍵" . kp . "不是熱鍵,腳本退出", 2, 1) Continue } Else If hyf_isNum(kp) ;是數字,則直接跳到該窗口 { If ObjTotal[kp].hwnd { hyf_winActivate(ObjTotal[kp].hwnd, "ID") hyf_tooltip("您按下了" . kp . "鍵`n之前窗口和該窗口不同類,已激活熱鍵第1個窗口`n窗口列表:`n`n" . Win_All, 2) } Else hyf_tooltip("按鍵" . kp . "無效,腳本退出", , 1) Continue } Else hyf_tooltip("按鍵" . kp . "無效,腳本退出", , 1) } Return hyf_gREP_Match(str, zz) ;全局正則 {{{3 { ;ms.value(0), ms.Len(0), ms.Pos(0)分別存儲子項目的值,長度和位置 options := "U)^[imsxACDJOPSUX`a`n`r]+\)" zz := (RegExMatch(zz, options, Opt) ? (InStr(Opt, "O", 1) ? "" : "O") : "O)") . zz m := {Len:{0:0}} ms := [] p := 1 While (p := RegExMatch(str, zz, m, p + m.Len[0])) ms[A_Index] := m Return ms } hyf_winGet(cmd := "title", WinTitle := "A") ;不支持Pos等多變量輸出命令 {{{3 { If (cmd = "title") WinGetTitle, v, %WinTitle% Else If (cmd = "Class") WinGetClass, v, %WinTitle% Else If (cmd = "Text") WinGetText, v, %WinTitle% Else WinGet, v, %cmd%, %WinTitle% Return v } hyf_tooltip(str, t := 1, ExitScript := 0, x := "", y := "") ;提示t秒並自動消失 {{{3 { t *= 1000 ToolTip, %str%, %x%, %y% SetTimer, hyf_removeToolTip, -%t% If ExitScript { Gui, Destroy Exit } } hyf_winActivate(t, m := "") ;可以支持對象的值,m為Ahk_后面的值,如ID, Class, pid, exe等 {{{3 { t := (m = "") ? t :"Ahk_" . m . A_Space . t WinActivate %t% } hyf_getKeyOfValueInObj1(obj, value, key := "") ;獲取單索引參數對象里的k鍵匹配v值的鍵 {{{3 { ;比如獲取obj[n] = {"a":x1, "b":y1}里鍵b的值為3的序號n,則函數參數為(obj, 3, "b"),若為數組,則key="" If (key = "") { For k, v In obj If (v = value) Return k } Else { For k, v In obj If (v[key] = value) Return k } } hyf_waitKeyAndReturn(k := "All", t := "") ;t秒內等待按下任意鍵並返回按鍵名或超時(個人修改版) {{{3 { If (t != "") t := "T" . t Suspend On If (k = "All") || (k = "A") Input, SingleKey, I%t%, ``0123456789-=:[]\'./ABCDEFGHIJKLMNOPQRSTUVWXYZ{LControl}{RControl}{LAlt}{RAlt}{LShift}{RShift}{LWin}{RWin}{Enter}{Escape}{CapsLock}{AppsKey}{F1}{F2}{F3}{F4}{F5}{F6}{F7}{F8}{F9}{F10}{F11}{F12}{Left}{Right}{Up}{Down}{Home}{End}{PGUP}{PGDN}{Del}{Ins}{BS}{CapsLock}{NumLock}{Numpad0}{Numpad1}{Numpad2}{Numpad3}{Numpad4}{Numpad5}{Numpad6}{Numpad7}{Numpad8}{Numpad9}{NumpadDot}{NumpadDiv}{NumpadMult}{NumpadAdd}{NumpadSub}{NumpadEnter}{PrintScreen}{ScrollLock}{Pause}{Space}{Tab}`,; ;最后為需要轉義的特殊符號,;放最后只是避免語法錯誤顯示 Else If (k = "xsj") ;修飾鍵,包括了Tab Input, SingleKey, I%t%, {Tab}{LControl}{RControl}{LAlt}{RAlt}{LShift}{RShift}{LWin}{RWin}{Enter}{Escape}{CapsLock}{AppsKey}{F1}{F2}{F3}{F4}{F5}{F6}{F7}{F8}{F9}{F10}{F11}{F12}{Left}{Right}{Up}{Down}{Home}{End}{PGUP}{PGDN}{Del}{Ins}{BS}{CapsLock}{NumLock}{NumpadDot}{NumpadDiv}{NumpadMult}{NumpadAdd}{NumpadSub}{NumpadEnter}{PrintScreen}{ScrollLock}{Pause} ;最后為需要轉義的特殊符號,;放最后只是避免語法錯誤顯示 Else Input, SingleKey, I%t%, %k% Suspend Off Return (ErrorLevel = "TimeOut") ? "TimeOut" : SubStr(ErrorLevel, 8) } hyf_isWord(char) ;是否字母 {{{3 { Return (char ~= "i)[a-z]") } hyf_getKeyOfValueInObj2(obj, value, key := "") ;獲取雙索引參數對象里的k鍵匹配v值的鍵,返回數組 {{{3 { ;比如獲取obj[m][n] = {"a":x1, "b":y1}里鍵b的值為3的序號m和n,則函數參數為(obj, 3, "b") o := {} If (key = "") { For k1, v1 In obj For k2, v2 In v1 If (v2 = value) { o[1] := k1 o[2] := k2 Return o } } Else { For k1, v1 In obj For k2, v2 In v1 If (v2[key] = value) { o[1] := k1 o[2] := k2 Return o } } } hyf_isNum(char) ;是否數字 {{{3 { Return (char ~= "\d") } hyf_removeToolTip() ;清除ToolTip {{{3 { ToolTip }