检测使用C#更改的活动窗口而不进行轮询
当当前活动窗口更改时,如何调用回调。我已经看到了如何使用CBTProc来实现。但是,全局事件不容易与托管代码挂钩。我想找到一种不需要投票的方式。我更喜欢事件驱动的方法检测使用C#更改的活动窗口而不进行轮询,c#,windows,events,winapi,C#,Windows,Events,Winapi,当当前活动窗口更改时,如何调用回调。我已经看到了如何使用CBTProc来实现。但是,全局事件不容易与托管代码挂钩。我想找到一种不需要投票的方式。我更喜欢事件驱动的方法 关于您可以使用SetWinEventHook并收听事件\系统\前台事件。使用WINEVENT\u OUTOFCONTEXT标志以避免全局钩子问题。创建一个新的windows窗体项目,添加一个文本框,使其多行,并将textbox Dock属性设置为fill,将其命名为Log并粘贴到以下代码中(您需要将System.Runtime.I
关于您可以使用
SetWinEventHook
并收听事件\系统\前台
事件。使用WINEVENT\u OUTOFCONTEXT
标志以避免全局钩子问题。创建一个新的windows窗体项目,添加一个文本框,使其多行,并将textbox Dock属性设置为fill,将其命名为Log并粘贴到以下代码中(您需要将System.Runtime.InteropServices添加到您的使用中)
我知道这条线很旧,但为了将来使用: 运行代码时,您会在一段时间后注意到崩溃。这是由表单构造函数中的行引起的:
public Form1()
{
InitializeComponent();
WinEventDelegate dele = new WinEventDelegate(WinEventProc);//<-causing ERROR
IntPtr m_hhook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, IntPtr.Zero, dele, 0, 0, WINEVENT_OUTOFCONTEXT);
}
…现在一切正常根据,你不能在.NET中做全局钩子,因为全局钩子是如何监视这些类型的事件的,看起来你的其他选项是轮询或写一些非托管代码(例如C++),它提供了一个你可以从C语言访问的接口。吉姆,我想你有正确的答案。吉姆实际上只是部分正确。他一定浏览了那篇文章。键盘和鼠标挂钩是全局的(如果你读到最后,你会看到),你可以从C#中做这些,但是,你不能从C#中做你想做的事情。你能给出一些例子吗?附加信息:你的上下文外函数必须很快。()根据Savvas Sopiadis的回答,
dele
的范围需要扩大,以防止该代表被处置。有关更多信息,请参阅上的注释。这似乎不适用于控制台应用程序,有人知道为什么吗?我删除了InitializeComponent()。@AnthonyRaimondo显然“如果您有一个Console.ReadLine处于活动状态,它不会启动”。请参阅以减少互操作调用并稍微清理代码<不需要code>GetForegroundWindow(),因为WinEventProc
已经以hwnd
的形式接收前台句柄,该句柄可用于获取标题。最后还应调用。
public Form1()
{
InitializeComponent();
WinEventDelegate dele = new WinEventDelegate(WinEventProc);//<-causing ERROR
IntPtr m_hhook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, IntPtr.Zero, dele, 0, 0, WINEVENT_OUTOFCONTEXT);
}
public Form1()
{
InitializeComponent();
dele = new WinEventDelegate(WinEventProc);
IntPtr m_hhook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, IntPtr.Zero, dele, 0, 0, WINEVENT_OUTOFCONTEXT);
}
WinEventDelegate dele = null;