Owner-draw listbox problem...

I am trying to figure out how to set the ODS_DISABLED style on an item in my owner-draw listbox so that when I get a WM_DRAWITEM the ODS_DISABLED flag is set in DRAWITEMSTRUCT.itemState

Who is Participating?
Answers2000Connect With a Mentor Commented:
The simple answer is you can't (at least not the way I think you want to do it).

The reason being that these ODS_ flags apply to the individual items being owner draw.  As the DRAWITEMSTRUCT is used for owner draw of a number of things - buttons, combos, menus, listboxes - not all the ODS_ flags are applicable in all cases.  

The ODS_DISABLED style is normal used to detect a disabled menu item (because on menu's you can disable individual items).  It doesn't apply to list boxes, as there is no built-in functionality to disable individual items in the list.

Okay how to get round this ?

(1) If you want to disable the entire list box (i.e. it will stop working completely) - use EnableWindow( hWndListBox, FALSE ) ;   You can detect if the entire listbox is disabled by using IsWindowEnabled()

(ii) Guessing by your question's wording - I think you want to disable individual list box items ?  As this functionality is not built in to the standard list box functionality, you need to either add this functionality or simulate it.

The best way to do this is store a flag for each list box item to indicate if it's disabled.  You can either do this in your own array / map / structures - or alternatively use the item data of each list box item.

Windows let's you associate a 32bit integer with each list box item.  Use this as your own flag to indicate if an item is disabled or not.

You can set this for list box items using the LB_SETITEMDATA message - (Don't forget if changing the state of the item's data it won't automatically repaint - you need to do something like { InvalidateRect( hWndListbox, NULL, FALSE ) ; UpdateWindow( hWndListBox ) ; } to force a repaint.

When you want to test if the enabled/disabled flag is set for a particular item (e.g. on your handler for WM_DRAWITEM) retrieve this flag for the list box item using the LB_GETITEMDATA message, and then paint the item appropriately.

Finally before you implement this you will want to think carefully about what you mean by disabled.  Can disabled items still be selected ?  Can disabled items still have the focus ?  

Whatever you decide, the easiest way to implement changes in the rules is to let the list box function normally - but change your painting code - so for example if disabled items can't be selected - then still let Windows/the-user select them - but always paint them "as if" they weren't selected.  In this case, these "selected but not selected" items would also be handled as if they weren't selected when retrieving information from the list box (e.g. when the user presses OK on your dialog).

scooleyAuthor Commented:
I figured this is the answer I would recieve... I have actually already implemented this by subclassing the standard listbox control and setting the item data to a point to a struct, the struct contains two items, my dword flags for drawing, and a void* for the items data (LB_SETITEMDATA).

Thanks anyway!
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.