aboutsummaryrefslogtreecommitdiff
path: root/out/scripts.ahk
diff options
context:
space:
mode:
Diffstat (limited to 'out/scripts.ahk')
-rw-r--r--out/scripts.ahk864
1 files changed, 864 insertions, 0 deletions
diff --git a/out/scripts.ahk b/out/scripts.ahk
new file mode 100644
index 0000000..ece6515
--- /dev/null
+++ b/out/scripts.ahk
@@ -0,0 +1,864 @@
+#Include ../lib/Acc.ahk
+
+; Directives ------------------------------------------------------------------
+
+
+#SingleInstance Force
+#Persistent
+#NoEnv
+#WinActivateForce
+#MaxHotkeysPerInterval 200
+
+; Initialization --------------------------------------------------------------
+
+WindowMessageHandlers := []
+
+DoubleClickClicked := false
+JumpPaths := { s: env("Sync")
+ , w: env("Sync") "\Projekt\john.ankarstrom.se\htdocs"
+ , e: env("Personal")
+ , d: env("Personal") "\Downloads"
+ , b: "C:\Program Files\KM-Goanna\k-meleon.exe"
+ , m: "C:\Program Files\Mozilla Thunderbird\thunderbird.exe" }
+layouts := { ru: DllCall("LoadKeyboardLayout", "Str", "00000419", "Int", 1)
+ , sv: DllCall("LoadKeyboardLayout", "Str", "0000041D", "Int", 1) }
+ShowLayout()
+WindowMessageHandlers.Push("LayoutWindowMessage")
+OnMessage(0x404, "NotifyIcon")
+ShellApp := ComObjCreate("Shell.Application")
+GroupAdd, Explorer, ahk_class CabinetWClass
+GroupAdd, Explorer, ahk_class ExploreWClass
+GroupAdd, Desktop, ahk_class Progman
+GroupAdd, Desktop, ahk_class WorkerW
+GroupAdd, ExplorerDesktop, ahk_class CabinetWClass
+GroupAdd, ExplorerDesktop, ahk_class ExploreWClass
+GroupAdd, ExplorerDesktop, ahk_class Progman
+GroupAdd, ExplorerDesktop, ahk_class WorkerW
+Menu, Tray, NoStandard
+Menu, Tray, Tip, %A_ScriptName%
+Menu, Tray, Add, &Open directory..., TrayOpen
+Menu, Tray, Add, Re&build..., TrayRebuild
+Menu, Tray, Add, &Reload, TrayReload
+Menu, Tray, Add, E&xit, TrayExit
+Gui, OSD:+AlwaysOnTop +LastFound +Owner +Disabled -Caption
+Gui, OSD:Color, FFFFFF
+Gui, OSD:Font, s30, VCR OSD Mono
+Gui, OSD:Add, Text, vOSD c00BB00, % " "
+WinSet, TransColor, FFFFFF 250
+y := A_ScreenHeight - 100
+Gui, OSD:Show, x0 y%y% AutoSize NA, OSD
+GroupAdd, WindowsExplorer, ahk_class CabinetWClass
+GroupAdd, WindowsExplorer, ahk_class ExploreWClass
+Gui, FakeWindow:+LastFound +Owner +Disabled -Caption
+Gui, +hwndFakeWindowHwnd
+y := A_ScreenHeight - 100
+Gui, FakeWindow:Show, x0 y%y% AutoSize NA, FakeWindow
+WindowMessageHandlers.Push("WindowsWindowMessage")
+
+Gui +LastFound
+DllCall("RegisterShellHookWindow", UInt, WinExist())
+msg := DllCall("RegisterWindowMessage", Str, "SHELLHOOK")
+OnMessage(msg, "WindowMessage")
+return
+
+; Body ------------------------------------------------------------------------
+
+; Open in new Explorer window
+#s::
+ToolTip, ...
+SendInput, {Blind}{LWin Up}
+Input, k, L1
+if (JumpPaths[k] != "")
+{
+ if (InStr(FileExist(JumpPaths[k]), "D"))
+ Run, % "explorer /n, """ JumpPaths[k] """"
+ else
+ Run, % """" JumpPaths[k] """"
+}
+ToolTip
+return
+; Open in current (or new) Explorer window
+!#s::
+ToolTip, ...
+SendInput, {Blind}{LWin Up}
+Input, k, L1
+if (JumpPaths[k] != "")
+ if ((e := Explorer()) != -1) ; (see tt.programs.explorer.ahk)
+ e.Navigate(JumpPaths[k])
+ else
+ Run, % "explorer """ JumpPaths[k] """"
+ToolTip
+return
+LWin & LShift::
+LShift & LWin:: ; (my CapsLock is mapped to LWin)
+PostMessage, 0x50, 2, 0,, A ; WM_INPUTLANGCHANGEREQUEST
+Sleep, 100
+ShowLayout() ; display new layout in tray icon
+return
+#IfWinActive ahk_class Emacs
+; RAlt::Alt
+#IfWinActive ahk_class ConsoleWindowClass
+!F4::WinClose, A
+#IfWinActive ahk_exe WINWORD.EXE
+XButton1::SendInput, +{F5} ; cycle cursor position backwards
+#IfWinActive ahk_class Audition v1.5
++WheelUp::
+Loop, 30
+ SendInput, ^+{Left}
+return
++WheelDown::
+Loop, 30
+ SendInput, ^+{Right}
+return
+#IfWinActive ahk_class EVERYTHING
+WheelUp::Up
+WheelDown::Down
+#IfWinActive ahk_class SciTEWindow
+F2::Gosub, TrayRebuild ; rebuild scripts.ahk
+#IfWinActive ahk_class MozillaWindowClass
++^!+::SendInput, ^!{WheelUp}
++^!-::SendInput, ^!{WheelDown}
+!s::SendInput, ^k
+F3::SendInput, !{Left}
+F4::SendInput, !{Right}
+!F1::SendInput, {WheelUp}
+!F2::SendInput, {WheelDown}
+F1::
+Loop, 5
+ SendInput, {WheelUp}
+return
+F2::
+Loop, 5
+ SendInput, {WheelDown}
+return
+#IfWinActive ahk_class KMeleon Browser Window
+F3::SendInput, !{Left}
+F4::SendInput, !{Right}
+!F1::SendInput, {LAlt Up}{Up}
+!F2::SendInput, {LAlt Up}{Down}
+F1::
+Loop, 5
+ SendInput, {WheelUp}
+return
+F2::
+Loop, 5
+ SendInput, {WheelDown}
+return
+#IfWinActive ahk_class MediaPlayerClassicW
+Esc::
+WinGetPos, x, y, w, h
+if (x = 0 and y = 0 and w = A_ScreenWidth and h = A_ScreenHeight)
+ SendInput, {F11}
+return
+~RShift::
+WinGetPos, x, y, w, h, A
+if not (x = 0 and y = 0 and w = A_ScreenWidth and h = A_ScreenHeight)
+ return
+MouseGetPos, mx, my
+MouseMove, % A_ScreenWidth, % A_ScreenHeight, 0
+KeyWait, RShift
+MouseMove, % mx, % my, 0
+return
+~LShift::
+WinGetPos, x, y, w, h, A
+MouseGetPos, mx, my
+SendInput, {LCtrl Down}7{LCtrl Up}
+if (x = 0 and y = 0 and w = A_ScreenWidth and h = A_ScreenHeight)
+ MouseMove, % A_ScreenWidth, 0, 0
+KeyWait, LShift
+MouseMove, % mx, % my, 0
+SendInput, {LCtrl Down}7{LCtrl Up}
+return
+#IfWinActive
+#IfWinActive ahk_group ExplorerDesktop
+; Open new window/command prompt
+^n::Run, % "explorer /n,""" ExplorerPath() """"
+^p::Run, % "cmd /k cd /d """ ExplorerPath() """"
++^p::
+path := ExplorerPath()
+Run, % "C:\Documents and Settings\All Users\Start Menu\Programs\Microsoft Visual Studio 2010 Express\Visual Studio Command Prompt (2010).lnk"
+WinWait, ahk_class ConsoleWindowClass
+SendInput, % "cd " path "{Return}"
+return
+; Create new folder/file
+^+n::
+FileCreateDir, % ExplorerPath() "\New Folder"
+SendInput, {F5}New Folder{F2}
+return
+^!n::
+FileAppend,, % ExplorerPath() "\New Text Document.txt"
+SendInput, {F5}New Text Document.txt{F2}
+return
+; Edit file
+#IfWinActive
+LWin & LButton::
+MouseGetPos,,, hwnd
+DllCall("SetForegroundWindow", "UInt", hwnd)
+if (not DoubleClick()) ; see tt.doubleclick.ahk
+ return
+if (not WinActive("ahk_group Explorer"))
+{
+ SendInput, {Click}
+ return
+}
+; fall through to next hotkey
+#IfWinActive ahk_group Explorer
+#NumPadEnter::
+#Enter::
+i := Explorer().Document.FocusedItem
+if (i.IsFolder)
+ return
+ShellApp.ShellExecute(i.path, "", "", "Edit", 1)
+return
+; Directory navigation
+LAlt & Up::
+RAlt & Up::
+e := Explorer()
+path := e.Document.Folder.Self.path
+if (InStr(path, "::{") = 1)
+ return
+slash := InStr(path, "\", 0, 0)
+if (slash = StrLen(path))
+ slash := InStr(path, "\", 0, 0, 2)
+if (slash = 0)
+ parent = ::{20D04FE0-3AEA-1069-A2D8-08002B30309D} ; My Computer
+else
+ parent := SubStr(path, 1, slash)
+e.Navigate(parent)
+return
+LAlt & Down::
+RAlt & Down::
+path := ExplorerPath()
+if (InStr(path, "::{") = 1)
+ return
+Explorer().Navigate(path) ; go to real path of folder
+return
+; Toggle hidden status
+^h::
+SSF_SHOWALLOBJECTS := 0x0001
+VarSetCapacity(SHELLSTATE, 32, 0)
+DllCall("Shell32\SHGetSetSettings", "Ptr", &SHELLSTATE, "UInt", SSF_SHOWALLOBJECTS, "Int", false)
+NumPut(NumGet(SHELLSTATE) ^ (1 << 0), SHELLSTATE,, "Int")
+DllCall("Shell32\SHGetSetSettings", "Ptr", &SHELLSTATE, "UInt", SSF_SHOWALLOBJECTS, "Int", true)
+WinGet, win, List, ahk_group Explorer
+Loop, % win
+ PostMessage, 0x111, 41504,,, % "ahk_id " win%A_Index% ; refresh
+return
+; Sort and display options
+^q::ExplorerFolderView("name")
+^w::ExplorerFolderView("modified")
+^e::ExplorerFolderView("type")
+^t::ExplorerFolderView("created")
+^g::ExplorerFolderView("groups")
+^s::ExplorerFolderView("tiles")
+^d::ExplorerFolderView("icons")
+^+d::ExplorerFolderView("thumbnails")
+^f::ExplorerFolderView("details")
+^+f::ExplorerFolderView("list")
+^!q::ExplorerFolderView("name", true)
+^!w::ExplorerFolderView("modified", true)
+^!e::ExplorerFolderView("type", true)
+^!t::ExplorerFolderView("created", true)
+^!g::ExplorerFolderView("groups", true)
+^!s::ExplorerFolderView("tiles", true)
+^!d::ExplorerFolderView("icons", true)
+^!+d::ExplorerFolderView("thumbnails", true)
+^!f::ExplorerFolderView("details", true)
+^!+f::ExplorerFolderView("list", true)
+#IfWinActive
+;§ & LButton::SendInput, {WheelDown}
+;§ & RButton::SendInput, {WheelUp}
+; <^>!§::SendInput, {Text}§
+#IfWinActive ahk_class PuTTY
+PgUp::
+Loop, 5
+ SendInput, ^{PgUp}
+return
+PgDn::
+Loop, 5
+ SendInput, ^{PgDn}
+return
+#IfWinActive ahk_class SUMATRA_PDF_FRAME
+PgUp::SendInput, {PgUp}
+PgDn::SendInput, {PgDn}
+#IfWinActive ahk_class Chrome_WidgetWin_1
+PgUp::SendInput, {PgUp}
+PgDn::SendInput, {PgDn}
+#IfWinActive
+PgUp::
+Loop, 5
+ SendInput, {WheelUp}
+return
+PgDn::
+Loop, 5
+ SendInput, {WheelDown}
+return
+<^>!PgUp::SendInput, {PgUp}
+<^>!PgDn::SendInput, {PgDn}
+XButton2::SendInput, {XButton2}
+XButton2 & WheelUp::SetVolume(GetKeyState("Shift") ? 2 : 1)
+XButton2 & WheelDown::SetVolume(GetKeyState("Shift") ? -2 : -1)
+RAlt & F6::SetVolume(GetKeyState("Shift") ? 2 : 1)
+RAlt & F5::SetVolume(GetKeyState("Shift") ? -2 : -1)
+#q::WinSet, Bottom,, A
+#a::WinSet, Top,, A
+#t::WinSet, AlwaysOnTop, Toggle, A
+#y::
+WinGet, t, Transparent, A
+if (t = OFF)
+ WinSet, Transparent, 180, A
+else
+ WinSet, Transparent, OFF, A
+return
+#b::WinSet, Bottom,, A
+#!m::WinMove, A,, 0, 0
+#z::WinMinimize, A
+#v::
+WinGet, mm, MinMax, A
+if (mm = 1)
+ WinRestore, A
+else
+ WinMaximize, A
+return
+#x:: ; minimize all except current
+WinGet, hwnd, id, A
+WinGet, s, Style, ahk_id %hwnd%
+WinSet, Style, -0x20000, ahk_id %hwnd% ; WS_MINIMIZEBOX
+WinMinimizeAll
+Sleep, 50
+WinSet, Style, % s, ahk_id %hwnd%
+WinActivate, ahk_id %hwnd%
+WinGet, mm, MinMax, ahk_id %hwnd%
+if (mm = -1)
+ WinRestore, ahk_id %hwnd%
+return
+#c:: ; minimize last window
+SendInput, !{Tab}
+Sleep, 50
+WinMinimize, A
+return
+/*
+#!m:: ; fix minimization bug (?)
+WinGet, hwnd, id, A
+parent := DllCall("GetParent", "uint", hwnd)
+WinGet, progman, id, Program Manager ahk_class Progman
+DllCall("SetParent", "uint", hwnd, "uint", progman)
+DllCall("SetParent", "uint", hwnd, "uint", parent)
+return
+*/
+/*
+#c::
+GWL_HWNDPARENT := -8
+MouseGetPos,,, hwnd
+WindowDisabled := hwnd
+return
+*/
+/*
+$!Tab::
+HandleAltTab:
+if (WindowDisabled)
+ WinSet, Disable,, ahk_id %WindowDisabled%
+SendInput, {LAlt Down}{Tab}
+Hotkey, $!Tab, HandleAltTab, Off
+Hotkey, $!+Tab, HandleAltShiftTab, Off
+while (GetKeyState("LAlt", "P") and not esc := GetKeyState("Esc", "P"))
+ Sleep, 1
+if (esc)
+ SendInput, {Esc}
+SendInput, {LAlt Up}
+Hotkey, $!Tab, HandleAltTab, On
+Hotkey, $!+Tab, HandleAltShiftTab, On
+WinSet, Enable,, ahk_id %WindowDisabled%
+return
+$!+Tab::
+HandleAltShiftTab:
+if (WindowDisabled)
+ WinSet, Disable,, ahk_id %WindowDisabled%
+if (WinActive("A") = WindowDisabled)
+ SendInput, {LAlt Down}{LShift Down}{Tab}{LShift Up}{Tab}
+else
+ SendInput, {LAlt Down}{LShift Down}{Tab}{LShift Up}
+Hotkey, $!Tab, HandleAltTab, Off
+Hotkey, $!+Tab, HandleAltShiftTab, Off
+while (GetKeyState("LAlt", "P") and not esc := GetKeyState("Esc", "P"))
+ Sleep, 1
+if (esc)
+ SendInput, {Esc}
+SendInput, {LAlt Up}
+Hotkey, $!Tab, HandleAltTab, On
+Hotkey, $!+Tab, HandleAltShiftTab, On
+WinSet, Enable,, ahk_id %WindowDisabled%
+return
+*/
+^RButton::
+hwndp := WinActive("A")
+MouseGetPos,,, hwnd
+if (hwnd = hwndp)
+{
+ WinSet, Top,, A
+ return
+}
+DllCall("SetForegroundWindow", "UInt", hwnd)
+WinSet, AlwaysOnTop, On, ahk_id %hwndp%
+WinSet, AlwaysOnTop, Off, ahk_id %hwndp%
+return
+#1::FocusButton(1)
+#2::FocusButton(2)
+#3::FocusButton(3)
+#4::FocusButton(4)
+#5::FocusButton(5)
+#6::FocusButton(6)
+#7::FocusButton(7)
+#8::FocusButton(8)
+#9::FocusButton(9)
+#0::FocusButton(10)
+
+; Miscellaneous
+
+#Space::CapsLock
+#PrintScreen::Media_Prev
+#ScrollLock::Media_Play_Pause
+#Pause::Media_Next
+
+#e::Run, % "explorer /n, ::{20D04FE0-3AEA-1069-A2D8-08002B30309D}"
+#!t::WinSet, AlwaysOnTop,, ahk_class tooltips_class32 ; fix bug
+
+; Sleep
+
+^+F12 Up::
+Sleep, 600
+DllCall("PowrProf\SetSuspendState", "int", 0, "int", 0, "int", 0)
+return
+
++F12 Up::
+Sleep, 600
+SendMessage,0x112,0xF170,2,,Program Manager ; turn off monitor
+return
+
+; Library ---------------------------------------------------------------------
+
+DoubleClick(alternate := false)
+{
+
+
+ global DoubleClickClicked
+ global DoubleClickPriorX
+ global DoubleClickPriorY
+ global DoubleClickLast
+ SysGet, SM_CXDOUBLECLK, 36
+ SysGet, SM_CYDOUBLECLK, 37
+ max := DllCall("User32\GetDoubleClickTime")
+
+ tmp := A_CoordModeMouse
+ CoordMode, Mouse, Screen
+ MouseGetPos, x, y
+ CoordMode, Mouse, %tmp%
+
+ if (not DoubleClickClicked)
+ {
+ if (alternate)
+ SendInput, {Click, right}
+ else
+ SendInput, {Click}
+ DoubleClickPriorX := x
+ DoubleClickPriorY := y
+ DoubleClickLast := A_TickCount
+ DoubleClickClicked := true
+ return false
+ }
+
+ if (A_TickCount - DoubleClickLast > max
+ || abs(x - DoubleClickPriorX) > SM_CXDOUBLECLK
+ || abs(y - DoubleClickPriorY) > SM_CYDOUBLECLK)
+ {
+ if (alternate)
+ SendInput, {Click, right}
+ else
+ SendInput, {Click}
+ DoubleClickPriorX := x
+ DoubleClickPriorY := y
+ DoubleClickLast := A_TickCount
+ DoubleClickClicked := true
+ return false
+ }
+
+ DoubleClickClicked := false
+ return true
+}
+env(name)
+{
+ EnvGet, r, %name%
+ return r
+}
+ShowLayout(hwnd := "")
+{
+ global layouts
+ f := A_FormatInteger
+ SetFormat, Integer, H
+ if (hwnd = "")
+ WinGet, hwnd, id, A
+ thread := DllCall("GetWindowThreadProcessId", "UInt",hwnd, "UInt",0)
+ layout := DllCall("user32.dll\GetKeyboardLayout", "UInt",thread, "UInt")
+ for k, v in layouts
+ {
+ if (layout = v)
+ {
+ if (FileExist(k ".ico"))
+ Menu, Tray, Icon, %k%.ico
+ break
+ }
+ }
+ SetFormat, Integer, %f%
+}
+LayoutWindowMessage(wParam, lParam)
+{
+ if (wParam = 4 or wParam = 32772) ; HSHELL_WINDOW_ACTIVATED | HSHELL_RUDEAPPACTIVATED
+ {
+ ShowLayout(lParam)
+ WinSet, AlwaysOnTop, On, OSD
+ }
+}
+NotifyIcon(wParam, lParam)
+{
+ if (lParam = 0x202) ; WM_LBUTTONUP
+ Run, % "Rundll32 Shell32.dll,Control_RunDLL input.dll,,{C07337D3-DB2C-4D0B-9A93-B722A6C106E2}"
+}
+Explorer(hwnd := "")
+{
+ global ShellApp
+ if (hwnd = "")
+ WinGet, hwnd, id, A
+ for window in ShellApp.Windows
+ if (window.hwnd = hwnd)
+ return window
+ return -1
+}
+ExplorerPath()
+{
+ WinGetClass, cls, A
+ if (cls = "Progman" or cls = "WorkerW")
+ return %A_Desktop%
+ else
+ return Explorer().Document.Folder.Self.path
+}
+ExplorerFolderView(view, children := false)
+{
+ if (view = "name")
+ n := {m: 30210, d: -1}
+ else if (view = "modified")
+ n := {m: 30213, d: -1}
+ else if (view = "type")
+ n := {m: 30212, d: -1}
+ else if (view = "created")
+ n := {m: 30214, d: -1}
+ else if (view = "groups")
+ n := {m: 30209, d: -1}
+ else if (view = "tiles")
+ n := {m: 28718, d: 6}
+ else if (view = "icons")
+ n := {m: 28713, d: 1}
+ else if (view = "thumbnails")
+ n := {m: 28717, d: 5}
+ else if (view = "details")
+ n := {m: 28716, d: 4}
+ else if (view = "list")
+ n := {m: 28715, d: 3}
+
+ PostMessage, 0x111, % n.m, 0,, A ; change current folder
+ return
+ if (not children or m.d = -1)
+ return
+
+ old := A_BatchLines
+ SetBatchLines, -1
+
+ Loop, Files, % ExplorerPath() "\*", D
+ {
+ MsgBox, % A_LoopFileFullPath
+ }
+
+ SetBatchLines, % old
+}
+TrayOpen:
+Run, % "explorer " A_ScriptDir "\.."
+return
+TrayExit:
+ExitApp
+return
+TrayReload:
+Reload
+return
+TrayRebuild:
+RunWait, % A_ScriptDir "\..\build"
+Reload
+return
+SetVolume(n)
+{
+ SoundGet, w, WAVE
+ SoundSet, 15
+ w := round(w) + n
+ if (w > 100)
+ w := 100
+ if (w < 0)
+ w := 0
+ SoundSet, %w%, WAVE
+ OSD(w)
+}
+/*
+SetVolume(n)
+{
+ global wMax
+ static vMin := 4
+
+ SoundGet, s
+ SoundGet, w, WAVE
+ s := round(s)
+ w := round(w)
+
+ if (s > vMin or w > wMax)
+ wMax := w
+ else if (wMax = "")
+ wMax := 100
+
+ v := s + w - wMax + n
+
+ if (v > 100)
+ v := 100
+
+ if (v >= vMin)
+ {
+ s := v
+ w := wMax
+ }
+ else
+ {
+ s := vMin
+ w := wMax - vMin + v
+ }
+
+ SoundSet, %s%
+ SoundSet, %w%, WAVE
+ OSD(v) ; display volume on screen
+}
+*/
+OSD(text)
+{
+ SetTimer, RemoveOSD, Off
+ WinSet, AlwaysOnTop, On, OSD
+ GuiControl, OSD:Text, OSD, %text%
+ SetTimer, RemoveOSD, 3000
+ return
+}
+RemoveOSD:
+SetTimer, RemoveOSD, Off
+GuiControl, OSD:Text, OSD, % " "
+return
+WindowsWindowMessage(wParam, lParam)
+{
+ static HSHELL_GETMINRECT := 5
+ ; The active window is 0 during minimization (if animated)
+ if (wParam = HSHELL_GETMINRECT and WinActive("A") = 0)
+ {
+ hwnd := NumGet(lParam + 0)
+ WinWaitNotActive, ahk_id 0
+ Sleep, 20
+ InsertAfter(hwnd, "BOTTOM")
+ }
+}
+InsertAfter(hwnd = "", position = "BOTTOM")
+{
+ static SWP_NOSIZE := 0x0001
+ static SWP_NOMOVE := 0x0002
+ static SWP_ASYNCWINDOWPOS := 0x4000
+ static HWND_BOTTOM := 1
+ static HWND_NOTOPMOST := -2
+ static HWND_TOP := 0
+ static HWND_TOPMOST := -1
+ if (hwnd = "")
+ WinGet, hwnd, id, A
+ DllCall("SetWindowPos"
+ , "UInt", hwnd
+ , "UInt", HWND_%position%
+ , "Int", 0
+ , "Int", 0
+ , "Int", 0
+ , "Int", 0
+ , "UInt", SWP_NOSIZE | SWP_NOMOVE | SWP_ASYNCWINDOWPOS)
+}
+; https://code.google.com/archive/p/activatebynum/
+Add_hWndToArray(gi, hWnd)
+{
+ global
+ g_bundleSize%gi% := g_bundleSize%gi% + 1
+ local wi := g_bundleSize%gi%
+ g_hWnd%gi%_%wi% := hWnd
+}
+AddBundle(gi)
+{
+ global
+ g_bundleSize%gi% := 0
+}
+BundleSize(gi)
+{
+ global
+ return g_bundleSize%gi%
+}
+Get_hWndFromArray(gi, wi)
+{
+ global
+ return g_hWnd%gi%_%wi%
+}
+SetButtonTopLeftLoc(gi, x, y)
+{
+ global
+ g_xs%gi% := x
+ g_ys%gi% := y
+}
+Build_hWndArray(maxBundleCount)
+{
+ global g_bundleCount
+
+ WinGet, pidTaskbar, PID, ahk_class Shell_TrayWnd
+ hProc := DllCall("OpenProcess", "Uint", 0x38, "int", 0, "Uint", pidTaskbar)
+ pProc := DllCall("VirtualAllocEx", "Uint", hProc, "Uint", 0, "Uint", 32, "Uint", 0x1000, "Uint", 0x4)
+ idxTB := GetTaskSwBar()
+ SendMessage, 0x418, 0, 0, ToolbarWindow32%idxTB%, ahk_class Shell_TrayWnd ; TB_BUTTONCOUNT
+ buttonCount := ErrorLevel
+
+ g_bundleCount := 0
+
+ Loop, %buttonCount%
+ {
+ SendMessage, 0x417, A_Index-1, pProc, ToolbarWindow32%idxTB%, ahk_class Shell_TrayWnd ; TB_GETBUTTON
+
+ VarSetCapacity(btn, 32, 0)
+ DllCall("ReadProcessMemory", "Uint", hProc, "Uint", pProc, "Uint", &btn, "Uint", 32, "Uint", 0)
+
+ idn := NumGet(btn, 4)
+ Statyle := NumGet(btn, 8, "Char")
+ dwData := NumGet(btn, 12)
+ If Not dwData
+ dwData := NumGet(btn, 16, "int64")
+
+ DllCall("ReadProcessMemory", "Uint", hProc, "Uint", dwData, "int64P", hWnd:=0, "Uint", NumGet(btn,12) ? 4:8, "Uint", 0)
+
+ If Not hWnd ; group button, indicates the start of a group
+ {
+ If g_bundleCount >= %maxBundleCount%
+ Break
+ hidden := Statyle & 0x08 ; TBSTATE_HIDDEN
+ If Not hidden
+ {
+ grpCollapsed := true
+ g_bundleCount := g_bundleCount + 1
+ AddBundle(g_bundleCount)
+
+ GetTaskbarButtonTopLeft(idn, x, y)
+ SetButtonTopLeftLoc(g_bundleCount, x, y)
+ }
+ Else
+ grpCollapsed := false
+ }
+ else ; actual window button
+ {
+ If grpCollapsed
+ {
+ Add_hWndToArray(g_bundleCount, hWnd)
+ }
+ Else
+ {
+ g_bundleCount := g_bundleCount + 1
+ AddBundle(g_bundleCount)
+ Add_hWndToArray(g_bundleCount, hWnd)
+
+ GetTaskbarButtonTopLeft(idn, x, y)
+ SetButtonTopLeftLoc(g_bundleCount, x, y)
+ }
+ }
+ }
+ DllCall("VirtualFreeEx", "Uint", hProc, "Uint", pProc, "Uint", 0, "Uint", 0x8000)
+ DllCall("CloseHandle", "Uint", hProc)
+}
+FocusButton(n)
+{
+ global g_bundleCount
+
+ ; these static variables can become inaccurate if windows are created or closed
+ ; inbetween pressing of hotkeys, but in practice, we can safely ignore the
+ ; inaccuracy
+ static prevBundleIndex := 0
+ static prevWindowIndex := 0
+ Build_hWndArray(n)
+ if (g_bundleCount >= n)
+ {
+ bundleSize := BundleSize(n)
+
+ if n = %prevBundleIndex%
+ windowIndex := Mod(prevWindowIndex, bundleSize) + 1
+ else
+ windowIndex := 1
+ hWnd := Get_hWndFromArray(n, windowIndex)
+ If bundleSize > 1 ; cycle through windows in the same bundle
+ WinActivate, ahk_id %hWnd%
+ Else ; single-window bundle; toggles between activating (restoring) and minimizing the window
+ IfWinActive, ahk_id %hWnd%
+ WinMinimize, ahk_id %hWnd%
+ Else
+ WinActivate, ahk_id %hWnd%
+
+ prevBundleIndex := n
+ prevWindowIndex := windowIndex
+ }
+}
+GetTaskSwBar()
+{
+ ControlGet, hParent, hWnd,, MSTaskSwWClass1 , ahk_class Shell_TrayWnd
+ ControlGet, hChild , hWnd,, ToolbarWindow321, ahk_id %hParent%
+ Loop
+ {
+ ControlGet, hWnd, hWnd,, ToolbarWindow32%A_Index%, ahk_class Shell_TrayWnd
+ If Not hWnd
+ Break
+ Else If hWnd = %hChild%
+ {
+ idxTB := A_Index
+ Break
+ }
+ }
+ Return idxTB
+}
+GetTaskbarButtonTopLeft(id, ByRef x, ByRef y)
+{
+ idxTB := GetTaskSwBar()
+ WinGet, pidTaskbar, PID, ahk_class Shell_TrayWnd
+ hProc := DllCall("OpenProcess", "Uint", 0x38, "int", 0, "Uint", pidTaskbar)
+ pProc := DllCall("VirtualAllocEx", "Uint", hProc, "Uint", 0, "Uint", 32, "Uint", 0x1000, "Uint", 0x4)
+ idxTB := GetTaskSwBar()
+ SendMessage, 0x433, id, pProc, ToolbarWindow32%idxTB%, ahk_class Shell_TrayWnd ; TB_GETRECT
+ ;IfEqual, ErrorLevel, 0, return "Err: can't get rect"
+
+ VarSetCapacity(rect, 32, 0)
+ DllCall("ReadProcessMemory", "Uint", hProc, "Uint", pProc, "Uint", &rect, "Uint", 32, "Uint", 0)
+
+ DllCall("VirtualFreeEx", "Uint", hProc, "Uint", pProc, "Uint", 0, "Uint", 0x8000)
+ DllCall("CloseHandle", "Uint", hProc)
+
+ ControlGet, hWnd, hWnd,, ToolbarWindow32%idxTB%, ahk_class Shell_TrayWnd
+ WinGetPos, x, y, w, h, ahk_id %hWnd%
+
+ left := NumGet(rect, 0)
+ top := NumGet(rect, 4)
+ right := NumGet(rect, 8)
+ bottom := NumGet(rect, 12)
+ x := x + left
+ y := y + top
+}
+
+WindowMessage(wParam, lParam)
+{
+ global WindowMessageHandlers
+ for k, v in WindowMessageHandlers
+ {
+ %v%(wParam, lParam)
+ }
+}