屏蔽WPF窗体拖动到屏幕边缘最大化

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gao271003105/article/details/85061422

调用一些WindowsAPI可以实现此需求

   public partial class ShellWindow : Window
    {
        [DllImport("user32.dll", EntryPoint = "GetWindowLong")]
        public static extern int GetWindowLong(IntPtr hwnd, int nIndex);

        [DllImport("user32.dll", EntryPoint = "SetWindowLong")]
        public static extern int SetWindowLong(IntPtr hMenu, int nIndex, int dwNewLong);

        [DllImport("user32.dll")]
        private static extern int SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);

        private bool m_IsHide;
        public ShellWindow()
        {
            IsHide = false;
            InitializeComponent();
        }

        private void ShellWindow_OnClosed(object sender, EventArgs e)
        {
            var dataContext = DataContext as WindowViewModelBase;
            this.Owner.PreviewMouseLeftButtonUp -= Owner_PreviewMouseLeftButtonUp;
            this.Owner.PreviewMouseMove -= Owner_PreviewMouseMove;
            dataContext?.OnWindowClosed();
        }

        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            if (IsHide)
            {
                this.Hide();
                e.Cancel = true;
            }
            else
            {
                base.OnClosing(e);
            }           
        }

        private void ShellWindow_OnLoaded(object sender, RoutedEventArgs e)
        {
            if (this.ResizeMode == ResizeMode.CanResize ||
                this.ResizeMode == ResizeMode.CanResizeWithGrip)
            {
                IntPtr windowHandle = new WindowInteropHelper(this).Handle;
                HwndSource windowSource = HwndSource.FromHwnd(windowHandle);
                windowSource.AddHook(WndProc);
                DisableMaxmizebox(true);//Shielding automatically maximize when drag the window to the edge of the screen 
            }
        }

        class NativeMethods
        {
            public const int WM_NCHITTEST = 0x84;
            public const int HTCAPTION = 2;
            public const int HTLEFT = 10;
            public const int HTRIGHT = 11;
            public const int HTTOP = 12;
            public const int HTTOPLEFT = 13;
            public const int HTTOPRIGHT = 14;
            public const int HTBOTTOM = 15;
            public const int HTBOTTOMLEFT = 16;
            public const int HTBOTTOMRIGHT = 17;
        }
        public   bool bResizeFlag = false;
        private static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            
            int GripSize = 16;
            int BorderSize = 7;
            ShellWindow win = (ShellWindow)System.Windows.Interop.HwndSource.FromHwnd(hwnd).RootVisual;
            if(win == null)
            {
                return IntPtr.Zero;
            }
            if (msg == NativeMethods.WM_NCHITTEST)
            {
                int x = lParam.ToInt32() << 16 >> 16, y = lParam.ToInt32() >> 16;
                Point pos = win.PointFromScreen(new Point(x, y));

                //bottom
                if (pos.X > GripSize &&
                    pos.X < win.ActualWidth - GripSize &&
                    pos.Y >= win.ActualHeight - BorderSize)
                {
                    handled = true;
                    //return (IntPtr)NativeMethods.HTBOTTOM;
                }

                //Right
                if (pos.Y > GripSize &&
                    pos.X > win.ActualWidth - BorderSize &&
                    pos.Y < win.ActualHeight - GripSize)
                {
                    handled = true;
                    //return (IntPtr)NativeMethods.HTRIGHT;
                }

                // Top, Left, Right, Corners, Etc.
                //HTBOTTOMRIGHT
                if (pos.X > win.ActualWidth - GripSize &&
                    pos.X  <= win.ActualWidth &&
                    pos.Y  <=win.ActualHeight &&
                    pos.Y >= win.ActualHeight - GripSize)
                {
                    handled = true;

                    win.SetEvent(win.PointToScreen(pos));
                    win.bResizeFlag = true;
                    return IntPtr.Zero;
                    //return (IntPtr)NativeMethods.HTBOTTOMRIGHT;
                }
            }

            return IntPtr.Zero;
        }
        private void DisableMaxmizebox(bool isDisable)
        {
            int GWL_STYLE = -16;
            int WS_MAXIMIZEBOX = 0x00010000;
            int SWP_NOSIZE = 0x0001;
            int SWP_NOMOVE = 0x0002;
            int SWP_FRAMECHANGED = 0x0020;
            int WS_CLIPSIBLINGS = 0x04000000;

            IntPtr handle = new WindowInteropHelper(this).Handle;
            int nStyle = GetWindowLong(handle, GWL_STYLE);
            if (isDisable)
            {
                nStyle &= ~(WS_MAXIMIZEBOX);
            }
            else
            {
                nStyle |= WS_MAXIMIZEBOX;
            }

            SetWindowLong(handle, GWL_STYLE, nStyle);
            SetWindowPos(handle, IntPtr.Zero, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED);
        }

        private void ShellWindow_OnKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key != Key.Escape)
            {
                e.Handled = false;
                return;
            }

            this.Close();
            e.Handled = true;
        }
        Point pos = new Point();
        private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            this.Focus();
        }
        bool bAllowDragMoveFlag = false;

        public void  SetEvent(Point cur)
        {
            pos = cur;
            this.Owner.PreviewMouseMove -= Owner_PreviewMouseMove;
            this.Owner.PreviewMouseMove += Owner_PreviewMouseMove;
            this.Owner.PreviewMouseLeftButtonUp -= Owner_PreviewMouseLeftButtonUp;
            this.Owner.PreviewMouseLeftButtonUp += Owner_PreviewMouseLeftButtonUp;
        }
        protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
        {
            base.OnPreviewMouseDown(e);
            pos = e.GetPosition(this);
            if (pos.Y >= 0 && pos.Y <= 70)
            {
                this.Owner.PreviewMouseMove -= Owner_PreviewMouseMove;
                this.Owner.PreviewMouseMove += Owner_PreviewMouseMove;
                this.Owner.PreviewMouseLeftButtonUp -= Owner_PreviewMouseLeftButtonUp;
                this.Owner.PreviewMouseLeftButtonUp += Owner_PreviewMouseLeftButtonUp;
                bAllowDragMoveFlag = true;
            }
            else
            {
                bAllowDragMoveFlag = false;
            }
            pos = this.PointToScreen(pos);
        }

        private void Owner_PreviewMouseLeftButtonUp(object sender, System.Windows.Input.MouseEventArgs e)
        {
            this.Owner.PreviewMouseLeftButtonUp -= Owner_PreviewMouseLeftButtonUp;
            this.Owner.PreviewMouseMove -= Owner_PreviewMouseMove;
            bResizeFlag = false;

        }

        private void Owner_PreviewMouseMove(object sender, MouseEventArgs e)
        {
            if(e.LeftButton == MouseButtonState.Pressed)
            {
                if (bAllowDragMoveFlag)
                {
                    Point cur = e.GetPosition(this.Owner);
                    cur = this.Owner.PointToScreen(cur);
                    cur = this.PointFromScreen(cur);
                    MoveWindow(e, cur);
                    return;
                }
                if (bResizeFlag)
                {
                    Point cur = e.GetPosition(this.Owner);
                    cur = this.Owner.PointToScreen(cur);
                    cur = this.PointFromScreen(cur);
                    ReSizeWindow(e, cur);
                }
            }
        }

        private void ReSizeWindow(MouseEventArgs e, Point cur)
        {
            try {
                if (e.LeftButton == MouseButtonState.Pressed)
                {
                    if (bResizeFlag)
                    {
                        cur = this.PointToScreen(cur);
                        double x = cur.X - pos.X;
                        double y = cur.Y - pos.Y;
                        this.Width = this.ActualWidth + x;
                        this.Height = this.ActualHeight + y;
                    }
                    else
                    {
                        cur = this.PointToScreen(cur);
                    }
                    pos = cur;
                }
                else
                {
                    cur = this.PointToScreen(cur);
                    pos = cur;
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.StackTrace);
            }
        }
        private void MoveWindow(MouseEventArgs e,Point cur)
        {
            try {
                if (e.LeftButton == MouseButtonState.Pressed)
                {
                    if (bAllowDragMoveFlag)
                    {
                        cur = this.PointToScreen(cur);
                        double x = cur.X - pos.X;
                        double y = cur.Y - pos.Y;
                        if (this.Left + x >= -this.ActualWidth + 100 && this.Top + y >= -49)
                        {
                            this.Left += x;
                            this.Top += y;
                        }
                    }
                    else
                    {
                        cur = this.PointToScreen(cur);
                    }
                    pos = cur;
                }
                else
                {
                    cur = this.PointToScreen(cur);
                    pos = cur;
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.StackTrace);
            }
        }
        protected override void OnPreviewMouseMove(MouseEventArgs e)
        {
            base.OnPreviewMouseMove(e);
            Point cur = e.GetPosition(this);
            if (bAllowDragMoveFlag)
            {
                MoveWindow(e, cur);
                return;
            }
            if(bResizeFlag)
            {
                ReSizeWindow(e, cur);
            }
        }

        protected virtual void OnMouseMove(MouseEventArgs e)
        {
            base.OnPreviewMouseMove(e);
           /// MoveWindow(e);
        }

        protected override void OnPreviewMouseUp(MouseButtonEventArgs e)
        {
            bAllowDragMoveFlag = false;
            bResizeFlag = false;
            this.Owner.PreviewMouseLeftButtonUp -= Owner_PreviewMouseLeftButtonUp;
            this.Owner.PreviewMouseMove -= Owner_PreviewMouseMove;
            base.OnPreviewMouseUp(e);
        }
        public bool IsHide { set; get; }
    }

猜你喜欢

转载自blog.csdn.net/gao271003105/article/details/85061422
今日推荐