首页 > 解决方案 > 在 Winforms 按钮派生控件中捕获鼠标事件

问题描述

我有一个从 Button 派生的 winforms 控件,其目的是显示一些对话框。因此,可以通过选项卡“激活”控件或根据应用程序状态单击鼠标。在某些情况下需要强制选项卡访问,以确保填写先前的字段。因此,我需要“捕获”鼠标点击它,以便根据应用程序状态允许或禁止鼠标事件。为了捕获制表键,我重写了 OnEnter() 并且它工作正常。我还重写了 OnClick()、OnMouseDown() 和 OnMouseClick(),但无济于事:程序控制总是默默地传递给 OnEnter() 方法。调试器永远不会在 OnClick() 或 OnMouse*() 方法中停止,因此我无法发出事件起源信号并在需要时阻止核心执行。有人可以帮忙吗?当然,我不喜欢捕获 windows 消息队列;以前的一些经历不开心。TIA

标签: c#winformsmouseevent

解决方案


使用简单的消息泵过滤,如此处所述(https://www.daniweb.com/programming/software-development/threads/304777/how-to-temporarily-disabling-mouse-clicks-on-a-vb-net- form ) 有这样的类

// relevant usings...
using System.Security.Permissions;
...
using System.Windows.Forms;

namespace YourNameSpace
{
    public class MouseFilter : IMessageFilter
    {
        protected static bool inEffect = false;
        public static bool ActiveFiltering { set { inEffect = value; } }
        const int LButtonDown = 0x201;
        const int LButtonUp = 0x202;
        const int LButtonDoubleClick = 0x203;

        [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
        public bool PreFilterMessage( ref Message m )
        {
            if (!inEffect)
                return false;
            bool result = false;
            switch (m.Msg) {
                case LButtonDown:
                case LButtonUp:
                case LButtonDoubleClick:
                     result = true;
                     break;
            }
            return result;
        }
    }
}

静态属性 ActiveFiltering 提供了一种根据需要启用/禁用鼠标单击过滤的方法。当然,Program类必须执行 Application.AddMessageFilter(new MouseFilter()); 但是,inEffect = false,它不会干扰正常的一般鼠标操作。我的控件在需要时会禁用鼠标,否则会保持启用状态。解决方案并不完美,但有可能。最糟糕的缺点是当控件取消鼠标点击时,没有人可以转到其他控件或窗口自身。


推荐阅读