Esempio n. 1
0
        public static void HandleWmPaint(ref Message m, Control control, Action <PaintEventArgs> paint)
        {
            var  ps            = new WinApi.PAINTSTRUCT();
            bool needDisposeDc = false;

            try {
                Rectangle clip;
                IntPtr    dc;
                if (m.WParam == IntPtr.Zero)
                {
                    dc = WinApi.BeginPaint(new HandleRef(control, control.Handle), ref ps);
                    if (dc == IntPtr.Zero)
                    {
                        return;
                    }
                    needDisposeDc = true;
                    clip          = new Rectangle(ps.rcPaint_left, ps.rcPaint_top, ps.rcPaint_right - ps.rcPaint_left, ps.rcPaint_bottom - ps.rcPaint_top);
                }
                else
                {
                    dc   = m.WParam;
                    clip = control.ClientRectangle;
                }

                if (clip.Width > 0 && clip.Height > 0)
                {
                    try {
                        using (var bufferedGraphics = BufferedGraphicsManager.Current.Allocate(dc, control.ClientRectangle)) {
                            bufferedGraphics.Graphics.SetClip(clip);
                            using (var pevent = new PaintEventArgs(bufferedGraphics.Graphics, clip)) {
                                paint?.Invoke(pevent);
                            }
                            bufferedGraphics.Render();
                        }
                    } catch (Exception ex) {
                        // BufferContext.Allocate will throw out of memory exceptions
                        // when it fails to create a device dependent bitmap while trying to
                        // get information about the device we are painting on.
                        // That is not the same as a system running out of memory and there is a
                        // very good chance that we can continue to paint successfully. We cannot
                        // check whether double buffering is supported in this case, and we will disable it.
                        // We could set a specific string when throwing the exception and check for it here
                        // to distinguish between that case and real out of memory exceptions but we
                        // see no reasons justifying the additional complexity.
                        if (!(ex is OutOfMemoryException))
                        {
                            throw;
                        }
                    }
                }
            } finally {
                if (needDisposeDc)
                {
                    WinApi.EndPaint(new HandleRef(control, control.Handle), ref ps);
                }
            }
        }
Esempio n. 2
0
        protected override void WndProc(ref Message m)
        {
            const int WM_PAINT = 0xF;
            const int WM_PRINTCLIENT = 0x0318;
            const int WM_CTLCOLORLISTBOX = 0x0134;
            const int CB_ADDSTRING = 0x143;
            const int CB_INSERTSTRING = 0x14A;
            const int CB_DELETESTRING = 0x0144;

            WinApi.RECT rect = new WinApi.RECT();

            switch (m.Msg)
            {
                case WM_CTLCOLORLISTBOX:
                    if (IsMultiColumnDropDown && base.DroppedDown)
                    {
                        BarUtilities.InvokeDelayed(new MethodInvoker(delegate { base.DroppedDown = false; }), 10);
                        break;
                    }

                    if (BarFunctions.IsWindows7 && !IsMultiColumnDropDown)
                    {
                        if (m_DropDownHandle != m.LParam)
                            ReleasePopupHandler();

                        if (_PopupMsgHandler == null)
                            CreatePopupHandler(m.LParam);
                    }

                    m_DropDownHandle = m.LParam;

                    if (!IsMultiColumnDropDown && (m_DropDownHeight > 0 || this.Items.Count == 0))
                    {
                        WinApi.GetWindowRect(m.LParam, ref rect);
                        int height = m_DropDownHeight;
                        if (this.Items.Count == 0)
                            height = Math.Max(18, this.ItemHeight);
                        Point thisLocation = this.PointToScreen(Point.Empty);
                        if (rect.Top < thisLocation.Y)
                            rect.Top = thisLocation.Y + this.Height;
                        NativeFunctions.SetWindowPos(m.LParam, IntPtr.Zero, rect.Left, rect.Top, rect.Width,
                                                     height, NativeFunctions.SWP_NOACTIVATE);
                    }
                    break;

                case (int)WinApi.WindowsMessages.CB_GETDROPPEDSTATE:

                    base.WndProc(ref m);

                    if (m.Result == IntPtr.Zero && DroppedDownInternal && !IsMultiColumnDropDown)
                        DroppedDownInternal = false;
                    return;

                case NativeFunctions.WM_SETFOCUS:
                    if (m.WParam != this.Handle)
                        m_LastFocusWindow = m.WParam;

                    break;

                case CB_ADDSTRING:
                    if (this.Items.Count > 0)
                    {
                        ComboItem cb = this.Items[this.Items.Count - 1] as ComboItem;

                        if (cb != null)
                            cb.m_ComboBox = this;
                    }
                    break;

                case CB_INSERTSTRING:
                    int index = WinApi.ToInt(m.WParam);

                    if (index >= 0 && index < this.Items.Count)
                    {
                        ComboItem cb = this.Items[index] as ComboItem;

                        if (cb != null)
                            cb.m_ComboBox = this;
                    }

                    m_SelectedIndexInternal = -1;
                    break;

                case CB_DELETESTRING:
                    m_SelectedIndexInternal = -1;
                    break;

                case NativeFunctions.WM_USER + 7:
                    if (this.DropDownStyle == ComboBoxStyle.DropDown && !m_Focused)
                        this.SelectionLength = 0;

                    this.Invalidate(true);
                    return;
                case (int)WinApi.WindowsMessages.WM_LBUTTONDOWN:
                    {
                        if (IsMultiColumnDropDown)
                        {
                            if (IsPopupOpen)
                                CloseMultiColumnDropDown();
                            else if (DateTime.Now.Subtract(_MultiDropDownClosedAtTime).TotalMilliseconds > 500 && (this.Focused || this.Focus()))
                            {
                                OpenMultiColumnDropDown();
                            }
                            return; // Don't call base
                        }
                        break;
                    }
                case (int)WinApi.WindowsMessages.WM_REFLECTCOMMAND:
                    {
                        if (IsMultiColumnDropDown)
                        {
                            int wp = WinApi.HIWORD(m.WParam);
                            if (wp == CBN_DROPDOWN)
                            {
                                OpenMultiColumnDropDown();
                                return; // Don't call base
                            }
                            else if (wp == CBN_CLOSEUP)
                            {
                                if (DateTime.Now.Subtract(_MultiDropDownOpenedAtTime).TotalMilliseconds > 900)
                                {
                                    CloseMultiColumnDropDown();
                                    return; // Don't call base
                                }
                            }
                        }
                        break;
                    }
            }

            if (m_DefaultStyle)
            {
                base.WndProc(ref m);
                return;
            }

            if ((m.Msg == WM_PAINT || m.Msg == WM_PRINTCLIENT) && DrawMode != DrawMode.Normal)
            {
                WinApi.GetWindowRect(m.HWnd, ref rect);
                Rectangle r = new Rectangle(0, 0, rect.Width, rect.Height);

                if (m.Msg == WM_PAINT)
                {
                    WinApi.PAINTSTRUCT ps = new WinApi.PAINTSTRUCT();

                    IntPtr hdc = WinApi.BeginPaint(m.HWnd, ref ps);

                    using (Graphics gHdc = Graphics.FromHdc(hdc))
                    {
                        using (BufferedBitmap bmp = new BufferedBitmap(gHdc, r))
                        {
                            PaintComboBox(bmp.Graphics, r);

                            bmp.Render(gHdc);
                        }
                    }

                    WinApi.EndPaint(m.HWnd, ref ps);
                }
                else
                {
                    using (Graphics g = Graphics.FromHdc(m.WParam))
                        PaintComboBox(g, r);
                }

                if (this.Parent is ItemControl)
                    ((ItemControl)this.Parent).UpdateKeyTipsCanvas();
            }
            else
            {
                base.WndProc(ref m);
            }
        }
        internal bool WndProc(ref Message m)
        {
            if (m.Msg == (int)WinApi.WindowsMessages.SBM_SETSCROLLINFO || m.Msg == 0x2114 || m.Msg == 0x2115 || m.Msg == (int)WinApi.WindowsMessages.WM_MOUSEMOVE)
            {
                CallBaseWndProc(ref m);
                SendDelayPaintMessage();
                return false;
            }
            else if (m.Msg == (int)WinApi.WindowsMessages.WM_SIZE)
            {
                CallBaseWndProc(ref m);
                m_FirstPaint = true;
                SendDelayPaintMessage();
                return false;
            }
            else if (m.Msg == (int)WinApi.WindowsMessages.WM_ERASEBKGND)
            {
                //PaintUsingDC();
                //m.Result = new IntPtr(1);
                return false;
            }
            else if (m.Msg == (int)WinApi.WindowsMessages.WM_LBUTTONDOWN)
            {
                Point p = new Point(WinApi.LOWORD(m.LParam), WinApi.HIWORD(m.LParam));
                InternalMouseDown(new MouseEventArgs(GetMouseButton(m.WParam.ToInt32()), 0, p.X, p.Y, 0));
                return false;
            }
            else if (m.Msg == (int)WinApi.WindowsMessages.WM_LBUTTONUP)
            {
                Point p = new Point(WinApi.LOWORD(m.LParam), WinApi.HIWORD(m.LParam));
                InternalMouseUp(new MouseEventArgs(GetMouseButton(m.WParam.ToInt32()), 0, p.X, p.Y, 0));
                return false;
            }
            else if (m.Msg == (int)WinApi.WindowsMessages.WM_LBUTTONDBLCLK)
            {
                Point p = new Point(WinApi.LOWORD(m.LParam), WinApi.HIWORD(m.LParam));
                InternalMouseDoubleClick(new MouseEventArgs(GetMouseButton(m.WParam.ToInt32()), 0, p.X, p.Y, 0));
                return false;
            }
            else if (m.Msg == NativeFunctions.WM_USER + 7)
            {
                PaintUsingDC();
            }
            else if (m.Msg == (int)WinApi.WindowsMessages.WM_SYSTIMER)
            {
                if (m_ScrollBarCore.MouseOverPart == ScrollBarCore.eScrollPart.Track && Control.MouseButtons == MouseButtons.Left)
                {
                    Point p = m_ParentScrollBar.PointToClient(Control.MousePosition);
                    OnMouseMove(new MouseEventArgs(Control.MouseButtons, 0, p.X, p.Y, 0));
                }
            }
            else if (m.Msg == (int)WinApi.WindowsMessages.WM_CAPTURECHANGED)
            {
                // Recapture the mouse...
                if (m.LParam == IntPtr.Zero && Control.MouseButtons == MouseButtons.Left && m_ScrollBarCore.MouseOverPart == ScrollBarCore.eScrollPart.Track)
                {
                    m_ParentScrollBar.Capture = true;
                }
            }

            if (m.Msg == (int)WinApi.WindowsMessages.WM_PAINT)
            {
                if (m_FirstPaint)
                {
                    // Call to base actually updates values returned by GetScrollBarInfo
                    CallBaseWndProc(ref m);
                    // Repaint the control once that is done
                    SendDelayPaintMessage();
                    m_FirstPaint = false;
                }
                WinApi.PAINTSTRUCT ps = new WinApi.PAINTSTRUCT();
                IntPtr hdc = WinApi.BeginPaint(m.HWnd, ref ps);
                try
                {
                    Graphics g = Graphics.FromHdc(hdc);
                    try
                    {
                        PaintInternal(g, hdc);
                    }
                    finally
                    {
                        g.Dispose();
                    }
                }
                finally
                {
                    WinApi.EndPaint(m.HWnd, ref ps);
                }
                return false;
            }
            return true;
        }
Esempio n. 4
0
            protected override void WndProc(ref Message m)
            {
                if (m.Msg == (int)WinApi.WindowsMessages.WM_PAINT)
                {
                    WinApi.PAINTSTRUCT ps = new WinApi.PAINTSTRUCT();
                    IntPtr hdc = WinApi.BeginPaint(m.HWnd, ref ps);
                    try
                    {
                        Graphics g = Graphics.FromHdc(hdc);
                        try
                        {
                            WinApi.RECT r = new WinApi.RECT();
                            WinApi.GetWindowRect(m.HWnd, ref r);
                            Rectangle rc = new Rectangle(0, 0, r.Width, r.Height);
                            using (BufferedBitmap bb = new BufferedBitmap(hdc, rc))
                            {
                                m_Parent.PaintHeaderBackground(bb.Graphics, rc);

                                IList columns = m_Parent.GetOrderedColumnList();

                                int x = 0;
                                foreach (ColumnHeader h in columns)
                                {

                                    Rectangle hr = new Rectangle(x, 0, h.Width, r.Height);
                                    ListViewItemStates state = ListViewItemStates.ShowKeyboardCues;
                                    if (m_MouseDown && hr.Contains(m_MouseDownPoint))
                                    {
                                        Rectangle rt = hr;
                                        rt.Inflate(-6, 0);
                                        if (rt.Contains(m_MouseDownPoint))
                                            state |= ListViewItemStates.Selected;
                                    }

                                    m_Parent.DrawColumnHeaderInternal(new DrawListViewColumnHeaderEventArgs(bb.Graphics, hr, h.DisplayIndex, h,
                                        state, SystemColors.ControlText, Color.Empty, m_Parent.ColumnHeaderFont ?? m_Parent.Font));
                                    x += h.Width;
                                }
                                bb.Render(g);
                            }
                        }
                        finally
                        {
                            g.Dispose();
                        }
                    }
                    finally
                    {
                        WinApi.EndPaint(m.HWnd, ref ps);
                    }
                    return;
                }
                else if (m.Msg == (int)WinApi.WindowsMessages.WM_LBUTTONDOWN)
                {
                    if (m_Parent.HeaderStyle == ColumnHeaderStyle.Clickable)
                    {
                        m_MouseDown = true;
                        m_MouseDownPoint = new Point(WinApi.LOWORD(m.LParam), WinApi.HIWORD(m.LParam));
                        WinApi.RedrawWindow(m.HWnd, IntPtr.Zero, IntPtr.Zero, WinApi.RedrawWindowFlags.RDW_INVALIDATE);
                    }
                }
                else if (m.Msg == (int)WinApi.WindowsMessages.WM_LBUTTONUP)
                {
                    m_MouseDown = false;
                    m_MouseDownPoint = Point.Empty;
                }
                else if (m.Msg == (int)WinApi.WindowsMessages.WM_MOUSEMOVE && m_MouseDown)
                {
                    m_MouseDownPoint = new Point(WinApi.LOWORD(m.LParam), WinApi.HIWORD(m.LParam));
                }

                base.WndProc(ref m);
            }