What states are possible in a DRAWITEMSTRUCT structure?
DRAWITEMSTRUCT structure has an
itemState member which contains a number of bits describing the state of the item being drawn. How do those states map to the underlying control?
Most of the states are rather obvious. For a list box item to be selected, it means that the item is part of the selection. But what does selected mean for a button?
Since people like tables, I’ll put the answer in a table:
|menu item ID||item index or −1||item index or −1|
|Default menu item|
|Is edit control|
|item index||item index||item index||part index|
Okay, now that it’s all in a table, how do I read the table?
A box is blank if the corresponding flag is not currently used by the control type. (No guarantees about the future.) For example, as of this writing, button controls do not set an
itemID, nor do they ever ask for
You may have noticed that the box for
CtlType is blank for status controls. That’s an oops. The status bar control forgot to set the
CtlType when it sends the
WM_DRAWITEM message, so the value is uninitialized garbage. The way to detect a status bar control is to check the window handle. (This works in general. You can always detect a control by checking the window handle.)
For list boxes and combo boxes, the
itemID can have the special value
-1 to mean “I am drawing a list box/combo box where no item is selected.” For list boxes, this happens when the list box is empty. For combo boxes, this happens when the user types text into the edit box that does not match any of the items in the list portion of the combo box.
Most of the other box entries are self-explanatory. For the most part, the flag name matches the conditions under which the corresponding flag is set. For example, the
ODS_FOCUS flag is set when the list box item being drawn is the selected item.
Note that the
ODS_SELECTED flag is used for button and header controls to indicate that the control should be drawn in the pushed state. For example, the user may have put focus on a button control and pressed the space bar and not yet released it, or the application may have manually set the
BST_PUSHED state. Header controls can get into a pushed state if you enable the
List view controls set the
ODS_CHECKED flag if a check box should be drawn over the item. This happens if the
LVS_EX_AUTOCHECKSELECT extended style is specified and the item is selected. (Normally, the check box is drawn to the side as a state image.)
ODS_COMBOBOXEDIT flag is used only by combo box controls. It is set if the item being drawn is the edit portion of a combo box control. If not set, then the item being drawn is in the list box portion of the combo box control.
Finally, there is a box marked Oops.
The static control is supposed to set
ODS_DISABLED if the static control is disabled. And that’s what happens if you are using the classic static control. However, there is a typo in the the fancy themed static control, and it sets the
ODS_DISBALED flag incorrectly. If you are owner-drawing a themed static control, and you want to draw differently depending on whether the control is disabled, then you should ignore the
ODS_DISABLED flag and instead draw the disabled state based on the result of calling
The bug in the themed static control cannot be fixed for compatibility reasons. I can pretty much guarantee that there is some application which doesn’t draw correctly if the
ODS_DISABLED flag is not set.