将MouseWheel消息发送到System.Windows.Forms.WebBrowser [英] Send MouseWheel messages to System.Windows.Forms.WebBrowser

查看:89
本文介绍了将MouseWheel消息发送到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.

这是我所做的:

  1. 已实现IMessageFilter.PreFilterMessage.
  2. 将过滤器注册到Application.AddMessageFilter.
  3. 在过滤器中,收听WM_MOUSEWHEEL消息.
  4. 使用SendMessage将消息转发到目标控件(在我的情况下为WebBrowser).
  1. Implemented IMessageFilter.PreFilterMessage.
  2. Registered the filter it with Application.AddMessageFilter.
  3. In the filter, listen for WM_MOUSEWHEEL messages.
  4. Forward the messages using SendMessage to the target control (in my case WebBrowser).

在代码中,如下所示:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆