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

2023-09-03 02:40:58 作者:待我温柔似水淹死你可好

我有需要能够检测何时特定的窗口得到和失去焦点.NET应用程序。具体的窗口,我很感兴趣的是属于我无法控制其他应用程序,但我确实有窗口句柄。

I have a .NET application that needs to be able to detect when a specific window gets and loses focus. The specific window i'm interested in belongs to another application that I have no control over, although I do have the Window Handle.

我真的后,最好的方式来解决这个问题。到目前为止,我可以看到两种方式:

I'm really after the best way to tackle this. So far, I can see 2 possibilities:

使用Win32调用一个计时器来监控状态的任何变化。不是很大,因为它缺少运行状态的变化,例如风险如果窗口被激活则定时器时间内处于非活动状态 使用钩子(SetWindowsHookEx函数)拦截消息的窗口。听起来像它应该工作,但关注的是)全球级的钩子不会从.NET code工作,所以将需要本地和b)会这样被认为是病毒/键盘记录型活性,因此阻断操作系统?

我敢肯定有其他的选择也一样,如果是的话,我很乐意听到他们的声音!

I'm sure there are other options too, if so, i'd love to hear them!

推荐答案

简单的方法是有可能使用的 SetWinEventHook ,监听EVENT_SYSTEM_FOREGROUND事件。你需要使用它的WINEVENT_OUTOFCONTEXT标志使用它在.net中:当您使用此标志时,Windows路由通知回自己的过程,所以你并不需要一个单独的非托管的DLL。但是请注意,code调用此方法必须有一个消息循环运行。

Simplest way is likely to use SetWinEventHook, listening for EVENT_SYSTEM_FOREGROUND events. You need to use it with the WINEVENT_OUTOFCONTEXT flag to use it in .net: when you use this flag, Windows routes the notifications back to your own process, so you don't need a separate unmanaged DLL. Note however that the code that calls this method must have a message loop running.

快速一份关于如何涉及对方的回答中提到的文章:那篇文章的重点是SetWindowsHook API。 SetWinEventHook是一个单独的API,但是你用同样的方法来设置P / Invoke调用,并成立一个委托回调 - 但请注意,这两种API在这两个API使用不同的参数调用自己和回调。 SetWinEventHook拥有SetWindowsHook的主要优点是,对于某些类型的挂钩,SetWindowsHook的需要的使用单独的非托管的DLL,它不能在.NET中直接做的。然而SetWinEventHook允许任何类型的回调,使用一个单独的非托管的DLL或通知​​,而无需一个DLL原工艺,因此更加.NET友好。

Quick note on how this relates to the article mentioned in the other answer: that article focuses on the SetWindowsHook API. SetWinEventHook is a separate API, but you use the same technique to set up the P/Invoke call, and to set up a delegate for the callback - though note that the two APIs use different parameters in both the API calls themselves and in the callbacks. The main advantage that SetWinEventHook has over SetWindowsHook is that for some types of hooks, SetWindowsHook requires the use of a separate unmanaged DLL, which you can't do directly in .net. SetWinEventHook however allows either type of callback, using either a separate unmanaged DLL or notifying the original process without requiring a DLL, so is more .net-friendly.