2012-02-16 125 views
3

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

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

+7

这没有意义。一个按钮闪烁,因为当用户忙于使用窗口时,程序试图在前台推窗。用户非常喜欢防止这种焦点窃取。 Google SPI_SETFOREGROUNDLOCKTIMEOUT如果你想忽略它。 – 2012-02-16 04:46:12

+0

你可以在你的任务栏区域做一个PixelSearch(可以找到:'$ taskbar = WinGetHandle(“[Class:Shell_TrayWnd]”)','$ taskbarPos = WinGetPos($ taskbar)','$ tasklistPos = ControlGetPos($ taskbar ($ taskbarPos [0] + $ tasklistPos [0],$ taskbarPos [1] + $ tasklistPos [1],$ taskbarPos [0],“”,“[CLASS:MSTaskListWClass; INSTANCE:1]”)') ] + $ tasklistPos [2],$ taskbarPos [1] + $ tasklistPos [3],0x00CCCC00)''0x00CCCC00'就是橙色的闪光颜色......寻找一个不断的发生。 – Samoth 2012-02-20 22:39:22

回答

2

要直接回答您的问题,没有简单的(记录和可靠的)方法来检测窗口的闪烁。它由于FlashWindow/FlashWindowEx而发生。一个非常干扰和严厉的选择是执行两个API的全局钩子。您可以通过向每个用户模式应用程序注入DLL并执行本地钩子/绕道来通知您拥有的某个中央可执行文件。

但是,您提出的问题存在更大的潜在问题,这使得它非常不可取。想象一下,如果应用程序没有焦点,它会不断闪烁。你的应用会将其设置为前景。如果有two such applications,会发生什么?


使用WH_SHELL钩如雷蒙建议是不是太困难,并通过调用SetWindowsHookEx为这样做:

SetWindowsHookEx(WH_SHELL, hook_proc, NULL, dwPID); 

此设置与HOOKPROChook_procdwPID壳钩是线程这我们想把这个钩子与之联系起来。既然你提到你已经知道你想要定位哪个程序,我假设你已经有了一个HWND。你需要生成dwPID,它可以为这样做:

DWORD dwID = GetWindowThreadProcessId(hwnd, NULL) 

这将填充dwPIDHWND的关联PID。对于下一步,我假定钩子过程在当前可执行文件中,而不是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的钩子进行清理。

+0

我只关心一个会闪烁的特定程序,所以这个问题永远不会出现。你将能够阐明如何将DLL注入到应用程序中吗?我不太清楚钩子是什么。 – Michael 2012-02-17 23:45:15