当程序用户将活动窗口更改为其他进程的窗口时,是否会发生事件或创建事件的方法?
如果没有这样的事件,做出类似事情的最佳方式是什么?
我目前正在使用一个每3秒运行一次Process.GetCurrentProcess()的计时器,但我正在寻找更好,更有效的方法,而且我不想降低间隔,因为存在风险使程序占用太多资源,或者需要花费太多时间来不断检查活动过程。
我知道有很多Windows内置的功能基本上是隐藏的,我没有足够的知识可以知道,所以如果有人知道这样的事情,那么如果你能提供帮助就会很棒我出去了。
答案 0 :(得分:5)
SetWinEventHook API完全符合您的要求。您需要做的就是在应用程序启动时使用正确的选项调用此选项,并且只要用户从桌面上当前运行的任何进程更改焦点,您就应该开始接收通知。
[DllImport("user32.dll", SetLastError = true)]
internal static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, WinEventProc lpfnWinEventProc, int idProcess, int idThread, uint dwflags);
[DllImport("user32.dll")]
internal static extern int UnhookWinEvent(IntPtr hWinEventHook);
internal delegate void WinEventProc(IntPtr hWinEventHook, uint iEvent, IntPtr hWnd, int idObject, int idChild, int dwEventThread, int dwmsEventTime);
const uint WINEVENT_OUTOFCONTEXT = 0;
const uint EVENT_SYSTEM_FOREGROUND = 3;
private IntPtr winHook;
private WinEventProc listener;
public void StartListeningForWindowChanges()
{
listener = new WinEventProc(EventCallback);
//setting the window hook
winHook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, IntPtr.Zero, listener, 0, 0, WINEVENT_OUTOFCONTEXT);
}
public void StopListeningForWindowChanges()
{
UnhookWinEvent(winHook);
}
private static void EventCallback(IntPtr hWinEventHook, uint iEvent, IntPtr hWnd, int idObject, int idChild, int dwEventThread, int dwmsEventTime)
{
// handle active window changed!
}
答案 1 :(得分:1)
我想说其中一种方法是使用Windows钩子,即CBT钩子。它听起来更接近“旧的好”Win32 API和通用C / C ++人员。同时,据我所知,还有C#版本http://msdn.microsoft.com/en-us/magazine/cc188966.aspx#S5
所以想法是每次获得HCBT_ACTIVATE类型的钩子事件(要激活的窗口)时检查当前进程,然后检查拥有该窗口的进程。如果它与以前记住的过程不匹配 - 是时候开始你的活动了。唯一要记住的是你自己的动作也可能触发CBT钩子(你必须避免无休止的自推进循环!)。