【问题标题】:WinForms window drag eventWinForms 窗口拖动事件
【发布时间】:2010-03-31 17:52:27
【问题描述】:

WinForms 中是否存在在拖动窗口时触发的事件?

或者有没有更好的方法来做我想做的事:在拖动窗口时将窗口不透明度降低到 80%?

不幸的是,搜索起来非常棘手,因为每个人都在寻找从 shell 或其他对象中拖放的内容。

【问题讨论】:

    标签: winforms events opacity drag


    【解决方案1】:

    不需要 WndProc 黑客,这工作正常:

    protected override void OnResizeBegin(EventArgs e) {
      this.Opacity = 0.6;
    }
    protected override void OnResizeEnd(EventArgs e) {
      this.Opacity = 1.0;
    }
    

    移动也会触发 OnResizeXxx 事件。

    【讨论】:

    • 这个很好。它处理得更好。如果您在 Win7 上执行 Aero-shake 之类的操作,然后再次执行以恢复窗口,它会丢失句柄并保持窗口保持设置的不透明度,直到您再次移动它。
    • +1 但不好的是,如果您在应用程序的标题栏上按住鼠标右键,它会被视为“onresizebegin”事件。
    【解决方案2】:

    这是您想要的LocationChanged 事件:

    private void YourApp_LocationChanged(object sender, EventArgs e)
    {
        this.Opacity = 0.8;
    }
    

    您必须覆盖 WndProc 并处理退出移动事件以将不透明度重置回 1:

    protected override void WndProc(ref Message m)
    {
        Trace.WriteLine(m.ToString());
        switch (m.Msg)
        {
            case WMEXITSIZEMOVE:
                this.Opacity = 1.0;
                break;
        }
        base.WndProc(ref m);
    }
    

    不要忘记定义消息代码:

    private const int WMEXITSIZEMOVE = 0x0232;
    

    处理WM_ENTERSIZEMOVE(代码0x0231)消息而不是LocationChanged 可能更有效,因为这只会导致设置不透明度一次(在拖动开始时),而不是在整个拖动过程中持续设置.

    【讨论】:

    • 我会同时尝试 WMEXITSIZEMOVE 和 WM_ENTERSIZEMOVE,但这肯定能满足我的需要。谢谢!
    • @Steve - 我的意思是使用 WM_ENTERSIZEMOVE 而不是 LocationChanged。
    • 我怀疑这会起作用,除非您将常规表单的不透明度设置为 99%
    • @nobugz - 默认Opacity1.0。我已经让这两个版本的代码在一个应用程序中运行,没有任何问题。
    • 将不透明度从 1.0 更改为 0.8 时会重新创建窗口句柄。那必须取消模态大小/移动循环,你会得到一个全新的窗口。如果它仍然有效,请考虑这种无用的喋喋不休。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-19
    • 1970-01-01
    • 2011-04-29
    • 1970-01-01
    • 2018-02-22
    • 2018-10-22
    • 1970-01-01
    相关资源
    最近更新 更多