[AHK]给XP系统任务栏上打开的窗口定义热键

发布时间:2024-03-02 13:01

#SingleInstance,force
#WinActivateForce
/*
限制:windows XP系统适用

功能:给XP任务栏上打开的窗口定义热键


热键定义方式1:win+1-0切换前十个窗口
热键定义方式2:
CapsLock+1-4切换前1-4个窗口
CapsLock+q-r切换 第5-8个窗口
CapsLock+a-f切换 第9-12个窗口
CapsLock+z-v切换 第13-16个窗口

当前脚本是两种方式同时起作用的。


作者:sunwind
时间:原作品20090613,20151227稍加修改未优化
*/
Loop 10
{
	n := A_Index-1
	Hotkey, #%n%, Focus%n%
	Hotkey, #Numpad%n%, Focus%n%
}

Hotkey, CapsLock & 1,Focus1
Hotkey, CapsLock & 2,Focus2
Hotkey, CapsLock & 3,Focus3
Hotkey, CapsLock & 4,Focus4

Hotkey, CapsLock & q,Focusq
Hotkey, CapsLock & w,Focusw
Hotkey, CapsLock & e,Focuse
Hotkey, CapsLock & r,Focusr

Hotkey, CapsLock & a,Focusa
Hotkey, CapsLock & s,Focuss
Hotkey, CapsLock & d,Focusd
Hotkey, CapsLock & f,Focusf

Hotkey, CapsLock & z,Focusz
Hotkey, CapsLock & x,Focusx
Hotkey, CapsLock & c,Focusc
Hotkey, CapsLock & v,Focusv

return

test:
MsgBox %A_ThisHotkey%
return
Focus1:
FocusButton(1)
return
Focus2:
FocusButton(2)
return
Focus3:
FocusButton(3)
return
Focus4:
FocusButton(4)
return

Focus5:
Focusq:
FocusButton(5)
return
Focus6:
Focusw:
FocusButton(6)
return
Focus7:
Focuse:
FocusButton(7)
return
Focus8:
Focusr:
FocusButton(8)
return
Focus9:
Focusa:
FocusButton(9)
return
Focus0:
Focuss:
FocusButton(10)
return
Focusd:
FocusButton(11)
return
Focusf:
FocusButton(12)
return

Focusz:
FocusButton(13)
return
Focusx:
FocusButton(14)
return
Focusc:
FocusButton(15)
return
Focusv:
FocusButton(16)
return
#-::
#NumpadSub::
	ShowToolTips()
	SetTimer, RemoveToolTips, -1000
Return

RemoveToolTips:
	Loop, 10
		ToolTip,,,,%A_Index%
Return

ShowToolTips()
{
	global g_bundleCount
    Build_hWndArray(10)

	CoordMode, ToolTip, Screen
	Loop, %g_bundleCount%
	{
		If A_Index < 5
			continue
			
		x := g_xs%A_Index%
		y := g_ys%A_Index%
		If A_Index = 10
			text = 0
		Else
			text = %A_Index%
		
		ToolTip, %text%, %x%, %y%, %A_Index%
	}
}

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
}

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号