//插入树的节点 hPrev = GetTreeCtrl().InsertItem(&tvins); } lpMalloc->Free(lpifqThisItem); lpifqThisItem=0; } lpMalloc->Free(lpi); return; } } else return; Done: if (lpe) lpe->Release(); if (lpi && lpMalloc) lpMalloc->Free(lpi); if (lpifqThisItem && lpMalloc) lpMalloc->Free(lpifqThisItem); if (lpMalloc) lpMalloc->Release(); }
void CLeftView::FillTreeView(LPSHELLFOLDER lpsf,LPITEMIDLIST lpifq,HTREEITEM hParent) { TV_ITEM tvi; // TreeView Item. TV_INSERTSTRUCT tvins; // TreeView Insert Struct. HTREEITEM hPrev = NULL; HTREEITEM hItemEdrive=0; LPSHELLFOLDER lpsf2=NULL; LPENUMIDLIST lpe=NULL; LPITEMIDLIST lpi=NULL, lpiTemp=NULL, lpifqThisItem=NULL; LPTVITEMDATA lptvid=NULL; LPMALLOC lpMalloc=NULL; ULONG ulFetched; UINT uCount=0; HRESULT hr; char szBuff[256]; HWND hwnd=::GetParent(m_hWnd); CTreeCtrl &Tree=GetTreeCtrl(); // Allocate a shell memory object. hr=::SHGetMalloc(&lpMalloc); if (FAILED(hr)) return; if (SUCCEEDED(hr)) { // Get the IEnumIDList object for the given folder. hr=lpsf->EnumObjects(hwnd, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &lpe); if (SUCCEEDED(hr)) { // Enumerate throught the list of folder and non-folder objects. while (S_OK==lpe->Next(1, &lpi, &ulFetched)) { //Create a fully qualified path to the current item //The SH* shell api's take a fully qualified path pidl, //(see GetIcon above where I call SHGetFileInfo) whereas the //interface methods take a relative path pidl. ULONG ulAttrs = SFGAO_HASSUBFOLDER | SFGAO_FOLDER; // Determine what type of object we have. lpsf->GetAttributesOf(1, (const struct _ITEMIDLIST **)&lpi, &ulAttrs); if (ulAttrs & (SFGAO_HASSUBFOLDER | SFGAO_FOLDER)) { //We need this next if statement so that we don't add things like //the MSN to our tree. MSN is not a folder, but according to the //shell it has subfolders. if (ulAttrs & SFGAO_FOLDER) { tvi.mask= TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; if (ulAttrs & SFGAO_HASSUBFOLDER) { //This item has sub-folders, so let's put the + in the TreeView. //The first time the user clicks on the item, we'll populate the //sub-folders. tvi.cChildren=1; tvi.mask |= TVIF_CHILDREN; }
//OK, let's get some memory for our ITEMDATA struct lptvid = (LPTVITEMDATA)lpMalloc->Alloc(sizeof(TVITEMDATA)); if (!lptvid) goto Done; // Error - could not allocate memory.
//Now get the friendly name that we'll put in the treeview. if (!GetName(lpsf, lpi, SHGDN_NORMAL, szBuff)) goto Done; // Error - could not get friendly name. tvi.pszText = szBuff; tvi.cchTextMax = MAX_PATH;
lpifqThisItem=ConcatPidls(lpifq, lpi);
//Now, make a copy of the ITEMIDLIST lptvid->lpi=CopyITEMID(lpMalloc, lpi);
GetNormalAndSelectedIcons(lpifqThisItem, &tvi);
lptvid->lpsfParent=lpsf; //Store the parent folders SF lpsf->AddRef(); lptvid->lpifq=ConcatPidls(lpifq, lpi);
tvi.lParam = (LPARAM)lptvid;
// Populate the TreeVeiw Insert Struct // The item is the one filled above. // Insert it after the last item inserted at this level. // And indicate this is a root entry. tvins.item = tvi; tvins.hInsertAfter = hPrev; tvins.hParent = hParent;
// Add the item to the tree hPrev = Tree.InsertItem(&tvins); if(strstr(szBuff,"E:") && !strchr(szBuff,'\\')) { hItemEdrive=hPrev; } } // Free this items task allocator. lpMalloc->Free(lpifqThisItem); lpifqThisItem=0; } lpMalloc->Free(lpi); //Free the pidl that the shell gave us. lpi=0; } } } else return;Done:
if (lpe) lpe->Release(); //The following 2 if statements will only be TRUE if we got here on an //error condition from the "goto" statement. Otherwise, we free this memory //at the end of the while loop above. if (lpi && lpMalloc) lpMalloc->Free(lpi); if (lpifqThisItem && lpMalloc) lpMalloc->Free(lpifqThisItem); if (lpMalloc) lpMalloc->Release(); } 注意:if(strstr(szBuff,"E:") && !strchr(szBuff,'\\')) { hItemEdrive=hPrev;// 这个就是要返回的 }
返回 E:盘 的 hItemEdrive 即:
HTREEITEM hItemEdrive=FillTreeView(lpsf, NULL, hParent);
GetTreeCtrl().Expand (hItemEdrive,TVE_EXPAND);//展开“E:”节点
至于 hItemEdrive 就是 name=“E:” 的item
void DirTreeView::FillTreeView(LPSHELLFOLDER lpsf, LPITEMIDLIST lpifq, HTREEITEM hParent)
{
TV_ITEM tvi; // TreeView Item.
TV_INSERTSTRUCT tvins; // TreeView Insert Struct.
HTREEITEM hPrev = NULL; // Previous Item Added.//
LPENUMIDLIST lpe=NULL;
LPITEMIDLIST lpi=NULL, lpiTemp=NULL, lpifqThisItem=NULL;
LPTVITEMDATA lptvid=NULL;
LPMALLOC lpMalloc=NULL;
ULONG ulFetched;
HRESULT hr;
char szBuff[256];
HWND hwnd=::GetParent(m_hWnd);
//分配一个shell内存对象
hr=::SHGetMalloc(&lpMalloc);
if (FAILED(hr))
return; //如果成功地分配了空间
if (SUCCEEDED(hr))
{
hr=lpsf->EnumObjects(hwnd, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &lpe);
if (SUCCEEDED(hr))
{
//枚举出其中的文件夹
while (S_OK==lpe->Next(1, &lpi, &ulFetched))
{
ULONG ulAttrs = SFGAO_HASSUBFOLDER | SFGAO_FOLDER;
lpsf->GetAttributesOf(1, (LPCITEMIDLIST*) &lpi, &ulAttrs);
if (ulAttrs & (SFGAO_HASSUBFOLDER | SFGAO_FOLDER))
{
tvi.mask= TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
//如果有子文件夹
if (ulAttrs & SFGAO_HASSUBFOLDER)
{
tvi.cChildren=1;
tvi.mask |= TVIF_CHILDREN;
}
lptvid = (LPTVITEMDATA)lpMalloc->Alloc(sizeof(TVITEMDATA)); if (!lptvid)
goto Done;
if (!GetName(lpsf, lpi, SHGDN_NORMAL, szBuff))
goto Done;
//所插入项的名称
tvi.pszText = szBuff; lpifqThisItem=ConcatPidls(lpifq, lpi);
lptvid->lpi=(LPITEMIDLIST)lpMalloc->
Alloc(lpi->mkid.cb+sizeof(lpi->mkid.cb)); CopyMemory((PVOID)lptvid->lpi, (CONST VOID *)lpi,
lpi->mkid.cb+sizeof(lpi->mkid.cb));
GetNormalAndSelectedIcons(lpifqThisItem, &tvi);
lptvid->lpsfParent=lpsf;
lptvid->lpifq=ConcatPidls(lpifq, lpi); tvi.lParam = (LPARAM)lptvid;
tvins.item = tvi;
tvins.hInsertAfter = hPrev;
tvins.hParent = hParent;
//插入树的节点
hPrev = GetTreeCtrl().InsertItem(&tvins);
}
lpMalloc->Free(lpifqThisItem);
lpifqThisItem=0;
}
lpMalloc->Free(lpi);
return;
}
}
else
return;
Done:
if (lpe)
lpe->Release();
if (lpi && lpMalloc)
lpMalloc->Free(lpi);
if (lpifqThisItem && lpMalloc)
lpMalloc->Free(lpifqThisItem);
if (lpMalloc)
lpMalloc->Release();
}
void CLeftView::FillTreeView(LPSHELLFOLDER lpsf,LPITEMIDLIST lpifq,HTREEITEM hParent)
{
TV_ITEM tvi; // TreeView Item.
TV_INSERTSTRUCT tvins; // TreeView Insert Struct.
HTREEITEM hPrev = NULL;
HTREEITEM hItemEdrive=0;
LPSHELLFOLDER lpsf2=NULL;
LPENUMIDLIST lpe=NULL;
LPITEMIDLIST lpi=NULL, lpiTemp=NULL, lpifqThisItem=NULL;
LPTVITEMDATA lptvid=NULL;
LPMALLOC lpMalloc=NULL;
ULONG ulFetched;
UINT uCount=0;
HRESULT hr;
char szBuff[256];
HWND hwnd=::GetParent(m_hWnd);
CTreeCtrl &Tree=GetTreeCtrl(); // Allocate a shell memory object.
hr=::SHGetMalloc(&lpMalloc);
if (FAILED(hr))
return; if (SUCCEEDED(hr))
{
// Get the IEnumIDList object for the given folder.
hr=lpsf->EnumObjects(hwnd, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &lpe); if (SUCCEEDED(hr))
{
// Enumerate throught the list of folder and non-folder objects.
while (S_OK==lpe->Next(1, &lpi, &ulFetched))
{
//Create a fully qualified path to the current item
//The SH* shell api's take a fully qualified path pidl,
//(see GetIcon above where I call SHGetFileInfo) whereas the
//interface methods take a relative path pidl.
ULONG ulAttrs = SFGAO_HASSUBFOLDER | SFGAO_FOLDER; // Determine what type of object we have.
lpsf->GetAttributesOf(1, (const struct _ITEMIDLIST **)&lpi, &ulAttrs); if (ulAttrs & (SFGAO_HASSUBFOLDER | SFGAO_FOLDER))
{
//We need this next if statement so that we don't add things like
//the MSN to our tree. MSN is not a folder, but according to the
//shell it has subfolders.
if (ulAttrs & SFGAO_FOLDER)
{
tvi.mask= TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; if (ulAttrs & SFGAO_HASSUBFOLDER)
{
//This item has sub-folders, so let's put the + in the TreeView.
//The first time the user clicks on the item, we'll populate the
//sub-folders.
tvi.cChildren=1;
tvi.mask |= TVIF_CHILDREN;
}
//OK, let's get some memory for our ITEMDATA struct
lptvid = (LPTVITEMDATA)lpMalloc->Alloc(sizeof(TVITEMDATA));
if (!lptvid)
goto Done; // Error - could not allocate memory.
//Now get the friendly name that we'll put in the treeview.
if (!GetName(lpsf, lpi, SHGDN_NORMAL, szBuff))
goto Done; // Error - could not get friendly name.
tvi.pszText = szBuff;
tvi.cchTextMax = MAX_PATH;
lpifqThisItem=ConcatPidls(lpifq, lpi);
//Now, make a copy of the ITEMIDLIST
lptvid->lpi=CopyITEMID(lpMalloc, lpi);
GetNormalAndSelectedIcons(lpifqThisItem, &tvi);
lptvid->lpsfParent=lpsf; //Store the parent folders SF
lpsf->AddRef(); lptvid->lpifq=ConcatPidls(lpifq, lpi);
tvi.lParam = (LPARAM)lptvid;
// Populate the TreeVeiw Insert Struct
// The item is the one filled above.
// Insert it after the last item inserted at this level.
// And indicate this is a root entry.
tvins.item = tvi;
tvins.hInsertAfter = hPrev;
tvins.hParent = hParent;
// Add the item to the tree
hPrev = Tree.InsertItem(&tvins);
if(strstr(szBuff,"E:") && !strchr(szBuff,'\\'))
{
hItemEdrive=hPrev;
}
}
// Free this items task allocator.
lpMalloc->Free(lpifqThisItem);
lpifqThisItem=0;
} lpMalloc->Free(lpi); //Free the pidl that the shell gave us.
lpi=0;
}
} }
else
return;Done:
if (lpe)
lpe->Release(); //The following 2 if statements will only be TRUE if we got here on an
//error condition from the "goto" statement. Otherwise, we free this memory
//at the end of the while loop above.
if (lpi && lpMalloc)
lpMalloc->Free(lpi);
if (lpifqThisItem && lpMalloc)
lpMalloc->Free(lpifqThisItem); if (lpMalloc)
lpMalloc->Release();
}
注意:if(strstr(szBuff,"E:") && !strchr(szBuff,'\\'))
{
hItemEdrive=hPrev;// 这个就是要返回的
}
那就要 展开 “计算机”后才能 看到 E:看看 你的 Expend 代码。
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; LPTVITEMDATA lptvid;
HRESULT hr;
LPSHELLFOLDER lpsf=NULL;
if ((pNMTreeView->itemNew.state & TVIS_EXPANDEDONCE))
return;
lptvid=(LPTVITEMDATA)pNMTreeView->itemNew.lParam;
if (lptvid)
{
hr=lptvid->lpsfParent->BindToObject(lptvid->lpi,
0, IID_IShellFolder,(LPVOID *)&lpsf);
if (SUCCEEDED(hr))
{
FillTreeView(lpsf,lptvid->lpifq,pNMTreeView->itemNew.hItem);
}
}
*pResult = 0;
}
求解释!
hParent = GetTreeCtrl().InsertItem(&tvis);//插入根节点
h_计算机=FillTreeView(lpsf, NULL, hParent);
GetTreeCtrl().Expand (hParent,TVE_EXPAND);//展开“桌面”节点
在 FillTreeView 里 先查 ‘计算机’即:
if(strcmp(szBuff,"计算机")==0)
{
h_计算机=hPrev;
}
然后再展开 ‘计算机’
叫你把 void FillTreeView() 改 HTREEITEM FillTreeView() 你没改。
hItemEdrive=hPrev;// 这个就是要返回的
即 return hItemEdrive;
我给你写了一段:放在:
lpsf->Release ();
}
后,FillTreeView 就不用改了(改 回去)。
CTreeCtrl &Tree=GetTreeCtrl();
#if 1
HTREEITEM hChild=Tree.GetChildItem(hParent);//hParent=桌面
CString str=Tree.GetItemText(hChild);
while(str != "计算机")
{// 查找 '计算机'
hChild=Tree.GetNextSiblingItem(hChild);
str=Tree.GetItemText(hChild);
afxDump << str << "\n";
}
// 找到 “计算机”, 展开他
Tree.Expand(hChild,TVE_EXPAND);
// 再找 ’E:"
HTREEITEM hEdrive=Tree.GetChildItem(hChild);// hChild="计算机"
str=Tree.GetItemText(hEdrive);
while(str.Find("E:") < 0)
{// 查找 'E:'
hEdrive=Tree.GetNextSiblingItem(hEdrive);
str=Tree.GetItemText(hEdrive);
afxDump << str << "\n";
}
// 找到 “E:”
Tree.Expand(hEdrive,TVE_EXPAND);
Tree.Select(hEdrive,TVGN_FIRSTVISIBLE);
#endif