NO

Author Topic: Retrieve struct items of treeview.lParam  (Read 6207 times)

jvanroos

  • Guest
Retrieve struct items of treeview.lParam
« on: February 25, 2015, 07:19:01 PM »
I have following structure:

struct Tournaments
{
      unsigned int id;
   unsigned int itemid;
};

struct Tournaments Tournament;

I assign values to Tournament:

   Tournament.id = 1;
   Tournament.itemid = 2;


...in the code I insert this structure in my treeview.lParam item:
Code: [Select]
tvinsert.hParent = hParent;
Before = hParent;
tvinsert.hInsertAfter = TVI_LAST;
tvinsert.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
tvinsert.item.pszText = szEventName;
tvinsert.item.lParam = (LPARAM) &Tournament;
tvinsert.item.iImage = 9;
tvinsert.item.iSelectedImage = 9;

Parent = (HTREEITEM) SendMessage(g_hwndTreeview, TVM_INSERTITEM, 0, (LPARAM) &tvinsert);
...and in the Notify code I retrieve the item back:
Code: [Select]

tvi.mask = TVIF_PARAM | TVIF_TEXT;
SendMessage(g_hwndTreeview, TVM_GETITEM, 0, (LPARAM) &tvi);
Assuming tvi holds the structure previously inserted, how can I get hold of
the structure items id & itemid ??

If necessary I can provide the whole code...

Offline DMac

  • Member
  • *
  • Posts: 272
Re: Retrieve struct items of treeview.lParam
« Reply #1 on: February 26, 2015, 07:38:20 PM »
You could try something like this:

Code: [Select]
Tournament*  TreeView_GetTournament(HWND hTree, HTREEITEM hItem)
{
    TVITEM tv = { 0 };

    tv.mask = TVIF_PARAM | TVIF_HANDLE;
    tv.hItem = hItem;

    if (TreeView_GetItem(hTree, &tv))
    {
        return (Tournament*)tv.lParam;
    }
    return NULL;
}

BOOL TreeView_OnNotify(LPNMHDR pnm)
{

     HITEM hItem = ((LPNMTREEVIEW)pnm)->itemNew.hItem

     Tournament *lpTournament = TreeView_GetTournament(hTree, hItem);
     if(NULL != lpTournament)
     {
          unsigned int id = lpTournament->id;
          unsigned int itemid = lpTournament->itemid;

          //
          //Do calculations etc....
          //
     }
return FALSE;
}
« Last Edit: March 30, 2015, 08:06:29 PM by DMac »
No one cares how much you know,
until they know how much you care.

jvanroos

  • Guest
Re: Retrieve struct items of treeview.lParam
« Reply #2 on: February 28, 2015, 06:01:24 PM »
Thanks,

I will give it a go... I think I even forgot the TVIF_HANDLE in the tvi.mask part.



jvanroos

  • Guest
Re: Retrieve struct items of treeview.lParam
« Reply #3 on: March 30, 2015, 11:47:48 AM »
@DMac or anybody else :-):

I am now able to store items in the treeview and retrieving them.

However when I add a new item (from a listbox) to the treeview and selecting that item by clicking it or leftmouse-clicking returns the wrong address of the tournament pointer.

I traced the insert routine to see if the tournament structure is correctly added to the lParam of the treeview item and that seems correct.

Since all this is a bit difficult to explain in text I have added the source code.

Would you mind having a look at it and maybe tell me what I did wrong ?

You can add an item by right-clicking a tournament and then an contextmenu will popup. (add eventitem)
« Last Edit: March 30, 2015, 11:50:38 AM by jvanroos »

Offline TimoVJL

  • Global Moderator
  • Member
  • *****
  • Posts: 2115
Re: Retrieve struct items of treeview.lParam
« Reply #4 on: March 30, 2015, 03:26:53 PM »
Check this in line 92
Code: [Select]
static TOURNAMENT tournaments[512][64] = {0};Perhaps using global variable and dynamically allocated space could be better.
« Last Edit: March 30, 2015, 03:29:32 PM by TimoVJL »
May the source be with you

jvanroos

  • Guest
Re: Retrieve struct items of treeview.lParam
« Reply #5 on: March 30, 2015, 04:42:44 PM »
Thanks for the reply!

This is what i did (for the people who are interested) and it works like a charm!

Code: [Select]
TOURNAMENT * p;

Each time I add an item to the treeview I allocate memory:

p = malloc(sizeof(TOURNAMENT));
p->id = iEventId;
p->item = iEventItem;

...and in the TV_INSERTSTRUCT :

tvis.item.lParam = (LPARAM) p;

after filling the treeview I free the memory.

free(p);


Offline DMac

  • Member
  • *
  • Posts: 272
Re: Retrieve struct items of treeview.lParam
« Reply #6 on: March 30, 2015, 08:04:06 PM »
For the edification of any who might read this thread:

When using heap allocated data structures in a treeview be sure to free the pointer only after the data structure is no longer needed.  That is when the tree node is deleted or the treeview itself is deleted.

The treeview provides a notification for this very purpose.  The TVN_DELETEITEM notification is sent to the treeview's parent control (dialog or main window) via the WM_NOTIFY message.

Code: [Select]
static BOOL TreeView_FreeItemInfo(HWND hTree, HTREEITEM hItem)
{
    TVITEM tv = { 0 };

    tv.mask = TVIF_PARAM | TVIF_HANDLE;
    tv.hItem = hItem;

    if (TreeView_GetItem(hTree, &tv))
    {
        free((TOURNAMENT *)tv.lParam);
        return TRUE;
    }
    return FALSE;
}

INT_PTR CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_NOTIFY:
        switch (((LPNMHDR)lParam)->code)
        {
        case TVN_DELETEITEM:
            TreeView_FreeItemInfo(((LPNMHDR)lParam)->hwndFrom,
                  (LPNMTREEVIEW)lParam)->itemOld.hItem);
            break;
        ... // More cases on WM_NOTIFY switch.
        break;
        }
    ...  // More cases on message switch.
    }
    return FALSE;
}
No one cares how much you know,
until they know how much you care.

jvanroos

  • Guest
Re: Retrieve struct items of treeview.lParam
« Reply #7 on: March 30, 2015, 09:35:56 PM »
Nice one DMac!

I was freeing the memory after creation of the treeview.
I will implement freeing the memory when an item is removed from the treeview, as you suggested.

Thank u.