【问题标题】:Moving 2 forms at the same time同时移动 2 个表格
【发布时间】:2011-11-18 16:27:15
【问题描述】:

我在这里有点卡住了。我试图在不使用 OnMove、LocationChanged、Docking 等的情况下同时移动 2 个表单。

与其位置交互的唯一方法是覆盖 WndProc。可能有用的是表单 A 是表单 B 的所有者。因此,每当移动 A 时,我也想移动 B。不是同一个位置,而是同一个距离。

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == 0x0084)
        {
              Form[] temp = this.OwnedForms;

              if(temp.Length > 0) 
              {
                    /* moving temp[0] to the same ratio as this form */
              }

              m.Result = (IntPtr)2;
              return;
        }
        base.WndProc(ref m);
    }

A 和 B 具有相同的 WndProc,因为它们是来自同一类的 2 个对象。

【问题讨论】:

    标签: c# winforms winapi


    【解决方案1】:

    避免使用 LocationChanged 事件没有任何意义:

        private Point lastPos;
    
        protected override void OnLoad(EventArgs e) {
            base.OnLoad(e);
            lastPos = this.Location;
        }
    
        protected override void OnLocationChanged(EventArgs e) {
            base.OnLocationChanged(e);
            foreach (var frm in this.OwnedForms) {
                frm.Location = new Point(frm.Location.X + this.Left - lastPos.X,
                    frm.Location.Y + this.Top - lastPos.Y);
            }
            lastPos = this.Location;
        }
    
        protected override void WndProc(ref Message m) {
            // Move borderless window with click-and-drag on client window
            if (m.Msg == 0x84) m.Result = (IntPtr)2;
            else base.WndProc(ref m);
        }
    

    【讨论】:

    • 如果 locationchanged 在我的情况下可以工作,我会使用它。但由于我使用的是仅包含图像的 alpha 混合 layeredwindow,因此我必须找到一种解决方法。
    • 我不明白相关性。无论用户使用标题栏移动它还是因为它是无边框窗口而以其他方式移动它,LocationChanged 事件仍然会触发。由您尝试在 WndProc() 中捕获的同一窗口消息触发。 WM_NCHITTEST 与它没有太大关系,只是用于移动无边框窗口。
    【解决方案2】:

    我设法解决了这个问题:

    protected override void WndProc(ref Message m)
    {
        Form temp = this.Owner;
    
        if (m.Msg == 0x0084)
        {
              m.Result = (IntPtr)2;
              return;
        }
    
        if (m.Msg == 0x0216 && temp != null)
        {
             if (!movedonce)
             {
                  oldlocationx = this.Location.X;
                  oldlocationy = this.Location.Y;
                  movedonce = true;
             }
    
             temp.Location = new Point(temp.Location.X + this.Location.X - oldlocationx, temp.Location.Y + this.Location.Y - oldlocationy);
             oldlocationx = this.Location.X;
             oldlocationy = this.Location.Y;
        }
    
        base.WndProc(ref m);
    }
    

    【讨论】:

    • 什么是moveonce和这个?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 2017-06-13
    • 1970-01-01
    • 1970-01-01
    • 2014-11-11
    • 2013-09-27
    相关资源
    最近更新 更多