dijiyd wrote:
I was kind of confused at first, because I clicked the edit control. After that, I couldn't use the up/down key to switch between entries.
In the new version the Tab key is also enabled to allow switching keyboard focus back to the list box if the user clicks the input line before typing the search string.
Code:
;
; iswitchw - Incrementally switch between windows using substrings
;
;
; When this script is triggered via its hotkey the list of titles of
; all visible windows appears. The list can be narrowed quickly to a
; particular window by typing a substring of a window title.
;
; When the list is narrowed the desired window can be selected using
; the cursor keys and Enter. If the substring matches exactly one
; window that window is activated immediately (configurable, see the
; "autoactivateifonlyone" variable).
;
; The window selection can be cancelled with Esc.
;
;
; For the idea the credit goes to the creators of the iswitchb
; package for the Emacs editor
;
;
; TODO:
;
; - Relying on generated control names (e.g. Static1) is not robust
; Can we specify them?
;
; - Handle doubleclick selection on the listbox
;
;----------------------------------------------------------------------
;
; User configuration
;
; set this to blank if you don't want to select the only matching window
; automatically
autoactivateifonlyone = yes
; path to sound file played when the user types a substring which
; does not match any of the windows
;
; set this to blank if you don't want a sound
;
nomatchsound = %windir%\Media\ding.wav
if nomatchsound <>
ifnotexist, %nomatchsound%
msgbox, Sound file %nomatchsound% not found. No sound will be played.
;----------------------------------------------------------------------
SetTitleMatchMode, 2
wintitle = Window Switcher
Gui, Add, ListBox, vWindow x6 y11 w270 h250,
Gui, Add, Text, x6 y264 w50 h20, Search`:
Gui, Add, Edit, x66 y261 w210 h20,
;----------------------------------------------------------------------
;
; I never use the CapsLock key, that's why I chose it.
;
CapsLock::
GuiControl,, Edit1
GoSub, RefreshWindowList
Gui, Show, x428 y215 h294 w285, %wintitle%
Loop
{
Input, input, L1, {enter}{esc}{backspace}{up}{down}{pgup}{pgdn}{tab}
if ErrorLevel = EndKey:enter
{
Gui, submit
WinActivate, %window%
break
}
if ErrorLevel = EndKey:escape
{
Gui, cancel
break
}
if ErrorLevel = EndKey:backspace
{
GoSub, DeleteSearchChar
continue
}
; pass these keys to the selector window
if ErrorLevel = EndKey:tab
{
Send, {tab}
continue
}
if ErrorLevel = EndKey:up
{
Send, {up}
continue
}
if ErrorLevel = EndKey:down
{
Send, {down}
continue
}
if ErrorLevel = EndKey:pgup
{
Send, {pgup}
continue
}
if ErrorLevel = EndKey:pgdn
{
Send, {pgdn}
continue
}
; FIXME: probably other error level cases
; should be handled here (interruption?)
GuiControlGet, search,, Edit1
GuiControl,, Edit1, %search%%input%
GoSub, RefreshWindowList
}
return
;----------------------------------------------------------------------
;
; Refresh the list of windows according to the search criteria
;
RefreshWindowList:
GuiControlGet, search,, Edit1
winlist = |
numwin = 0
WinGet, id, list, , , Program Manager
Loop, %id%
{
StringTrimRight, this_id, id%a_index%, 0
WinGetTitle, title, ahk_id %this_id%
; don't add windows with empty titles
if title =
continue
; don't add the switcher window
if title contains %wintitle%
continue
; don't add the windows not matching the search string
; if there is a search string
if title not contains %search%,
continue
winlist = %winlist%%title%|
numwin += 1
}
; if the pattern didn't match any window
if numwin = 0
; if the search string is empty then we can't do much
if search =
{
msgbox, There are no windows on the screen.
exit
}
; delete the last character
else
{
if nomatchsound <>
SoundPlay, %nomatchsound%
GoSub, DeleteSearchChar
return
}
; show the list
Sort, winlist, D|
GuiControl,, ListBox1, %winlist%
GuiControl, Choose, ListBox1, 1
if numwin = 1
if autoactivateifonlyone <>
{
Gui, submit
WinActivate, %window%
exit
}
return
;----------------------------------------------------------------------
;
; Delete last search char and update the window list
;
DeleteSearchChar:
GuiControlGet, search,, Edit1
if search =
return
StringTrimRight, search, search, 1
GuiControl,, Edit1, %search%
GoSub, RefreshWindowList
return