private void ChangeCursor(ChromeHitTest test) { var cs = this.Cursor; switch (test) { case ChromeHitTest.Left: case ChromeHitTest.Right: cs = Cursors.SizeWE; break; case ChromeHitTest.Top: case ChromeHitTest.Bottom: cs = Cursors.SizeNS; break; case ChromeHitTest.TopLeft: case ChromeHitTest.BottomRight: cs = Cursors.SizeNWSE; break; case ChromeHitTest.TopRight: case ChromeHitTest.BottomLeft: cs = Cursors.SizeNESW; break; } if (cs != Cursor) { Cursor = cs; } }
/// <summary> /// Sets the HitTestType property for an UI element. /// </summary> /// <param name="element">The UI element.</param> /// <param name="type">The hit-test type.</param> /// <exception cref="System.ArgumentNullException">element</exception> public static void SetHitTestType(DependencyObject element, ChromeHitTest type) { if (element == null) { throw new ArgumentNullException("element"); } element.SetValue(HitTestTypeProperty, type); }
private ChromeHitTest HandleNcHitTest(IntPtr lParam) { Point screenPoint = lParam.ToPoint(); Point windowPoint = ContentWindow.PointFromScreen(screenPoint); ChromeHitTest location = ChromeHitTest.Client; var element = ContentWindow.InputHitTest(windowPoint); if (element != null) { location = Chrome.GetHitTestType((DependencyObject)element); } if (_resizeGrip != null && _resizeGrip.Visibility == System.Windows.Visibility.Visible && VisualTreeHelper.HitTest(_resizeGrip, _resizeGrip.PointFromScreen(screenPoint)) != null) { location = _resizeGrip.FlowDirection == System.Windows.FlowDirection.LeftToRight ? ChromeHitTest.BottomRight : ChromeHitTest.BottomLeft; } //Debug.WriteLine(location); return(location); }
private ChromeHitTest HandleHcHitTest(IntPtr lParam) { ChromeHitTest res = ChromeHitTest.Border; if (_manager.ContentWindow.ResizeMode == ResizeMode.CanResizeWithGrip || _manager.ContentWindow.ResizeMode == ResizeMode.CanResize) { var pt = (Point)lParam.ToPoint(); pt = PointFromScreen(pt); //Debug.WriteLine("NC pt = " + pt); int diagSize = (int)(2 * PadSize * UIHooks.GetWindowDpiScale(_manager.ContentWindow)); switch (Side) { case BorderSide.Left: if (pt.Y <= diagSize) { res = ChromeHitTest.TopLeft; } else if (pt.Y >= Height - diagSize) { res = ChromeHitTest.BottomLeft; } else { res = ChromeHitTest.Left; } break; case BorderSide.Top: if (pt.X <= diagSize) { res = ChromeHitTest.TopLeft; } else if (pt.X >= Width - diagSize) { res = ChromeHitTest.TopRight; } else { res = ChromeHitTest.Top; } break; case BorderSide.Right: if (pt.Y <= diagSize) { res = ChromeHitTest.TopRight; } else if (pt.Y >= Height - diagSize) { res = ChromeHitTest.BottomRight; } else { res = ChromeHitTest.Right; } break; case BorderSide.Bottom: if (pt.X <= diagSize) { res = ChromeHitTest.BottomLeft; } else if (pt.X >= Width - diagSize) { res = ChromeHitTest.BottomRight; } else { res = ChromeHitTest.Bottom; } break; } //Debug.WriteLine("Side {0}({1},{2}) at {3}, res = {4}", Side, Width, Height, pt, res); } return(_lastHitTest = res); }
IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { IntPtr retVal = IntPtr.Zero; if (!handled) { try { var wmsg = (WindowMessage)msg; //Debug.WriteLine(wmsg); switch (wmsg) { //case WindowMessage.WM_NCCALCSIZE: // handled = true; // break; //case WindowMessage.WM_MOUSEMOVE: // var pt = (Point)lParam.ToPoint(); // Debug.WriteLine("WM point = " + pt); // break; case WindowMessage.WM_NCHITTEST: //pt = (Point)lParam.ToPoint(); //Debug.WriteLine("NC point = " + PointFromScreen(pt)); ChromeHitTest test = HandleHcHitTest(lParam); // Don't actual report this window as NC anymore and just change cursor instead. // This allows content window to properly get IsMouseOver=false at edges if (Mouse.LeftButton != MouseButtonState.Pressed) { ChangeCursor(test); } //retVal = new IntPtr((int)test); //handled = true; break; //case WindowMessage.WM_NCRBUTTONDOWN: //case WindowMessage.WM_NCMBUTTONDOWN: //case WindowMessage.WM_NCRBUTTONDBLCLK: //case WindowMessage.WM_NCMBUTTONDBLCLK: //case WindowMessage.WM_RBUTTONDBLCLK: //case WindowMessage.WM_MBUTTONDBLCLK: //case WindowMessage.WM_LBUTTONDBLCLK: // handled = true; // User32.SetForegroundWindow(_manager.hWndContent); // break; //case WindowMessage.WM_NCLBUTTONDOWN: //case WindowMessage.WM_NCLBUTTONDBLCLK: // handled = true; // // pass resizer msg to the content window instead // User32.SetForegroundWindow(_manager.hWndContent); // User32.SendMessage(_manager.hWndContent, (uint)msg, wParam, lParam); // break; case WindowMessage.WM_RBUTTONDOWN: case WindowMessage.WM_MBUTTONDOWN: case WindowMessage.WM_RBUTTONDBLCLK: case WindowMessage.WM_MBUTTONDBLCLK: handled = true; User32.SetForegroundWindow(_manager.hWndContent); break; case WindowMessage.WM_LBUTTONDOWN: case WindowMessage.WM_LBUTTONDBLCLK: var hitTest = _lastHitTest; //Debug.WriteLine("Should send {0} to content window.", hitTest); if (hitTest != ChromeHitTest.Client) { User32.SetForegroundWindow(_manager.hWndContent); User32.PostMessage(_manager.hWndContent, (uint)(msg - NC_TO_WM_DIFF), new IntPtr((int)hitTest), IntPtr.Zero); //User32.SendMessage(_manager.hWndContent, (uint)(msg - NC_TO_WM_DIFF), new IntPtr((int)hitTest), IntPtr.Zero); handled = true; } break; case WindowMessage.WM_MOUSEACTIVATE: //var lowword = 0xffff & lParam.ToInt32(); //var hchit = (ChromeHitTest)lowword; // in case of non-resizable window eat this msg //if (hchit == ChromeHitTest.Client) //{ // retVal = new IntPtr((int)MouseActivate.MA_NOACTIVATEANDEAT); //} //else //{ retVal = new IntPtr((int)MouseActivate.MA_NOACTIVATE); //} handled = true; break; case WindowMessage.WM_GETMINMAXINFO: // overridden so max size = normal max + resize border (for when content window is max size without maximizing) //var thick = 2 * (int)PadSize; //MINMAXINFO para = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO)); //var orig = para.ptMaxTrackSize; //orig.x += thick; //orig.y += thick; //para.ptMaxTrackSize = orig; //Marshal.StructureToPtr(para, lParam, true); break; } } catch { } } return(retVal); }