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); } } }
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; }
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); }