c++winapitreeviewcommon-controlslparam

TVITEM LPARAM to store string


I've got a treeview listing files that are dropped upon it.

When I make a new treeview item, I'd like to store the address of the file as a string in that item, and retrieve it for various nefarious purposes at a later point in time.

Looking at the TVITEM structure in Microsoft docs, apparently LPARAM is the place to store a value:

lParam

Type: LPARAM

A value to associate with the item.

So, I have gone ahead and done that:

TVITEM tvi;
tvi.mask = TVIF_TEXT;
tvi.pszText = const_cast<char *> (str0.c_str());
tvi.cchTextMax = sizeof(tvi.pszText);
tvi.lParam = (LPARAM) foo;  // SETTING LPARAM HERE, foo IS A const char * 

TVINSERTSTRUCT tvis;
tvis.item = tvi;
tvis.hInsertAfter = 0;
tvis.hParent = hti0;

// Send message to update tree, and return tree item.
return TreeView_InsertItem(tvw_filelist_, &tvis);

Then, when I try to retrieve my value...

HTREEITEM htiSel = TreeView_GetSelection(tvw_filelist_);

TVITEM tvItem;
tvItem.hItem = htiSel;

TreeView_GetItem(tvw_filelist_, &tvItem);
const char * info = (const char *) tvItem.lParam;
MessageBox(NULL, info, "Alert", MB_OK);

...I just get garbage, indicating my pointer went out of scope or is taking a nap or something. The size of that pointer is always 4.

Is this the right way to do what I'm trying to do? If so, what's going on?


Solution

  • Of course, take the time to post a question after a long time trying to figure it out, and the answer shows up in seconds.

    Turns out the TVITEM mask needs to include TVIF_PARAM, similar to this question.

    If I change the above code to:

    tvi.mask = TVIF_TEXT | TVIF_PARAM;
    

    it works as expected.

    I'm still not sure if this is the recommended use for LPARAM, though.