How to remove systray icon after process was closed?

Get help with using AutoHotkey and its commands and hotkeys
genaro
Posts: 11
Joined: 09 Feb 2016, 20:07

How to remove systray icon after process was closed?

15 Nov 2019, 16:26

After I close my program

Code: Select all

	Process, close, Lingvo.exe   
	Process, close, Lvagent.exe
	Process, close, Lvagent64.exe
it leaves an icon in the lower right corner until I hover on it. How do I get rid of the icon right away?

http://i.imgur.com/Vx8uuOL.png

How do I post image lol?

[Mod edit: Provisional topic name added.]
gregster
Posts: 3379
Joined: 30 Sep 2013, 06:48

Re: How to remove systray icon after process was closed?

15 Nov 2019, 16:34

genaro wrote:
15 Nov 2019, 16:26
How do I post image lol?
Welcome back.
Either be more active on the forum to be able to post external links or upload the image to the forum via the forum editor: Attachments > Add files > (Place inline)


PS: I fixed your link and added a topic name (you may edit that - or better don't :) Your edit would just break the image link again.).
User avatar
JoeWinograd
Posts: 1345
Joined: 10 Feb 2014, 20:00

Re: How to remove systray icon after process was closed?

15 Nov 2019, 16:53

Hi genaro,

The method that I use is thanks to Cyruz, Sean, and FanaticGuru, and their awesome TrayIcon Library. The version that I'm using is here:
https://autohotkey.com/boards/viewtopic.php?p=9186#p9186

The key to the solution is to remove the icon before doing the Process,Close via a call like this:

TrayIcon_Remove(hWnd,uID)

Works a charm! Regards, Joe
genaro
Posts: 11
Joined: 09 Feb 2016, 20:07

Re: How to remove systray icon after process was closed?

15 Nov 2019, 18:39

JoeWinograd wrote:
15 Nov 2019, 16:53
Hi genaro,

The method that I use is thanks to Cyruz, Sean, and FanaticGuru, and their awesome TrayIcon Library. The version that I'm using is here:
https://autohotkey.com/boards/viewtopic.php?p=9186#p9186

The key to the solution is to remove the icon before doing the Process,Close via a call like this:

TrayIcon_Remove(hWnd,uID)

Works a charm! Regards, Joe
I've no idea how to use. Should I change hwnd with something?
User avatar
JoeWinograd
Posts: 1345
Joined: 10 Feb 2014, 20:00

Re: How to remove systray icon after process was closed?

15 Nov 2019, 21:03

I presume that you know about parameters in functions. If not, study the doc here:
https://www.autohotkey.com/docs/Functions.htm#param

All of the parameters in the library's functions are defined in the TrayIcon_GetInfo function. The call to TrayIcon_Remove requires hWnd and uID as params. You can get those easily with a call to TrayIcon_GetInfo, where the param is the name of the executable. Once you get hWnd and uID from TrayIcon_GetInfo (keep in mind that it returns an object), call TrayIcon_Remove with those params. Do that for each of your three executables before you do the Process,Close on each.

Let me know if you need additional help writing the script. Regards, Joe
User avatar
JoeWinograd
Posts: 1345
Joined: 10 Feb 2014, 20:00

Re: How to remove systray icon after process was closed?

15 Nov 2019, 23:54

Hi genaro,
I haven't heard back from you on my previous post and I'm going offline now for the evening, so I'll leave you with some code that works with one of your executables:

Code: Select all

ProgramEXE:="Lingvo.exe"
oTrayInfo:={}
oTrayInfo:=TrayIcon_GetInfo(ProgramEXE)
For index,item in oTrayInfo
{
  UniqueID:=item.uID
  Handle:=item.hWnd
}
TrayIcon_Remove(Handle,UniqueID)
Process,Close,%ProgramEXE%
You could parameterize it into a function for your other two executables (and, potentially, other executables in the future) or do it the easy way and copy/paste the snippet twice, changing the ProgramEXE assignment statement to have Lvagent.exe in one copy and Lvagent64.exe in the second one. Of course, you'll need to have the library in your script or via #Include TrayIconLibrary.ahk. Regards, Joe
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

Re: How to remove systray icon after process was closed?

19 Nov 2019, 18:11

Here's a script with no dependencies:

Code: Select all

q:: ;systray - remove icons for closed processes
;warning: the script remotely accesses the memory of explorer.exe, so could potentially crash it
;tested on Windows 7
DetectHiddenWindows, On
WinGet, hWnd, ID, ahk_class NotifyIconOverflowWindow
ControlGet, hCtl, Hwnd,, ToolbarWindow321, % "ahk_id " hWnd
WinGetPos, vWinX, vWinY,,, % "ahk_id " hWnd
WinGetPos, vCtlX, vCtlY,,, % "ahk_id " hCtl

SendMessage, 0x418, 0, 0,, % "ahk_id " hCtl ;TB_BUTTONCOUNT := 0x418
vCount := ErrorLevel

;remote access: open
WinGet, vPID, PID, % "ahk_id " hWnd
if !vPID
	return
vAccess := 0x18 ;PROCESS_VM_READ := 0x10 ;PROCESS_VM_OPERATION := 0x8
vAllocationType := 0x1000 ;MEM_COMMIT := 0x1000
vProtect := 0x4 ;PAGE_READWRITE := 0x4
vSize := 16
hProc := DllCall("kernel32\OpenProcess", "UInt",vAccess, "Int",0, "UInt",vPID, "Ptr")
pBuf := DllCall("kernel32\VirtualAllocEx", "Ptr",hProc, "Ptr",0, "UPtr",vSize, "UInt",vAllocationType, "UInt",vProtect, "Ptr")

vIndex := vCount-1 ;0-based index
Loop % vCount
{
	VarSetCapacity(RECT, 16, 0)
	SendMessage, 0x41D, % vIndex, % pBuf,, % "ahk_id " hCtl ;TB_GETITEMRECT := 0x41D
	DllCall("kernel32\ReadProcessMemory", "Ptr",hProc, "Ptr",pBuf, "Ptr",&RECT, "UPtr",vSize, "Ptr",0)
	vPosX := NumGet(&RECT, 0, "Int")
	vPosY := NumGet(&RECT, 4, "Int")
	vPosW := NumGet(&RECT, 8, "Int") - vPosX
	vPosH := NumGet(&RECT, 12, "Int") - vPosY
	vPosX += vPosW/2, vPosY += vPosH/2
	PostMessage, 0x200, 0, % (vPosX & 0xFFFF)|(vPosY<<16),, % "ahk_id " hCtl ;WM_MOUSEMOVE := 0x200
	vIndex--

	;CoordMode, Mouse, Screen
	;MouseMove, % vCtlX + vPosX, % vCtlY + vPosY ;to visually the confirm coordinates
	;Sleep, 100
}

;remote access: close
;MEM_RELEASE := 0x8000
DllCall("kernel32\VirtualFreeEx", "Ptr",hProc, "Ptr",pBuf, "UPtr",vSize, "UInt",0x8000)
DllCall("kernel32\CloseHandle", "Ptr",hProc)
MsgBox, % "done"
return

Here's a simpler script, but that requires Acc:

Code: Select all

;[Acc functions]
;Acc library (MSAA) and AccViewer download links - AutoHotkey Community
;https://autohotkey.com/boards/viewtopic.php?f=6&t=26201

q:: ;systray - remove icons for closed processes (via Acc)
;tested on Windows 7
DetectHiddenWindows, On
WinGet, hWnd, ID, ahk_class NotifyIconOverflowWindow
oAcc := Acc_Get("Object", "4.2.4", 0, "ahk_id " hWnd)
vCount := oAcc.accChildCount()
hCtl := Acc_WindowFromObject(oAcc)
;WinGetPos, vWinX, vWinY,,, % "ahk_id " hWnd
WinGetPos, vCtlX, vCtlY,,, % "ahk_id " hCtl

vIndex := vCount
Loop % vCount
{
	oRect := Acc_Location(oAcc, vIndex)
	vPosX := Round(oRect.x + oRect.w/2) - vCtlX
	vPosY := Round(oRect.y + oRect.h/2) - vCtlY
	PostMessage, 0x200, 0, % (vPosX & 0xFFFF)|(vPosY<<16),, % "ahk_id " hCtl ;WM_MOUSEMOVE := 0x200
	vIndex--

	;CoordMode, Mouse, Screen
	;MouseMove, % vCtlX+vPosX, % vCtlY+vPosY ;to visually confirm the coordinates
	;Sleep, 100
}

oAcc := oRect := ""
MsgBox, % "done"
return

Here's a script to generate icons (for terminated processes) to be removed:

Code: Select all

;systray - start script and terminate it (leave icons in the systray)
;warning: terminates the script
DetectHiddenWindows, On
WinGet, vPID, PID, % "ahk_id " A_ScriptHwnd
SoundBeep
Process, Close, % vPID
return

Link (some related code):
Programatically right clicking on a tray icon - Ask for Help - AutoHotkey Community
https://autohotkey.com/board/topic/5485-programatically-right-clicking-on-a-tray-icon/
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Ask For Help”

Who is online

Users browsing this forum: Bing [Bot], boiler, Odlanir, pn4265 and 227 guests