Detect application icon change ?

Get help with using AutoHotkey and its commands and hotkeys
User avatar
Sir Teddy the First
Posts: 94
Joined: 05 Aug 2019, 12:31
Contact:

Re: Detect application icon change ?

22 Aug 2019, 01:57

Hi,
you could do an ImageSearch for the new icon or just a PixelGetColor to detect that.
But depending on what program it is, there might be an easier solution.
:eh: :think:
tmplinshi
Posts: 1600
Joined: 01 Oct 2013, 14:57

Re: Detect application icon change ?

22 Aug 2019, 02:14

Code: Select all

#Include TrayIcon.ahk ; https://www.autohotkey.com/boards/viewtopic.php?t=1229
#Persistent
ExeName := "StrokesPlus.exe"
SetTimer, DetectTrayIconChange, 1000
Return

DetectTrayIconChange:
	o := TrayIcon_GetInfo(ExeName)
	if (hIconPre && o[1].hIcon != hIconPre)
	{
		MsgBox Icon Changed. Do Something.
	}
	hIconPre := o[1].hIcon
Return
The above works, but costs about 0.15% CPU. The following code reduced to 0.05% CPU.

Code: Select all

#Persistent
info := new TrayIconInfo("StrokesPlus.exe")
SetTimer, DetectTrayIconChange, 1000
Return

DetectTrayIconChange:
	if (hIconPre && info.hIcon != hIconPre)
	{
		MsgBox Icon Changed. Do Something.
	}
	hIconPre := info.hIcon
Return

; Based on TrayIcon (https://www.autohotkey.com/boards/viewtopic.php?t=1229)
class TrayIconInfo
{
	__New(sExeName)
	{
		dhw := A_DetectHiddenWindows
		DetectHiddenWindows, On

		oTrayInfo := []
		For key,sTray in ["Shell_TrayWnd", "NotifyIconOverflowWindow"]
		{
			idxTB := this.TrayIcon_GetTrayBar(sTray)
			WinGet, pidTaskbar, PID, ahk_class %sTray%
			
			this.hProc := DllCall("OpenProcess",	UInt,0x38, Int,0, UInt,pidTaskbar)
			this.pRB   := DllCall("VirtualAllocEx", Ptr,this.hProc, Ptr,0, UPtr,20, UInt,0x1000, UInt,0x04)

			this.szBtn := VarSetCapacity(btn, (A_Is64bitOS ? 32 : 20), 0)
			this.szNfo := VarSetCapacity(nfo, (A_Is64bitOS ? 32 : 24), 0)

			; TB_BUTTONCOUNT = 0x0418
			SendMessage, 0x0418, 0, 0, ToolbarWindow32%idxTB%, ahk_class %sTray%
			Loop, %ErrorLevel%
			{
				; TB_GETBUTTON 0x0417
				SendMessage, 0x0417, A_Index-1, this.pRB, ToolbarWindow32%idxTB%, ahk_class %sTray%
				DllCall("ReadProcessMemory", Ptr,this.hProc, Ptr,this.pRB, Ptr,&btn, UPtr,this.szBtn, UPtr,0)
				dwData  := NumGet(btn, (A_Is64bitOS ? 16 : 12), "UPtr")
				DllCall("ReadProcessMemory", Ptr,this.hProc, Ptr,dwData, Ptr,&nfo, UPtr,this.szNfo, UPtr,0)

				hWnd  := NumGet(nfo, 0, "Ptr")
				WinGet, sProcess, ProcessName, ahk_id %hWnd%
				if (sProcess = sExeName)
				{
					DetectHiddenWindows, %dhw%
					this.nfo := &nfo
					this.btn := &btn
					return this
				}
			}
		}

		DetectHiddenWindows, %dhw%
		throw, "Unable to get info"
	}

	__Delete()
	{
		DllCall("VirtualFreeEx", Ptr,this.hProc, Ptr,this.pRB, UPtr,0, UInt,0x8000)
		DllCall("CloseHandle",   Ptr,this.hProc)
	}

	hIcon
	{
		get {
			DllCall("ReadProcessMemory", Ptr,this.hProc, Ptr,this.pRB, Ptr,this.btn, UPtr,this.szBtn, UPtr,0)
			dwData  := NumGet(this.btn, (A_Is64bitOS ? 16 : 12), "UPtr")
			DllCall("ReadProcessMemory", Ptr,this.hProc, Ptr,dwData, Ptr,this.nfo, UPtr,this.szNfo, UPtr,0)
			return NumGet(this.nfo, (A_Is64bitOS ? 24 : 20), "Ptr")
		}
	}

	TrayIcon_GetTrayBar(sTray:="Shell_TrayWnd")
	{
		d := A_DetectHiddenWindows
		DetectHiddenWindows, On
		WinGet, ControlList, ControlList, ahk_class %sTray%
		RegExMatch(ControlList, "(?<=ToolbarWindow32)\d+(?!.*ToolbarWindow32)", nTB)
		Loop, %nTB%
		{
			ControlGet, hWnd, hWnd,, ToolbarWindow32%A_Index%, ahk_class %sTray%
			hParent := DllCall( "GetParent", Ptr, hWnd )
			WinGetClass, sClass, ahk_id %hParent%
			If !(sClass == "SysPager" || sClass == "NotifyIconOverflowWindow" )
				Continue
			idxTB := A_Index
			Break
		}
		DetectHiddenWindows, %d%
		Return idxTB
	}
}

Return to “Ask For Help”

Who is online

Users browsing this forum: Bing [Bot], Google [Bot], grossermanitu, HiSoKa, mikeyww, pAnDeLa, TAC109 and 42 guests