/// <summary>Occurs when a Windows message is dispatched.</summary> /// <param name="message">Message to process.</param> /// <remarks>Overrides WM_PAINT, WM_ERASEBKGND.</remarks> protected override void WndProc(ref Message m) { const int WM_PAINT = 0x000F; const int WM_PRINTCLIENT = 0x0318; const int WM_ERASEBKGND = 0x0014; const int WM_MOUSEHOVER = 0x02A1; const int WM_NOTIFY = 0x004E; NMHDR nm1; bool messageProcessed = false; switch (m.Msg) { case 7: // WM_SETFOCUS //try { base.WndProc(ref m); } // skip immediate parent to avoid focus problems //catch{} m.Result = IntPtr.Zero; messageProcessed = true; break; // case (int)WindowsMessage.WM_REFLECT + (int)WindowsMessage.WM_NOTIFY: case (0x0400 + 0x1c00 + WM_NOTIFY): m.Result = IntPtr.Zero; nm1 = (NMHDR) m.GetLParam(typeof (NMHDR)); switch (nm1.code) { case (int) ListViewNotificationCodes.LVN_ITEMCHANGED: messageProcessed = true; break; case (int) ListViewNotificationCodes.LVN_GETDISPINFOW: OnDispInfoNotice(ref m, false); messageProcessed = true; break; // ignore dragging as we are virtual and ListView doesnt like it. case (int) ListViewNotificationCodes.LVN_BEGINDRAG: OnBeginDrag(ref m); messageProcessed = true; break; case (int) ListViewNotificationCodes.LVN_BEGINRDRAG: OnBeginDrag(ref m); messageProcessed = true; break; case (int) NotificationCodes.NM_CUSTOMDRAW: m.Result = new IntPtr((int) OnCustomDraw(ref m)); messageProcessed = true; break; case (int) ListViewNotificationCodes.LVN_ODSTATECHANGED: { messageProcessed = true; var lvod = (NMLVODSTATECHANGE) m.GetLParam(typeof (NMLVODSTATECHANGE)); int num1 = lvod.uOldState & (int) ListViewItemStates.LVIS_SELECTED; int num2 = lvod.uNewState & (int) ListViewItemStates.LVIS_SELECTED; if (num2 == num1) return; OnSelectedIndexChanged(EventArgs.Empty); break; } default: break; } break; case WM_NOTIFY: nm1 = (NMHDR) m.GetLParam(typeof (NMHDR)); if (nm1.code == (int) NotificationCodes.NM_RCLICK) { IntPtr header = SendMessage(Handle, (int) ListViewMessages.LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero); uint curpos = GetMessagePos(); Point ptheader = PointToClient(new Point((short) curpos, (int) curpos >> 16)); var hdhti = new HDHITTESTINFO(); hdhti.pt = ptheader; SendMessage(header, HeaderMessageCodes.HDM_HITTEST, IntPtr.Zero, ref hdhti); OnColumnRightClick(new ColumnClickEventArgs(hdhti.iItem)); } else if (nm1.code == (int) HeaderNotificationCodes.HDN_ITEMCLICKW) { if (OnCustomSort(ref m)) { m.Result = IntPtr.Zero; messageProcessed = true; } } break; case WM_ERASEBKGND: //removes flicker return; case WM_MOUSEHOVER: messageProcessed = true; break; case WM_PAINT: // The designer host does not call OnResize() if (internalGraphics == null) OnResize(EventArgs.Empty); //Set up var updateRect = new RECT(); if (GetUpdateRect(m.HWnd, ref updateRect, false) == 0) break; var paintStruct = new PAINTSTRUCT(); IntPtr screenHdc = BeginPaint(m.HWnd, ref paintStruct); using (Graphics screenGraphics = Graphics.FromHdc(screenHdc)) { //Draw Internal Graphics internalGraphics.Clear(BackColor); IntPtr hdc = internalGraphics.GetHdc(); Message printClientMessage = Message.Create(Handle, WM_PRINTCLIENT, hdc, IntPtr.Zero); DefWndProc(ref printClientMessage); internalGraphics.ReleaseHdc(hdc); //Add the missing OnPaint() call OnPaint(new PaintEventArgs(internalGraphics, Rectangle.FromLTRB( updateRect.left, updateRect.top, updateRect.right, updateRect.bottom))); //Draw Screen Graphics screenGraphics.DrawImage(internalBitmap, 0, 0); } //Tear down EndPaint(m.HWnd, ref paintStruct); return; default: break; } if (!messageProcessed) { try { base.WndProc(ref m); } catch { } } }
private static extern int SendMessage(IntPtr hWnd, HeaderMessageCodes uMsg, IntPtr wParam, ref HDHITTESTINFO lParam);