ListView DrawItem/MeasureItem frustrations


chris s.

I'm trying to get DrawItem and MeasureItem working on a ListView, with
a view to drawing items in LargeIcon view. I've managed to get
DrawItem working okay, using the code below. My problem is with the
MeasureItem event. The event is only ever called once, and most
annoyingly, are never called when the view isn't the details view.

I've tinkered about with the owner-drawn listview projects on, and have discovered you need to handle ITEMPREPAINT
for non-details view listviews. The problem with this is, MeasureItem
isn't supported (or rather, I don't know how to handle it), and so you
end up having to handle or Mouse events yourself.

This removes the point of the control being derived from ListView - to
utilise all the functionality a listview has in.

I also tried creating ListViewItemCollections and ListViewItems
myself, but gave up with that as I was getting nowhere.

Hopefully you've read to this stage and haven't dropped off. If anyone
can suggest controls (commercial/free), websites, FAQs etc. that'd be

The code:
// Majority of this is a merger of UtilityLibrary and google groups
public class MyListView : ListView
public int CtlType;
public int CtlID;
public int itemID;
public int itemWidth;
public int itemHeight;
public IntPtr itemData;

private struct RECT
public int left;
public int top;
public int right;
public int bottom;

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

private enum ReflectedMessages
OCM__BASE = (0x0400 + 0x1c00),

public event System.Windows.Forms.DrawItemEventHandler DrawItem;
public event MeasureItemEventHandler MeasureItem;
public const int LVS_OWNERDRAWFIXED = 0x0400;
private DrawMode drawMode;

public MyListView()
this.drawMode = DrawMode.Normal;

protected override CreateParams CreateParams
CreateParams cp = base.CreateParams;
cp.Style |= (drawMode != DrawMode.Normal) ? LVS_OWNERDRAWFIXED : 0;
return cp;

public virtual DrawMode DrawMode
get { return drawMode; }
set { drawMode = value; }

protected virtual void
OnDrawItem(System.Windows.Forms.DrawItemEventArgs e)


public virtual void OnMeasureItem(MeasureItemEventArgs e)


protected override void WndProc(ref System.Windows.Forms.Message m)
base.WndProc(ref m);

switch (m.Msg)
case (int)ReflectedMessages.OCM_DRAWITEM:
DrawItemStruct dis =

Graphics graph = Graphics.FromHdc(dis.hDC);
Rectangle rect = new
Rectangle(dis.rcItem.left,,dis.rcItem.right -
dis.rcItem.left,dis.rcItem.bottom -;
int index = dis.itemID;
DrawItemState state = DrawItemState.None;

System.Windows.Forms.DrawItemEventArgs e = new
System.Windows.Forms.DrawItemEventArgs(graph, Font, rect, index,
state, ForeColor, BackColor);
if ( this.DrawItem != null )


case 8236:
this.WmReflectMeasureItem(ref m);


private void WmReflectMeasureItem(ref Message m)
Graphics graphics1;
MeasureItemEventArgs args1;
m.GetLParam( typeof(MEASUREITEMSTRUCT) );
if ((this.drawMode == DrawMode.OwnerDrawVariable) &&
(measureitemstruct1.itemID >= 0))
graphics1 = Graphics.FromHwnd(this.Handle);
args1 = new MeasureItemEventArgs(graphics1,
measureitemstruct1.itemID, 20);
if ( this.MeasureItem != null )
measureitemstruct1.itemHeight = args1.ItemHeight;

measureitemstruct1.itemHeight = 20;//this.ItemHeight;
Marshal.StructureToPtr(measureitemstruct1, m.LParam, false);
m.Result = ((IntPtr) 1);



moreno borsalino

I made a porting of FotoVision from VisualBasic.Net to C#. I ported
only the ASP.NET web application. I used the C# ASP.NET application to
realize a web site with my digital photos that are designed to be used
as full-screen computer desktop backgrounds. The images are available
for free download in 1600x1200 resolution.
I made available the FotoVision C# source code in this website at :

If you know a web ring of other sites that feature similar content
please let me known.

Moreno Borsalino

Visit my desktop photos collection at
(made with FotoVision)

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question