2

I use CTreeCtrl and I want to catch TVN_SELCHANGING event. If I use one selection, TVN_SELCHANGING is run. But if I set TVS_EX_MULTISELECT ex_style, TVN_SELCHANGING is not processed.

What is the reason? What to do with it?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Michal Hadraba
  • 347
  • 1
  • 11

1 Answers1

3

The TVS_EX_MULTISELECT style prevents TVN_SELCHANGING from being sent for unknown reasons.

TVN_ITEMCHANGING is sent however and you can use that to fake TVN_SELCHANGING in your own window procedure:

...
case TVN_ITEMCHANGING:
    {
        NMTVITEMCHANGE*pTVIC = (NMTVITEMCHANGE*) lParam;
        if (pTVIC->uChanged == TVIF_STATE && ((pTVIC->uStateOld ^ pTVIC->uStateNew) & TVIS_SELECTED) && (TreeView_GetExtendedStyle(pTVIC->hdr.hwndFrom) & TVS_EX_MULTISELECT))
        {
            static HTREEITEM old = 0;
            if (pTVIC->uStateNew & TVIS_SELECTED)
            {
                UINT mask = TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM|TVIF_STATE;
                NMTREEVIEW nmtv = { };
                nmtv.hdr = pTVIC->hdr, nmtv.hdr.code = TVN_SELCHANGING, nmtv.action = TVC_UNKNOWN;
                TreeView_GetItem(pTVIC->hdr.hwndFrom, (nmtv.itemNew.hItem = pTVIC->hItem, nmtv.itemNew.mask = mask, &nmtv.itemNew));
                if (old) TreeView_GetItem(pTVIC->hdr.hwndFrom, (nmtv.itemOld.hItem = old, nmtv.itemOld.mask = mask, &nmtv.itemOld));
                SendMessage(GetParent(pTVIC->hdr.hwndFrom), WM_NOTIFY, pTVIC->hdr.idFrom, (LPARAM) &nmtv);
                old = 0;
            }
            else
            {
                old = pTVIC->hItem; // Note: This assumes the de-selection item change message is sent before the selection item change message!
            }
        }
    }
    break;
...
Anders
  • 97,548
  • 12
  • 110
  • 164