首页 文章

自定义按钮MouseLeave事件

提问于
浏览
4

我用一些面板和图片框制作了一个自定义按钮 . 使用MouseEnter和MouseLeave,我设置适当的悬停图像,如普通按钮 .

问题是如果我在控件上移动鼠标太快,它有时不会触发MouseLeave事件 . 这样,按钮在悬停状态下被“锁定” .

截图问题:http://www.jesconsultancy.nl/images/screens/screen_prblm.png

右侧的按钮被锁定在“悬停”状态 .

我怎么解决这个问题?

谢谢 .

2 回答

  • 1

    圣洁......那太乱了!
    首先, UserControl 是非常错误的 . 我建议你让你的控件继承自 Control 并自己绘制图像和文本 .
    其次,你为什么要用反射?
    第三,为什么有那么多控件?

    这会错过这个事件,因为更新需要太多!

    这里有一些简单控制可能的代码,永远不会错过一个事件:

    using System;
    using System.Drawing;
    using System.Windows.Forms;
    
    namespace lol
    {
        public class BlackWhiteControl : Control
        {
            protected override void OnMouseEnter(EventArgs e)
            {
                base.OnMouseEnter(e);
    
                this.BackColor = Color.Black;
            }
    
            protected override void OnMouseLeave(EventArgs e)
            {
                base.OnMouseLeave(e);
    
                this.BackColor = Color.White;
            }
        }
    }
    
  • 0

    当鼠标离开客户区时,您应该自动收到WM_MOUSELEAVE窗口消息,然后此消息的基类处理将调用OnMouseLeave方法 . 如果这真的没有发生,你当然可以解决它 . 只需直接拦截WM_MOUSEMOVE,然后进行Win32 API调用,请求在鼠标离开控件时通知您 .

    使用以下简单的WndProc覆盖...

    private bool _mouseOver = false;
            protected override void WndProc(ref Message m)
            {
                switch (m.Msg)
                {
                    case PI.WM_MOUSEMOVE:
                        if (!_mouseOver)
                        {
                            PI.TRACKMOUSEEVENTS tme = new PI.TRACKMOUSEEVENTS();
                            tme.cbSize = (uint)Marshal.SizeOf(typeof(PI.TRACKMOUSEEVENTS));
                            tme.dwHoverTime = 100;
                            tme.dwFlags = (int)(PI.TME_LEAVE);
                            tme.hWnd = Handle;
                            PI.TrackMouseEvent(ref tme);
                            _mouseOver = true;
                        }
                        base.WndProc(ref m);
                        break;
                    case PI.WM_MOUSELEAVE:
                        _mouseOver = false;
                        base.WndProc(ref m);
                        break;
                }
            }
    

    平台调用您需要的信息是......

    internal const int WM_MOUSEMOVE = 0x0200;
        internal const int WM_MOUSELEAVE = 0x02A3;
        internal const int TME_LEAVE = 0x0002;
    
        [StructLayout(LayoutKind.Sequential)]
        internal struct TRACKMOUSEEVENTS
        {
            public uint cbSize;
            public uint dwFlags;
            public IntPtr hWnd;
            public uint dwHoverTime;
        }
    

    希望有所帮助 .

相关问题