Standard ListBox and ListView controls do not natively support expanding/collapsing items, however it is possible to implement it in a ListBox with some extra work.
Give the ListBox the LBS_OWNERDRAWVARIABLE
list box style to allow the list to contain items of different heights. When a new item is added to the list, the ListBox will send a WM_MEASUREITEM
message to its parent window asking for the item's initial height. Return an appropriate height based on whether the item should be displayed as collapsed or expanded.
Once an item has been added to the list, you can send the ListBox a LB_SETITEMHEIGHT
message to assign a new height for that item based on whether it should now be displayed collapsed or expanded. Then invalidate the ListBox to trigger a repaint of the items.
The LBS_OWNERDRAW...
styles require you to manually draw each list item whenever the ListBox sends a WM_DRAWITEM
message to its parent window. You can draw the requested item on the provided HDC
however you want, such as with the DrawText()
function, configuring its parameters based on whether the item's text is currently being displayed as collapsed or expanded. Also use the state information provided by the message itself to configure the HDC
's font and background/foreground colors as desired (particularly important when rendering items in the selected and focused states).
With that in place, all you have left to do is make your click handler determine the index of the item being clicked on (via GetMessagePos()
, ScreenToClient()
, and LB_ITEMFROMPOINT
), and then assign it a new height based on its new expanded/collapsed state, and let the resulting repaint draw the new text accordingly.