To create your root item:
TV_INSERTSTRUCT tvInsertStruct;
tvInsertStruct.hParent=NULL;
tvInsertStruct.hInsertAfter=TVI_LAST;
tvInsertStruct.item.pszText=_T("ROOT");
tvInsertStruct.item.mask=TVIF_TEXT;
const HTREEITEM hRootItem= m_tree.InsertItem(&tvInsertStruct);
To insert sub-items hanging on the root:
for(int i=0; i<SomeCollection.GetCount(); i++)
{
const CElement* pElement= SomeCollection.GetAt(i);
ASSERT(pElement);
CString Name = pElement->GetName();
tvInsertStruct.hParent = hRootItem;
tvInsertStruct.hInsertAfter = TVI_LAST;
const LPTSTR cutJobNameTemp = Name.GetBuffer(0);
tvInsertStruct.item.pszText = cutJobNameTemp;
tvInsertStruct.item.mask = TVIF_TEXT;
HTREEITEM hItem = m_tree.InsertItem(&tvInsertStruct);
ASSERT(hItem);
tree.SetItemData(hItem, (DWORD_PTR)pElement);
}
The code line that answers your question is SetItemData
: with it you can directly associate a tree node handle with a memory address.111
To see all nodes open just add:
ExpandTreeCtrl(m_tree);
NOTE: I know the following is not the cleanest approach to handle the selection of an item on the tree, so I replaced it with a more proper way that also handles keyboard
To get an entry point for your app to respond to Clicks on the tree, you can add in its parent dialog (or control)'s message map
ON_NOTIFY(NM_CLICK, IDC_TREE, OnNMClickTree)
and implement its handling function
void CMyDialog::OnNMClickTree(NMHDR *pNMHDR, LRESULT *pResult)
{
UINT flags;
CPoint point;
GetCursorPos(&point);
*pResult= 0;
CTreeCtrl* pTree= dynamic_cast <CTreeCtrl*> (this->GetDlgItem(pNMHDR->idFrom));
if(pTree)
{
pTree->ScreenToClient(&point);
HTREEITEM hItem = pTree->HitTest(point, &flags);
if( (flags & TVHT_ONITEMINDENT) || (flags & TVHT_ONITEMBUTTON) ) //do nothing when clicking on the [+]expand / [-]collapse of the tree
return;
if(!hItem)
return;
// If you want to get item text:
CString sText= pTree->GetItemText(hItem);
//To get your element:
CElement* pElement = (CElement*)pTree->GetItemData(hItem);
}
}
To get an entry point for your app to respond to the change of the currently selected item on the tree, you can add in its parent dialog (or control)'s message map
ON_NOTIFY(TVN_SELCHANGED,IDC_TREE, OnTreeCtrlSelChanged)
and implement its handling function
void CMyDialog::OnTreeCtrlSelChanged(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*) pNMHDR;
HTREEITEM hItem = pNMTreeView->itemNew.hItem;
if(!hItem)
return;
// If you want to get item text:
CString sText= m_tree.GetItemText(hItem);
//To get your element:
CElement* pElement = (CElement*)m_tree.GetItemData(hItem);
}
The line that is now dereferencing to access the CElement
data associated with the tree node is GetItemData
. Then do what you intend with the pointer you got.