2

I have a listbox in which multiple list items are there. I want to implement something like if we click on the list item, it will collapse and show the summary of the clicked item:

enter image description here

I have been searching this on the web for quite sometime but haven't got any good solution. I am very new to Win32. Any suggestions on how to approach this like which control should I use. Any help will be appreciated.

  • 2
    What is your question? Do you have code that isn't working? Then show your [MCVE]. Do you want code that works? We don't do that here. Do you want a direction to a tutorial or to code that works? We don't do that here, either. – Lightness Races in Orbit Oct 03 '16 at 08:36
  • 1
    @VipinNagar The question is specifically about `winapi`. The answer you provided is about html... –  Oct 03 '16 at 08:55
  • 4
    A [List Box](https://msdn.microsoft.com/en-us/library/windows/desktop/bb775146.aspx) doesn't provide that feature, neither does a [List View](https://msdn.microsoft.com/en-us/library/windows/desktop/bb774737.aspx). You'll either implement your own, or use a library, like MFC (see [CMFCPropertyGridCtrl](https://msdn.microsoft.com/en-us/library/bb983759.aspx) and similar). @VipinNagar: Trying to help is fine. However, if *trying* is all you have to offer, just don't. – IInspectable Oct 03 '16 at 09:14
  • It is possible to do with a standard ListBox. I have done it before. But it does take some extra work to pull off. – Remy Lebeau Oct 04 '16 at 01:08
  • A ListView DOES support this since a while (Vista I think). Look out for "Groups" on Listviews. LVM_ENABLEGROUPVIEW, LVM_INSERTGROUP. You need to enable visual controls (add ComnCtr 6.0 to your manifest - see here) – Marco Freudenberger Aug 13 '20 at 08:24

1 Answers1

5

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.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770