问题
I am writing a script in autohotkey. The purpose of the script is to change the action performed by the program that someone clicks on the taskbar. For Example if someone say triple clicks IE on the taskbar it opens in in private mode. I have some code of this below, my problem is I am trying to find a way to automatically determine the location of the taskbar icons on the taskbar so that the program can set it's bounds for each click. I have tried looking in the registry and I have also tried extracting the icons from the programs and searching for them on screen using imagesearch but it fails to find the icons.... Any way I can accomplish this?
CODE
#NoEnv ; Recommended for performance and compatibility with future
AutoHotkey releases.
; #Warn ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
#SingleInstance Force
CoordMode, Mouse, Screen
Time = 500
~Lbutton::
;if there is a double left click
If (A_PriorHotKey = A_ThisHotKey and A_TimeSincePriorHotkey < Time)
{
Count ++
}
Else
{
Count = 1
}
SetTimer, Handler, %Time%
return
Handler:
SetTimer, Handler, Off
IfEqual, Count, 2
{
If (Mouse_y > 1040)
{
If (Mouse_x > 50) and (Mouse_x < 98) ;over my explorer icon
{
Run, "%A_AppData%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\Internet Explorer.lnk"
}
If (Mouse_x > 99) and (Mouse_x < 147 ) ; over powershell ise
{
Run, explorer.exe
}
If (Mouse_x > 148) and (Mouse_x < 196 ) ; over chrome
{
Run, "%A_AppData%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\outlook 2013.lnk"
}
If (Mouse_x > 197) and (Mouse_x < 245) ; over ie
{
Run, "%A_AppData%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\Active Directory Users and Computers.lnk"
}
If (Mouse_x > 246) and (Mouse_x < 294 ) ; over vs 2015
{
Run, "%A_AppData%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\DHCP.lnk"
}
If (Mouse_x > 295) and (Mouse_x < 343 ) ; over pusbullet
{
Run, "%A_AppData%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\DNS.lnk"
}
}
}
IfEqual, Count, 3
{
If (Mouse_y > 1040)
{
If (Mouse_x > 50) and (Mouse_x < 98) ;over my explorer icon
{
Run, "%A_AppData%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\Internet Explorer.lnk" -private
}
If (Mouse_x > 99) and (Mouse_x < 147 ) ; over powershell ise
{
Run, explorer.exe
}
If (Mouse_x > 148) and (Mouse_x < 196 ) ; over chrome
{
Run, "%A_AppData%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\outlook 2013.lnk"
}
If (Mouse_x > 197) and (Mouse_x < 245) ; over ie
{
Run, "%A_AppData%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\Active Directory Users and Computers.lnk"
}
If (Mouse_x > 246) and (Mouse_x < 294 ) ; over vs 2015
{
Run, "%A_AppData%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\DHCP.lnk"
}
If (Mouse_x > 295) and (Mouse_x < 343 ) ; over pusbullet
{
Run, "%A_AppData%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\DNS.lnk"
}
}
}
回答1:
I've tried similar things before and let me tell you, the locations of the icons are not in the registry. I logged every file/registry access that occurred when clicking or moving a taskbar icon. So I can only assume that this information is stored in the explorer process. You can more or less proof that by moving around the taskbar icons and then restarting the explorer process. The taskbar icon positions will be reset then.
Blauhirn already pointed to a little workaround that I wrote some time ago. But it's really limited...
A properly set up image search should work though.
- find all windows
- find the process that runs each window and extract the icon from its exe
(or even better find a way to extract the icon form the window directly.) - find out which size the taskbar icons are
- maybe resize the extracted icons using gdip
- then create a taskbar specific lbutton hotkey that does an image search on a small radius around the mouse in the taskbar.
But that would take a lot of research and work..
The cleanest thing would probably be to use a shell hook. But ahk scripts that make use of shell hooks are very rare, so that would mean even more research..
Edit:
I just realized that you are talking about pinned icons in particular.
For that you could loop through the directory that holds all the pinned shortcuts...
Just to give you some idea:
(completely untested and the imagesearch most likely needs adjustment)
CoordMode, Mouse, Screen
~LButton::
If (A_TimeSincePriorHotkey<400) and (A_PriorHotkey="~LButton") {
WinGetPos, taskBarX, taskBarY, taskBarW, taskBarH, ahk_class Shell_TrayWnd
MouseGetPos, mouseX, mouseY
If (mouseX >= taskBarX && mouseY >= taskBarY && mouseX <= taskBarX+taskBarW && mouseY <= taskBarY+taskBarH)
OnDoubleClickTaskbar(mouseX, mouseY, taskBarX, taskBarY, taskBarW, taskBarH)
}
Return
OnDoubleClickTaskbar(mX,mY,tX,tY,tH,tW) {
iconSize := GetTaskbarIconSize()
pinnedIcons := GetPinnedIcons()
Loop % pinnedIcons.MaxIndex() {
ico := pinnedIcons[A_Index]
ImageSearch, foundX, foundY, tX, tY, tW, tH, % "*Icon" ico.index " " "*20" " " "*w" iconSize " " "*h" iconSize " " ico.icon
If (!ErrorLevel)
MsgBox, % "Icon found: " ico.icon "," ico.index " at " "x" foundX " y" foundY
Else
MsgBox, % "Icon not found: " ico.icon "," ico.index
}
}
GetPinnedIcons() {
pinnedIcons := []
Loop, % A_AppData "\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\*.lnk"
{
FileGetShortcut, % A_LoopFileFullPath, shortCutTarget,,,, icon, iconIndex
pinnedIcons[A_Index] := {"icon":icon, "index": iconIndex}
}
Return pinnedIcons
}
GetTaskbarIconSize() {
Return 32
}
来源:https://stackoverflow.com/questions/34888422/find-cordinates-of-pinned-taskbar-shorcuts