Tuesday, 13 September 2011

C# Moving forms without border






Currently, I have found two way of doing that task.

1. Override void WndProc:
protected override void WndProc(ref Message m)
{
      base.WndProc(ref m);

      int WM_NCHITTEST = 0x84;
      if (m.Msg == WM_NCHITTEST)
      {
           int HTCLIENT = 1;
           int HTCAPTION = 2;
           base.WndProc(ref m);
           //control.mousebuttons gets a value indicating which of the mouse buttons is in a pressed state. 
           //so only left click will send to titlebar
           //and also works with contextmenustrip
           if (Control.MouseButtons == MouseButtons.Left)
           {
               if (m.Result.ToInt32() == HTCLIENT)
               {
                   m.Result = (IntPtr)HTCAPTION;
               }
           }
           return;
       }

       base.WndProc(ref m);

}

This one is actually send all mouse action from client area to it's title bar.
More windows message detail can be find here.
Detail about WM_NCHITTEST result can be find here.
Pro:
Easy to set up.
Con:
It sends all the mouse action towards title bar. Even if you specify which mouse button's action will send through, but still. All of that button's action will send to title bar which cause conflict with some mouse action setting.
For example if you want to do certain task with left mouse button double click. That method send all left button's action to title bar for form's movement action. That cause double click not working at all.
Also, as it override form's WndProc. Only action happen on that form will be send to title bar. But if you have panel or other control set up on the form. Mouse move form will not work on those controls.



2. Use control or form's button event to simulate form's movement.

//Mouse Drag properties. 
 private bool _bDragging = false;
 private Point _pLastPos;

private void Control_MouseDown(object sender, MouseEventArgs e)
{
     if (e.Button == System.Windows.Forms.MouseButtons.Left)
     {
          _bDragging = true;
          _pLastPos = this.PointToScreen(e.Location);
     }
}

private void Control_MouseUp(object sender, MouseEventArgs e)
{
     if (e.Button == System.Windows.Forms.MouseButtons.Left)
     {
          _bDragging = false;
     }
}

private void Control_MouseMove(object sender, MouseEventArgs e)
{
     if (!_bDragging) return;
     Point pCurrentPos = this.PointToScreen(e.Location);
     this.Location = new Point(this.Left + pCurrentPos.X - _pLastPos.X, this.Top + pCurrentPos.Y - _pLastPos.Y);
     _pLastPos = pCurrentPos;
}

This one is just a pack of event for mouse action.
You have to specify which mouse button action will be use towards form's movement. Else, any mouse button's click and drag will cause action.

Pro:
It will not conflict with other mouse action setting.
Con:
You have to set up for every control and form you want to let it have that moving form ability.

No comments:

Post a Comment