1
+ /**
2
+ * @Name: 窗口切换
3
+ * @Version: 0.0.1
4
+ * @Author: ruchuby
5
+ * @LastEditors: ruchuby
6
+ * @LastEditTime: 2023-05-12
7
+ * @Description: 窗口切换,支持使用拼音首字母检索窗口标题进行切换,类似Switcheroo
8
+ */
9
+
10
+ /*
11
+ ===Starter Plugin Info==>
12
+ {
13
+ "author": "ruchuby",
14
+ "version": "0.0.1",
15
+ "introduction": "窗口切换,支持使用拼音首字母检索窗口标题进行切换,类似Switcheroo",
16
+ "icon": "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAA81JREFUWEftll9oW3UUx7/nd9NMKqZTVtT1bjrSrXeNw4cW0iGjLY048GUKLXN/UF+UbdJ2Ix2ID8sQlC3q2jqQKfqkuGXIRAYTmtmOPZhBYKDE3m2pqe3dyli3ka7t/nT3d+TepNrWpLnZXPegPwiXJN9zvh/OOb/7+xEe8qKH7I//CAAzeQ8PqKS4VHaXGAMbKoanK3/fFag5FC8Zf3yJyiRUlqYKIhWgCgDWUwVYBWB9/3sxH1bYtUffqJ53DFAZGSkHTTULoNpOzqyybYInZ6QeAWAAZIDYYImLYDYg2IBUDHhuGzzuahSkvA7gKX502XpHACuPDgXB/L6VnAhnbQMpL1omxMK44zKNlLnCQAuZToZ61ZHUBiZxDJBvFgTwRobXC8gTTLwl2fzsN04MnGhWHh3qZWmeKghgCcE8eaHlmZedJHaqKQ4A0C80L982N3lp+49PL1qkeK0hB5B98tKs7rwQfPD6vhd/zQXlGED99JdNd2/eWnrzSnoCyBjN+JQCuA4gBcLvYEoC5gAxJZnoPQABKZXVNz5u1OdCzAvgCZ58hwS/AUZNJpCHQZRixqAABi0zk0VSlsjkxAeBy/nKXtYRPQYQp8NNrzoG8ASjG4nwLTPvJcHHpSJSNz4MXHXa25m6xcGeBib6Mh0OWFWbtfJWoGx3NA6mnnS46d1cpr61nzxhQtFYkkZkLrc1RHH95/bjc/VZgN50OPCPYc8L4An2hBQF31Wc7p8070JjkhpIVDGxRgwNQHnG1O75ULZFDQR83R9r25qjAs4AtLoDIYDWALQKsI1cACYAWAOkE+OcFKwTFF0Zu3oukQjdmTarruv0S1BMYfIlzrT+Nv374o6f6hmyb94KVPq7PS7iE9awAGYURKPEQp9i6MkzrYbT3mt13b2AeUqP7QwVBaCt7XwJTF/psbbZB4ZT56zu3gHs0iv1eqy1sUjPWfKiASJ/MBPtoEzvFxag8kgqRCT2MOBbEIDyWu9eEkp95p3GDQAusSk3J19b0bcQAN+X13q7pvtFhEE3XD8kWpZds3fzg2xBWUf0CwBL0uHAK/nm64EBlHWcbAY4woQtY/sDee8R/zrAyLo1Vq8bwDzMEPvHPmo6ON/uotX+zu1M9LYea3v+frZhVV1Xkpg/u7zuuZ7bbveVydHSUXxeO1UoJ2n+rhoQ4gTe1R9rP1AoINf/mr/rLRAOzX0VO8lln1I+f3e1KRABs89JUA7NJUBu1mM7+4qN/+uYrHph32NkurMXkOLSKI+444m+HePFRWXUBS+l95K0mJj/Af4E/+8XBQoX0rkAAAAASUVORK5CYII="
17
+ }
18
+ <==Starter Plugin Info===
19
+ */
20
+
21
+
22
+ #Include ..\Utils\PluginHelper.ah2
23
+ PluginHelper.addEntryFunc((* ) => Plugin_窗口切换.main()) ; 添加入口函数等待执行
24
+
25
+ # DllLoad " dwmapi" ; 预先加载dwmapi.dll
26
+
27
+ class Plugin_窗口切换 {
28
+
29
+ static main() {
30
+ SplitPath (A_LineFile , & name) ; 获取插件id即文件名
31
+ this.name := name
32
+ this.hwnd := PluginHelper.searchGuiHwnd
33
+
34
+ this.addToStartupMode()
35
+ }
36
+
37
+ ; 获取所有窗口列表(结果和Alt+Tab一致)
38
+ static getAllAltWinList() ; v0.21 by SKAN for ah2 on D51K/D51O @ autohotkey.com/r?t=99157
39
+ {
40
+ Static S_OK := 0 ; 非0时表示DwmGetWindowAttribute函数错误
41
+
42
+ Local List := []
43
+ , Style := 0
44
+ , ExStyle := 0
45
+ , hwnd := 0
46
+
47
+ For , hwnd in WinGetList()
48
+ If IsVisible(hwnd)
49
+ && StyledRight(hwnd)
50
+ && IsAltTabWindow(hwnd)
51
+ List.Push(hwnd)
52
+
53
+ Return List
54
+
55
+ IsVisible(hwnd, Cloaked := 0 )
56
+ {
57
+ If S_OK = 0
58
+ S_OK := DllCall (" dwmapi\DwmGetWindowAttribute" , " ptr" , hwnd
59
+ , " int" , 14 ; DWMWA_CLOAKED
60
+ , " uintp" , & Cloaked
61
+ , " int" , 4 ; sizeof uint
62
+ )
63
+
64
+ Style := WinGetStyle(hwnd)
65
+ Return (Style & 0x10000000 ) && ! Cloaked ; WS_VISIBLE
66
+ }
67
+
68
+
69
+ StyledRight(hwnd)
70
+ {
71
+ ExStyle := WinGetExStyle(hwnd)
72
+
73
+ Return (ExStyle & 0x8000000 ) ? False ; WS_EX_NOACTIVATE
74
+ : (ExStyle & 0x40000 ) ? True ; WS_EX_APPWINDOW
75
+ : (ExStyle & 0x80 ) ? False ; WS_EX_TOOLWINDOW
76
+ : True
77
+ }
78
+
79
+
80
+ IsAltTabWindow(Hwnd)
81
+ {
82
+
83
+ ExStyle := WinGetExStyle(hwnd)
84
+ If (ExStyle & 0x40000 ) ; WS_EX_APPWINDOW
85
+ Return True
86
+
87
+ While hwnd := DllCall (" GetParent" , " ptr" , hwnd, " ptr" )
88
+ {
89
+ If IsVisible(Hwnd)
90
+ Return False
91
+
92
+ ExStyle := WinGetExStyle(hwnd)
93
+
94
+ If (ExStyle & 0x80 ) ; WS_EX_TOOLWINDOW
95
+ && ! (ExStyle & 0x40000 ) ; WS_EX_APPWINDOW
96
+ Return False
97
+ }
98
+
99
+ Return ! Hwnd
100
+ }
101
+ }
102
+
103
+ ; 获取匹配搜索的窗口信息列表
104
+ static getWinList(searchText) {
105
+ o := A_DetectHiddenWindows
106
+ DetectHiddenWindows (false )
107
+
108
+ out := []
109
+ idList := this.getAllAltWinList()
110
+ for id in idList {
111
+ ; 窗口不存在则跳过
112
+ if (! WinExist (" ahk_id " id ))
113
+ continue
114
+
115
+ title := WinGetTitle ()
116
+ if (
117
+ id == this.hwnd || ; 是主程序窗口则跳过
118
+ ; 带有搜索内容 且 标题或转拼音首字母后 都不包含搜索文本则跳过
119
+ searchText &&
120
+ ! (
121
+ InStr (title, searchText) ||
122
+ Instr (PluginHelper.Utils.chineseFirstChar(title), searchText) ; 标题中文
123
+ )
124
+ )
125
+ continue
126
+
127
+ ; 获取hIcon
128
+ if ! (hIcon := SendMessage (0x7F , 0 , 0 ))
129
+ if ! (hIcon := SendMessage (0x7F , 1 , 0 ))
130
+ if (! (hIcon := SendMessage (0x7F , 2 , 0 )))
131
+ if (! (hIcon := DllCall (" GetClassLongPtr" , " Ptr" , id , " Int" , - 14 , " Ptr" )))
132
+ if (! (hIcon := DllCall (" GetClassLongPtr" , " Ptr" , id , " Int" , - 34 , " Ptr" )))
133
+ hIcon := DllCall (" LoadIcon" , " uint" , 0 , " uint" , 32512 ) ; 使用默认图标
134
+
135
+ ; 添加到输出列表
136
+ out.push({ hwnd: id , title: title, hIcon: hIcon })
137
+ }
138
+
139
+ DetectHiddenWindows (o)
140
+
141
+ if (out.Length >= 2 ) {
142
+ ; 交换1,2元素位置
143
+ tmp := out[1 ]
144
+ out[1 ] := out[2 ]
145
+ out[2 ] := tmp
146
+ }
147
+ return out
148
+ }
149
+
150
+ static addToStartupMode() {
151
+ searchHandler (that, searchText ) {
152
+ that.pluginSearchResult := this.getWinList(searchText)
153
+
154
+ ; 定义了loadImgsHandler,重载当前图像列表
155
+ that.reloadLVIL(true )
156
+
157
+ ; 重新加载列表
158
+ that.listView.Opt(" -Redraw" ) ; 禁用重绘
159
+
160
+ ; that.listView.Delete() ; reloadLVIL中已经删除了
161
+ for item in that.pluginSearchResult
162
+ that.listView.Add(" icon" that.imgPathToImgListIndex[item.hwnd], " " item.title)
163
+
164
+ that.resizeGui() ; 根据搜索结果数量调整gui尺寸 并启用重绘
165
+ }
166
+
167
+ runHandler (that, rowNum ) {
168
+ ; 激活对应窗口然后隐藏搜索框
169
+ hwnd := that.pluginSearchResult[rowNum].hwnd
170
+ try WinActivate (" ahk_id " hwnd)
171
+ catch {
172
+ ; 激活失败则重载搜索结果
173
+ searchHandler(that, PluginHelper.searchText)
174
+ return
175
+ }
176
+ PluginHelper.hideSearchGui()
177
+ }
178
+
179
+ loadImgsHandler (that ) {
180
+ static defaultHIcon := DllCall (" LoadIcon" , " uint" , 0 , " uint" , 32512 ) ; 默认图标
181
+
182
+ that.imgPathToImgListIndex[" default" ] := IL_Add (that.imgListID, " hIcon:*" defaultHIcon)
183
+ for item in that.pluginSearchResult {
184
+ ; hwnd作为路径
185
+ index := IL_Add (that.imgListID, " hIcon:*" item.hIcon)
186
+ ; 加载失败则使用默认图标
187
+ that.imgPathToImgListIndex[item.hwnd] := index ? index : that.imgPathToImgListIndex[" default" ]
188
+ }
189
+ }
190
+
191
+ PluginHelper.addPluginToStartupMode(
192
+ this.name ,
193
+ " 窗口切换" ,
194
+ [" CKQH" ],
195
+ (* ) => PluginHelper.showPluginMode(
196
+ [],
197
+ searchHandler,
198
+ runHandler, {
199
+ loadImgsHandler: loadImgsHandler,
200
+ thumb: PluginHelper.getPluginHIcon(this.name )
201
+ }
202
+ )
203
+ )
204
+ }
205
+ }
0 commit comments