Winforms - 单击/拖动表单中的任意位置以移动它,就像在表单标题中单击一样

Jos*_*gle 19 .net winforms

我正在创建一个在Winforms应用程序中使用的小模式窗体.它基本上是各种进度条.但我希望用户能够单击表单中的任意位置并拖动它以在桌面仍在显示时在桌面上移动它.

我该如何实现这种行为?

小智 24

Microsoft知识库文章320687对此问题有详细解答.

基本上,当正在测试的点位于表单的客户区域时,您覆盖WndProc方法将HTCAPTION返回到WM_NCHITTEST消息 - 这实际上告诉Windows将点击处理完全相同表格的标题.

private const int WM_NCHITTEST = 0x84;
private const int HTCLIENT = 0x1;
private const int HTCAPTION = 0x2;

protected override void WndProc(ref Message m)
{
  switch(m.Msg)
  {
    case WM_NCHITTEST:
      base.WndProc(ref m);
      if ((int)m.Result == HTCLIENT)
      {
        m.Result = (IntPtr)HTCAPTION;
      }

      return;
  }

  base.WndProc(ref m);
}
Run Code Online (Sandbox Code Playgroud)


Fly*_*wat 13

这是使用P/Invoke执行此操作的方法.

public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HTCAPTION = 0x2;
[DllImport("User32.dll")]
public static extern bool ReleaseCapture();
[DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);

void Form_Load(object sender, EventArgs e)
{
   this.MouseDown += new MouseEventHandler(Form_MouseDown);  
}

void Form_MouseDown(object sender, MouseEventArgs e)
{                        
    if (e.Button == MouseButtons.Left)
    {
        ReleaseCapture();
        SendMessage(Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 要使此功能在有人单击标签时起作用,只需在Form Load方法中(在this.MouseDown行的正下方)添加此额外的代码行。this.label1 + = new MouseEventHandler(Form_MouseDown); (2认同)

aku*_*aku 5

下面的代码假设 ProgressBarForm 表单有一个 ProgressBar 控件,其Dock属性设置为Fill

public partial class ProgressBarForm : Form
{
    private bool mouseDown;
    private Point lastPos;

    public ProgressBarForm()
    {
        InitializeComponent();
    }

    private void progressBar1_MouseMove(object sender, MouseEventArgs e)
    {
        if (mouseDown)
        {
            int xoffset = MousePosition.X - lastPos.X;
            int yoffset = MousePosition.Y - lastPos.Y;
            Left += xoffset;
            Top += yoffset;
            lastPos = MousePosition;
        }
    }

    private void progressBar1_MouseDown(object sender, MouseEventArgs e)
    {
        mouseDown = true;
        lastPos = MousePosition;
    }

    private void progressBar1_MouseUp(object sender, MouseEventArgs e)
    {
        mouseDown = false;
    }
}
Run Code Online (Sandbox Code Playgroud)