Old script to hide unusued tray icons broken with Win10 update
Posted: 06 Oct 2016, 10:41
I have an ancient script written by Sean several years ago that clears out all old tray icons. For instance if you terminate an AHK script or any other program with a tray icon, it will remove the icon from the system tray. The full script is shown below, although it's really just cleanup of something Sean wrote so I've never really understood it.
This code quit working with the Windows 10 update that was pushed out around 10/26/16. I'm wondering if anybody else has figured out how to fix this yet. If so, I would appreciate any tips. If not I will have to figure it out since life is not worth living with orphaned tray icons, and post the results.
TIA,
Wade Hatler
https://autohotkey.com/boards/viewtopic.php?t=1229
This code quit working with the Windows 10 update that was pushed out around 10/26/16. I'm wondering if anybody else has figured out how to fix this yet. If so, I would appreciate any tips. If not I will have to figure it out since life is not worth living with orphaned tray icons, and post the results.
TIA,
Wade Hatler
https://autohotkey.com/boards/viewtopic.php?t=1229
Code: Select all
#SingleInstance force
DetectHiddenWindows, On
#NoTrayIcon
NoTrayOrphans()
ExitApp
Return
NoTrayOrphans() {
TrayInfo:= TrayIcons2(sExeName,"ahk_class Shell_TrayWnd","ToolbarWindow32" . GetTrayBar()) "`n"
. TrayIcons2(sExeName,"ahk_class NotifyIconOverflowWindow","ToolbarWindow321")
While Item:= StrX(TrayInfo, "idx:" ,N,0, "`n" ,1,0, N) {
ProcessName:= StrX(Item, "| Process: ",1,11, "|",1,2)
ProcesshWnd:= StrX(Item, "hWnd: ",1,6, " ",1,1)
ProcessuID := StrX(Item, "| uID: ",1,7, " ",1,1)
If !ProcessName {
DTrace(ProcesshWnd, ProcessuID)
RemoveTrayIcon(ProcesshWnd, ProcessuID)
}
}
}
RemoveTrayIcon(hWnd, uID, nMsg = 0, hIcon = 0, nRemove = 2) {
NumPut(VarSetCapacity(ni,444,0), ni)
NumPut(hWnd , ni, 4)
NumPut(uID , ni, 8)
NumPut(1|2|4, ni,12)
NumPut(nMsg , ni,16)
NumPut(hIcon, ni,20)
Return DllCall("shell32\Shell_NotifyIconA", "Uint", nRemove, "Uint", &ni)
}
TrayIcons2(sExeName,traywindow,control) {
DetectHiddenWindows, On
WinGet, pidTaskbar, PID, %traywindow%
hProc:= DllCall("OpenProcess", "Uint", 0x38, "int", 0, "Uint", pidTaskbar)
pProc:= DllCall("VirtualAllocEx", "Uint", hProc, "Uint", 0, "Uint", 32, "Uint", 0x1000, "Uint", 0x4)
SendMessage, 0x418, 0, 0, %control%, %traywindow%
Loop, %ErrorLevel%
{
SendMessage, 0x417, A_Index-1, pProc, %control%, %traywindow%
VarSetCapacity(btn,32,0), VarSetCapacity(nfo,32,0)
DllCall("ReadProcessMemory", "Uint", hProc, "Uint", pProc, "Uint", &btn, "Uint", 32, "Uint", 0)
iBitmap := NumGet(btn, 0)
idn := NumGet(btn, 4)
Statyle := NumGet(btn, 8)
If dwData := NumGet(btn,12)
iString := NumGet(btn,16)
Else dwData := NumGet(btn,16,"int64"), iString:=NumGet(btn,24,"int64")
DllCall("ReadProcessMemory", "Uint", hProc, "Uint", dwData, "Uint", &nfo, "Uint", 32, "Uint", 0)
If NumGet(btn,12)
hWnd := NumGet(nfo, 0)
, uID := NumGet(nfo, 4)
, nMsg := NumGet(nfo, 8)
, hIcon := NumGet(nfo,20)
Else
hWnd := NumGet(nfo, 0,"int64"), uID:=NumGet(nfo, 8), nMsg:=NumGet(nfo,12), hIcon := NumGet(nfo,24)
WinGet, pid, PID, ahk_id %hWnd%
WinGet, sProcess, ProcessName, ahk_id %hWnd%
WinGetClass, sClass, ahk_id %hWnd%
If !sExeName || (sExeName = sProcess) || (sExeName = pid)
VarSetCapacity(sTooltip,128), VarSetCapacity(wTooltip,128*2)
, DllCall("ReadProcessMemory", "Uint", hProc, "Uint", iString, "Uint", &wTooltip, "Uint", 128*2, "Uint", 0)
, DllCall("WideCharToMultiByte", "Uint", 0, "Uint", 0, "str", wTooltip, "int", -1, "str", sTooltip, "int", 128, "Uint", 0, "Uint", 0)
, sTrayIcons .= "idx: " . A_Index-1 . " | idn: " . idn . " | Pid: " . pid . " | uID: " . uID . " | MessageID: " . nMsg . " | hWnd: " . hWnd . " | Class: " . sClass . " | Process: " . sProcess . " | Icon: " . hIcon . " | Tooltip: " . wTooltip . "`n"
}
DllCall("VirtualFreeEx", "Uint", hProc, "Uint", pProc, "Uint", 0, "Uint", 0x8000)
DllCall("CloseHandle", "Uint", hProc)
return sTrayIcons
}
GetTrayBar() {
ControlGet, hParent, hWnd,, TrayNotifyWnd1 , 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
}
StrX( H, Bs="",BO=0,BT=1, ES="",EO=0,ET=1, ByRef N="" ) {
Return SubStr(H,P:=(((Z:=StrLen(ES))+(X:=StrLen(H))+StrLen(Bs)-Z-X)?((T:=InStr(H,Bs,0,((BO
<0)?(1):(BO))))?(T+BT):(X+1)):(1)),(N:=P+((Z)?((T:=InStr(H,ES,0,((EO)?(P+1):(0))))?(T-P+Z
+(0-ET)):(X+P)):(X)))-P)
} ; By SKAN: http://www.autohotkey.com/community/viewtopic.php?p=312116#p312116