public MouseDragAction(IntPtr hwnd, Point initialMousePosition)
        {
            mHwnd = hwnd;
            mInitialMousePosition = initialMousePosition;

            var windowPlacement = WinAPI.GetPlacement(hwnd);

            if (windowPlacement == WinAPI.ShowWindowCommands.SW_MAXIMIZE)
            {
                WinAPI.ShowWindow(hwnd, WinAPI.ShowWindowCommands.SW_RESTORE);
            }

            if (!WinAPI.GetWindowRect(hwnd, out var windowRect))
            {
                throw new InvalidOperationException(
                          $"Could not get window rect of window {hwnd}");
            }

            mInitialWindowPosition = new Point(windowRect.Left, windowRect.Top);

            mInvisibleWindow = new InvisibleWindow();
            mInvisibleWindow.CenterAt(initialMousePosition);
            mInvisibleWindow.Cursor = Cursors.Hand;
            mInvisibleWindow.Show();

            mSnapRectangle = new SnapRectangle()
            {
                Visible = false
            };
        }
        public MouseResizeAction(IntPtr hwnd, Point initialMousePosition)
        {
            mInitialMousePosition = initialMousePosition;
            mHwnd = hwnd;

            if (!WinAPI.GetWindowRect(hwnd, out var rect))
            {
                throw new InvalidOperationException($"Could not get window rect of window {hwnd}");
            }

            var cornerSize = Properties.Settings.Default.sideWidth / 2;
            var sideSize   = cornerSize;

            mInitialWindowRect = mNewWindowRect =
                new Rectangle(rect.Left, rect.Top,
                              rect.Right - rect.Left,
                              rect.Bottom - rect.Top);

            var normalizedMousePos = new PointF(
                (initialMousePosition.X - mInitialWindowRect.X)
                / (float)mInitialWindowRect.Width,
                (initialMousePosition.Y - mInitialWindowRect.Y)
                / (float)mInitialWindowRect.Height);

            var areas = new Dictionary <ResizeMode, RectangleF> {
                [ResizeMode.TopLeft]     = new RectangleF(0, 0, cornerSize, cornerSize),
                [ResizeMode.TopRight]    = new RectangleF(1 - cornerSize, 0, cornerSize, cornerSize),
                [ResizeMode.BottomLeft]  = new RectangleF(0, 1 - cornerSize, cornerSize, cornerSize),
                [ResizeMode.BottomRight] = new RectangleF(1 - cornerSize, 1 - cornerSize, cornerSize, cornerSize),

                [ResizeMode.Top]    = new RectangleF(0, 0, 1, sideSize),
                [ResizeMode.Left]   = new RectangleF(0, 0, sideSize, 1),
                [ResizeMode.Right]  = new RectangleF(1 - sideSize, 0, sideSize, 1),
                [ResizeMode.Bottom] = new RectangleF(0, 1 - sideSize, 1, sideSize),
            };

            WinAPI.SendMessageW(hwnd, WinAPI.WM_ENTERSIZEMOVE, IntPtr.Zero, IntPtr.Zero);

            if (areas.TryFirstOrDefault(kvp => kvp.Value.Contains(normalizedMousePos), out var areaKvp))
            {
                mResizeMode = areaKvp.Key;
            }
            else
            {
                mResizeMode = ResizeMode.All;
            }

            mInvisibleWindow = new InvisibleWindow();
            mInvisibleWindow.CenterAt(initialMousePosition);
            mInvisibleWindow.Cursor = Cursors[mResizeMode];
            mInvisibleWindow.Show();

            mUpdateTimer          = new Timer();
            mUpdateTimer.Interval = 25;
            mUpdateTimer.Tick    += UpdateTimer_Tick;
            mUpdateTimer.Start();
        }