将项目添加到 CTreectrl C++

Posted

技术标签:

【中文标题】将项目添加到 CTreectrl C++【英文标题】:Adding item to CTreectrl C++ 【发布时间】:2016-08-25 11:27:15 【问题描述】:

我需要将项目从 VB 转换为 C++。

VB中有Tree控件。 用于将项目添加到树控件“添加”方法(节点集合) 已使用,其中包含一个名为“key”的参数,并且可以在单击该特定项目时检索相同的键。

在使用 TVITEM 或 TVITEMEX 结构的 CTreeCtrl InsertItem 函数中是否有这样的规定,我们可以为树控件的每个项目添加一个键并在单击它时将其取回?

【问题讨论】:

TVITEM LPARAM to store string的可能重复 谢谢。检索时我该怎么做。当单击一个项目并且我使用 OnTvnSelchangedTree() 事件来获取数据时,我需要它。我试着做 LPARAM lp = pNMTreeView->itemNew.lParam;但它不会返回我存储的内容。 CTreeCtrl::GetSelectedItem() 为您提供当前选定的项目。但是您问的是“将项目添加到 CTreectrl” 【参考方案1】:

创建根项目:

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);

插入挂在根上的子项:

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);

回答您问题的代码行是SetItemData:您可以使用它直接将树节点句柄与内存地址相关联。111

要查看所有打开的节点,只需添加:

ExpandTreeCtrl(m_tree);

注意: 我知道以下不是处理树上项目选择的最干净的方法,所以我用一种更合适的方法替换了它,也可以处理键盘 em>

要为您的应用获取响应树上点击的入口点,您可以在其父对话框(或控件)的消息映射中添加

ON_NOTIFY(NM_CLICK, IDC_TREE, OnNMClickTree) 

并实现其处理功能

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);



要让您的应用程序响应树上当前选定项的更改的入口点,您可以在其父对话框(或控件)的消息映射中添加

ON_NOTIFY(TVN_SELCHANGED,IDC_TREE, OnTreeCtrlSelChanged)

并实现其处理功能

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);

现在取消引用以访问与树节点关联的CElement 数据的行是GetItemData。然后用你得到的指针做你想做的事。

【讨论】:

如果用户使用键盘更改项目,这将不起作用。只需使用ON_NOTIFY(TVN_SELCHANGED, IDC_TREE1, OnTreeSelChanged)... @BarmakShemirani:我刚刚支持了你的评论,我会根据情况改变我的答案。 我能知道 CElement 是什么吗?? CElement 是你实现的一个类,代表你在每个树节点的类型。或者您想添加更简单类型的节点,如int,或其他内置类型,如CString

以上是关于将项目添加到 CTreectrl C++的主要内容,如果未能解决你的问题,请参考以下文章

如何在 CTreeCtrl 的背景中添加水印或 png 或位图?

CTreeCtrl - 获取项目位置

调用 SelectItem 函数时如何强制 CTreeCtrl 不滚动到项目?

MFC:使用CTreeCtrl和CToolbar创建一个类(CWnd?)

如何将 ctree 节点变成向量?

将 ctree 输出转换为 JSON 格式(用于 D3 树布局)