Win+Tab键实现自定义程序列表间的窗口切换
程序是用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
}
Win+Tab键实现自定义程序列表间的窗口切换的更多相关文章
- 如何使用Win+R快捷键打开自定义程序
鉴于大家对于提高效率这块有争议,更改了下标题. 大家平时一定都使用过Win+R运行快捷键, 在运行里可以快捷的打开一些系统软件,比如说输入mstsc是打开远程连接,输入explorer是打开文件管理器 ...
- Win+Ctrl键设置
转载:http://www.win7u.com/jc/9156.html Ctrl+V:这是Win10命令提示符里新增的, Win+Prt Sc:屏幕截图.按下该快捷键后,Win8系统教程.你知道wi ...
- 实现Tab键的空格功能
有时使用编辑框需要用到按Tab键空两格,可能这时Tab键的功能不是空格而是页面切换等,这时需要设置: $(document).bind('keydown', function (event) { if ...
- GcSpreadSheet自定义Tab键选择
最开始的时候需要在GcSpreadSheet中按Tab在需要输入的cell中切换,在模板中定义Tab的切换规则:后来又有一个新的要求,因为在使用的时候会出现数据不平的情况,这个时候需要在标记中的不平数 ...
- Source Insight 4.0 文件类型、编码格式、tab转空格、tab键自动补全设置。。。
1.编码格式 -- 在 Options->Preferences->Files 中的最下面,Default enconding 为 UTF-8 2.tab转空格 其他相关设置如下: 以下 ...
- 发送WIN+SAPCE键,WINDOWS,空格键
键盘代码部份转自:http://www.cnblogs.com/cpcpc/archive/2011/02/22/2123055.html 由于喜欢用CTRL+空格键切换输入法,在WIN8上有所不习惯 ...
- WPF案例(-)模拟Windows7 Win+Tab切换
原文:WPF案例(-)模拟Windows7 Win+Tab切换 一个使用Wpf模拟Windows7 Win+Tab页面切换的小程序,使用快捷键Ctrl+Down或Ctrl+Up在示例程序各个页面元素之 ...
- C++ tab键实现自动补全输入功能
一.简介 由于项目中写了个测试的控制台程序,是每次读取一行,即通过getline()来实现的,所以每次必须输入全路径名称,才能实现运行. 大家都觉得麻烦,就写了个tab键自动选择补全的. 目前基本可实 ...
- 在微信小程序页面间传递数据总结
在微信小程序页面间传递数据 原文链接:https://www.jianshu.com/p/dae1bac5fc75 在开发微信小程序过程之中,遇到这么一些需要在微信小程序页面之间进行数据的传递的情况, ...
随机推荐
- WPF Hidden和Collapsed
对于这两种设定,其实已经提示的很清楚了 Visibility="Hidden"不显示元素,但是在布局为元素保留空间 Visibility="Collapsed" ...
- pageHelper 分页插件使用
第一步:引入pageHelper的jar包. 链接:https://pan.baidu.com/s/1m3EyAmd_eoAsay0aM7uEkA 提取码:xmfi 第二步:需要在SqlMapConf ...
- 【研究】Struts2-048漏洞
1.1 漏洞背景 2017年7月7日,Apache Struts发布最新的安全公告,Apache Struts2-strus1-plugin插件存在远程代码执行的高危漏洞,漏洞编号为CVE-2017- ...
- Java8如何用
2014年发布的Java8,现在应该是业界使用最普遍的Java版本,可很多Java开发人员并没有充分发挥这4年前发布的版本的优点, 本文就是带着“学以致用”的目的去了解Java8,挖掘编码中可提高效率 ...
- C/S架构与B/S架构的区别
什么是C/S结构和B/S结构? C/S结构 C/S结构是指Client/Server (客户机/服务器) 结构,是大家熟知的软件系统体系结构,通过将任务合理分配到Client端和Server端,降低了 ...
- Ignite cahce 存储object类型数据和object类型数据序列化后string存储区别
Ignite cache在存储时 object类型的数据和 序列化该object成string类型 两者存储时间差不多. 但是这两者在读取出来的时候,string类型比object类型快很多. 以下为 ...
- RedisClient 连接redis 提示 ERR Client sent AUTH, but no password is set
- Java中forEach, 用来遍历数组
这里的for是Java中forEach, 用来遍历数组的.for(int i : d) 就是遍历int型数组d的 每一次访问数组d的时候读取的数据放入int型的i中.和for(int i=0;i< ...
- java中HashMap的keySet()和values()
我们通常说,keySet()返回所有的键,values()返回所有的值,其实是不太对的,因为无论是keySet()和values(),其实都没有实质的内容,且容我慢慢说来. 他们前者返回了一个Set, ...
- nyoj 211——Cow Contest——————【floyd传递闭包】
Cow Contest 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 N (1 ≤ N ≤ 100) cows, conveniently numbered 1.. ...