protected override void WndProc(ref Message m) { switch (m.Msg) { case 0x000F: //WM_PAINT if (parent.FullyCustomHeader) { Win32.RECT update = new Win32.RECT(); if (Win32.GetUpdateRect(m.HWnd, ref update, false) == 0) { break; } //Fill the paintstruct Win32.PAINTSTRUCT ps = new Win32.PAINTSTRUCT(); IntPtr hdc = Win32.BeginPaint(m.HWnd, ref ps); //Create graphics object from the hdc Graphics g = Graphics.FromHdc(hdc); //Get the non-item rectangle int left = 0; Win32.RECT itemRect = new Win32.RECT(); for (int i = 0; i < parent.Columns.Count; i++) { //HDM_GETITEMRECT Win32.SendMessage(m.HWnd, 0x1200 + 7, i, ref itemRect); left += itemRect.right - itemRect.left; } parent.headerHeight = itemRect.bottom - itemRect.top; if (left >= ps.rcPaint.left) { left = ps.rcPaint.left; } Rectangle r = new Rectangle(left, ps.rcPaint.top, ps.rcPaint.right - left, ps.rcPaint.bottom - ps.rcPaint.top); Rectangle r1 = new Rectangle(ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right - left, ps.rcPaint.bottom - ps.rcPaint.top); g.FillRectangle(new SolidBrush(parent.headerBackColor), r); //If we have a valid event handler - call it if (parent.DrawHeader != null && !parent.DefaultCustomDraw) { parent.DrawHeader(new DrawHeaderEventArgs(g, r, itemRect.bottom - itemRect.top)); } else { parent.DrawHeaderBorder(new DrawHeaderEventArgs(g, r, itemRect.bottom - itemRect.top)); } //Now we have to check if we have owner-draw columns and fill //the DRAWITEMSTRUCT appropriately int counter = 0; foreach (ListColumn mm in parent.Columns) { if (mm.OwnerDraw) { Win32.DRAWITEMSTRUCT dis = new Win32.DRAWITEMSTRUCT(); dis.ctrlType = 100; //ODT_HEADER dis.hwnd = m.HWnd; dis.hdc = hdc; dis.itemAction = 0x0001; //ODA_DRAWENTIRE dis.itemID = counter; //Must find if some item is pressed Win32.HDHITTESTINFO hi = new Win32.HDHITTESTINFO(); hi.pt.X = parent.PointToClient(MousePosition).X; hi.pt.Y = parent.PointToClient(MousePosition).Y; int hotItem = Win32.SendMessage(m.HWnd, 0x1200 + 6, 0, ref hi); //If clicked on a divider - we don't have hot item if (hi.flags == 0x0004 || hotItem != counter) { hotItem = -1; } if (hotItem != -1 && mouseDown) { dis.itemState = 0x0001; //ODS_SELECTED } else { dis.itemState = 0x0020; } //HDM_GETITEMRECT Win32.SendMessage(m.HWnd, 0x1200 + 7, counter, ref itemRect); dis.rcItem = itemRect; //Send message WM_DRAWITEM Win32.SendMessage(parent.Handle, 0x002B, 0, ref dis); } counter++; } Win32.EndPaint(m.HWnd, ref ps); } else { base.WndProc(ref m); } break; case 0x0014: //WM_ERASEBKGND //We don't need to do anything here in order to reduce flicker if (parent.FullyCustomHeader) { break; } else { base.WndProc(ref m); } break; case 0x0201: //WM_LBUTTONDOWN mouseDown = true; base.WndProc(ref m); break; case 0x0202: //WM_LBUTTONUP mouseDown = false; base.WndProc(ref m); break; case 0x1200 + 5: //HDM_LAYOUT base.WndProc(ref m); break; case 0x0030: //WM_SETFONT if (parent.IncreaseHeaderHeight > 0) { System.Drawing.Font f = new System.Drawing.Font(parent.Font.Name, parent.Font.SizeInPoints + parent.IncreaseHeaderHeight); m.WParam = f.ToHfont(); } base.WndProc(ref m); break; default: base.WndProc(ref m); break; } }
protected override void WndProc(ref Message m) { switch(m.Msg) { case 0x000F://WM_PAINT if(parent.FullyCustomHeader) { Win32.RECT update = new Win32.RECT(); if(Win32.GetUpdateRect(m.HWnd,ref update, false)==0) break; //Fill the paintstruct Win32.PAINTSTRUCT ps = new Win32.PAINTSTRUCT(); IntPtr hdc = Win32.BeginPaint(m.HWnd, ref ps); //Create graphics object from the hdc Graphics g = Graphics.FromHdc(hdc); //Get the non-item rectangle int left = 0; Win32.RECT itemRect = new Win32.RECT(); for(int i=0; i<parent.Columns.Count; i++) { //HDM_GETITEMRECT Win32.SendMessage(m.HWnd, 0x1200+7, i, ref itemRect); left += itemRect.right-itemRect.left; } parent.headerHeight = itemRect.bottom-itemRect.top; if(left >= ps.rcPaint.left) left = ps.rcPaint.left; Rectangle r = new Rectangle(left, ps.rcPaint.top, ps.rcPaint.right-left, ps.rcPaint.bottom-ps.rcPaint.top); Rectangle r1 = new Rectangle(ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right-left, ps.rcPaint.bottom-ps.rcPaint.top); g.FillRectangle(new SolidBrush(parent.headerBackColor),r); //If we have a valid event handler - call it if(parent.DrawHeader != null && !parent.DefaultCustomDraw) parent.DrawHeader(new DrawHeaderEventArgs(g,r, itemRect.bottom-itemRect.top)); else parent.DrawHeaderBorder(new DrawHeaderEventArgs(g,r, itemRect.bottom-itemRect.top)); //Now we have to check if we have owner-draw columns and fill //the DRAWITEMSTRUCT appropriately int counter = 0; foreach(ListColumn mm in parent.Columns) { if(mm.OwnerDraw) { Win32.DRAWITEMSTRUCT dis = new Win32.DRAWITEMSTRUCT(); dis.ctrlType = 100;//ODT_HEADER dis.hwnd = m.HWnd; dis.hdc = hdc; dis.itemAction = 0x0001;//ODA_DRAWENTIRE dis.itemID = counter; //Must find if some item is pressed Win32.HDHITTESTINFO hi = new Win32.HDHITTESTINFO(); hi.pt.X = parent.PointToClient(MousePosition).X; hi.pt.Y = parent.PointToClient(MousePosition).Y; int hotItem = Win32.SendMessage(m.HWnd, 0x1200+6, 0, ref hi); //If clicked on a divider - we don't have hot item if(hi.flags == 0x0004 || hotItem != counter) hotItem = -1; if(hotItem != -1 && mouseDown) dis.itemState = 0x0001;//ODS_SELECTED else dis.itemState = 0x0020; //HDM_GETITEMRECT Win32.SendMessage(m.HWnd, 0x1200+7, counter, ref itemRect); dis.rcItem = itemRect; //Send message WM_DRAWITEM Win32.SendMessage(parent.Handle,0x002B,0,ref dis); } counter++; } Win32.EndPaint(m.HWnd, ref ps); } else base.WndProc(ref m); break; case 0x0014://WM_ERASEBKGND //We don't need to do anything here in order to reduce flicker if(parent.FullyCustomHeader) break; else base.WndProc(ref m); break; case 0x0201://WM_LBUTTONDOWN mouseDown = true; base.WndProc(ref m); break; case 0x0202://WM_LBUTTONUP mouseDown = false; base.WndProc(ref m); break; case 0x1200+5://HDM_LAYOUT base.WndProc(ref m); break; case 0x0030://WM_SETFONT if(parent.IncreaseHeaderHeight > 0) { System.Drawing.Font f = new System.Drawing.Font(parent.Font.Name, parent.Font.SizeInPoints + parent.IncreaseHeaderHeight); m.WParam = f.ToHfont(); } base.WndProc(ref m); break; default: base.WndProc(ref m); break; } }