检测任务栏图标闪烁

时间:2012-02-16 04:40:45

标签: windows winapi windows-7 taskbar autoit

我想创建一个脚本,用于检测任务栏图标何时闪烁,并激活程序。我想使用AutoIt或Windows API。

如何检测程序的任务栏图标何时开始闪烁?

2 个答案:

答案 0 :(得分:4)

使用RegisterShellHookWindow API并侦听HSHELL_FLASH消息。

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

答案 1 :(得分:2)

要直接回答您的问题,没有简单(记录和可靠)的方法来检测窗口的闪烁。它是FlashWindow / FlashWindowEx的结果。一个非常侵入性和苛刻的选择是执行两个API的全局挂钩。您可以通过向每个usermode应用程序注入一个DLL并执行本地hook / detour来通知您拥有的某个中央可执行文件来实现此目的。

然而,你提议的内容存在更大的潜在问题,这使得它非常不受欢迎。想象一下一个应用程序,当它没有焦点时不断闪烁。您的应用会将其设置为前台。如果有two such applications会怎么样?


雷蒙德建议使用WH_SHELL钩子并不太困难,可以通过调用SetWindowsHookEx来完成:

SetWindowsHookEx(WH_SHELL, hook_proc, NULL, dwPID);

这将HOOKPROC设置为hook_proc的shell挂钩,dwPID是我们想要挂钩的线程。既然你提到你已经知道你想要定位哪个程序,我会假设你已经有了HWND那个窗口。您需要生成dwPID,可以这样做:

DWORD dwID = GetWindowThreadProcessId(hwnd, NULL)

这将使用dwPID的关联PID填充HWND。对于下一步,我假设钩子过程在当前可执行文件中而不是DLL。钩子程序可能是这样的:

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);
}

上面的代码尚未经过测试,可能包含错误,但应该让您大致了解该怎么做。

窗口挂钩需要注意的一件重要事情是必须从与目标具有相同比特性的程序中调用SetWindowHookEx。即如果您的目标是64位,则SetWindowHookEx的调用者也必须是64位。此外,完成后,您应该使用UnhookWindowsHookEx删除挂钩进行清理。