views:

624

answers:

5

I was planning to implememt owner-drawn of CListCtrl. I thought that drawing an item is after the item is inserted into the control. So my method is declare a class which is derived from CListCtrl and override its DrawItem() method. The problem is DrawItem is never invoked after inserting an item. Is there anything wrong with my method?

Thank you!

A: 

You need to set the LBS_OWNERDRAWFIXED style on the control. You can do that in the resource template or programmatically using the ModifyStyle() function.

example:

m_myListbox.ModifyStyle(0, LBS_OWNERDRAWFIXED, 0);
Adam Pierce
This is incorrect. LBS_OWNERDRAWFIXED is a list box style. For a CListCtrl, the appropriate style is LVS_OWNERDRAWFIXED.
ChrisN
A: 

The problem might be that you are not associating the window with an instance of your class. This is done with DDX_Control inside your dialog's DoDataExchange method. DDX_Control calls CWnd::SubclassWindow, which you can do yourself if you prefer.

Mark Ransom
A: 

Shall I override OnDrawItem() method? But how can I raise this event?

If you have set the LBS_OWNERDRAWFIXED or LBS_OWNERDRAWVARIABLE style on the list control, and you have properly connected the window to the C++ object, the OnDrawItem method will be called automatically. Both conditions are necessary.
Mark Ransom
I used ModifyStyle method to change the MyListCtrl object's (derived from CListCtrl) style with ModifyStyle(0, LVS_OWNERDRAWFIXED, 0), and I connected the Dialog with the object using DDX_Control(). I also override the DrawItem method. But The method is not invoked either when inserting an item.
A: 

It could be that you also need to override MeasureItem() and CompareItem(). See the Microsoft article TN014 for more detail.

Here is some code I cut & pasted out of one of my own projects so I know it works:

int CGraphicDroplist::CompareItem(LPCOMPAREITEMSTRUCT lpCompareItemStruct)
{
    return 0;
}

void CGraphicDroplist::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
    RECT r = lpDrawItemStruct->rcItem;
    CDC  pDC;
    pDC.Attach(lpDrawItemStruct->hDC);

// Put your code to draw the item here.

    pDC.Detach();
}

void CGraphicDroplist::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
    lpMeasureItemStruct->itemHeight = 100;
}
Adam Pierce
My class derived from CListCtrl, so there's no overridable methods like CompareItem or measureItem.Could you please explain to me what happends between an item is inserted to the CListCtrl and is displayed on the screen. And Can DrawItem() method draw the item specified by programmer?Thanks!
Ah, my mistake, I thought you were using CListBox. I'll post another answer.
Adam Pierce
+1  A: 

To get your DrawItem() override called in a CListCtrl derived class, you need to set the style LVS_OWNERDRAWFIXED and also set the control to "Report View" mode. As far as I know, ownerdraw only works in report mode.

Also check that the variable is the correct type in your header file (eg. CMyListCtrl and not CListCtrl) and check the DDX assignment is correct as Mark Ransom suggested.

Adam Pierce