Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

Use the RegisterShellHookWindow API and listen for HSHELL_FLASH messages.

http://msdn.microsoft.com/en-us/library/windows/desktop/ms644989(v=vs.85).aspx

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top