MouseHover 和 MouseLeave 事件控制

Posted

技术标签:

【中文标题】MouseHover 和 MouseLeave 事件控制【英文标题】:MouseHover and MouseLeave Events controlling 【发布时间】:2012-09-15 04:35:34 【问题描述】:

我正在构建一个简单的表单,它有一个简单的效果——当鼠标不在表单上时,不透明度会降低,当鼠标在表单上时,表单会变得不透明。我目前遇到了几个困难:-

    首先,我这样做了-

     this.MouseHover += new EventHandler(Form1_MouseHover);
     this.MouseLeave += new EventHandler(Form1_MouseLeave);
    

    但我的表单中也有 1 个richtextbox,当鼠标移过它时,表单再次失去了不透明度。我也必须添加这个:-

     richTextBox1.MouseHover+=new EventHandler(Form1_MouseHover);
     richTextBox1.MouseLeave+=new EventHandler(Form1_MouseLeave);
    

    想知道有没有更好的方法,因为richtextbox和表单边界之间还有一些差距,当鼠标光标移到那里时,表单正在失去不透明度。

    如果鼠标不在表单上(假设最初),则表单不透明。现在,我希望鼠标移过它时表单变得不透明,但只有当鼠标在表单上移动完全停止时才会发生这种情况。如果我继续将鼠标移到表单上,它不会变得不透明。这是事件存储在消息队列中的方式的问题吗?或者我能做些什么,因为我已经看到了我正在尝试实现的效果的应用程序。

【问题讨论】:

我不知道为什么它会显示我的第二个点(从“如果鼠标不是”再次作为第一个点开始。我尝试过编辑,它的标记为 2。在那里。无论如何.. . 您需要在编号列表的开头留一个空行。由于 Markdown 不允许您从 2 开始编号列表,因此它从 1 开始您的列表。我已经为你修好了。 【参考方案1】:

MouseEnter/Leave 事件太不可靠,无法执行此操作。最好的办法是使用一个计时器来检查鼠标是否仍在窗口内。在表单上放置一个 Timer 并使代码如下所示:

public partial class Form1 : Form 
    public Form1() 
        InitializeComponent();
        this.Opacity = 0.99;
        timer1.Interval = 200;
        timer1.Enabled = true;
        timer1.Tick += timer1_Tick;
    
    protected override void OnLoad(EventArgs e) 
        base.OnLoad(e);
        timer1_Tick(this, e);
    
    private void timer1_Tick(object sender, EventArgs e) 
        this.Opacity = this.Bounds.Contains(this.PointToClient(Cursor.Position)) ? 0.99 : 0.20;
    

顺便说一句:避免将不透明度增加到 1.0,这会强制重新创建本机窗口并且可能会产生很多副作用。最好使用 0.99。

【讨论】:

是什么让进入/离开事件不可靠? 一个好的答案不适合评论框,你必须点击按钮。 他发布了他的问题:***.com/questions/26638501/… 另见Pug's answer,它建议使用ClientRectangle代替Bounds【参考方案2】:

我可能错了,但你为什么要使用 MouseHover 事件? MouseHover 检测鼠标何时停止在窗体上移动,通常用于显示工具提示。

您要查找的事件是MouseEnter,它与MouseLeave 正好相反,它会检测鼠标何时进入窗口的客户端区域。

在离开事件中,只需检查光标位置是否在窗口客户端矩形中,以了解它是否确实离开了窗体,或者它是否只是在子控件的顶部。

如果您使用区域,则必须调整代码。

 private void Form1_MouseEnter(object sender, EventArgs e)
    
        this.Opacity = 1;
    

    private void Form1_MouseLeave(object sender, EventArgs e)
    

        if (!this.ClientRectangle.Contains(this.PointToClient(Cursor.Position)))
        
            this.Opacity = 0.5;
        
    

【讨论】:

我忘了提到我尝试将 MouseHover 作为 MouseEnter 本身的更改,认为这可能是为什么表单在richtextbox 和表单之间移动时失去不透明度的问题(你总是在平常的时候开始尝试愚蠢的事情不工作:-D) 每当鼠标进入 Richtextbox 和 Form 边界之间的细小间隙时,它仍然会失去不透明度。此外,当我将鼠标放在标题栏上时,表单不会变得不透明。什么给了? 是的。它没有按预期工作。我以为我不明白什么。 代码已更新。错误来自于 Cursor.Position 返回必须首先转换的屏幕坐标中的鼠标位置。至于标题栏,LeaveEvent 仅在鼠标在客户矩形中时触发,不包括标题栏。您可以解决此问题,但这需要另一种 API 繁重的方法。或者您可以通过将客户端矩形在顶部扩展 5 px 来使用 hack。但不会每次都有效。【参考方案3】:

添加一个计时器控件,然后在计时器的滴答事件中使用下面的控件。如果您的表单中有自定义/用户控件,上述答案将不起作用。所以必须使用ClientRectangle

this.Opacity = this.ClientRectangle.Contains(this.PointToClient(Cursor.Position)) ? 0.99 : 0.20;

【讨论】:

【参考方案4】:
private void Form1_MouseEnter(object sender, EventArgs e)

    this.Opacity = 1.0;


private void Form1_MouseLeave(object sender, EventArgs e)
 
    this.Opacity = 0.8;

【讨论】:

谢谢,但 EventHandlers 没有任何问题。第二个问题(由 Icfseth 解决)与 WHEN 事件被触发有关。第一个仍在等待中。

以上是关于MouseHover 和 MouseLeave 事件控制的主要内容,如果未能解决你的问题,请参考以下文章

MFC使用TRACKMOUSEEVENT触发mouseHover和mouseLeave

MFC中MouseLeave消息没有响应

C#文本框边框颜色如何改变

如何捕捉 QSystemTrayIcon 的 MouseHover 事件?

JQuery事件与效果

WIN32 API 中 WM_MOUSEHOVER 上的弹出窗口 - 如何关闭它?