将MouseWheel消息发送到System.Windows.Forms.WebBrowser [英] Send MouseWheel messages to System.Windows.Forms.WebBrowser
问题描述
我想转发在表单级别生成的MouseWheel
事件,以便即使嵌入的WebBrowser
控件没有焦点,也可以对其进行处理.
I wanted to forward MouseWheel
events produced at the form level, so that they would be processed by an embedded WebBrowser
control, even when that control didn't have the focus.
这是我所做的:
- 已实现
IMessageFilter.PreFilterMessage
. - 将过滤器注册到
Application.AddMessageFilter
. - 在过滤器中,收听
WM_MOUSEWHEEL
消息. - 使用
SendMessage
将消息转发到目标控件(在我的情况下为WebBrowser
).
- Implemented
IMessageFilter.PreFilterMessage
. - Registered the filter it with
Application.AddMessageFilter
. - In the filter, listen for
WM_MOUSEWHEEL
messages. - Forward the messages using
SendMessage
to the target control (in my caseWebBrowser
).
在代码中,如下所示:
bool IMessageFilter.PreFilterMessage(ref Message m)
{
if (m.Msg == 0x20A) // WM_MOUSEWHEEL
{
if (this.target != null)
{
var handle = this.target.Handle;
Native.SendMessage (handle, m.Message, m.WParam, m.LParam);
return true;
}
}
return false;
}
// Registering the message filter:
System.Windows.Forms.Application.AddMessageFilter (this);
// Win32 code:
protected static class NativeMethods
{
[System.Runtime.InteropServices.DllImport ("user32.dll")]
public static extern System.IntPtr SendMessage(System.IntPtr hWnd, System.Int32 Msg, System.IntPtr wParam, System.IntPtr lParam);
}
这不起作用.什么都没发生.
This does not work. Nothing happens.
但是,如果我不是指定WebBrowser
而是指定Panel
作为目标,则效果很好.
However, if instead of a WebBrowser
I specify a Panel
as the target, then this works wonderfully well.
推荐答案
对Spy ++的研究表明,WinForms中的WebBrowser
控件正在使用几层容器来包装实际的IE组件:
Investigating with Spy++ revealed that the WebBrowser
control in WinForms is using several layers of containers to wrap the real IE component:
System.Windows.Forms.WebBrowser
Shell Embedding
Shell DocObject View
Internet Explorer_Server
将事件发送到任何容器都不会产生任何效果.为了使此功能正常运行,必须将WM_MOUSEWHEEL
事件发送到Internet Explorer_Server
句柄.
Sending the events to any container won't have any effect. The WM_MOUSEWHEEL
events have to be sent to the Internet Explorer_Server
handle in order for this to work.
这是修改后的代码,它通过挖掘容器来查找IE组件:
Here is the modified code, which finds the IE component by digging into the containers:
bool IMessageFilter.PreFilterMessage(ref Message m)
{
if (m.Msg == 0x20A) // WM_MOUSEWHEEL
{
if (this.target != null)
{
var handle = this.target.Handle;
handle = NativeMethods.FindWindowEx (handle, IntPtr.Zero, "Shell Embedding", null);
handle = NativeMethods.FindWindowEx (handle, IntPtr.Zero, "Shell DocObject View", null);
handle = NativeMethods.FindWindowEx (handle, IntPtr.Zero, "Internet Explorer_Server", null);
Native.SendMessage (handle, m.Msg, m.WParam, m.LParam);
return true;
}
}
return false;
}
protected static class NativeMethods
{
[System.Runtime.InteropServices.DllImport ("user32.dll")]
public static extern System.IntPtr SendMessage(System.IntPtr hWnd, System.Int32 Msg, System.IntPtr wParam, System.IntPtr lParam);
[System.Runtime.InteropServices.DllImport ("user32.dll")]
public static extern System.IntPtr FindWindowEx(System.IntPtr hwndParent, System.IntPtr hwndChildAfter, string className, string windowName);
}
这篇关于将MouseWheel消息发送到System.Windows.Forms.WebBrowser的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!