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