在Winforms按钮派生的控件中捕获鼠标事件

时间:2018-07-03 20:43:38

标签: c# winforms mouseevent

我有一个衍生自Button的winforms控件,其目的是显示一些对话框。 因此,可以根据应用程序状态通过 tab 或单击鼠标来“激活”控件。在某些情况下,需要强制使用制表符访问权限,以确保填写之前的字段。 因此,我需要“捕获”鼠标单击,以便根据应用程序状态允许或不允许鼠标事件。 为了捕获Tab键,我重写了OnEnter(),它可以正常工作。 我还无济于事地覆盖了OnClick(),OnMouseDown()和OnMouseClick():程序控件始终以静默方式传递给OnEnter()方法。 调试器永远不会在OnClick()或OnMouse *()方法中停止,因此我无法通过信号通知事件起源并在需要时阻止核心执行。 有人可以帮忙吗?当然,我不喜欢捕获Windows消息队列。以前的一些经验并不令人满意。 TIA

1 个答案:

答案 0 :(得分:1)

使用简单的消息泵过滤,如此处(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,它不会干扰常规的常规鼠标操作。 我的控件会在需要时禁用鼠标,并注意使其保持启用状态。 解决方案不是完美的,但可行的。最严重的缺点是,当控件取消鼠标单击时,没有人可以转到其他控件或窗口自身。