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) { Win32.NMHEADER nm; switch (m.Msg) { case 0x004E: //WM_NOTIFY base.WndProc(ref m); Win32.NMHDR nmhdr = (Win32.NMHDR)m.GetLParam(typeof(Win32.NMHDR)); switch (nmhdr.code) { case (int)Win32.NM.NM_CLICK - 320: nm = (Win32.NMHEADER)m.GetLParam(typeof(Win32.NMHEADER)); if (ClickHeader != null) { sortColumn = nm.iItem; if (sortOrder == 1) { sortOrder = -1; } else { sortOrder = 1; } ClickHeader(this.Columns[nm.iItem], new HeaderEventArgs(nm.iItem, nm.iButton)); } break; case (0 - 300 - 26): //HDN_BEGINTRACK nm = (Win32.NMHEADER)m.GetLParam(typeof(Win32.NMHEADER)); if (BeginDragHeaderDivider != null) { BeginDragHeaderDivider(this.Columns[nm.iItem], new HeaderEventArgs(nm.iItem, nm.iButton)); } break; case (0 - 300 - 20): //HDN_ITEMCHANGING nm = (Win32.NMHEADER)m.GetLParam(typeof(Win32.NMHEADER)); //Adjust the column width Win32.RECT rect = new Win32.RECT(); //HDM_GETITEMRECT Win32.SendMessage(header.Handle, 0x1200 + 7, nm.iItem, ref rect); //Get the item height which is actually header's height this.headerHeight = rect.bottom - rect.top; //para pintar correctamente el progreso //Debug.Write("Parte 1: id:" + nm.iItem + " left=" + rect.left + "\n"); this.m_headerleft[nm.iItem] = rect.left; this.m_headerright[nm.iItem] = rect.right; this.Columns[nm.iItem].Width = rect.right - rect.left; if (DragHeaderDivider != null) { DragHeaderDivider(this.Columns[nm.iItem], new HeaderEventArgs(nm.iItem, nm.iButton)); } break; case (0 - 300 - 27): //HDN_ENDTRACK nm = (Win32.NMHEADER)m.GetLParam(typeof(Win32.NMHEADER)); if (EndDragHeaderDivider != null) { EndDragHeaderDivider(this.Columns[nm.iItem], new HeaderEventArgs(nm.iItem, nm.iButton)); } break; // case (0-300-11): //HDN_ENDDRAG // break; } break; case (int)Win32.OCM.OCM_NOTIFY: //Reflected WM_NOTIFY message Win32.NMHDR nmh = (Win32.NMHDR)m.GetLParam(typeof(Win32.NMHDR)); switch (nmh.code) { case (int)Win32.NM.NM_CUSTOMDRAW: Win32.NMCUSTOMDRAW nmcd = (Win32.NMCUSTOMDRAW)m.GetLParam(typeof(Win32.NMCUSTOMDRAW)); if (nmcd.hdr.hwndFrom != this.Handle) { break; } switch (nmcd.dwDrawStage) { case (int)Win32.CDDS.CDDS_PREPAINT: m.Result = (IntPtr)Win32.CDRF.CDRF_NOTIFYITEMDRAW; break; case (int)Win32.CDDS.CDDS_ITEMPREPAINT: m.Result = (IntPtr)Win32.CDRF.CDRF_NOTIFYITEMDRAW; break; case (int)(Win32.CDDS.CDDS_SUBITEM | Win32.CDDS.CDDS_ITEMPREPAINT): try { Win32.NMLVCUSTOMDRAW nmlv = (Win32.NMLVCUSTOMDRAW) m.GetLParam(typeof(Win32.NMLVCUSTOMDRAW)); if ((Columns[nmlv.iSubItem].subItemOwnerDraw) && (nmlv.nmcd.dwItemSpec < Items.Count)) { Rectangle recgrande = base.GetItemRect(nmlv.nmcd.dwItemSpec); Win32.RECT rc = new Win32.RECT(); if (nmlv.iSubItem > 0) { rc.top = nmlv.iSubItem; rc.left = 0; Win32.SendMessage(this.Handle, 0x1000 + 56, nmlv.nmcd.dwItemSpec, ref rc); } else { rc.top = 0; rc.left = 2; Win32.SendMessage(this.Handle, 0x1000 + 14, nmlv.nmcd.dwItemSpec, ref rc); } //Rectangle rec=new Rectangle(rc.left+1,rc.top,rc.right-rc.left-2, rc.bottom-rc.top-2); Rectangle rec = new Rectangle(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); //Point p=this.PointToClient(new Point(rc.left,rc.top)); //Point p2=this.PointToClient(new Point(rc.right,rc.bottom)); //Rectangle rec=new Rectangle(p.X,rc.top,p2.X-p.X,rc.bottom-rc.top-2); Graphics g = Graphics.FromHdc(nmlv.nmcd.hdc); OnDrawItem(nmlv.nmcd.dwItemSpec, nmlv.iSubItem, g, rec); g.Dispose(); //Win32.ReleaseDC(nmcd.hdr.hwndFrom,nmlv.nmcd.hdc); m.Result = (IntPtr)Win32.CDRF.CDRF_SKIPDEFAULT; } else { base.WndProc(ref m); //m.Result = (IntPtr)Win32.CDRF.CDRF_DODEFAULT; } Marshal.StructureToPtr(nmlv, m.LParam, true); } catch { base.WndProc(ref m); } break; } break; default: base.WndProc(ref m); break; } break; case 0x002B: //WM_DRAWITEM try { //Get the DRAWITEMSTRUCT from the LParam of the message Win32.DRAWITEMSTRUCT dis = (Win32.DRAWITEMSTRUCT)Marshal.PtrToStructure( m.LParam, typeof(Win32.DRAWITEMSTRUCT)); //agregar aqui la posicion x para pintar bien el progreso. //Debug.Write("parte3: id: " + dis.itemID + "\n"); this.m_headerleft[dis.itemID] = dis.rcItem.left; this.m_headerright[dis.itemID] = dis.rcItem.right; //Check if this message comes from the header if (dis.ctrlType == 100) //ODT_HEADER - it do comes from the header { //Get the graphics from the hdc field of the DRAWITEMSTRUCT Graphics g = Graphics.FromHdc(dis.hdc); //Create a rectangle from the RECT struct Rectangle r = new Rectangle(dis.rcItem.left, dis.rcItem.top, dis.rcItem.right - dis.rcItem.left, dis.rcItem.bottom - dis.rcItem.top); //Create new DrawItemState in its default state DrawItemState d = DrawItemState.Default; //Set the correct state for drawing if (dis.itemState == 0x0001) { d = DrawItemState.Selected; } //Create the DrawItemEventArgs object DrawItemEventArgs e = new DrawItemEventArgs(g, this.Font, r, dis.itemID, d); //If we have a handler attached call it and we don't want the default drawing if (DrawColumn != null && !defaultCustomDraw) { DrawColumn(this.Columns[dis.itemID], e); } else if (defaultCustomDraw) { DoMyCustomHeaderDraw(this.Columns[dis.itemID], e); } //Release the graphics object g.Dispose(); } } catch { try { base.WndProc(ref m); } catch {} } break; case 0x0002: //WM_DESTROY //Release the handle associated with the header control window header.ReleaseHandle(); base.WndProc(ref m); break; case 0x0014: //WM_ERASEBKGND if (this.Items.Count == 0) { base.WndProc(ref m); } else { try { Brush backBrush = new SolidBrush(BackColor); //up Rectangle clientRect = this.ClientRectangle; //this.GetItemAt(0,0).Index Rectangle rec = clientRect; Graphics g = Graphics.FromHdc(m.WParam); rec.X = clientRect.X; rec.Y = clientRect.Y; rec.Width = clientRect.Width; rec.Height = this.HeaderHeight + 2; g.FillRectangle(backBrush, rec); //left Rectangle itemRect = this.GetItemRect(0, ItemBoundsPortion.Entire); rec.Width = itemRect.Left - clientRect.Left + 2; rec.Height = clientRect.Height + itemRect.Height + 2; if (rec.Width > 0) { g.FillRectangle(backBrush, rec); } //right rec.X = itemRect.Right; rec.Y = clientRect.Top; rec.Width = clientRect.Width - itemRect.Width; rec.Height = clientRect.Height; g.FillRectangle(backBrush, rec); //Debug.WriteLine(rec.ToString()); //bottom itemRect = this.GetItemRect(this.Items.Count - 1, ItemBoundsPortion.Entire); rec.X = clientRect.Left; rec.Y = itemRect.Bottom; rec.Width = clientRect.Width; rec.Height = clientRect.Height - rec.Y + clientRect.Width; if (rec.Height > 0) { g.FillRectangle(backBrush, rec); } } catch { base.WndProc(ref m); } } break; default: try //Message 0x7b WM_CONTEXTMENU can cause exceptions if control is invisible { base.WndProc(ref m); } catch //(Exception e) { //Debug.WriteLine(e.ToString()); Visible = true; } break; } }