I want to make a script that detects when taskbar icon flashes, and activates a program. I would like to use AutoIt or the Windows API.
How to detect when a program's taskbar icon starts flashing?
I want to make a script that detects when taskbar icon flashes, and activates a program. I would like to use AutoIt or the Windows API.
How to detect when a program's taskbar icon starts flashing?
To answer your question directly, there is no easy (documented and reliable) way to detect the flashing of the window. It occurs as a result of FlashWindow/FlashWindowEx. A very intrusive and heavy-handed option is to perform global hooking of both APIs. You could do this by injecting a DLL to every usermode application and performing a local hook/detour which notifies some central executable you own.
However, there is a greater underlying problem with what you are proposing, which makes it extremely undesirable. Imagine an application which constantly flashes when it does not have focus. Your app would set it to the foreground. What would happen if there were two such applications?
Using a WH_SHELL
hook as Raymond suggests is not too difficult and is done by calling SetWindowsHookEx as so:
SetWindowsHookEx(WH_SHELL, hook_proc, NULL, dwPID);
This sets a shell hook with the HOOKPROC
as hook_proc
and dwPID
is the thread which we want to associate the hook with. Since you mention that you already know which program you want to target, I'll assume you have a HWND
to that window already. You need to generate the dwPID
, which can be done as so:
DWORD dwID = GetWindowThreadProcessId(hwnd, NULL)
This will populate dwPID
with the associated PID of the HWND
. For the next step, I assume the hook procedure to be in the current executable as opposed to a DLL. The hook procedure might be something like this:
LRESULT CALLBACK hook_proc(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode == HSHELL_REDRAW && lParam){
SetForegroundWindow(hwnd); // assumed hwnd is a global
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
The code above has not been tested and might contain mistakes but should give you a general idea of what to do.
One important thing to note with window hooks is that SetWindowHookEx
must be called from a program with the same bitiness as the target. i.e. if your target is 64 bit, the caller of SetWindowHookEx
must also be 64 bit. Also, after you are done, you should cleanup by removing your hook with UnhookWindowsHookEx.
Use the RegisterShellHookWindow API and listen for HSHELL_FLASH messages.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644989(v=vs.85).aspx