使用CTreeCtrl在treectrl中使用项目检索LPARAM

时间:2016-09-01 06:34:23

标签: c++ mfc

我必须递归地将一个子键列表添加到Tree控件中的项目。 我正在使用InsertItem,如下所示。我附加了这个元素的路径,以便我可以在单击树控件时检索。我能够添加值但无法检索它。

void CMyDlg::FillTreeWithRegistryKeysEx(CString sPath, HTREEITEM hItem)
{
    CString sRegKey = sPath.Left(sPath.Find(_T("\\")));
    sPath = sPath.Mid((sPath.Find(_T("\\")) + 1));
    sPath = CleanRegistryKey(sPath);

    int nKeyCount;
    CString  sSubKey = _T("");
    HKEY handle = GetHkey(sRegKey);
    HTREEITEM hReItem = NULL;
    HKEY phkey;

    std::vector<CString> sSubFolders;

    if (RegOpenKeyEx(handle, sPath, 0, KEY_ALL_ACCESS, &phkey) == ERROR_SUCCESS)
        sSubFolders = EnumRegistryKey(phkey);

    nKeyCount = sSubFolders.size();

    for (int nIndex = 0; nIndex < nKeyCount; nIndex++)
    {
        sSubKey = sPath + _T("\\") +sSubFolders.at(nIndex);
        hReItem = m_cTreeCtrl.InsertItem(TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM | TVIF_STATE, sSubFolders.at(nIndex), 
                                        icoClosedFolder, icoOpenFolder, 0, 0, (LPARAM)(LPCTSTR)sSubKey, hItem, TVI_LAST);

        FillTreeWithRegistryKeys(handle, sSubKey, hReItem);
    }
    RegCloseKey(phkey);
}


While retrieving the string is always blank.

void CMyDlg::OnTvnSelchangedTree(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);

    LPARAM lp = pNMTreeView->itemNew.lParam;
    CString sKey = (LPCTSTR)lp;
}


what is going wrong? 

2 个答案:

答案 0 :(得分:2)

传递给InsertItem的应用程序定义的LPARAM是一个字符串对象,一旦函数完成就会超出范围,更不用说它被每个循环迭代替换为一个新的字符串。我认为这不会起作用。

然而,TreeView控件会分配自己的文本副本,因此您可以安全地使用本地缓冲区填充pszText成员,如您所见。

答案 1 :(得分:1)

正如前面的回答所指出的那样,你使用LPARAM指向一个在函数退出时被销毁的字符串。解决方案是将字符串存储在永久存储中。有很多方法可以做到这一点。一种选择是使用CStringArray成员数据:

class CMyDlg : public CDialog
{
    CStringArray m_strings;
    ...
};
  • 将注册表项存储在m_strings中。
  • 使用InsertItem添加树项目,返回HTREEITEM
  • 使用tree.SetItemData将树项与m_strings
  • 中的索引相匹配
  • 使用tree.GetItemData检索该索引

示例:

BOOL CMyDlg::OnInitDialog()
{
    CDialog::OnInitDialog();
    ...
    m_strings.RemoveAll();
    addKey(L"SOFTWARE\\Microsoft\\Internet Explorer", tree.GetRootItem());
    return TRUE;
}

void CMyDlg::addKey(CString path, HTREEITEM parent)
{
    CRegKey rg;
    if (ERROR_SUCCESS != rg.Open(HKEY_CURRENT_USER, path))
        return;
    for (int i = 0;; i++)
    {
        wchar_t buf[300];
        DWORD bufsize = 300;
        if (rg.EnumKey(i, buf, &bufsize) != ERROR_SUCCESS) break;
        HTREEITEM hitem = tree.InsertItem(buf, parent);
        CString subkey = path + L"\\" + buf;
        m_strings.Add(subkey);
        tree.SetItemData(hitem, m_strings.GetCount() - 1);
        addKey(subkey, hitem);
    }
}

void CMyDlg::OnTvnSelchangedTree(NMHDR *pNMHDR, LRESULT *pResult)
{
    HTREEITEM hitem = tree.GetSelectedItem();
    if (!hitem) return;
    int i = tree.GetItemData(hitem);
    if (i >= 0 && i < m_strings.GetCount())
        SetWindowText(m_strings[i]);
}