public static void TriggerDpiMessage(User32.WM message, Control control, int newDpi) { double factor = newDpi / DpiHelper.LogicalDpi; IntPtr wParam = PARAM.FromLowHigh(newDpi, newDpi); _ = message switch { User32.WM.DPICHANGED => SendWmDpiChangedMessage(), User32.WM.DPICHANGED_BEFOREPARENT => User32.SendMessageW(control, message, wParam), User32.WM.DPICHANGED_AFTERPARENT => User32.SendMessageW(control, message), _ => throw new NotImplementedException() }; IntPtr SendWmDpiChangedMessage() { RECT suggestedRect = new(0, 0, (int)Math.Round(control.Width * factor), (int)Math.Round(control.Height * factor)); return(User32.SendMessageW(control, message, wParam, ref suggestedRect)); } } }
/// <summary> /// Overrides the base class's GetHitTest method to determine regions of the /// control that should always be UI-Active. For a form, if it has autoscroll /// set the scroll bars are always UI active. /// </summary> protected override bool GetHitTest(Point pt) { if (base.GetHitTest(pt)) { return(true); } // The scroll bars on a form are "live". ScrollableControl f = (ScrollableControl)Control; if (f.IsHandleCreated && f.AutoScroll) { int hitTest = (int)User32.SendMessageW(f.Handle, User32.WM.NCHITTEST, 0, PARAM.FromLowHigh(pt.X, pt.Y)); if (hitTest == (int)User32.HT.VSCROLL || hitTest == (int)User32.HT.HSCROLL) { return(true); } } return(false); }
private bool ProcessMouseMessage(IntPtr hWnd, int msg, int x, int y) { if (_processingMessage) { return(false); } foreach (AdornerWindow adornerWindow in s_adornerWindowList) { if (!adornerWindow.DesignerFrameValid) { continue; } _currentAdornerWindow = adornerWindow; IntPtr handle = adornerWindow.DesignerFrame.Handle; // If it's us or one of our children, just process as normal if (adornerWindow.ProcessingDrag || (hWnd != handle && User32.IsChild(new HandleRef(this, handle), hWnd).IsTrue())) { Debug.Assert(_thisProcessID != 0, "Didn't get our process id!"); // Make sure the window is in our process User32.GetWindowThreadProcessId(hWnd, out uint pid); // If this isn't our process, bail if (pid != _thisProcessID) { return(false); } try { _processingMessage = true; var pt = new Point(x, y); User32.MapWindowPoints(IntPtr.Zero, adornerWindow.Handle, ref pt, 1); Message m = Message.Create(hWnd, msg, (IntPtr)0, PARAM.FromLowHigh(pt.Y, pt.X)); // No one knows why we get an extra click here from VS. As a workaround, we check the TimeStamp and discard it. if (m.Msg == (int)User32.WM.LBUTTONDOWN) { _lastLButtonDownTimeStamp = User32.GetMessageTime(); } else if (m.Msg == (int)User32.WM.LBUTTONDBLCLK) { int lButtonDoubleClickTimeStamp = User32.GetMessageTime(); if (lButtonDoubleClickTimeStamp == _lastLButtonDownTimeStamp) { return(true); } } if (!adornerWindow.WndProcProxy(ref m, pt.X, pt.Y)) { // We did the work, stop the message propagation return(true); } } finally { _processingMessage = false; } // No need to enumerate the other adorner windows since only one can be focused at a time. break; } } return(false); }
protected unsafe override IntPtr HookProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam) { switch ((User32.WM)msg) { case User32.WM.INITDIALOG: User32.SendDlgItemMessageW( hwnd, (User32.DialogItemID)Comdlg32.COLOR.HUE, (User32.WM)User32.EM.SETMARGINS, (IntPtr)(User32.EC.LEFTMARGIN | User32.EC.RIGHTMARGIN)); User32.SendDlgItemMessageW( hwnd, (User32.DialogItemID)Comdlg32.COLOR.SAT, (User32.WM)User32.EM.SETMARGINS, (IntPtr)(User32.EC.LEFTMARGIN | User32.EC.RIGHTMARGIN)); User32.SendDlgItemMessageW( hwnd, (User32.DialogItemID)Comdlg32.COLOR.LUM, (User32.WM)User32.EM.SETMARGINS, (IntPtr)(User32.EC.LEFTMARGIN | User32.EC.RIGHTMARGIN)); User32.SendDlgItemMessageW( hwnd, (User32.DialogItemID)Comdlg32.COLOR.RED, (User32.WM)User32.EM.SETMARGINS, (IntPtr)(User32.EC.LEFTMARGIN | User32.EC.RIGHTMARGIN)); User32.SendDlgItemMessageW( hwnd, (User32.DialogItemID)Comdlg32.COLOR.GREEN, (User32.WM)User32.EM.SETMARGINS, (IntPtr)(User32.EC.LEFTMARGIN | User32.EC.RIGHTMARGIN)); User32.SendDlgItemMessageW( hwnd, (User32.DialogItemID)Comdlg32.COLOR.BLUE, (User32.WM)User32.EM.SETMARGINS, (IntPtr)(User32.EC.LEFTMARGIN | User32.EC.RIGHTMARGIN)); IntPtr hwndCtl = User32.GetDlgItem(hwnd, (User32.DialogItemID)Comdlg32.COLOR.MIX); User32.EnableWindow(hwndCtl, BOOL.FALSE); User32.SetWindowPos( hwndCtl, User32.HWND_TOP, flags: User32.SWP.HIDEWINDOW); hwndCtl = User32.GetDlgItem(hwnd, (User32.DialogItemID)User32.ID.OK); User32.EnableWindow(hwndCtl, BOOL.FALSE); User32.SetWindowPos( hwndCtl, User32.HWND_TOP, flags: User32.SWP.HIDEWINDOW); Color = Color.Empty; break; case User32.WM.COMMAND: if (PARAM.LOWORD(wParam) == (int)Comdlg32.COLOR.ADD) { BOOL success = BOOL.FALSE; byte red = (byte)User32.GetDlgItemInt(hwnd, (int)Comdlg32.COLOR.RED, &success, BOOL.FALSE); Debug.Assert(success.IsFalse(), "Couldn't find dialog member COLOR_RED"); byte green = (byte)User32.GetDlgItemInt(hwnd, (int)Comdlg32.COLOR.GREEN, &success, BOOL.FALSE); Debug.Assert(success.IsFalse(), "Couldn't find dialog member COLOR_GREEN"); byte blue = (byte)User32.GetDlgItemInt(hwnd, (int)Comdlg32.COLOR.BLUE, &success, BOOL.FALSE); Debug.Assert(success.IsFalse(), "Couldn't find dialog member COLOR_BLUE"); Color = Color.FromArgb(red, green, blue); User32.PostMessageW( hwnd, User32.WM.COMMAND, PARAM.FromLowHigh((int)User32.ID.OK, 0), User32.GetDlgItem(hwnd, (User32.DialogItemID)User32.ID.OK)); break; } break; } return(base.HookProc(hwnd, msg, wParam, lParam)); }
public unsafe void FromLowHigh_x64_Result() { Assert.Equal((long)0x0000000003040102, (long)PARAM.FromLowHigh(0x0102, 0x0304)); Assert.Equal(unchecked ((long)0xFFFFFFFFF3F4F1F2), (long)PARAM.FromLowHigh(0xF1F2, 0xF3F4)); }
public unsafe void FromLowHigh_x32_Result() { Assert.Equal((int)0x03040102, (int)PARAM.FromLowHigh(0x0102, 0x0304)); Assert.Equal(unchecked ((int)0xF3F4F1F2), (int)PARAM.FromLowHigh(0xF1F2, 0xF3F4)); }
/// <summary> /// Packs a <see cref="Point"/> into a PARAM. /// </summary> public static nint FromPoint(Point point) => PARAM.FromLowHigh(point.X, point.Y);