Example #1
0
            protected IntPtr HandleNCHitTest(IntPtr lParam)
            {
                // Because we still have the System Border (which technically extends beyond the actual window
                // into where the Drop shadows are), we can use DefWindowProc here to handle resizing, except
                // on the top. We'll handle that below
                var originalRet = Win32Interop.DefWindowProc(Hwnd, (uint)WM.NCHITTEST, IntPtr.Zero, lParam);

                if (originalRet != new IntPtr(1))
                {
                    return(originalRet);
                }

                // At this point, we know that the cursor is inside the client area so it
                // has to be either the little border at the top of our custom title bar,
                // the drag bar or something else in the XAML island. But the XAML Island
                // handles WM_NCHITTEST on its own so actually it cannot be the XAML
                // Island. Then it must be the drag bar or the little border at the top
                // which the user can use to move or resize the window.

                var point = PointToClient(PointFromLParam(lParam));

                RECT rcWindow;

                Win32Interop.GetWindowRect(Hwnd, out rcWindow);

                // On the Top border, the resize handle overlaps with the Titlebar area, which matches
                // a typical Win32 window or modern app window
                var  resizeBorderHeight = GetResizeHandleHeight();
                bool isOnResizeBorder   = point.Y < resizeBorderHeight;

                // Make sure the caption buttons still get precedence
                // This is where things get tricky too. On Win11, we still want to suppor the snap
                // layout feature when hovering over the Maximize button. Unfortunately no API exists
                // yet to call that manually if using a custom titlebar. But, if we return HT_MAXBUTTON
                // here, the pointer events no longer enter the window
                // See https://github.com/dotnet/wpf/issues/4825 for more on this...
                // To hack our way into making this work, we'll return HT_MAXBUTTON here, but manually
                // manage the state and handle stuff through the WM_NCLBUTTON... events
                // This only applies on Windows 11, Windows 10 will work normally b/c no snap layout thing

                if (_owner !.HitTestCaptionButtons(point))
                {
                    if (_isWindows11)
                    {
                        var result = _owner.HitTestMaximizeButton(point);

                        if (result)
                        {
                            _fakingMaximizeButton = true;
                            return(new IntPtr(9));
                        }
                    }
                }
Example #2
0
        private void ViewerPosUpdateHandler(object obj)
        {
            if (mainWindowHandle != IntPtr.Zero && dock != DockType.None)
            {
                if (Win32Interop.IsWindowVisible(mainWindowHandle))
                {
                    if (!Win32Interop.IsZoomed(mainWindowHandle))
                    {
                        Win32Interop.Rect currentPosition;
                        Win32Interop.GetWindowRect(mainWindowHandle, out currentPosition);
                        if (!currentPosition.IsSame(lastPosition))
                        {
                            this.SafeInvoke(() =>
                            {
                                ViewerPosUpdate(currentPosition);
                            });

                            lastPosition = currentPosition;
                        }
                    }
                }
            }
        }