예제 #1
0
        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);
        }
예제 #3
0
                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));
            }
예제 #5
0
 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));
 }
예제 #6
0
 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));
 }
예제 #7
0
 /// <summary>
 ///  Packs a <see cref="Point"/> into a PARAM.
 /// </summary>
 public static nint FromPoint(Point point)
 => PARAM.FromLowHigh(point.X, point.Y);