C# 截取另一个窗口的窗口消息
我正在使用CefGlue制作一个带有嵌入式webkit浏览器的应用程序,我需要在浏览器窗口中监听鼠标移动。winforms控件不会将鼠标事件传递给该控件,因此我无法侦听它们 然而,我发现了一个bug/feature请求,其中包含一个解决方案,但我无法理解如何实现它,我不熟悉直接在WinAPI中工作。开发商说我需要: 二,。特定于操作系统(windows)-在创建浏览器(CeffLifeSpanHandler.OnAfterCreated)后获取窗口句柄和子类 它们(窗口子类化技术)。事实上,现在我们有了本地人 类为CefBrowserWindow的窗口(由返回) CefBrowser.GetHost().GetWindowHandle()),然后是子窗口 Chrome_WidgetWin_0,然后是Chrome_RenderWidgetHostHWND。对于 拦截WM_鼠标移动您对Chrome_WidgetWin_0感兴趣 窗口,可通过CefBrowserWindow轻松获取。玩玩 使用Spy++进行精确查看 我用谷歌搜索了一下,但我不知道该怎么做。我的表格上有以下功能:C# 截取另一个窗口的窗口消息,c#,winapi,pinvoke,C#,Winapi,Pinvoke,我正在使用CefGlue制作一个带有嵌入式webkit浏览器的应用程序,我需要在浏览器窗口中监听鼠标移动。winforms控件不会将鼠标事件传递给该控件,因此我无法侦听它们 然而,我发现了一个bug/feature请求,其中包含一个解决方案,但我无法理解如何实现它,我不熟悉直接在WinAPI中工作。开发商说我需要: 二,。特定于操作系统(windows)-在创建浏览器(CeffLifeSpanHandler.OnAfterCreated)后获取窗口句柄和子类 它们(窗口子类化技术)。事实上,现在
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
protected override void WndProc(ref Message m) {
base.WndProc(ref m);
switch (m.Msg) {
case WM_MOUSEMOVE:
Console.WriteLine("Mouse move!");
break;
default:
Console.WriteLine(m.ToString());
break;
}
}
但是当我控制鼠标时,我从来没有看到鼠标移动。我怀疑我需要监听
CefBrowser.GetHost().GetWindowHandle()
的WndProc,但我不确定该怎么做。我找到了一个解决方案。我在WebLifeSpanHandler的OnAfterCreated事件中调用此函数
browser.Created += (sender, eventargs) => {
Console.WriteLine("Created.");
BrowserWindowPointer = browser.CefBrowser.GetHost().GetWindowHandle();
Console.WriteLine("BrowserWindowPointer: " + BrowserWindowPointer);
uint BrowserThreadId = GetWindowThreadProcessId(BrowserWindowPointer, IntPtr.Zero);
Console.WriteLine("Browser PID: " + BrowserThreadId);
MouseHookProcedure = new HookProc(this.MouseHookProc);
hHookMouse = SetWindowsHookEx(WH_MOUSE,
MouseHookProcedure,
(IntPtr)0,
BrowserThreadId);
if (hHookMouse == 0) {
Console.WriteLine("MouseHook Failed. Making cursor always visible.");
Cursor.Show();
}
KeyboardHookProcedure = new HookProc(this.KeyboardHookProc);
hHookKeyboard = SetWindowsHookEx(WH_KEYBOARD,
KeyboardHookProcedure,
(IntPtr)0,
BrowserThreadId);
};
我要找的函数是GetWindowThreadProcessId,我可以使用browser.CefBrowser.GetHost().GetWindowHandle()提供的窗口句柄
需要注意的一点是,钩子过程需要有更大的范围。C#没有看到它挂接到本机进程中,如果您让它超出范围,它将进行垃圾收集。为了解决这个问题,我将它们设置为类属性
证明文件:
- 如何在Visual C#.NET中设置Windows钩子提供了钩住鼠标事件的基础。修改为使用浏览器线程id
- MouseProc回调函数如何处理鼠标窗口钩子
- 键盘PROC回调函数如何处理键盘窗口挂钩。包括LPRAM的结构。重要提示:wParam包含输入密钥的虚拟密钥代码
- 虚拟钥匙代码钥匙及其虚拟钥匙代码列表,这样我就可以知道用户正在按哪个按钮
我的两个钩子(不是好代码,我不处理封送的数据):
我不确定这是否完全是必需的,特别是因为被钩住的线在接近时会消失,但为了更好的测量,在你听完之后,别忘了清理你的钩子。我在表单的dispose方法中执行此操作:
protected override void Dispose(bool disposing) {
base.Dispose();
if (disposing) {
if (hHookKeyboard != 0) {
UnhookWindowsHookEx(hHookKeyboard);
}
if (hHookMouse != 0) {
UnhookWindowsHookEx(hHookMouse);
}
}
}
我找到了解决办法。我在WebLifeSpanHandler的OnAfterCreated事件中调用此函数
browser.Created += (sender, eventargs) => {
Console.WriteLine("Created.");
BrowserWindowPointer = browser.CefBrowser.GetHost().GetWindowHandle();
Console.WriteLine("BrowserWindowPointer: " + BrowserWindowPointer);
uint BrowserThreadId = GetWindowThreadProcessId(BrowserWindowPointer, IntPtr.Zero);
Console.WriteLine("Browser PID: " + BrowserThreadId);
MouseHookProcedure = new HookProc(this.MouseHookProc);
hHookMouse = SetWindowsHookEx(WH_MOUSE,
MouseHookProcedure,
(IntPtr)0,
BrowserThreadId);
if (hHookMouse == 0) {
Console.WriteLine("MouseHook Failed. Making cursor always visible.");
Cursor.Show();
}
KeyboardHookProcedure = new HookProc(this.KeyboardHookProc);
hHookKeyboard = SetWindowsHookEx(WH_KEYBOARD,
KeyboardHookProcedure,
(IntPtr)0,
BrowserThreadId);
};
我要找的函数是GetWindowThreadProcessId,我可以使用browser.CefBrowser.GetHost().GetWindowHandle()提供的窗口句柄
需要注意的一点是,钩子过程需要有更大的范围。C#没有看到它挂接到本机进程中,如果您让它超出范围,它将进行垃圾收集。为了解决这个问题,我将它们设置为类属性
证明文件:
- 如何在Visual C#.NET中设置Windows钩子提供了钩住鼠标事件的基础。修改为使用浏览器线程id
- MouseProc回调函数如何处理鼠标窗口钩子
- 键盘PROC回调函数如何处理键盘窗口挂钩。包括LPRAM的结构。重要提示:wParam包含输入密钥的虚拟密钥代码
- 虚拟钥匙代码钥匙及其虚拟钥匙代码列表,这样我就可以知道用户正在按哪个按钮
我的两个钩子(不是好代码,我不处理封送的数据):
我不确定这是否完全是必需的,特别是因为被钩住的线在接近时会消失,但为了更好的测量,在你听完之后,别忘了清理你的钩子。我在表单的dispose方法中执行此操作:
protected override void Dispose(bool disposing) {
base.Dispose();
if (disposing) {
if (hHookKeyboard != 0) {
UnhookWindowsHookEx(hHookKeyboard);
}
if (hHookMouse != 0) {
UnhookWindowsHookEx(hHookMouse);
}
}
}
见