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!

Signature
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.
> Hi all,
>
[quoted text clipped - 10 lines]
>
> Thanks in advance!!!
Jose Fco Bonnin - 31 Dec 2004 09:38 GMT
If he only needs to get the OnPaint event called, why don't just set
SetStyle(ControlStyles.UserPaint,true);
in the derived control?
Bob Powell [MVP] - 31 Dec 2004 15:03 GMT
The OnPaint never tells you what items are being painted so it could be the
headers, the items or the sub-items being drawn.
ListView is a very loose wrapper around the old listview common control so
it's necessary to jump through a few hoops to get it right.

Signature
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.
> If he only needs to get the OnPaint event called, why don't just set
>
> SetStyle(ControlStyles.UserPaint,true);
>
> in the derived control?