代码之家  ›  专栏  ›  技术社区  ›  Pondidum

以编程方式开始移动窗体

  •  0
  • Pondidum  · 技术社区  · 17 年前

    我试图通过点击按钮来移动表单(使用标题栏)。

    我认为使用SendMessage会很简单:

    Const WM_LBUTTONDOWN As Integer = &H201
    
    Button1.Capture = False
    Cursor.Position = Me.Location + New Size(50, 8)
    
    SendMessage(Me.Handle, WM_LBUTTONDOWN, CType(1, IntPtr), IntPtr.Zero)
    

    但是,尽管如果光标位于表单客户端区域,它会发送消息,但似乎不会将其发送到表单标题栏(表单以某种方式捕获事件,尽管光标位于标题栏上而不是客户端区域)。

    有什么建议吗?

    3 回复  |  直到 7 年前
        1
  •  3
  •   Community Mohan Dere    9 年前

    WM_ NC LBUTTONDOWN (并通过 HTCAPTION wParam ).不过,我还不能完全确定这是否能完成你的目标。

    WM_NCHITTEST 消息和返回 HTTRANSPARENT .


    suggested Location 所有物你对他说“它需要在鼠标移动时移动”,这正是你能做和应该做的。

    class MyForm : Form{
        Point downAt;
    
        MyForm(){
            Label lbl      = new Label();
            lbl.AutoSize   = true;
            lbl.BackColor  = Color.Blue;
            lbl.ForeColor  = Color.White;
            lbl.Location   = new Point(50, 50);
            lbl.Text       = "Drag me to move this form.";
            lbl.Parent     = this;
            lbl.MouseDown += (s, e)=>downAt = e.Location;
            lbl.MouseMove += (s, e)=>{if(lbl.Capture) Location += (Size)e.Location - (Size)downAt;};
        }
    }
    

    但总的来说,这是一种简单易行的方法,它是一个完全不依赖任何平台调用的.NET解决方案(因此它应该可以移植到Unix上的Mono)。


    Sub New()
        Dim lbl As New Label
        lbl.AutoSize  = True
        lbl.BackColor = Color.Blue
        lbl.ForeColor = Color.White
        lbl.Location  = New Point(50, 50)
        lbl.Text      = "Drag me to move this form."
        lbl.Parent    = Me
        AddHandler lbl.MouseDown, Function(ByVal s As Object, ByVal e As MouseEventArgs)
            Me.downAt = e.Location
        End Function
        AddHandler lbl.MouseMove, Function(ByVal s As Object, ByVal e As MouseEventArgs)
            If lbl.Capture Then
                Me.Location = Me.Location + DirectCast(e.Location, Size) - DirectCast(Me.downAt, Size)
            End If
        End Function
    End Sub
    

    在VB.NET中,这可能不是最简洁的表达方式。我曾经 Reflector 帮我翻译一下。

        2
  •  2
  •   Rob Kennedy    17 年前

    LParam 价值观 wm_LButtonDown 消息接收中的鼠标位置 客户 wm_NCLButtonDown message . 我以前看到过这个问题的答案,但有一个更直接的途径,我希望它能起作用:发送一个 wm_SysCommand message ,并指定 sc_Move 旗帜

        3
  •  2
  •   Hans Passant    17 年前

    Point mLastPos;
    private void button1_MouseMove(object sender, MouseEventArgs e) {
      if (e.Button == MouseButtons.Left) {
        this.Location = new Point(this.Location.X + e.X - mLastPos.X,
          this.Location.Y + e.Y - mLastPos.Y);
      }
      // NOTE: else is intentional!
      else mLastPos = e.Location;
    }