WPF实现窗体在屏幕内移动拖拽,不超过屏幕边界

时间:2025-01-24 10:42:30
public partial class MainWindow : Window { private POINT _mouseDownPos; private bool _move; [DllImport("")] public static extern bool ClipCursor(ref RECT lpRect); [DllImport("", CharSet = CharSet.Auto)] public static extern bool GetCursorPos(out POINT pt); public MainWindow() { InitializeComponent(); } protected override void OnSourceInitialized(EventArgs e) { base.OnSourceInitialized(e); HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource; if (hwndSource != null) { hwndSource.AddHook(new HwndSourceHook((this.WndProc))); } } protected virtual IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { RECT nativeRect; switch (msg) { case 0x20: { int lp = lParam.ToInt32(); if ((lp & 0xFFFF) == 2 && ((lp >> 0x10) & 0xFFFF) == 0x201) { GetCursorPos(out _mouseDownPos); _move = true; } } break; case 0x231: if (_move) { System.Drawing.Rectangle rect = System.Windows.Forms.SystemInformation.VirtualScreen; Point ptLeftUp = new Point(0, 0); Point ptRightDown = new Point(this.ActualWidth, this.ActualHeight); ptLeftUp = this.PointToScreen(ptLeftUp); ptRightDown = this.PointToScreen(ptRightDown); nativeRect = new RECT( (int)(_mouseDownPos.X - ptLeftUp.X), (int)( _mouseDownPos.Y - ptLeftUp.Y), (int)( rect.Right - (ptRightDown.X - _mouseDownPos.X)), (int)( rect.Bottom - (ptRightDown.Y - _mouseDownPos.Y))); ClipCursor(ref nativeRect); } break; case 0x0232: if (_move) { nativeRect = new RECT(System.Windows.Forms.SystemInformation.VirtualScreen); ClipCursor(ref nativeRect); _move = false; } break; } return IntPtr.Zero; } [StructLayout(LayoutKind.Sequential)] public struct POINT { public int X; public int Y; public POINT(int x, int y) { this.X = x; this.Y = y; } public override string ToString() { return ("X:" + X + ", Y:" + Y); } } [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; } public RECT(System.Drawing.Rectangle rect) { Left = rect.Left; Top = rect.Top; Right = rect.Right; Bottom = rect.Bottom; } public System.Drawing.Rectangle Rect { get { return new System.Drawing.Rectangle( Left, Top, Right - Left, Bottom - Top); } } public Size Size { get { return new Size(Right - Left, Bottom - Top); } } public static RECT FromXYWH(int x, int y, int width, int height) { return new RECT(x, y, x + width, y + height); } public static RECT FromRectangle(System.Drawing.Rectangle rect) { return new RECT(rect.Left, rect.Top, rect.Right, rect.Bottom); } } }