www.pudn.com > lphant-v1.00-src.zip > eLePhantListView.cs
#region Copyright (c)2003 Juanjo < http://lphant.sourceforge.net >
/*
* This file is part of eLePhant
* Copyright (C)2003 Juanjo < j_u_a_n_j_o@users.sourceforge.net / http://lphant.sourceforge.net >
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#endregion
using System;
using System.ComponentModel;
using System.Collections;
using System.Diagnostics;
using System.Windows.Forms;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
namespace eLePhant.Client
{
//The delegate for the HeaderEventArgs class
public delegate void HeaderEventHandler(object sender, HeaderEventArgs e);
//The delegate for drawing the entire header
public delegate void DrawHeaderEventHandler(DrawHeaderEventArgs e);
//The delegate for click the header
public delegate void ClickHeaderEventHandler(ColumnClickEventHandler e);
public class eLePhantListView : ListView
{
public int SortColumnIndex;
//The event for drawing columns
public event DrawItemEventHandler DrawColumn;
//The event for handling the entire border drawing of the header
public event DrawHeaderEventHandler DrawHeader;
//Event handlers associated with the header control
public event HeaderEventHandler BeginDragHeaderDivider;
public event HeaderEventHandler DragHeaderDivider;
public event HeaderEventHandler EndDragHeaderDivider;
public event HeaderEventHandler ClickHeader;
private System.ComponentModel.Container components = null;
//private StringBuilder strB;
private Pen borderPen;
public int ScrollBarBKColor;
ListColumnArray myColumns;
public ImageList headerImages;
HeaderControl header;
bool ownerDrawHeader;
int increaseHeaderHeight;
public Color headerBackColor;
public Color headerForeColor;
int headerHeight;
bool defaultCustomDraw;
bool m_Loaded;
private int m_sortColumn;
protected int[] m_DefaultWidths;
public int sortOrder;
private int[] m_headerleft=new int[20];
private int[] m_headerright=new int[20];
private Pen m_ArrowPen;
public Color HeaderBorderColor
{
set
{
borderPen=new Pen(value);
}
}
public int sortColumn
{
get
{
return m_sortColumn;
}
set
{
m_sortColumn=value;
this.Refresh();
}
}
public eLePhantListView()
{
InitializeComponent();
//strB=new StringBuilder();
myColumns = new ListColumnArray();
ownerDrawHeader = false;
headerBackColor = Color.FromArgb(222,231,247);//SystemColors.Control;
headerForeColor= Color.Black;
ScrollBarBKColor = 0x00F7E7DE;
//m_ArrowPen=new Pen(headerForeColor);
m_ArrowPen=new Pen(Color.FromArgb(0x80,0,0,0));
borderPen=new Pen(Color.FromArgb(68,69,151));
increaseHeaderHeight = 0;
defaultCustomDraw = false;
this.CheckBoxes = false;
this.FullRowSelect=true;
this.AllowColumnReorder=true;
this.AutoArrange=false;
this.HideSelection=false;
ownerDrawHeader = true;
this.defaultCustomDraw=false;
headerImages=new ImageList();
sortColumn=-1;
sortOrder=1;
m_Loaded=false;
InsertColumns();
}
public int GetColumnPosition(int column)
{
Win32.LV_COLUMN pcol = new Win32.LV_COLUMN();
pcol.mask = Win32.LVCF_ORDER;
Win32.SendMessage(Handle, Win32.LVM_GETCOLUMN, column, ref pcol);
return (int)pcol.iOrder;
}
public void SetColumnPosition(int column, int position)
{
Win32.LV_COLUMN pcol = new Win32.LV_COLUMN();
pcol.mask = Win32.LVCF_ORDER;
pcol.iOrder = position;
Win32.SendMessage(Handle, Win32.LVM_SETCOLUMN, column, ref pcol);
}
public int GetColumnsWidth(int column)
{
return Win32.SendMessage(Handle,Win32.LVM_GETCOLUMNWIDTH,column,0);
}
public void SetColumnWidth(int column, int width)
{
IntPtr lPram=Win32.MakeLParam(width,0);
Win32.SendMessage(Handle,Win32.LVM_SETCOLUMNWIDTH,column,lPram);
}
public void SetFlatScrollBar()
{
IntPtr stylePtr;
int style;
stylePtr=Win32.SendMessage(this.Handle, 4151, IntPtr.Zero , IntPtr.Zero);
style=stylePtr.ToInt32();
style+=256;
stylePtr=(IntPtr)style;
Win32.SendMessage(this.Handle, 4150, IntPtr.Zero , stylePtr);
Win32.FlatSB_SetScrollProp(this.Handle,0x80,(IntPtr)ScrollBarBKColor,true);
Win32.FlatSB_SetScrollProp(this.Handle,0x40,(IntPtr)ScrollBarBKColor,true);
}
public void SavePreferences()
{
for (int i=0;im_DefaultWidths.Length))
def=60;
else
def=m_DefaultWidths[i];
Columns[i].Width=eLePhantForm.preferences.GetInt(Name+"ColumnWidth-"+i.ToString(),def);
}
}
private void m_LoadPreferences()
{
if (m_Loaded) return;
m_Loaded=true;
int newPosition;
for (int i=0;i
/// Clean up any resources being used.
///
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
protected virtual void OnDrawItem(int item,int column,Graphics g,Rectangle rec)
{
}
#region Overriden methods
protected override void OnResize(EventArgs e)
{
this.Invalidate();
base.OnResize (e);
}
protected override void OnHandleCreated(EventArgs e)
{
//Create a new HeaderControl object
header = new HeaderControl(this);
if(header.Handle != IntPtr.Zero)
{
if(headerImages != null)//If we have a valid header handle and a valid ImageList for it
//send a message HDM_SETIMAGELIST
Win32.SendMessage(header.Handle,0x1200+8,IntPtr.Zero,headerImages.Handle);
//Insert all the columns in Columns collection
if(this.Columns.Count > 0)
InsertColumns();
}
base.OnHandleCreated(e);
SetFlatScrollBar();
}
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.dwItemSpec0)
{
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;
}
}
#endregion
#region Drawing methods
void DrawHeaderBorder(DrawHeaderEventArgs e)
{
Graphics g = e.Graphics;
Rectangle r = new Rectangle(e.Bounds.Left,e.Bounds.Top,e.Bounds.Width,e.Bounds.Height);
if(r.Left == 0)
g.DrawLine(/*SystemPens.ControlLightLight*/borderPen,r.Left,r.Bottom,r.Left,r.Top);
if(r.Top == 0)
g.DrawLine(/*SystemPens.ControlLightLight*/borderPen,r.Left,r.Top,r.Right,r.Top);
if(r.Bottom == e.HeaderHeight)
g.DrawLine(/*SystemPens.ControlDark*/borderPen,r.Left,r.Bottom-1,r.Right,r.Bottom-1);
}
void DoMyCustomHeaderDraw(object sender, DrawItemEventArgs e)
{
ListColumn m = sender as ListColumn;
Graphics g = e.Graphics;
//Get the text width
SizeF szf = g.MeasureString(m.Text, this.Font);
int textWidth = (int)szf.Width+10;
Image image = null;
Rectangle r = e.Bounds;
int leftOffset = 4;
int rightOffset = 4;
StringFormat s = new StringFormat();
s.FormatFlags = StringFormatFlags.NoWrap;
s.Trimming = StringTrimming.EllipsisCharacter;
switch(m.TextAlign)
{
case HorizontalAlignment.Left:
s.Alignment = StringAlignment.Near;
break;
case HorizontalAlignment.Center:
s.Alignment = StringAlignment.Center;
break;
case HorizontalAlignment.Right:
s.Alignment = StringAlignment.Far;
break;
}
s.LineAlignment = StringAlignment.Center;
//Adjust the proper text bounds and get the correct image(if any)
// if(m.ImageIndex != -1 && headerImages != null)
// {
// if(m.ImageIndex + 1 > headerImages.Images.Count)
// image = null;
// else
// {
// if(m.ImageOnRight)
// rightOffset += 20;
// else
// leftOffset += 20;
// image = new Bitmap(headerImages.Images[m.ImageIndex],16,16);
// }
// }
if (this.Columns.IndexOf(m)==sortColumn)
rightOffset=13;
else
rightOffset=4;
leftOffset=2;
if(textWidth+leftOffset+rightOffset > r.Width)
textWidth = r.Width - leftOffset - rightOffset;
Rectangle text = new Rectangle(r.Left+leftOffset, r.Top,
textWidth, r.Height);
Rectangle img = Rectangle.Empty;
image=null;
if(!this.FullyCustomHeader)
g.FillRectangle(new SolidBrush(this.headerBackColor),r);
// if (HeaderImageList.Images.Count>1)
// {
// if ((this.Columns.IndexOf(m)==sortColumn)&&(sortOrder==1))
// image=this.HeaderImageList.Images[1];
// if ((this.Columns.IndexOf(m)==sortColumn)&&(sortOrder==-1))
// image=this.HeaderImageList.Images[0];
// }
// if(image != null)
// {
// if(m.ImageOnRight)
// img = new Rectangle(text.Right+4,(r.Height-16)/2,16,16);
// else
// img = new Rectangle(r.Left+2,(r.Height-16)/2,16,16);
// }
if ((this.Columns.IndexOf(m)==sortColumn)&&((e.State & DrawItemState.Selected)==0))
{
img = new Rectangle(text.Right+1,(r.Height-12)/2+5,8,7);
if (sortOrder<0)
g.DrawLines(m_ArrowPen,new Point[] {new Point(img.Left,img.Top),
new Point(img.Right,img.Top),
new Point(img.Left+(img.Width/2),img.Bottom-img.Height/2),
new Point(img.Left,img.Top)});
//For Filled arrows uncomment this
// g.FillPolygon(Brushes.Black,new Point[] {new Point(img.Left,img.Top),
// new Point(img.Right,img.Top),
// new Point(img.Left+(img.Width/2),img.Bottom-img.Height/2),
// new Point(img.Left,img.Top)});
else
g.DrawLines(m_ArrowPen,new Point[] {new Point(img.Left,img.Bottom-img.Height/2),
new Point(img.Right,img.Bottom-img.Height/2),
new Point(img.Left+(img.Width/2),img.Top),
new Point(img.Left,img.Bottom-img.Height/2)});
}
//This occurs when column is pressed
if ((e.State & DrawItemState.Selected)!=0)
{
g.DrawLine(SystemPens.ControlDark,r.Right-1, r.Bottom-1, r.Right-1, r.Top);
g.DrawLine(SystemPens.ControlLightLight,r.Right, r.Bottom-1, r.Right, r.Top);
g.DrawLine(SystemPens.ControlDark,r.Left+2, r.Bottom-3, r.Left+2, r.Top+2);
g.DrawLine(SystemPens.ControlDark,r.Left+2, r.Top+2, r.Right-3, r.Top+2);
g.DrawLine(SystemPens.ControlLightLight,r.Right-3, r.Top+2, r.Right-3, r.Bottom-3);
g.DrawLine(SystemPens.ControlLightLight,r.Right-3, r.Bottom-3, r.Left+2, r.Bottom-3);
if(image != null)
{
img.Offset(1,1);
g.DrawImage(image,img);
img.Offset(-1,-1);
}
text.Offset(1,1);
g.DrawString(m.Text,e.Font,new SolidBrush(headerForeColor),text,s);
text.Offset(-1,-1);
}
//Default state
else
{
g.DrawLine(new Pen(this.headerBackColor),r.Right-2, r.Bottom, r.Right-2, r.Top);
g.DrawLine(new Pen(this.headerBackColor),r.Right-1, r.Bottom, r.Right-1, r.Top);
g.DrawLine(SystemPens.ControlDark,r.Right-1, r.Bottom-1, r.Right-1, r.Top);
g.DrawLine(SystemPens.ControlLightLight,r.Right, r.Bottom-1, r.Right, r.Top);
g.DrawString(m.Text,e.Font,new SolidBrush(headerForeColor),text,s);
if(image != null)
g.DrawImage(image,img);
}
}
#endregion
#region InsertColumns Method
void InsertColumns()
{
int counter = 0;
foreach(ListColumn m in myColumns)
{
Win32.LVCOLUMN lvc = new Win32.LVCOLUMN();
lvc.mask = 0x0001|0x0008|0x0002|0x0004;//LVCF_FMT|LVCF_SUBITEM|LVCF_WIDTH|LVCF_TEXT
lvc.cx = m.Width;
lvc.subItem = counter;
lvc.text = m.Text;
switch(m.TextAlign)
{
case HorizontalAlignment.Left:
lvc.fmt = 0x0000;
break;
case HorizontalAlignment.Center:
lvc.fmt = 0x0002;
break;
case HorizontalAlignment.Right:
lvc.fmt = 0x0001;
break;
}
if(headerImages != null && m.ImageIndex != -1)
{
lvc.mask |= 0x0010;//LVCF_IMAGE
lvc.iImage = m.ImageIndex;
lvc.fmt |= 0x0800;//LVCFMT_IMAGE
if(m.ImageOnRight)
lvc.fmt |= 0x1000;
}
//Send message LVN_INSERTCOLUMN
Win32.SendMessage(this.Handle,0x1000+97,counter,ref lvc);
//Check if column is set to owner-draw
//If so - send message HDM_SETITEM with HDF_OWNERDRAW flag set
if(m.OwnerDraw)
{
Win32.HDITEM hdi = new Win32.HDITEM();
hdi.mask = (int)Win32.HDI.HDI_FORMAT;
hdi.fmt = (int)Win32.HDF.HDF_OWNERDRAW;
Win32.SendMessage(header.Handle,0x1200+12,counter,ref hdi);
}
counter++;
}
}
#endregion
#region Public properties
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public new ListColumnArray Columns
{
get{return myColumns;}
}
public int[] HeaderLeft
{
get {return m_headerleft;}
}
public int[] HeaderRight
{
get {return m_headerright;}
}
public ImageList HeaderImageList
{
get{return headerImages;}
set{headerImages = value;}
}
public bool FullyCustomHeader
{
get{return ownerDrawHeader;}
set{ownerDrawHeader = value;}
}
public IntPtr HeaderHandle
{
get{return header.Handle;}
}
public int IncreaseHeaderHeight
{
get{return increaseHeaderHeight;}
set
{
increaseHeaderHeight = value;
}
}
public int HeaderHeight
{
get{return headerHeight;}
}
public bool DefaultCustomDraw
{
get{return defaultCustomDraw;}
set{defaultCustomDraw = value;}
}
#endregion
#region HeaderControl class
internal class HeaderControl : NativeWindow
{
eLePhantListView parent;
bool mouseDown;
public HeaderControl(eLePhantListView m)
{
parent = m;
//Get the header control handle
IntPtr header = Win32.SendMessage(parent.Handle, (0x1000+31), IntPtr.Zero, IntPtr.Zero);
this.AssignHandle(header);
}
#region Overriden WndProc
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= 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;
}
}
#endregion
}
#endregion
#region Component Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
#region transformationRoutines
public static string SizeToString(uint size)
{
return SizeToString((ulong)size);
}
public static string SizeToString(ulong size)
{
if(size==0) return "0";
StringBuilder strB=new StringBuilder();
//strB.Remove(0,strB.Length);
if (size<1024)
{
strB.Append(size);
strB.Append(" "+eLePhantForm.Globalization["LBL_BYTE"]);
}
else if ((size>=1024)&&(size<1048576))
{
strB.Append(size/1024);
strB.Append(" "+eLePhantForm.Globalization["LBL_KBYTE"]);
}
else if ((size>=1048576)&&(size<1073741824))
{
strB.Append(((float)size/1048576F).ToString("###0.##"));
strB.Append(" "+eLePhantForm.Globalization["LBL_MBYTE"]);
}
else if (size>=1073741824)
{
strB.Append(((float)size/1073741824F).ToString("###0.##"));
strB.Append(" "+eLePhantForm.Globalization["LBL_GBYTE"]);
}
return strB.ToString();
}
public static string SpeedToString(float speed)
{
// if (speed<1024) return Convert.ToString(speed)+" B/s";
// if (speed<10240) return speed.ToString()+" KB/s";
// if (speed>=102400) return Convert.ToString(speed/1000)+" MB/s";
// return"";
StringBuilder strB=new StringBuilder();
strB.Remove(0,strB.Length);
if (speed<10240)
{
strB.Append(speed);
strB.Append(" "+eLePhantForm.Globalization["LBL_KBYTE"]+"/s");
}
else
{
strB.Append(speed/1024);
strB.Append(" "+eLePhantForm.Globalization["LBL_MBYTE"]+"/s");
}
return strB.ToString();
}
protected string PriorityToString(Types.Constants.Priority priority)
{
switch (priority)
{
case Types.Constants.Priority.VeryHigh: return eLePhantForm.Globalization["LBL_VERYHIGH"];
case Types.Constants.Priority.High: return eLePhantForm.Globalization["LBL_HIGH"];
case Types.Constants.Priority.Normal: return eLePhantForm.Globalization["LBL_NORMAL"];
case Types.Constants.Priority.Low: return eLePhantForm.Globalization["LBL_LOW"];
case Types.Constants.Priority.VeryLow: return eLePhantForm.Globalization["LBL_VERYLOW"];
}
return "";
}
protected string ServerPriorityToString(Types.Constants.ServerPriority priority)
{
switch (priority)
{
case Types.Constants.ServerPriority.High: return eLePhantForm.Globalization["LBL_HIGH"];
case Types.Constants.ServerPriority.Normal: return eLePhantForm.Globalization["LBL_NORMAL"];
case Types.Constants.ServerPriority.Low: return eLePhantForm.Globalization["LBL_LOW"];
}
return "";
}
#endregion
}
#region HeaderEventArgs class
public class HeaderEventArgs : EventArgs
{
int columnIndex;
int mouseButton;
public HeaderEventArgs(int index, int button)
{
columnIndex = index;
mouseButton = button;
}
public int ColumnIndex
{
get{return columnIndex;}
}
public int MouseButton
{
get{return mouseButton;}
}
}
#endregion
#region DrawHeaderEventArgs class
public class DrawHeaderEventArgs : EventArgs
{
Graphics graphics;
Rectangle bounds;
int height;
public DrawHeaderEventArgs(Graphics dc, Rectangle rect, int h)
{
graphics = dc;
bounds = rect;
height = h;
}
public Graphics Graphics
{
get{return graphics;}
}
public Rectangle Bounds
{
get{return bounds;}
}
public int HeaderHeight
{
get{return height;}
}
#endregion
}
}