.NET / Win32 - 用于检测属于另一个应用程序的窗口何时获得焦点的事件

时间:2011-08-22 17:02:42

标签: .net winapi

我有一个.NET应用程序需要能够检测特定窗口何时获取并失去焦点。我感兴趣的特定窗口属于我无法控制的另一个应用程序,虽然我有窗口句柄。

我真的想要解决这个问题的最佳方法。到目前为止,我可以看到两种可能性:

  1. 在计时器上使用Win32调用来监视状态的任何变化。不太好,因为它存在丢失状态变化的风险,例如:如果窗口变为活动状态,则在定时器间隔内处于非活动状态
  2. 使用挂钩(SetWindowsHookEx)拦截到窗口的消息。听起来它应该工作,但担心a)全局级钩子不能从.NET代码工作,所以需要本机和b)这可能被视为病毒/键盘记录类型活动,因此被操作系统阻止?
  3. 我确定还有其他选择,如果有的话,我很乐意听到它们!

2 个答案:

答案 0 :(得分:8)

最简单的方法是使用SetWinEventHook,监听EVENT_SYSTEM_FOREGROUND事件。您需要将它与WINEVENT_OUTOFCONTEXT标志一起使用才能在.net中使用它:当您使用此标志时,Windows会将通知路由回您自己的进程,因此您不需要单独的非托管DLL。但请注意,调用此方法的代码必须运行消息循环。

快速说明这与其他答案中提到的文章有何关联:该文章重点介绍SetWindowsHook API。 SetWinEventHook是一个单独的API,但您使用相同的技术来设置P / Invoke调用,并为回调设置委托 - 尽管请注意两个API在API调用本身和回调中使用不同的参数。 SetWinEventHook相对于SetWindowsHook的主要优点是,对于某些类型的钩子,SetWindowsHook 需要使用单独的非托管DLL,这是您无法直接在.net中执行的。但是,SetWinEventHook允许使用单独的非托管DLL或者在不需要DLL的情况下通知原始进程的任何类型的回调,因此更加友好。

答案 1 :(得分:0)

这是一篇关于在MSDN杂志中使用.NET实现Windows钩子的精彩文章:Windows Hooks in the .NET Framework

关于你的第二个问题,我从未听说过将这些api调用视为间谍软件行为的反病毒。

希望它有所帮助!