Displaying infotips for folded and unfolded listview items

Raymond Chen

Raymond

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.

Raymond Chen
Raymond Chen

Follow Raymond   

0 comments

Comments are closed.