You can do something like this (I used ClipCursor when the cursor can go outside of the window, but I think it could be better with a Low Level Mouse Hook (WH_MOUSE_LL )...)
public partial class Form1 : Form
{
[DllImport("User32.dll", SetLastError = true)]
public static extern bool MoveWindow(IntPtr hWnd, int x, int y, int cx, int cy, bool repaint);
[DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
public const int SWP_NOSIZE = 0x0001;
public const int SWP_NOMOVE = 0x0002;
public const int SWP_NOZORDER = 0x0004;
public const int SWP_NOREDRAW = 0x0008;
public const int SWP_NOACTIVATE = 0x0010;
public const int SWP_FRAMECHANGED = 0x0020; /* The frame changed: send WM_NCCALCSIZE */
public const int SWP_SHOWWINDOW = 0x0040;
public const int SWP_HIDEWINDOW = 0x0080;
public const int SWP_NOCOPYBITS = 0x0100;
public const int SWP_NOOWNERZORDER = 0x0200; /* Don't do owner Z ordering */
public const int SWP_NOSENDCHANGING = 0x0400; /* Don't send WM_WINDOWPOSCHANGING */
public const int SWP_DRAWFRAME = SWP_FRAMECHANGED;
public const int SWP_NOREPOSITION = SWP_NOOWNERZORDER;
public const int SWP_DEFERERASE = 0x2000;
public const int SWP_ASYNCWINDOWPOS = 0x4000;
[DllImport("User32.dll", SetLastError = true)]
static extern bool GetCursorPos(out POINT lpPoint);
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int x;
public int y;
public POINT(int X, int Y)
{
this.x = X;
this.y = Y;
}
}
[DllImport("User32.dll", SetLastError = true)]
public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
public RECT(int Left, int Top, int Right, int Bottom)
{
left = Left;
top = Top;
right = Right;
bottom = Bottom;
}
}
[DllImport("User32.dll", SetLastError = true)]
public static extern IntPtr SetCapture(IntPtr hWnd);
[DllImport("User32.dll", SetLastError = true)]
public static extern bool ReleaseCapture();
[DllImport("User32.dll", SetLastError = true)]
public static extern bool ClipCursor(ref RECT lpRect);
[DllImport("User32.dll", SetLastError = true)]
public static extern bool ClipCursor(IntPtr lpRect);
public const int WM_MOUSEMOVE = 0x0200;
public const int WM_LBUTTONDOWN = 0x0201;
public const int WM_LBUTTONUP = 0x0202;
public const int WM_LBUTTONDBLCLK = 0x0203;
public const int WM_RBUTTONDOWN = 0x0204;
public const int WM_RBUTTONUP = 0x0205;
public Form1()
{
InitializeComponent();
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
}
bool bMoving = false;
int nX = 0, nY = 0, nXWindow = 0, nYWindow = 0;
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_MOUSEMOVE)
{
if (bMoving)
{
POINT pt = new POINT();
GetCursorPos(out pt);
SetWindowPos(m.HWnd, IntPtr.Zero, nXWindow + (pt.x - nX), nYWindow + (pt.y - nY), 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOREDRAW);
//SetWindowPos(m.HWnd, IntPtr.Zero, nXWindow + (pt.x - nX), nYWindow + (pt.y - nY), 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_ASYNCWINDOWPOS);
RECT rc = new RECT();
GetWindowRect(this.Handle, out rc);
ClipCursor(ref rc);
}
else
ClipCursor(IntPtr.Zero);
}
else if(m.Msg == WM_LBUTTONDOWN)
{
bMoving = !bMoving;
if (bMoving)
{
SetCapture(this.Handle);
RECT rc = new RECT();
GetWindowRect(this.Handle, out rc);
nXWindow = rc.left;
nYWindow = rc.top;
POINT pt = new POINT();
GetCursorPos(out pt);
nX = pt.x;
nY = pt.y;
}
else
ReleaseCapture();
}
else if(m.Msg == WM_RBUTTONUP)
{
System.Windows.Forms.Application.Exit();
}
else
{
base.WndProc(ref m);
}
}
}