Ejemplo n.º 1
0
        /// <summary>
        /// WM_PAINT消息处理
        /// </summary>
        /// <param name="window">可双缓冲渲染的控件(客户区)</param>
        /// <param name="m">消息</param>
        /// <param name="e">如果该值为null,则自动创建默认PaintEventArgs.否则将直接使用该值作为OnPaint的参数</param>
        public static void WmPaint(IUIWindow window, ref Message m, PaintEventArgs e)
        {
            //========Begin
            IntPtr hWnd = m.HWnd;

            NativeMethods.PAINTSTRUCT ps = new NativeMethods.PAINTSTRUCT();
            IntPtr hDC = UnsafeNativeMethods.BeginPaint(hWnd, ref ps);

            //========Drawing
            try
            {
                if (e == null)
                {
                    using (Graphics g = Graphics.FromHdcInternal(hDC))
                    {
                        using (e = new PaintEventArgs(g, Rectangle.FromLTRB(ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom)))
                        {
                            OnPaint(window, e);
                        }
                    }
                }
                else
                {
                    OnPaint(window, e);
                }
            }
            finally
            {
                //========End
                UnsafeNativeMethods.EndPaint(hWnd, ref ps);
            }
        }
Ejemplo n.º 2
0
        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
            case NativeMethods.WM_LBUTTONDOWN:
                MouseLDown(NativeMethods.Util.LOWORD(m.LParam), NativeMethods.Util.HIWORD(m.LParam));
                break;

            case NativeMethods.WM_RBUTTONDOWN:
                MouseRDown(NativeMethods.Util.LOWORD(m.LParam), NativeMethods.Util.HIWORD(m.LParam));
                break;

            case NativeMethods.WM_LBUTTONUP:
                MouseLUp(NativeMethods.Util.LOWORD(m.LParam), NativeMethods.Util.HIWORD(m.LParam));
                break;

            case NativeMethods.WM_RBUTTONUP:
                MouseRUp(NativeMethods.Util.LOWORD(m.LParam), NativeMethods.Util.HIWORD(m.LParam));
                break;

            case NativeMethods.WM_TIMER:
                TimerHandle(m.WParam.ToInt32());
                break;

            case NativeMethods.WM_SIZE:
            {
                cx = NativeMethods.SignedLOWORD((int)m.LParam);
                cy = NativeMethods.SignedHIWORD((int)m.LParam);
                clientRectangle  = new Rectangle(0, 0, cx, cy);
                mineRectangle    = new Rectangle(12, 55, Setting.Column * 16, Setting.Row * 16);
                emotionRectangle = new Rectangle(cx / 2 - 13, 15, 25, 24);
                if (MessageSize != null)
                {
                    MessageSize(this, cx, cy);
                }
                Invalidate();
            }
            break;

            case NativeMethods.WM_PAINT:
            {
                NativeMethods.PAINTSTRUCT ps = new NativeMethods.PAINTSTRUCT();
                IntPtr hDC = UnsafeNativeMethods.BeginPaint(new HandleRef(this, Handle), ref ps);
                DrawPalette(hDC);
                UnsafeNativeMethods.EndPaint(new HandleRef(this, Handle), ref ps);
            }
                return;
            }
            base.WndProc(ref m);
        }
Ejemplo n.º 3
0
 protected override void WndProc(ref Message m)
 {
     switch (m.Msg)
     {
         case NativeMethods.WM_PAINT:
             if (!_bPainting)
             {
                 NativeMethods.PAINTSTRUCT ps = 
                     new NativeMethods.PAINTSTRUCT();
                 _bPainting = true;
                 NativeMethods.BeginPaint(m.HWnd, ref ps);
                 DrawUpDownButton();
                 NativeMethods.EndPaint(m.HWnd, ref ps);
                 _bPainting = false;
                 m.Result = NativeMethods.TRUE;
             }
             else
             {
                 base.WndProc(ref m);
             }
             break;
         default:
             base.WndProc(ref m);
             break;
     }
 }
Ejemplo n.º 4
0
        private void DoPaint()
        {
            NativeMethods.PAINTSTRUCT ps = new NativeMethods.PAINTSTRUCT();
            NativeMethods.HDC hdc;

            HandleRef handleRef = new HandleRef(this, _hWnd);
            hdc.h = UnsafeNativeMethods.BeginPaint(handleRef, ref ps);
            int retval = UnsafeNativeMethods.GetWindowLong(handleRef, NativeMethods.GWL_EXSTYLE);

            NativeMethods.RECT rcPaint = new NativeMethods.RECT(ps.rcPaint_left, ps.rcPaint_top, ps.rcPaint_right, ps.rcPaint_bottom);

            //
            // If we get a BeginPaint with an empty rect then check
            // if this is a special layered, non-redirected window
            // which would mean we need to do a full paint when it
            // won't cause a problem.
            //
            if (rcPaint.IsEmpty
                && ((retval & NativeMethods.WS_EX_LAYERED) != 0)
                && !UnsafeNativeMethods.GetLayeredWindowAttributes(_hWnd.MakeHandleRef(this), IntPtr.Zero, IntPtr.Zero, IntPtr.Zero)
                && !_isSessionDisconnected
                && !_isMinimized
                && (!_isSuspended || (UnsafeNativeMethods.GetSystemMetrics(SM.REMOTESESSION) != 0))) // 
                                                                                                     // notifications for the server monitor are being broad-casted when the
                                                                                                     // machine is in a non-local TS session. See Dev10 bug for more details.
            {
                rcPaint = new NativeMethods.RECT(
                          0,
                          0,
                          _hwndClientRectInScreenCoords.right - _hwndClientRectInScreenCoords.left,
                          _hwndClientRectInScreenCoords.bottom - _hwndClientRectInScreenCoords.top);
            }

            AdjustForRightToLeft(ref rcPaint, handleRef);

            if (!rcPaint.IsEmpty)
            {
                InvalidateRect(rcPaint);
            }

            UnsafeNativeMethods.EndPaint(_hWnd.MakeHandleRef(this), ref ps);
        }
Ejemplo n.º 5
0
        private void WmPaint(ref Message m)
        {
            if (base.DropDownStyle == ComboBoxStyle.Simple)
            {
                base.WndProc(ref m);
                return;
            }

            if (base.DropDownStyle == ComboBoxStyle.DropDown)
            {
                if (!_bPainting)
                {
                    NativeMethods.PAINTSTRUCT ps =
                        new NativeMethods.PAINTSTRUCT();

                    _bPainting = true;
                    NativeMethods.BeginPaint(m.HWnd, ref ps);

                    RenderComboBox(ref m);

                    NativeMethods.EndPaint(m.HWnd, ref ps);
                    _bPainting = false;
                    m.Result = NativeMethods.TRUE;
                }
                else
                {
                    base.WndProc(ref m);
                }
            }
            else
            {
                base.WndProc(ref m);
                RenderComboBox(ref m);
            }
        }
Ejemplo n.º 6
0
        protected override void WndProc(ref Message m)
        {
            try
            {
                switch (m.Msg)
                {
                    case NativeMethods.WM_GETOBJECT:
                        // Call DefWndProc here to get the Windows standard accessibility object for the header control.
                        // base.WndProc provides the WinForms object, which does not work correctly on Vista (bug 89037). 
                        DefWndProc(ref m);
                        return;
                    case NativeMethods.WM_SETCURSOR:
                        // We want the standard header cursors, not the default WinForms.Control behavior
                        DefWndProc(ref m);
                        return;
                    case NativeMethods.HDM_SETORDERARRAY:
                        if (!GetFlag(StateFlags.IgnoreSetOrderArray))
                        {
                            var itemCount = (int)NativeMethods.SendMessage(m.HWnd, NativeMethods.HDM_GETITEMCOUNT, 0, 0);
                            if (itemCount != (int)m.WParam)
                            {
                                // Sanity test
                                m.Result = IntPtr.Zero;
                                return;
                            }
                            var oldOrder = new int[itemCount];
                            NativeMethods.SendMessage(m.HWnd, NativeMethods.HDM_GETORDERARRAY, oldOrder.Length, oldOrder);
                            var newOrder = new int[itemCount];
                            Marshal.Copy(m.LParam, newOrder, 0, itemCount);
                            if (OnPotentialOrderChange(oldOrder, newOrder, false))
                            {
                                base.WndProc(ref m);
                                myAssociatedControl.UpdateHeaderControlWidths(this);
                            }
                            else
                            {
                                m.Result = IntPtr.Zero;
                            }
                            return;
                        }
                        break;
                    case NativeMethods.WM_LBUTTONUP:
                        if (GetFlag(StateFlags.Dragging)
                            && !GetFlag(StateFlags.DragCanceled))
                        {
                            // I'd like to do this in respose to HDM_SETORDERARRAY, but the control
                            // does not fire this when it does the resize on its own.
                            var oldOrder = new int[(int)NativeMethods.SendMessage(m.HWnd, NativeMethods.HDM_GETITEMCOUNT, 0, 0)];
                            NativeMethods.SendMessage(m.HWnd, NativeMethods.HDM_GETORDERARRAY, oldOrder.Length, oldOrder);
                            base.WndProc(ref m);
                            if (!GetFlag(StateFlags.Dragging))
                            {
                                var newOrder = new int[oldOrder.Length];
                                NativeMethods.SendMessage(m.HWnd, NativeMethods.HDM_GETORDERARRAY, newOrder.Length, newOrder);
                                if (!OnPotentialOrderChange(oldOrder, newOrder, true))
                                {
                                    SetFlag(StateFlags.IgnoreSetOrderArray, true);
                                    NativeMethods.SendMessage(m.HWnd, NativeMethods.HDM_SETORDERARRAY, oldOrder.Length, oldOrder);
                                    SetFlag(StateFlags.IgnoreSetOrderArray, false);
                                }
                            }
                            SetFlag(StateFlags.Dragging, false); // In case enddrag didn't fire for whatever reason
                            return;
                        }
                        else if (GetFlag(StateFlags.HeaderTracked))
                        {
                            myAssociatedControl.UpdateHeaderControlWidths(this);
                        }
                        break;
                    case NativeMethods.WM_LBUTTONDOWN:
                        SetFlag(StateFlags.HeaderTracked | StateFlags.Tracking | StateFlags.DragCanceled, false);
                        break;
                    case NativeMethods.WM_MOUSEMOVE:
                        if (GetFlag(StateFlags.Tracking))
                        {
                            // If we're tracking, then the range we allow is not the same as the range
                            // allowed by the header control. However, there is no way to stop the header
                            // control from drawing its line, so we simply never let the mouse move message
                            // with the out-of-bounds x position to get through to the control.
                            var currentPoint = PointToScreen(new Point((int)m.LParam));
                            var newPoint = LimitTrackedMousePosition(currentPoint);
                            if (newPoint != currentPoint)
                            {
                                // Do this with a SendMessage instead of recreating a Message structure
                                // so that normal processing can occur and GetMessagePos returns the constrained value
                                // downstream from here.
                                newPoint = PointToClient(newPoint);
                                m.Result = NativeMethods.SendMessage(
                                    m.HWnd, m.Msg, (int)m.WParam, NativeMethods.MAKELONG(newPoint.X, newPoint.Y));
                                return;
                            }
                            // When we're in full drag mode, the control doesn't send a track notification. Send one now
                            // so that the lines draw correctly.
                            if (!GetFlag(StateFlags.ReceivedTrack))
                            {
                                base.WndProc(ref m);
                                if (!GetFlag(StateFlags.ReceivedTrack))
                                {
                                    TrackSplitter(NativeMethods.GetMessagePos());
                                }
                                return;
                            }
                        }
                        break;
                    case NativeMethods.WM_CONTEXTMENU:
                        {
                            var notifyPoint = NativeMethods.GetMessagePos();
                            var hitInfo = new NativeMethods.HDHITTESTINFO(PointToClient(notifyPoint));
                            var index = (int)NativeMethods.SendMessage(m.HWnd, NativeMethods.HDM_HITTEST, 0, ref hitInfo);
                            if (index != -1
                                && (0 != (hitInfo.flags & NativeMethods.HDHITTESTINFO.Flags.HHT_ONHEADER)))
                            {
                                myAssociatedControl.OnRawColumnHeaderEvent(
                                    IndexToOrder(index), VirtualTreeColumnHeaderClickStyle.ContextMenu, notifyPoint);
                            }
                            break;
                        }
                    case NativeMethods.WM_CANCELMODE:
                        SetFlag(StateFlags.DragCanceled, true);
                        break;
                    case NativeMethods.WM_PAINT:
                        if (GetStyle(ControlStyles.UserPaint))
                        {
                            // if UserPaint is turned on, we can't do owner-draw, so just let
                            // the base handle it.
                            base.WndProc(ref m);
                        }
                        else
                        {
                            if (myOwnerDrawItemQueue != null)
                            {
                                myOwnerDrawItemQueue.Clear();
                            }
                            var ps = new NativeMethods.PAINTSTRUCT();
                            var dc = NativeMethods.BeginPaint(Handle, ref ps);
                            var oldPal = NativeMethods.SelectPalette(dc, Graphics.GetHalftonePalette(), 1);
                            try
                            {
                                using (var g = Graphics.FromHdc(dc))
                                {
                                    try
                                    {
                                        m.WParam = dc; // per MSDN, header control will use this DC for painting if provided.
                                        DefWndProc(ref m);
                                            // DefWndProc send the WM_DRAWITEM messages we will use to populate myOwnerDrawItemQueue.
                                        if (myOwnerDrawItemQueue != null)
                                        {
                                            for (var i = 0; i < myOwnerDrawItemQueue.Count; i++)
                                            {
                                                WmReflectDrawItem((NativeMethods.DRAWITEMSTRUCT)myOwnerDrawItemQueue[i], g);
                                            }
                                        }
                                    }
                                    finally
                                    {
                                        NativeMethods.EndPaint(Handle, ref ps);
                                    }
                                }
                            }
                            finally
                            {
                                if (oldPal != IntPtr.Zero)
                                {
                                    NativeMethods.SelectPalette(dc, oldPal, 0);
                                }
                            }
                        }
                        return;
                    case NativeMethods.WM_REFLECT + NativeMethods.WM_DRAWITEM:
                        if (myAssociatedControl != null)
                        {
                            var dis = (NativeMethods.DRAWITEMSTRUCT)m.GetLParam(typeof(NativeMethods.DRAWITEMSTRUCT));
                            // transform itemId into a native column index. this will get passed in 
                            // the DrawItemEventArgs via the DrawColumnHeaderItem event.
                            dis.itemId = IndexToOrder(dis.itemId);
                            if (myAssociatedControl.ColumnPermutation != null)
                            {
                                dis.itemId = myAssociatedControl.ColumnPermutation.GetNativeColumn(dis.itemId);
                            }
                            var header = myAssociatedControl.GetColumnHeader(dis.itemId);

                            // Queue the draw item message.  This allows us to do overlay drawing, because we can let
                            // the underlying control paint first if necessary.
                            if (myOwnerDrawItemQueue == null)
                            {
                                myOwnerDrawItemQueue = new ArrayList();
                            }
                            myOwnerDrawItemQueue.Add(dis);

                            // return 0 here if we want the column header to draw normally (i.e., we're doing overlay drawing)
                            // otherwise 1 to indicate no further handling of the message is necessary.  Either way we'll
                            // send the DrawHeaderControlItem event at the end of WM_PAINT processing since we've added an entry to the queue.
                            m.Result = (0 != (header.Style & VirtualTreeColumnHeaderStyles.OwnerDrawOverlay)) ? IntPtr.Zero : (IntPtr)1;
                        }
                        return;
                    case NativeMethods.WM_REFLECT + NativeMethods.WM_NOTIFY:
                        if (myAssociatedControl != null)
                        {
                            var code = Marshal.ReadIntPtr(m.LParam, 8).ToInt32();
                            switch (code)
                            {
                                case NativeMethods.HDN_BEGINTRACKW:
                                    {
                                        if (
                                            !BeginTrackingSplitter(
                                                IndexToOrder(Marshal.ReadInt32(m.LParam, NativeMethods.NMHEADER.iItemOffset)),
                                                NativeMethods.GetMessagePos()))
                                        {
                                            m.Result = (IntPtr)1; // Block the tracking
                                            return;
                                        }
                                        SetFlag(StateFlags.DragCanceled, false);
                                        SetFlag(StateFlags.Tracking, true);
                                        SetFlag(StateFlags.ReceivedTrack, false);
                                        return;
                                    }
                                case NativeMethods.HDN_TRACKW:
                                    SetFlag(StateFlags.ReceivedTrack, true);
                                    if (GetFlag(StateFlags.DragCanceled))
                                    {
                                        m.Result = (IntPtr)1;
                                    }
                                    else
                                    {
                                        TrackSplitter(NativeMethods.GetMessagePos());
                                    }
                                    return;
                                case NativeMethods.HDN_ENDTRACKW:
                                    bool canceled = GetFlag(StateFlags.DragCanceled);
                                    SetFlag(StateFlags.Tracking, false);
                                    if (!canceled
                                        && !GetFlag(StateFlags.ReceivedTrack))
                                    {
                                        // Need at least one track notification so that FinishTrackingSplitter works correctly
                                        TrackSplitter(NativeMethods.GetMessagePos());
                                    }
                                    FinishTrackingSplitter(canceled);
                                    if (!canceled)
                                    {
                                        SetFlag(StateFlags.HeaderTracked, true);
                                    }
                                    // Always cancel at this point, we'll pick this up in the mouse up.
                                    // This way, the resize algorithms don't have to be exactly the same
                                    m.Result = (IntPtr)1;
                                    return;
                                case NativeMethods.HDN_BEGINDRAG:
                                    if (GetFlag(StateFlags.DragCanceled))
                                    {
                                        m.Result = (IntPtr)1;
                                    }
                                    else
                                    {
                                        var index = Marshal.ReadInt32(m.LParam, NativeMethods.NMHEADER.iItemOffset);
                                        if (index < 0)
                                        {
                                            // Not sure why this is happening, but handle it
                                        }
                                        else if (BeginDrag(IndexToOrder(index)))
                                        {
                                            SetFlag(StateFlags.Dragging, true);
                                            SetFlag(StateFlags.DragCanceled, false);
                                        }
                                        else
                                        {
                                            SetFlag(StateFlags.DragCanceled, true);
                                            m.Result = (IntPtr)1;
                                        }
                                    }
                                    return;
                                case NativeMethods.HDN_ENDDRAG:
                                    SetFlag(StateFlags.Dragging, false);
                                    return;
                                case NativeMethods.HDN_ITEMCLICKW:
                                case NativeMethods.HDN_ITEMDBLCLICKW:
                                case NativeMethods.HDN_DIVIDERDBLCLICKW:
                                    {
                                        VirtualTreeColumnHeaderClickStyle style;
                                        switch (code)
                                        {
                                            case NativeMethods.HDN_ITEMCLICKW:
                                                style = VirtualTreeColumnHeaderClickStyle.Click;
                                                break;
                                            case NativeMethods.HDN_ITEMDBLCLICKW:
                                                style = VirtualTreeColumnHeaderClickStyle.DoubleClick;
                                                break;
                                            case NativeMethods.HDN_DIVIDERDBLCLICKW:
                                                style = VirtualTreeColumnHeaderClickStyle.DividerDoubleClick;
                                                break;
                                            default:
                                                Debug.Assert(false); // Shouldn't be here
                                                return;
                                        }
                                        myAssociatedControl.OnRawColumnHeaderEvent(
                                            IndexToOrder(Marshal.ReadInt32(m.LParam, NativeMethods.NMHEADER.iItemOffset)), style,
                                            NativeMethods.GetMessagePos());
                                        break;
                                    }
                            }
                        }
                        break;
                }
                base.WndProc(ref m);
            }
            catch (Exception e)
            {
                if (CriticalException.IsCriticalException(e))
                {
                    throw;
                }

                VirtualTreeControl.DisplayException(myAssociatedControl.Site, e);
            }
        }