Old script to hide unusued tray icons broken with Win10 update

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Wade Hatler
Posts: 60
Joined: 03 Oct 2013, 19:49
Location: Seattle Area
Contact:

Old script to hide unusued tray icons broken with Win10 update

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

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


User avatar
FanaticGuru
Posts: 1907
Joined: 30 Sep 2013, 22:25

Re: Old script to hide unusued tray icons broken with Win10 update

06 Oct 2016, 13:19

You might check out my post a little later in the thread you linked to.

https://autohotkey.com/boards/viewtopic ... 9198#p9186

I updated my version of TrayIcon to work with Windows 10.

I do not have a NoTrayOrphans() function but it seems to be using TrayIcon functions. It is definitely a good place to start to get the function you want working again.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
User avatar
Bon
Posts: 17
Joined: 11 Jan 2014, 07:31

Re: Old script to hide unusued tray icons broken with Win10 update

07 Oct 2016, 13:21

I have the same problem - I had Seans' script working, and it broke. So I tried your code, FanaticGuru, but according to SendMessage, the orphaned icon(s) just don't exist -

Code: Select all

SendMessage, 0x418, 0, 0, ToolbarWindow32%key%, ahk_class %sTray%   ; TB_BUTTONCOUNT
sets ErrorLevel to zero (no icons).

Strangely, though, I can still kill the icon with

Code: Select all

TrayIcon_Delete(0)
as long as it is the only one in Shell_TrayWnd...

I would really appreciate a solution!

TIA / Bon
Quidquid Latine dictum sit altum videtur
"Anything said in Latin sounds profound"
User avatar
FanaticGuru
Posts: 1907
Joined: 30 Sep 2013, 22:25

Re: Old script to hide unusued tray icons broken with Win10 update

07 Oct 2016, 13:53

It appears that NoTrayOrphans is just looking for Icons that have no ProcessName. If that is the case I can try writing a script that uses my TrayIcon_GetInfo and then look through all the icons and remove the ones that have no process.

For what ever reason I have not had problems with orphaned icons in a long time. What is a sure fire way to create them in Windows 10 so that I can test?

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
User avatar
kczx3
Posts: 1647
Joined: 06 Oct 2015, 21:39

Re: Old script to hide unusued tray icons broken with Win10 update

07 Oct 2016, 14:21

FanaticGuru wrote:It appears that NoTrayOrphans is just looking for Icons that have no ProcessName. If that is the case I can try writing a script that uses my TrayIcon_GetInfo and then look through all the icons and remove the ones that have no process.

For what ever reason I have not had problems with orphaned icons in a long time. What is a sure fire way to create them in Windows 10 so that I can test?

FG
I always get them when using DBGp with Notepad++ to debug ahk scripts. If you go to run the same script again with DBGp and the previous one is still running, it will prompt you to terminate the previous one. That almost always leaves an orphaned icon in the tray until you hover over it.
User avatar
Bon
Posts: 17
Joined: 11 Jan 2014, 07:31

Re: Old script to hide unusued tray icons broken with Win10 update

07 Oct 2016, 14:51

Alas, it is TrayIcon_GetInfo that doesn't see orphaned icons...
Quidquid Latine dictum sit altum videtur
"Anything said in Latin sounds profound"
User avatar
Bon
Posts: 17
Joined: 11 Jan 2014, 07:31

Re: Old script to hide unusued tray icons broken with Win10 update

09 Oct 2016, 10:07

That doesn't work for me now either, but I'm pretty sure it did before the latest MScrewup ... :(
Quidquid Latine dictum sit altum videtur
"Anything said in Latin sounds profound"

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: tabr3 and 153 guests