6

I have a windows form without title bar. I want to drag it by mouse. After searching on internet, I found this code for moving form:

protected override void WndProc(ref Message m)
{
    switch (m.Msg)
    {
        case 0x84:
            base.WndProc(ref m);
            if ((int)m.Result == 0x1)
                m.Result = (IntPtr)0x2;
            return;
    }
base.WndProc(ref m);
}

But it has a problem: It operates only on form regions which are not covered by any control. For example if I use label or group box, I can't move form by clicking on them.
How can I solve this problem?

niceman
  • 2,653
  • 29
  • 57
Hamid Reza
  • 477
  • 1
  • 4
  • 11
  • 1
    Are you sure you want to have click-and-drag-the-form to work when the user clicks on a control? Clicking then becomes ambiguous, is the user trying to do something with the control or not? Might be best to accept the way you have it working now. – RenniePet May 31 '14 at 04:05
  • Not for All controls. I want to have it only for controls that look like form background like label, group box, panel, rectangle shape , ... – Hamid Reza May 31 '14 at 05:20
  • 1
    There is a reason why forms have borders. Just use the standard border. Users will not expect to be able to click and drag on controls to move a form. – Cody Gray - on strike May 31 '14 at 06:42
  • @Hamid: I disagree - a label does not look like chrome (background). Nor does a groupbox. Panels and Rectangles may or may not but leaving enough background at the top should be good enough! For some special cases you may want to add the code mentioned, but users do not expect to move a window when they click and drag a label. – TaW Jun 02 '14 at 12:24
  • I'm agree with you. I leave enough background space at the top of form plus a label for title in that region. I want the user can move the form when he/she clicked on the label (title bar). – Hamid Reza Jun 03 '14 at 07:19
  • Possible duplicate of [Make a borderless form movable?](https://stackoverflow.com/questions/1592876/make-a-borderless-form-movable) – Elshan Jul 09 '17 at 23:09

5 Answers5

16

One way is to implement IMessageFilter like this.

public class MyForm : Form, IMessageFilter
{
    public const int WM_NCLBUTTONDOWN = 0xA1;
    public const int HT_CAPTION = 0x2;
    public const int WM_LBUTTONDOWN = 0x0201;

    [DllImportAttribute("user32.dll")]
    public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
    [DllImportAttribute("user32.dll")]
    public static extern bool ReleaseCapture();

    private HashSet<Control> controlsToMove = new HashSet<Control>();

    public MyForm()
    {
        Application.AddMessageFilter(this);

        controlsToMove.Add(this);
        controlsToMove.Add(this.myLabel);//Add whatever controls here you want to move the form when it is clicked and dragged
    }

    public bool PreFilterMessage(ref Message m)
    {
       if (m.Msg == WM_LBUTTONDOWN &&
            controlsToMove.Contains(Control.FromHandle(m.HWnd)))
        {
            ReleaseCapture();
            SendMessage(this.Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
            return true;
        }
        return false;
    }
}
Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189
4

This is basically what you are looking to do:

Make a borderless form movable?

You might be able to add the same code to the mouse down event of other controls on your form to accomplish the same thing.

Community
  • 1
  • 1
Mutex
  • 72
  • 4
3

Make a borderless form movable?

public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HT_CAPTION = 0x2;

[System.Runtime.InteropServices.DllImportAttribute("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[System.Runtime.InteropServices.DllImportAttribute("user32.dll")]
public static extern bool ReleaseCapture();

private void Form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{     
    if (e.Button == MouseButtons.Left)
    {
        ReleaseCapture();
        SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
    }
}
Elshan
  • 7,339
  • 4
  • 71
  • 106
2

When the user presses the mouse down over the lblMoveForm Label in the form, the following event handler executes.

     // On left button, let the user drag the form.
private void lblMoveForm_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        // Release the mouse capture started by the mouse down.
        lblMoveForm.Capture = false; //select control

        // Create and send a WM_NCLBUTTONDOWN message.
        const int WM_NCLBUTTONDOWN = 0x00A1;
        const int HTCAPTION = 2;
        Message msg =
            Message.Create(this.Handle, WM_NCLBUTTONDOWN,
                new IntPtr(HTCAPTION), IntPtr.Zero);
        this.DefWndProc(ref msg);
    }
}
0
//For base form moving
private const int HT_CAPTION = 0x2;
private const int WM_NCHITTEST = 0x84;
private const int HT_CLIENT = 0x1;

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);
    if (m.Msg == WM_NCHITTEST)
        m.Result = (IntPtr)(HT_CAPTION);
}


//For any component you also want use to move form
private bool arrastando= false;
private Point pontoinicial= new Point(0,0);
private Point meu_offset;

//use this method for component event called MouseDown
private void dragMouseDown(object sender, MouseEventArgs e)
{
    arrastando = true;
    pontoinicial = new Point(e.X, e.Y);
}
//use this method for component event called MouseUp
private void dragMouseUp(object sender, MouseEventArgs e)
{
    arrastando=false;
}
//use this method for component event called MouseMove
private void dragMouseMove(object sender, MouseEventArgs e)
{
    if (arrastando)
    {
    Point p = PointToScreen(e.Location);
    ActiveForm.Location = new Point(p.X - this.pontoinicial.X,
                                    p.Y - this.pontoinicial.Y);
    }
}
  
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Oct 09 '22 at 18:42