• Welcome to Valhalla Legends Archive.
 

Emulating ListView-style deselection in a ListBox (C++)

Started by Skywing, March 26, 2003, 01:13 AM

Previous topic - Next topic

Skywing

I recently wanted to emulate ListView-style deselection behavior for a ListBox, and wrote the following code which might be of use to somebody else.

What I mean by emulating the ListView-style deslection behavior is that clicking outside of the extent of the text of an item in report view will deselect the item.  By default, a ListBox counts an item as having a width approximately equal to the ListBox's width for purposes of selection hit-tests.

You may wish to trap WM_LBUTTONDBLCLK and WM_RBUTTONDBLCLK as well.

This code is Unicode-compatible and requires tchar.h in addition to windowsx.h and windows.h.  The alloca function requires memory.h; replace with any other method of allocating temporary storage if you so desire.

INT_PTR CALLBACK OnListBoxMessage(HWND hWnd, UINT uMsg, WPARAM wParam,
                                          LPARAM lParam)
{
   switch(uMsg) {

   case WM_LBUTTONDOWN:
   case WM_RBUTTONDOWN:
      {
         LONG_PTR Index;

         Index = SendMessage(hWnd, LB_ITEMFROMPOINT, 0, lParam);

         if(Index == LB_ERR)
            break;

         RECT ItemRect;

         if(SendMessage(hWnd, LB_GETITEMRECT, (WPARAM)Index, (LPARAM)&ItemRect) == LB_ERR)
            break;

         size_t Size = (size_t)SendMessage(hWnd, LB_GETTEXTLEN, (WPARAM)Index, 0);

         if(Size == (size_t)LB_ERR)
            break;

         LPTSTR Text = (LPTSTR)alloca(Size+1);

         if(SendMessage(hWnd, LB_GETTEXT, (WPARAM)Index, (LPARAM)Text) == LB_ERR)
            break;

         HDC DC = GetDC(hWnd);
         DrawText(DC, Text, -1, &ItemRect, DT_CALCRECT | DT_NOPREFIX);
         OffsetRect(&ItemRect, 1, 0);
         ReleaseDC(hWnd, DC);

         if(GET_X_LPARAM(lParam) > ItemRect.right) {
            SendMessage(hWnd, LB_SETCURSEL, (WPARAM)-1, 0);
            return 0;
         }
      }

   }

   return CallWindowProc(OriginalListBoxProc, hWnd, uMsg, wParam, lParam);
}