WPF Window Resizing(WindowResizer.dll)改進

WPF Window Resizing(CodeProject原文)

原文中的代碼演示瞭如何動態實時改變WPF窗口的方法,不過在測試中發現一個小問題,即當鼠標按下後一直向一個方向縮小窗口的時候,當鼠標超過了另一條邊的時候(在左邊框按下,一直向右拖動鼠標,直到鼠標超過右邊框時,異常就出現了,其他四個方向同理)會引發異常.

以下代碼在原來的基礎上,主要修改了updateSize函數,解決了問題.


2013-04-02:新問題,找時間修改

      1,當拖動左邊框的時候,右邊框應固定不動,但現在右邊框則在不停的閃動,雖然最後的位置是正確的。同樣,上下拖動也存在相同的問題。是因爲時時改變了當前窗口的左上角座標點位置,重繪引起的閃動。


完整代碼示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Runtime.InteropServices;
using System.Windows.Interop;
using System.Threading;
using System.Windows.Media.Effects;

namespace DNBSoft.WPF
{
    public class WindowResizer
    {
        private Window target = null;

        private bool resizeRight = false;
        private bool resizeLeft = false;
        private bool resizeUp = false;
        private bool resizeDown = false;

        private Dictionary<UIElement, short> leftElements = new Dictionary<UIElement, short>();
        private Dictionary<UIElement, short> rightElements = new Dictionary<UIElement, short>();
        private Dictionary<UIElement, short> upElements = new Dictionary<UIElement, short>();
        private Dictionary<UIElement, short> downElements = new Dictionary<UIElement, short>();

        private PointAPI startMousePoint = new PointAPI();          //鼠標左鍵點下時的座標點
        private Size startWindowSize = new Size();                  //鼠標左鍵點下時,窗口的大小
        private Point startWindowLeftUpPoint = new Point();         //鼠標左鍵點下時,窗口左上角座標點位置

        public int minWidth = 10;
        public int minHeight = 10;

        private delegate void RefreshDelegate();

        public WindowResizer(Window target)
        {
            this.target = target;

            if (target == null)
            {
                throw new Exception("Invalid Window handle");
            }
        }

        #region add resize components
        private void connectMouseHandlers(UIElement element)
        {
            element.MouseLeftButtonDown += new MouseButtonEventHandler(element_MouseLeftButtonDown);
            element.MouseEnter += new MouseEventHandler(element_MouseEnter);
            element.MouseLeave += new MouseEventHandler(setArrowCursor);
        }

        public void addResizerRight(UIElement element)
        {
            connectMouseHandlers(element);
            rightElements.Add(element, 0);
        }

        public void addResizerLeft(UIElement element)
        {
            connectMouseHandlers(element);
            leftElements.Add(element, 0);
        }

        public void addResizerUp(UIElement element)
        {
            connectMouseHandlers(element);
            upElements.Add(element, 0);
        }

        public void addResizerDown(UIElement element)
        {
            connectMouseHandlers(element);
            downElements.Add(element, 0);
        }

        public void addResizerRightDown(UIElement element)
        {
            connectMouseHandlers(element);
            rightElements.Add(element, 0);
            downElements.Add(element, 0);
        }

        public void addResizerLeftDown(UIElement element)
        {
            connectMouseHandlers(element);
            leftElements.Add(element, 0);
            downElements.Add(element, 0);
        }

        public void addResizerRightUp(UIElement element)
        {
            connectMouseHandlers(element);
            rightElements.Add(element, 0);
            upElements.Add(element, 0);
        }

        public void addResizerLeftUp(UIElement element)
        {
            connectMouseHandlers(element);
            leftElements.Add(element, 0);
            upElements.Add(element, 0);
        }
        #endregion

        #region resize handlers
        private void element_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            GetCursorPos(out startMousePoint);
            startWindowSize = new Size(target.Width, target.Height);
            startWindowLeftUpPoint = new Point(target.Left, target.Top);

            #region updateResizeDirection
            UIElement sourceSender = (UIElement)sender;
            if (leftElements.ContainsKey(sourceSender))
            {
                resizeLeft = true;
            }
            if (rightElements.ContainsKey(sourceSender))
            {
                resizeRight = true;
            }
            if (upElements.ContainsKey(sourceSender))
            {
                resizeUp = true;
            }
            if (downElements.ContainsKey(sourceSender))
            {
                resizeDown = true;
            }
            #endregion

            Thread t = new Thread(new ThreadStart(updateSizeLoop));
            t.Name = "Mouse Position Poll Thread";
            t.Start();
        }

        private void updateSizeLoop()
        {
            try
            {
                while (resizeDown || resizeLeft || resizeRight || resizeUp)
                {
                    target.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Render, new RefreshDelegate(updateSize));
                    target.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Render, new RefreshDelegate(updateMouseDown));
                    Thread.Sleep(20);
                }

                target.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Render, new RefreshDelegate(setArrowCursor));
            }
            catch (Exception)
            {
            }
        }

        #region updates
        private void updateSize()
        {
            PointAPI currentMousePoint = new PointAPI();
            GetCursorPos(out currentMousePoint);

            try
            {
                if (resizeRight)
                {
                    //如果當鼠標左鍵點下時,窗口的寬度已經達到最小值,
                    if (target.Width == minWidth)
                    {
                        //鼠標向右移動,表示當前是將窗口變大,此時窗口只能變大,因爲已經達到最小寬度了
                        if ((startMousePoint.X - currentMousePoint.X) < 0)
                        {
                            target.Width = this.startWindowSize.Width - (startMousePoint.X - currentMousePoint.X);
                        }
                    }
                    else
                    {
                        //此時,窗口可大可小
                        if ((this.startWindowSize.Width - (startMousePoint.X - currentMousePoint.X)) >= minWidth)
                        {
                            target.Width = this.startWindowSize.Width - (startMousePoint.X - currentMousePoint.X);
                        }
                        else
                        {
                            //此時,只能限制窗口爲最小值,不能繼續變小
                            target.Width = minWidth;
                        }
                    }
                }

                if (resizeDown)
                {
                    if (target.Height == minHeight)
                    {
                        if ((startMousePoint.Y - currentMousePoint.Y) < 0)
                        {
                            target.Height = startWindowSize.Height - (startMousePoint.Y - currentMousePoint.Y);
                        }
                    }
                    else
                    {
                        if ((startWindowSize.Height - (startMousePoint.Y - currentMousePoint.Y)) >= minHeight)
                        {
                            target.Height = startWindowSize.Height - (startMousePoint.Y - currentMousePoint.Y);
                        }
                        else
                        {
                            target.Height = minHeight;
                        }
                    }
                }

                if (resizeLeft)
                {
                    if (target.Width == minWidth)
                    {
                        if ((startMousePoint.X - currentMousePoint.X) > 0)
                        {
                            target.Width = startWindowSize.Width + (startMousePoint.X - currentMousePoint.X);
                            target.Left = startWindowLeftUpPoint.X - (startMousePoint.X - currentMousePoint.X);
                        }
                    }
                    else
                    {
                        if ((this.startWindowSize.Width + (startMousePoint.X - currentMousePoint.X)) >= minWidth)
                        {
                            target.Width = startWindowSize.Width + (startMousePoint.X - currentMousePoint.X);
                            target.Left = startWindowLeftUpPoint.X - (startMousePoint.X - currentMousePoint.X);
                        }
                        else
                        {
                            target.Width = minWidth;
                            target.Left = startWindowLeftUpPoint.X + startWindowSize.Width - target.Width;
                        }
                    }
                }

                if (resizeUp)
                {
                    if (target.Height == minHeight)
                    {
                        if ((startMousePoint.Y - currentMousePoint.Y) > 0)
                        {
                            target.Height = startWindowSize.Height + (startMousePoint.Y - currentMousePoint.Y);
                            target.Top = startWindowLeftUpPoint.Y - (startMousePoint.Y - currentMousePoint.Y);
                        }
                        else
                        {
                            target.Height = minHeight;
                            target.Top = startWindowLeftUpPoint.Y + startWindowSize.Height - target.Height;
                        }
                    }
                    else
                    {
                        if ((startWindowSize.Height + (startMousePoint.Y - currentMousePoint.Y)) >= minHeight)
                        {
                            target.Height = startWindowSize.Height + (startMousePoint.Y - currentMousePoint.Y);
                            target.Top = startWindowLeftUpPoint.Y - (startMousePoint.Y - currentMousePoint.Y);
                        }
                        else
                        {
                            target.Height = minHeight;
                            target.Top = startWindowLeftUpPoint.Y + startWindowSize.Height - target.Height;
                        }
                    }
                }
            }
            catch
            {
            }
        }

        private void updateMouseDown()
        {
            if (Mouse.LeftButton == MouseButtonState.Released)
            {
                resizeRight = false;
                resizeLeft = false;
                resizeUp = false;
                resizeDown = false;
            }
        }
        #endregion
        #endregion

        #region cursor updates
        private void element_MouseEnter(object sender, MouseEventArgs e)
        {
            bool resizeRight = false;
            bool resizeLeft = false;
            bool resizeUp = false;
            bool resizeDown = false;

            UIElement sourceSender = (UIElement)sender;
            if (leftElements.ContainsKey(sourceSender))
            {
                resizeLeft = true;
            }
            if (rightElements.ContainsKey(sourceSender))
            {
                resizeRight = true;
            }
            if (upElements.ContainsKey(sourceSender))
            {
                resizeUp = true;
            }
            if (downElements.ContainsKey(sourceSender))
            {
                resizeDown = true;
            }

            if ((resizeLeft && resizeDown) || (resizeRight && resizeUp))
            {
                setNESWCursor(sender, e);
            }
            else if ((resizeRight && resizeDown) || (resizeLeft && resizeUp))
            {
                setNWSECursor(sender, e);
            }
            else if (resizeLeft || resizeRight)
            {
                setWECursor(sender, e);
            }
            else if (resizeUp || resizeDown)
            {
                setNSCursor(sender, e);
            }
        }

        private void setWECursor(object sender, MouseEventArgs e)
        {
            target.Cursor = Cursors.SizeWE;
        }

        private void setNSCursor(object sender, MouseEventArgs e)
        {
            target.Cursor = Cursors.SizeNS;
        }

        private void setNESWCursor(object sender, MouseEventArgs e)
        {
            target.Cursor = Cursors.SizeNESW;
        }

        private void setNWSECursor(object sender, MouseEventArgs e)
        {
            target.Cursor = Cursors.SizeNWSE;
        }

        private void setArrowCursor(object sender, MouseEventArgs e)
        {
            if (!resizeDown && !resizeLeft && !resizeRight && !resizeUp)
            {
                target.Cursor = Cursors.Arrow;
            }
        }

        private void setArrowCursor()
        {
            target.Cursor = Cursors.Arrow;
        }
        #endregion

        #region external call
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool GetCursorPos(out PointAPI lpPoint);

        private struct PointAPI
        {
            public int X;
            public int Y;
        }
        #endregion
    }
}

代碼下載

以下代碼加入了控制窗口最大化的時候不遮蓋任務欄

1,加入最小寬度,最小高度的限制

2,限制最大高度不超過屏幕的工作區域,避免向下拖動時,拖動到任務欄以下的區域,被任務欄遮蓋。

在窗口的構造函數中調用。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Runtime.InteropServices;
using System.Windows.Interop;
using System.Threading;
using System.Windows.Media.Effects;

namespace DNBSoft.WPF
{
    public class WindowResizer
    {
        private Window target = null;

        private bool resizeRight = false;
        private bool resizeLeft = false;
        private bool resizeUp = false;
        private bool resizeDown = false;

        private Dictionary<UIElement, short> leftElements = new Dictionary<UIElement, short>();
        private Dictionary<UIElement, short> rightElements = new Dictionary<UIElement, short>();
        private Dictionary<UIElement, short> upElements = new Dictionary<UIElement, short>();
        private Dictionary<UIElement, short> downElements = new Dictionary<UIElement, short>();

        private PointAPI startMousePoint = new PointAPI();          //鼠標左鍵點下時的座標點
        private Size startWindowSize = new Size();                  //鼠標左鍵點下時,窗口的大小
        private Point startWindowLeftUpPoint = new Point();         //鼠標左鍵點下時,窗口左上角座標點位置
        private static int workAreaMaxHeight = -1;                          //工作區域最大高度

        public int minWidth = 10;
        public int minHeight = 10;

        private HwndSource hs;

        private delegate void RefreshDelegate();

        public WindowResizer(Window target)
        {
            this.target = target;

            if (target == null)
            {
                throw new Exception("Invalid Window handle");
            }

            //窗口大小發生變化時,及時調整窗口最大高度和寬度,防止遮蓋任務欄
            this.target.SourceInitialized += new EventHandler(MyMacClass_SourceInitialized);
        }

        #region 這一部分用於最大化時不遮蔽任務欄

        private void MyMacClass_SourceInitialized(object sender, EventArgs e)
        {
            hs = PresentationSource.FromVisual((Visual)sender) as HwndSource;
            hs.AddHook(new HwndSourceHook(WndProc));
        }

        private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            switch (msg)
            {
                case 0x0024:/* WM_GETMINMAXINFO */
                    WmGetMinMaxInfo(hwnd, lParam);
                    handled = true;
                    break;
                default: break;
            }
            return (System.IntPtr)0;
        }

        private static void WmGetMinMaxInfo(System.IntPtr hwnd, System.IntPtr lParam)
        {
            MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));

            // Adjust the maximized size and position to fit the work area of the correct monitor
            int MONITOR_DEFAULTTONEAREST = 0x00000002;
            System.IntPtr monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);

            if (monitor != System.IntPtr.Zero)
            {
                MONITORINFO monitorInfo = new MONITORINFO();
                GetMonitorInfo(monitor, monitorInfo);
                RECT rcWorkArea = monitorInfo.rcWork;
                RECT rcMonitorArea = monitorInfo.rcMonitor;
                mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.left - rcMonitorArea.left);
                mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top);

                // 這行如果不註釋掉在多顯示器情況下顯示會有問題! 
                // mmi.ptMaxSize.x = Math.Abs(rcWorkArea.right - rcWorkArea.left);
                mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top);
                workAreaMaxHeight = mmi.ptMaxSize.y;

                //當窗口的任務欄自動隱藏時,最大化的時候最下邊要留幾個像素的空白,否則此窗口將屏幕鋪滿,則鼠標移到最下邊時,任務欄無法自動彈出
                if (rcWorkArea.Height == rcMonitorArea.Height)
                {
                    mmi.ptMaxSize.y -= 2;
                }
            }

            Marshal.StructureToPtr(mmi, lParam, true);
        }

        [DllImport("user32")]
        internal static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi);

        [DllImport("User32")]
        internal static extern IntPtr MonitorFromWindow(IntPtr handle, int flags);

        /// <summary>
        /// POINT aka POINTAPI
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct POINT
        {
            /// <summary>
            /// x coordinate of point.
            /// </summary>
            public int x;
            /// <summary>
            /// y coordinate of point.
            /// </summary>
            public int y;

            /// <summary>
            /// Construct a point of coordinates (x,y).
            /// </summary>
            public POINT(int x, int y)
            {
                this.x = x;
                this.y = y;
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MINMAXINFO
        {
            public POINT ptReserved;
            public POINT ptMaxSize;
            public POINT ptMaxPosition;
            public POINT ptMinTrackSize;
            public POINT ptMaxTrackSize;
        };

        [StructLayout(LayoutKind.Sequential, Pack = 0)]
        public struct RECT
        {
            /// <summary> Win32 </summary>
            public int left;
            /// <summary> Win32 </summary>
            public int top;
            /// <summary> Win32 </summary>
            public int right;
            /// <summary> Win32 </summary>
            public int bottom;

            /// <summary> Win32 </summary>
            public static readonly RECT Empty = new RECT();

            /// <summary> Win32 </summary>
            public int Width
            {
                get { return Math.Abs(right - left); }  // Abs needed for BIDI OS
            }
            /// <summary> Win32 </summary>
            public int Height
            {
                get { return bottom - top; }
            }

            /// <summary> Win32 </summary>
            public RECT(int left, int top, int right, int bottom)
            {
                this.left = left;
                this.top = top;
                this.right = right;
                this.bottom = bottom;
            }


            /// <summary> Win32 </summary>
            public RECT(RECT rcSrc)
            {
                this.left = rcSrc.left;
                this.top = rcSrc.top;
                this.right = rcSrc.right;
                this.bottom = rcSrc.bottom;
            }
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public class MONITORINFO
        {
            /// <summary>
            /// </summary>            
            public int cbSize = Marshal.SizeOf(typeof(MONITORINFO));

            /// <summary>
            /// </summary>            
            public RECT rcMonitor = new RECT();

            /// <summary>
            /// </summary>            
            public RECT rcWork = new RECT();

            /// <summary>
            /// </summary>            
            public int dwFlags = 0;
        }

        #endregion

        #region add resize components
        private void connectMouseHandlers(UIElement element)
        {
            element.MouseLeftButtonDown += new MouseButtonEventHandler(element_MouseLeftButtonDown);
            element.MouseEnter += new MouseEventHandler(element_MouseEnter);
            element.MouseLeave += new MouseEventHandler(setArrowCursor);
        }

        public void addResizerRight(UIElement element)
        {
            connectMouseHandlers(element);
            rightElements.Add(element, 0);
        }

        public void addResizerLeft(UIElement element)
        {
            connectMouseHandlers(element);
            leftElements.Add(element, 0);
        }

        public void addResizerUp(UIElement element)
        {
            connectMouseHandlers(element);
            upElements.Add(element, 0);
        }

        public void addResizerDown(UIElement element)
        {
            connectMouseHandlers(element);
            downElements.Add(element, 0);
        }

        public void addResizerRightDown(UIElement element)
        {
            connectMouseHandlers(element);
            rightElements.Add(element, 0);
            downElements.Add(element, 0);
        }

        public void addResizerLeftDown(UIElement element)
        {
            connectMouseHandlers(element);
            leftElements.Add(element, 0);
            downElements.Add(element, 0);
        }

        public void addResizerRightUp(UIElement element)
        {
            connectMouseHandlers(element);
            rightElements.Add(element, 0);
            upElements.Add(element, 0);
        }

        public void addResizerLeftUp(UIElement element)
        {
            connectMouseHandlers(element);
            leftElements.Add(element, 0);
            upElements.Add(element, 0);
        }
        #endregion

        #region resize handlers
        private void element_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            GetCursorPos(out startMousePoint);
            startWindowSize = new Size(target.Width, target.Height);
            startWindowLeftUpPoint = new Point(target.Left, target.Top);

            #region updateResizeDirection
            UIElement sourceSender = (UIElement)sender;
            if (leftElements.ContainsKey(sourceSender))
            {
                resizeLeft = true;
            }
            if (rightElements.ContainsKey(sourceSender))
            {
                resizeRight = true;
            }
            if (upElements.ContainsKey(sourceSender))
            {
                resizeUp = true;
            }
            if (downElements.ContainsKey(sourceSender))
            {
                resizeDown = true;
            }
            #endregion

            Thread t = new Thread(new ThreadStart(updateSizeLoop));
            t.Name = "Mouse Position Poll Thread";
            t.Start();
        }

        private void updateSizeLoop()
        {
            try
            {
                while (resizeDown || resizeLeft || resizeRight || resizeUp)
                {
                    target.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Render, new RefreshDelegate(updateSize));
                    target.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Render, new RefreshDelegate(updateMouseDown));
                    Thread.Sleep(25);
                }

                target.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Render, new RefreshDelegate(setArrowCursor));
            }
            catch (Exception)
            {
            }
        }

        #region updates
        private void updateSize()
        {
            PointAPI currentMousePoint = new PointAPI();
            GetCursorPos(out currentMousePoint);

            try
            {
                if (resizeRight)
                {
                    //如果當鼠標左鍵點下時,窗口的寬度已經達到最小值,
                    if (target.Width == minWidth)
                    {
                        //鼠標向右移動,表示當前是將窗口變大,此時窗口只能變大,因爲已經達到最小寬度了
                        if ((startMousePoint.X - currentMousePoint.X) < 0)
                        {
                            target.Width = this.startWindowSize.Width - (startMousePoint.X - currentMousePoint.X);
                        }
                    }
                    else
                    {
                        //此時,窗口可大可小
                        if ((this.startWindowSize.Width - (startMousePoint.X - currentMousePoint.X)) >= minWidth)
                        {
                            target.Width = this.startWindowSize.Width - (startMousePoint.X - currentMousePoint.X);
                        }
                        else
                        {
                            //此時,只能限制窗口爲最小值,不能繼續變小
                            target.Width = minWidth;
                        }
                    }
                }

                if (resizeDown)
                {
                    if (target.Height == minHeight)
                    {
                        if ((startMousePoint.Y - currentMousePoint.Y) < 0)
                        {
                            //限制窗口的最底端,不能低於任務欄,即不能被任務欄遮擋
                            if (workAreaMaxHeight > 0)
                            {
                                target.Height = (((startWindowSize.Height - (startMousePoint.Y - currentMousePoint.Y)) + target.Top) <= workAreaMaxHeight) ? (startWindowSize.Height - (startMousePoint.Y - currentMousePoint.Y)) : (workAreaMaxHeight - target.Top);
                            }
                            else
                            {
                                target.Height = startWindowSize.Height - (startMousePoint.Y - currentMousePoint.Y);
                            }
                        }
                    }
                    else
                    {
                        if ((startWindowSize.Height - (startMousePoint.Y - currentMousePoint.Y)) >= minHeight)
                        {
                            if (workAreaMaxHeight > 0)
                            {
                                target.Height = (((startWindowSize.Height - (startMousePoint.Y - currentMousePoint.Y)) + target.Top) <= workAreaMaxHeight) ? (startWindowSize.Height - (startMousePoint.Y - currentMousePoint.Y)) : (workAreaMaxHeight - target.Top);
                            }
                            else
                            {
                                target.Height = startWindowSize.Height - (startMousePoint.Y - currentMousePoint.Y);
                            }
                        }
                        else
                        {
                            target.Height = minHeight;
                        }
                    }
                }

                if (resizeLeft)
                {
                    if (target.Width == minWidth)
                    {
                        if ((startMousePoint.X - currentMousePoint.X) > 0)
                        {
                            target.Width = startWindowSize.Width + (startMousePoint.X - currentMousePoint.X);
                            target.Left = startWindowLeftUpPoint.X - (startMousePoint.X - currentMousePoint.X);
                        }
                    }
                    else
                    {
                        if ((this.startWindowSize.Width + (startMousePoint.X - currentMousePoint.X)) >= minWidth)
                        {
                            target.Width = startWindowSize.Width + (startMousePoint.X - currentMousePoint.X);
                            target.Left = startWindowLeftUpPoint.X - (startMousePoint.X - currentMousePoint.X);
                        }
                        else
                        {
                            target.Width = minWidth;
                            target.Left = startWindowLeftUpPoint.X + startWindowSize.Width - target.Width;
                        }
                    }
                }

                if (resizeUp)
                {
                    if (target.Height == minHeight)
                    {
                        if ((startMousePoint.Y - currentMousePoint.Y) > 0)
                        {
                            target.Height = startWindowSize.Height + (startMousePoint.Y - currentMousePoint.Y);
                            target.Top = startWindowLeftUpPoint.Y - (startMousePoint.Y - currentMousePoint.Y);
                        }
                        else
                        {
                            target.Height = minHeight;
                            target.Top = startWindowLeftUpPoint.Y + startWindowSize.Height - target.Height;
                        }
                    }
                    else
                    {
                        if ((startWindowSize.Height + (startMousePoint.Y - currentMousePoint.Y)) >= minHeight)
                        {
                            target.Height = startWindowSize.Height + (startMousePoint.Y - currentMousePoint.Y);
                            target.Top = startWindowLeftUpPoint.Y - (startMousePoint.Y - currentMousePoint.Y);
                        }
                        else
                        {
                            target.Height = minHeight;
                            target.Top = startWindowLeftUpPoint.Y + startWindowSize.Height - target.Height;
                        }
                    }
                }
            }
            catch
            {
            }
        }

        private void updateMouseDown()
        {
            if (Mouse.LeftButton == MouseButtonState.Released)
            {
                resizeRight = false;
                resizeLeft = false;
                resizeUp = false;
                resizeDown = false;
            }
        }
        #endregion
        #endregion

        #region cursor updates
        private void element_MouseEnter(object sender, MouseEventArgs e)
        {
            bool resizeRight = false;
            bool resizeLeft = false;
            bool resizeUp = false;
            bool resizeDown = false;

            UIElement sourceSender = (UIElement)sender;
            if (leftElements.ContainsKey(sourceSender))
            {
                resizeLeft = true;
            }
            if (rightElements.ContainsKey(sourceSender))
            {
                resizeRight = true;
            }
            if (upElements.ContainsKey(sourceSender))
            {
                resizeUp = true;
            }
            if (downElements.ContainsKey(sourceSender))
            {
                resizeDown = true;
            }

            if ((resizeLeft && resizeDown) || (resizeRight && resizeUp))
            {
                setNESWCursor(sender, e);
            }
            else if ((resizeRight && resizeDown) || (resizeLeft && resizeUp))
            {
                setNWSECursor(sender, e);
            }
            else if (resizeLeft || resizeRight)
            {
                setWECursor(sender, e);
            }
            else if (resizeUp || resizeDown)
            {
                setNSCursor(sender, e);
            }
        }

        private void setWECursor(object sender, MouseEventArgs e)
        {
            target.Cursor = Cursors.SizeWE;
        }

        private void setNSCursor(object sender, MouseEventArgs e)
        {
            target.Cursor = Cursors.SizeNS;
        }

        private void setNESWCursor(object sender, MouseEventArgs e)
        {
            target.Cursor = Cursors.SizeNESW;
        }

        private void setNWSECursor(object sender, MouseEventArgs e)
        {
            target.Cursor = Cursors.SizeNWSE;
        }

        private void setArrowCursor(object sender, MouseEventArgs e)
        {
            if (!resizeDown && !resizeLeft && !resizeRight && !resizeUp)
            {
                target.Cursor = Cursors.Arrow;
            }
        }

        private void setArrowCursor()
        {
            target.Cursor = Cursors.Arrow;
        }
        #endregion

        #region external call
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool GetCursorPos(out PointAPI lpPoint);

        private struct PointAPI
        {
            public int X;
            public int Y;
        }
        #endregion
    }
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章