Hide/restore tray icon of another process/ahk_script by pid/hwnd Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
-_+
Posts: 70
Joined: 06 Dec 2014, 12:43

Hide/restore tray icon of another process/ahk_script by pid/hwnd

02 Sep 2016, 09:13

Here lexikos provided a way to hide and restore script's own icon:
lexikos wrote:

Code: Select all

MsgBox This script has an icon.
If killTrayIcon(A_ScriptHwnd)
    MsgBox And now it doesn't.
If restoreTrayIcon(A_ScriptHwnd)
    MsgBox And now it does again.

killTrayIcon(scriptHwnd) {
    DetectHiddenWindows, On
    Static NIM_DELETE := 2, AHK_NOTIFYICON := 1028
    VarSetCapacity(nic, size := 936 + 4 * A_PtrSize)
    NumPut(size, nic, 0, "UInt")
    NumPut(scriptHwnd, nic, A_PtrSize)
    NumPut(AHK_NOTIFYICON, nic, A_PtrSize * 2, "UInt")
    Return DllCall("Shell32\Shell_NotifyIcon", "UInt", NIM_DELETE, "Ptr", &nic)
}

restoreTrayIcon(scriptHwnd) {
    DetectHiddenWindows, On
    WM_TASKBARCREATED := DllCall("RegisterWindowMessage", "Str", "TaskbarCreated")
    PostMessage, WM_TASKBARCREATED,,,, ahk_id %scriptHwnd%
}
This above script works, but I can't make those functions work with the icon of another script.
Say we have script dummy.ahk with the code #Persistent that, for the ease of example we are going to start right from the script that is supposed to kill its tray icon:

Code: Select all

Run, dummy.ahk,,, dummy_pid
While !(dummy_hwnd)	; 
	WinGet, dummy_hwnd, ID, ahk_pid %dummy_pid%
	; dummy_hwnd := WinExist("ahk_pid " dummy_pid)
killTrayIcon(dummy_hwnd)	; fails
I know there's tic's HideTrayIcon(idn, bHide = True), Sean's similar function, that function's further development into a whole lib with the help of Cyruz, and even Chef's version of a lib to do the same. Problem is - they all operate with some uids/idns instead of something related to a process: working directly with PID - would be the best, working with hwnd - would be okay.

Could someone, please, tell me why doesn't lexikos's script work with hwnd of another ahk script and how to make it work by hwnd (or more preferably right by PID)?
Last edited by -_+ on 02 Sep 2016, 21:12, edited 1 time in total.
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: Hide/restore tray icon of another process/ahk_script by pid/hwnd  Topic is solved

02 Sep 2016, 20:36

The system might require that the process which calls Shell_NotifyIcon actually owns the icon/hwnd. Which version of Windows are you on?

Even if that's not the case, this method would only work with AutoHotkey scripts because we know the ID of the icon in advance (it is AHK_NOTIFYICON). For scripts, there's a very easy alternative: call Menu Tray, NoIcon. To trigger it from another script, you only need a few lines of code to define a function and register it with OnMessage.

It only takes one step to get from PID to HWND for a script, or more likely, you can just replace ahk_id %hwnd% with ahk_class AutoHotkey ahk_pid %pid%.
While !(dummy_hwnd) ;
WinGet, dummy_hwnd, ID, ahk_pid %dummy_pid%
Did you use DetectHiddenWindows On? Either way, it would probably be better to use WinWait followed by dummy_hwnd := WinExist().
-_+
Posts: 70
Joined: 06 Dec 2014, 12:43

Re: Hide/restore tray icon of another process/ahk_script by pid/hwnd

02 Sep 2016, 21:04

Windows7SP1x64, latest ahk_x64.
I am trying to make it work at least for AHK scripts' icons.
I don't like the Menu, Tray, NoIcon approach as it requires modification of other scripts, I'd rather have a single script commanding others.
Yes, I did use DetectHIddenWindows, On (although I forgot to mention it in the example code in this thread, but real code surely always had it) and I also did some debugging to make sure that the variable dummy_hwnd actually gets a value (not sure if the right one, but I hope so).

So it turns out, that sometimes the above mentioned code catches wrong hwnd and that happens only when I didn't bother to close the old instance of the script before executing a new one, because I relied on #SingleInstance, force, but seems like it doesn't work fast enough or due to some other reason - my code catches wrong hwnd in such a case. It got resolved by specifying ahk_class AutoHotkey along with ahk_pid as WinTitle parameter for WinGet

Thank you for your help.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: aitaixy, dipahk and 208 guests