You have to delve into the wonderful world of custom control painting to do
this.
To turn on custom painting in detail view you need to override CreateParams
and add the LVS_OWNERDRAWFIXED (0x0400) style to the parameters.
public enum LVSDefs
{
LVS_ICON =0x0000,
LVS_REPORT =0x0001,
LVS_SMALLICON =0x0002,
LVS_LIST =0x0003,
LVS_TYPEMASK =0x0003,
LVS_SINGLESEL =0x0004,
LVS_SHOWSELALWAYS =0x0008,
LVS_SORTASCENDING =0x0010,
LVS_SORTDESCENDING =0x0020,
LVS_SHAREIMAGELISTS =0x0040,
LVS_NOLABELWRAP =0x0080,
LVS_AUTOARRANGE =0x0100,
LVS_EDITLABELS =0x0200,
LVS_OWNERDATA =0x1000,
LVS_NOSCROLL =0x2000,
LVS_TYPESTYLEMASK =0xfc00,
LVS_ALIGNTOP =0x0000,
LVS_ALIGNLEFT =0x0800,
LVS_ALIGNMASK =0x0c00,
LVS_OWNERDRAWFIXED =0x0400,
LVS_NOCOLUMNHEADER =0x4000,
LVS_NOSORTHEADER =0x8000
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp=base.CreateParams;
cp.Style|=(int)LVSDefs.LVS_OWNERDRAWFIXED;
return cp;
}
}
Then you need to override WndProc and trap the reflected WM_DRAWITEM message
This is a combination of WM_REFLECT and WM_DRAWITEM (0x202b)
#region Windows Message Definitions converted from WinUser.h
public enum WMDefs
{
WM_DRAWITEM =0x002B,
WM_REFLECT =0x2000,
}
#endregion
protected override void WndProc(ref Message m)
{
switch(m.Msg)
{
case (int)(WMDefs.WM_REFLECT | WMDefs.WM_DRAWITEM):
ProcessDrawItem(ref m);
break;
default:
base.WndProc (ref m);
break;
}
}
Upon reception of this message you need to get a DRAWITEMSTRUCT from the
LPARAM and do whatever drawing you need...
[StructLayout(LayoutKind.Sequential)]
public struct DRAWITEMSTRUCT
{
public int CtlType;
public int CtlID;
public int itemID;
public int itemAction;
public int itemState;
public IntPtr hwndItem;
public IntPtr hDC;
public RECT rcItem;
public IntPtr itemData;
}
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
public int Width
{
get{return right-left;}
}
public int Height
{
get{return bottom-top;}
}
}
private void ProcessDrawItem(ref Message m)
{
//Extract the structure from the LParam.
DRAWITEMSTRUCT dis=(DRAWITEMSTRUCT)Marshal.PtrToStructure(m.LParam,
typeof(DRAWITEMSTRUCT));
//Wrap the hDC in a Graphics object
Graphics g=Graphics.FromHdc(dis.hDC);
//read the horizontal scroll position
int hScroll=GetScrollPos(this.Handle,SBDefs.SB_HORZ);
//obtain the item that needs to be drawn
ListViewItem i=this.Items[dis.itemID];
//get the rectangle of the item
Rectangle rcItem=new Rectangle(dis.rcItem.left, dis.rcItem.top,
this.ClientSize.Width+hScroll, dis.rcItem.Height);
//Draw in the item rectangle here
//We processed the message
m.Result=(IntPtr)1;
}
Have fun!
--
Bob Powell [MVP]
Visual C#, System.Drawing
Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm
Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm
All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.