December 13th, 2006

Displaying infotips for folded and unfolded listview items

When displaying infotips for listview items, you have to deal with both the folded and unfolded case. “Folded” is the term used to describe a listview item in large icon mode whose text has been truncated due to length. When the user selects the item, the full text is revealed, a process known as “unfolding”.

Take our scratch program and make the following changes:

#include <strsafe.h>
BOOL
OnCreate(HWND hwnd, LPCREATESTRUCT lpcs)
{
  g_hwndChild = CreateWindow(WC_LISTVIEW, NULL,
                             WS_CHILD | WS_VISIBLE | LVS_ICON,
                             0, 0, 0, 0,
                             hwnd, (HMENU)1, g_hinst, 0);
  if (!g_hwndChild) return FALSE;
  ListView_SetExtendedListViewStyleEx(g_hwndChild,
                             LVS_EX_INFOTIP,
                             LVS_EX_INFOTIP);
  LVITEM item;
  item.iItem = 0; // added 9pm
  item.iSubItem = 0;
  item.mask = LVIF_TEXT;
  item.pszText = TEXT("Item with a long name that will be truncated");
  if (ListView_InsertItem(g_hwndChild, &item) < 0)
    return FALSE;
  return TRUE;
}
void OnGetInfoTip(HWND hwnd, NMLVGETINFOTIP *pit)
{
 if (!pit->cchTextMax) return;
 if (pit->dwFlags & LVGIT_UNFOLDED) {
  pit->pszText[0] = TEXT('\0');
 } else {
  StringCchCat(pit->pszText, pit->cchTextMax, TEXT("\r\n"));
 }
 StringCchCat(pit->pszText, pit->cchTextMax, TEXT("Here is an infotip"));
}
LRESULT OnNotify(HWND hwnd, int idCtrl, NMHDR *pnm)
{
 if (idCtrl == 1) {
  switch (pnm->code) {
  case LVN_GETINFOTIP:
   OnGetInfoTip(hwnd, (NMLVGETINFOTIP*)pnm);
   break;
  }
 }
 return 0;
}
  HANDLE_MSG(hwnd, WM_NOTIFY, OnNotify);

We create our listview, enable infotips, and add a single item with a rather long name. When you run the program, observe that the item’s text is truncated at two lines if it is not selected, but it expands to full size when you selected it.

When the listview notifies us that it’s time to display the infotip, we check whether the item is folded or unfolded. If it is unfolded, then we set the buffer to an empty string so that our StringCchCat at the end will merely copy the infotip text into the buffer. On the other hand, if the item is folded, then we append a line terminator because we want the infotip to contain the full text of the item, followed by the tip text.

When you run this program, hover over the item both when it is folded and unfolded, and observe that the folded infotip includes the name of the item. This is a detail of infotips that is called out in the documentation but which many programs fail to observe.

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

0 comments

Discussion are closed.