【问题标题】:Windows Forms: capturing MouseWheelWindows 窗体:捕获 MouseWheel
【发布时间】:2011-01-22 18:53:44
【问题描述】:

我有一个 Windows 窗体(在 C#.NET 中工作)。

表单顶部有几个面板,底部有一些 ComboBoxes 和 DataGridViews。

我想使用顶部面板上的滚动事件,但如果选择例如ComboBox 失去焦点。面板包含各种其他控件。

当鼠标悬停在任何面板上时,我怎么能总是收到鼠标滚轮事件? 到目前为止,我尝试使用 MouseEnter / MouseEnter 事件,但没有成功。

【问题讨论】:

    标签: .net winforms mousewheel


    【解决方案1】:

    您所描述的内容听起来像是您想要复制例如 Microsoft Outlook 的功能,您无需实际单击以使控件聚焦以使用鼠标滚轮。

    这是一个需要解决的相对高级的问题:它涉及实现包含表单的IMessageFilter 接口,查找WM_MOUSEWHEEL 事件并将它们定向到鼠标悬停的控件。

    这是一个例子(来自here):

    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    
    namespace WindowsApplication1 {
      public partial class Form1 : Form, IMessageFilter {
        public Form1() {
          InitializeComponent();
          Application.AddMessageFilter(this);
        }
    
        public bool PreFilterMessage(ref Message m) {
          if (m.Msg == 0x20a) {
            // WM_MOUSEWHEEL, find the control at screen position m.LParam
            Point pos = new Point(m.LParam.ToInt32());
            IntPtr hWnd = WindowFromPoint(pos);
            if (hWnd != IntPtr.Zero && hWnd != m.HWnd && Control.FromHandle(hWnd) != null) {
              SendMessage(hWnd, m.Msg, m.WParam, m.LParam);
              return true;
            }
          }
          return false;
        }
    
        // P/Invoke declarations
        [DllImport("user32.dll")]
        private static extern IntPtr WindowFromPoint(Point pt);
        [DllImport("user32.dll")]
        private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
      }
    }
    

    请注意,此代码对应用程序中的所有表单都有效,而不仅仅是主表单。

    【讨论】:

    • 谢谢,在那里看到了,但我不确定为什么处理 WM_MOUSEWHEEL 不是很理想。
    • 嘿,这是我的代码!不太确定此处需要的归属是否合适,应该是。
    • 发帖者的评论是“Windows 对 MouseWheel 事件的处理不是很理想”,这意味着鼠标滚轮的默认 Windows 实现意味着它将事件发送到具有焦点的控件,而不是正如大多数人所期望或希望的那样,鼠标悬停在上面的控件。
    • @Hans Passant,@Jon Grant 谢谢...顺便说一句:我可以让它只在某些控件上工作吗?即如果没有聚焦则不滚动组合框?
    • 刚刚实现了类似的东西,但有一个额外的测试:“Control.FromHandle(hWnd).FindForm() == this”,以确保它只适用于同一表单上控件的消息。跨度>
    【解决方案2】:

    每个控件都有一个鼠标滚轮事件,当控件获得焦点时鼠标滚轮移动时会发生该事件。

    查看此内容了解更多信息:Control.MouseWheel Event

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多