Пример #1
0
        protected unsafe override LResult WindowProcedure(WindowHandle window, MessageType message, WParam wParam, LParam lParam)
        {
            switch (message)
            {
            case MessageType.Create:
                _baseUnits = Windows.GetDialogBaseUnits();
                _btnWidth  = _baseUnits.Width * 8;
                _btnHeight = _baseUnits.Height * 4;

                // Create the owner-draw pushbuttons
                _hwndSmaller = Windows.CreateWindow("button", "",
                                                    WindowStyles.Child | WindowStyles.Visible | (WindowStyles)ButtonStyles.OwnerDrawn,
                                                    ExtendedWindowStyles.Default,
                                                    new Rectangle(0, 0, _btnWidth, _btnHeight),
                                                    window, (MenuHandle)ID_SMALLER, ModuleInstance, IntPtr.Zero);

                _hwndLarger = Windows.CreateWindow("button", "",
                                                   WindowStyles.Child | WindowStyles.Visible | (WindowStyles)ButtonStyles.OwnerDrawn,
                                                   ExtendedWindowStyles.Default,
                                                   new Rectangle(0, 0, _btnWidth, _btnHeight),
                                                   window, (MenuHandle)ID_LARGER, ModuleInstance, IntPtr.Zero);
                return(0);

            case MessageType.Size:
                _cxClient = lParam.LowWord;
                _cyClient = lParam.HighWord;

                // Move the buttons to the new center
                _hwndSmaller.MoveWindow(
                    new Rectangle(_cxClient / 2 - 3 * _btnWidth / 2, _cyClient / 2 - _btnHeight / 2, _btnWidth, _btnHeight),
                    repaint: true);
                _hwndLarger.MoveWindow(
                    new Rectangle(_cxClient / 2 + _btnWidth / 2, _cyClient / 2 - _btnHeight / 2, _btnWidth, _btnHeight),
                    repaint: true);
                return(0);

            case MessageType.Command:
                Rectangle rc = window.GetWindowRectangle();

                // Make the window 10% smaller or larger
                switch ((int)(uint)wParam)
                {
                case ID_SMALLER:
                    rc.Inflate(rc.Width / -10, rc.Height / -10);
                    break;

                case ID_LARGER:
                    rc.Inflate(rc.Width / 10, rc.Height / 10);
                    break;
                }

                window.MoveWindow(new Rectangle(rc.Left, rc.Top, rc.Right - rc.Left, rc.Bottom - rc.Top), repaint: true);
                return(0);

            case MessageType.DrawItem:
                DRAWITEMSTRUCT *pdis = (DRAWITEMSTRUCT *)lParam;

                // Fill area with white and frame it black
                using (DeviceContext dc = new DeviceContext(pdis->hDC))
                {
                    Rectangle rect = pdis->rcItem;

                    dc.FillRectangle(rect, StockBrush.White);
                    dc.FrameRectangle(rect, StockBrush.Black);

                    // Draw inward and outward black triangles
                    int cx = rect.Right - rect.Left;
                    int cy = rect.Bottom - rect.Top;

                    Point[] pt = new Point[3];

                    switch ((int)pdis->CtlID)
                    {
                    case ID_SMALLER:
                        pt[0].X = 3 * cx / 8; pt[0].Y = 1 * cy / 8;
                        pt[1].X = 5 * cx / 8; pt[1].Y = 1 * cy / 8;
                        pt[2].X = 4 * cx / 8; pt[2].Y = 3 * cy / 8;
                        Triangle(dc, pt);
                        pt[0].X = 7 * cx / 8; pt[0].Y = 3 * cy / 8;
                        pt[1].X = 7 * cx / 8; pt[1].Y = 5 * cy / 8;
                        pt[2].X = 5 * cx / 8; pt[2].Y = 4 * cy / 8;
                        Triangle(dc, pt);
                        pt[0].X = 5 * cx / 8; pt[0].Y = 7 * cy / 8;
                        pt[1].X = 3 * cx / 8; pt[1].Y = 7 * cy / 8;
                        pt[2].X = 4 * cx / 8; pt[2].Y = 5 * cy / 8;
                        Triangle(dc, pt);
                        pt[0].X = 1 * cx / 8; pt[0].Y = 5 * cy / 8;
                        pt[1].X = 1 * cx / 8; pt[1].Y = 3 * cy / 8;
                        pt[2].X = 3 * cx / 8; pt[2].Y = 4 * cy / 8;
                        Triangle(dc, pt);
                        break;

                    case ID_LARGER:
                        pt[0].X = 5 * cx / 8; pt[0].Y = 3 * cy / 8;
                        pt[1].X = 3 * cx / 8; pt[1].Y = 3 * cy / 8;
                        pt[2].X = 4 * cx / 8; pt[2].Y = 1 * cy / 8;
                        Triangle(dc, pt);
                        pt[0].X = 5 * cx / 8; pt[0].Y = 5 * cy / 8;
                        pt[1].X = 5 * cx / 8; pt[1].Y = 3 * cy / 8;
                        pt[2].X = 7 * cx / 8; pt[2].Y = 4 * cy / 8;
                        Triangle(dc, pt);
                        pt[0].X = 3 * cx / 8; pt[0].Y = 5 * cy / 8;
                        pt[1].X = 5 * cx / 8; pt[1].Y = 5 * cy / 8;
                        pt[2].X = 4 * cx / 8; pt[2].Y = 7 * cy / 8;
                        Triangle(dc, pt);
                        pt[0].X = 3 * cx / 8; pt[0].Y = 3 * cy / 8;
                        pt[1].X = 3 * cx / 8; pt[1].Y = 5 * cy / 8;
                        pt[2].X = 1 * cx / 8; pt[2].Y = 4 * cy / 8;
                        Triangle(dc, pt);
                        break;
                    }

                    // Invert the rectangle if the button is selected
                    if ((pdis->itemState & OwnerDrawStates.Selected) != 0)
                    {
                        dc.InvertRectangle(rect);
                    }

                    if ((pdis->itemState & OwnerDrawStates.Focus) != 0)
                    {
                        rect = Rectangle.FromLTRB(
                            rect.Left + cx / 16,
                            rect.Top + cy / 16,
                            rect.Right - cx / 16,
                            rect.Bottom - cy / 16);

                        dc.DrawFocusRectangle(rect);
                    }
                }
                return(0);
            }

            return(base.WindowProcedure(window, message, wParam, lParam));
        }
Пример #2
0
        public static unsafe void ReflectMessage(ref Message msg, out bool handled)
        {
            IntPtr hWndChild = IntPtr.Zero;

            if (msg.MessageId == WindowMessages.WM_COMMAND)
            {
                if (msg.LParam != IntPtr.Zero)
                {
                    hWndChild = msg.LParam;
                }
            }
            else if (msg.MessageId == WindowMessages.WM_NOTIFY)
            {
                NMHDR *header = (NMHDR *)msg.LParam;
                hWndChild = header->hWndFrom;
            }
            else if (msg.MessageId == WindowMessages.WM_PARENTNOTIFY)
            {
                uint submessage = (uint)((int)msg.WParam & 0xFFFF);
                if (submessage == WindowMessages.WM_CREATE || submessage == WindowMessages.WM_DESTROY)
                {
                    hWndChild = msg.LParam;
                }
                else
                {
                    int controlId = ((int)msg.WParam >> 16) & 0xFFFF;
                    hWndChild = NativeMethods.GetDlgItem(msg.TargetHandle, controlId);
                }
            }
            else if (msg.MessageId == WindowMessages.WM_DRAWITEM)
            {
                if (msg.WParam != IntPtr.Zero)
                {
                    DRAWITEMSTRUCT *drawItemStruct = (DRAWITEMSTRUCT *)msg.WParam;
                    hWndChild = drawItemStruct->hwndItem;
                }
            }
            else if (msg.MessageId == WindowMessages.WM_MEASUREITEM)
            {
                if (msg.WParam != IntPtr.Zero)
                {
                    MEASUREITEMSTRUCT *measureItemStruct = (MEASUREITEMSTRUCT *)msg.WParam;
                    hWndChild = NativeMethods.GetDlgItem(msg.TargetHandle, (int)measureItemStruct->CtlID);
                }
            }
            else if (msg.MessageId == WindowMessages.WM_COMPAREITEM)
            {
                if (msg.WParam != IntPtr.Zero)
                {
                    COMPAREITEMSTRUCT *compareStruct = (COMPAREITEMSTRUCT *)msg.WParam;
                    hWndChild = compareStruct->hwndItem;
                }
            }
            else if (msg.MessageId == WindowMessages.WM_DELETEITEM)
            {
                if (msg.WParam != IntPtr.Zero)
                {
                    DELETEITEMSTRUCT *deleteStruct = (DELETEITEMSTRUCT *)msg.WParam;
                    hWndChild = deleteStruct->hwndItem;
                }
            }
            else if (msg.MessageId == WindowMessages.WM_VKEYTOITEM || msg.MessageId == WindowMessages.WM_CHARTOITEM ||
                     msg.MessageId == WindowMessages.WM_HSCROLL || msg.MessageId == WindowMessages.WM_VSCROLL)
            {
                hWndChild = msg.LParam;
            }
            else if (msg.MessageId == WindowMessages.WM_CTLCOLORBTN || msg.MessageId == WindowMessages.WM_CTLCOLORDLG ||
                     msg.MessageId == WindowMessages.WM_CTLCOLOREDIT || msg.MessageId == WindowMessages.WM_CTLCOLORMSGBOX ||
                     msg.MessageId == WindowMessages.WM_CTLCOLORMSGBOX || msg.MessageId == WindowMessages.WM_CTLCOLORSCROLLBAR ||
                     msg.MessageId == WindowMessages.WM_CTLCOLORSTATIC)
            {
                hWndChild = msg.LParam;
            }

            if (hWndChild == IntPtr.Zero)
            {
                handled = false;
                return;
            }

            if (!NativeMethods.IsWindow(hWndChild))
            {
                throw new InvalidOperationException("hwndChild not a valid HWND");
            }

            // This code relies on the fact that NativeMethods.GetProp() returns IntPtr.Zero
            // if the property has not been set. This code only cares if the handled flag
            // was set to true. If the flag is false, this code behaves the same as if
            // SetReflectedMessageHandled() was never called at all.

            NativeMethods.RemoveProp(hWndChild, HandledProperty); // clear it out, just in case
            IntPtr result = NativeMethods.SendMessage(hWndChild, msg.MessageId + WM_REFLECTED_MESSAGE_BASE, msg.WParam, msg.LParam);

            handled = NativeMethods.GetProp(hWndChild, HandledProperty) != IntPtr.Zero;
            NativeMethods.RemoveProp(hWndChild, HandledProperty);
            if (handled)
            {
                msg.Result = result;
            }
        }
Пример #3
0
        static unsafe LRESULT WindowProcedure(WindowHandle window, WindowMessage message, WPARAM wParam, LPARAM lParam)
        {
            switch (message)
            {
            case WindowMessage.Create:
                baseUnits = Windows.GetDialogBaseUnits();
                btnWidth  = baseUnits.cx * 8;
                btnHeight = baseUnits.cy * 4;

                // Create the owner-draw pushbuttons
                CREATESTRUCT *create = (CREATESTRUCT *)lParam;

                hwndSmaller = Windows.CreateWindow("button", "",
                                                   WindowStyles.Child | WindowStyles.Visible | (WindowStyles)ButtonStyles.OwnerDrawn,
                                                   ExtendedWindowStyles.None,
                                                   0, 0, btnWidth, btnHeight,
                                                   window, (IntPtr)ID_SMALLER, create->Instance, IntPtr.Zero);
                hwndLarger = Windows.CreateWindow("button", "",
                                                  WindowStyles.Child | WindowStyles.Visible | (WindowStyles)ButtonStyles.OwnerDrawn,
                                                  ExtendedWindowStyles.None,
                                                  0, 0, btnWidth, btnHeight,
                                                  window, (IntPtr)ID_LARGER, create->Instance, IntPtr.Zero);

                return(0);

            case WindowMessage.Size:
                cxClient = lParam.LowWord;
                cyClient = lParam.HighWord;

                // Move the buttons to the new center
                hwndSmaller.MoveWindow(cxClient / 2 - 3 * btnWidth / 2, cyClient / 2 - btnHeight / 2,
                                       btnWidth, btnHeight, true);
                hwndLarger.MoveWindow(cxClient / 2 + btnWidth / 2, cyClient / 2 - btnHeight / 2,
                                      btnWidth, btnHeight, true);
                return(0);

            case WindowMessage.Command:
                RECT rc = window.GetWindowRectangle();

                // Make the window 10% smaller or larger
                switch ((int)(uint)wParam)
                {
                case ID_SMALLER:
                    rc.left   += cxClient / 20;
                    rc.right  -= cxClient / 20;
                    rc.top    += cyClient / 20;
                    rc.bottom -= cyClient / 20;
                    break;

                case ID_LARGER:
                    rc.left   -= cxClient / 20;
                    rc.right  += cxClient / 20;
                    rc.top    -= cyClient / 20;
                    rc.bottom += cyClient / 20;
                    break;
                }

                window.MoveWindow(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, true);
                return(0);

            case WindowMessage.DrawItem:
                DRAWITEMSTRUCT *pdis = (DRAWITEMSTRUCT *)lParam;

                // Fill area with white and frame it black
                using (DeviceContext dc = pdis->DeviceContext)
                {
                    RECT rect = pdis->rcItem;

                    dc.FillRectangle(rect, StockBrush.White);
                    dc.FrameRectangle(rect, StockBrush.Black);

                    // Draw inward and outward black triangles
                    int cx = rect.right - rect.left;
                    int cy = rect.bottom - rect.top;

                    POINT[] pt = new POINT[3];

                    switch ((int)pdis->CtlID)
                    {
                    case ID_SMALLER:
                        pt[0].x = 3 * cx / 8; pt[0].y = 1 * cy / 8;
                        pt[1].x = 5 * cx / 8; pt[1].y = 1 * cy / 8;
                        pt[2].x = 4 * cx / 8; pt[2].y = 3 * cy / 8;
                        Triangle(dc, pt);
                        pt[0].x = 7 * cx / 8; pt[0].y = 3 * cy / 8;
                        pt[1].x = 7 * cx / 8; pt[1].y = 5 * cy / 8;
                        pt[2].x = 5 * cx / 8; pt[2].y = 4 * cy / 8;
                        Triangle(dc, pt);
                        pt[0].x = 5 * cx / 8; pt[0].y = 7 * cy / 8;
                        pt[1].x = 3 * cx / 8; pt[1].y = 7 * cy / 8;
                        pt[2].x = 4 * cx / 8; pt[2].y = 5 * cy / 8;
                        Triangle(dc, pt);
                        pt[0].x = 1 * cx / 8; pt[0].y = 5 * cy / 8;
                        pt[1].x = 1 * cx / 8; pt[1].y = 3 * cy / 8;
                        pt[2].x = 3 * cx / 8; pt[2].y = 4 * cy / 8;
                        Triangle(dc, pt);
                        break;

                    case ID_LARGER:
                        pt[0].x = 5 * cx / 8; pt[0].y = 3 * cy / 8;
                        pt[1].x = 3 * cx / 8; pt[1].y = 3 * cy / 8;
                        pt[2].x = 4 * cx / 8; pt[2].y = 1 * cy / 8;
                        Triangle(dc, pt);
                        pt[0].x = 5 * cx / 8; pt[0].y = 5 * cy / 8;
                        pt[1].x = 5 * cx / 8; pt[1].y = 3 * cy / 8;
                        pt[2].x = 7 * cx / 8; pt[2].y = 4 * cy / 8;
                        Triangle(dc, pt);
                        pt[0].x = 3 * cx / 8; pt[0].y = 5 * cy / 8;
                        pt[1].x = 5 * cx / 8; pt[1].y = 5 * cy / 8;
                        pt[2].x = 4 * cx / 8; pt[2].y = 7 * cy / 8;
                        Triangle(dc, pt);
                        pt[0].x = 3 * cx / 8; pt[0].y = 3 * cy / 8;
                        pt[1].x = 3 * cx / 8; pt[1].y = 5 * cy / 8;
                        pt[2].x = 1 * cx / 8; pt[2].y = 4 * cy / 8;
                        Triangle(dc, pt);
                        break;
                    }

                    // Invert the rectangle if the button is selected
                    if ((pdis->itemState & OwnerDrawStates.Selected) != 0)
                    {
                        dc.InvertRectangle(rect);
                    }

                    if ((pdis->itemState & OwnerDrawStates.Focus) != 0)
                    {
                        rect.left   += cx / 16;
                        rect.top    += cy / 16;
                        rect.right  -= cx / 16;
                        rect.bottom -= cy / 16;

                        dc.DrawFocusRectangle(rect);
                    }
                }
                return(0);

            case WindowMessage.Destroy:
                Windows.PostQuitMessage(0);
                return(0);
            }

            return(Windows.DefaultWindowProcedure(window, message, wParam, lParam));
        }
Пример #4
0
 public DrawItem(LParam lParam)
 {
     _drawItemStruct = (DRAWITEMSTRUCT *)lParam;
 }