15,979
社区成员
发帖
与我相关
我的任务
分享
void DirTreeView::OnInitialUpdate()
{
CTreeView::OnInitialUpdate();
CTreeCtrl &Tree=GetTreeCtrl();
LPSHELLFOLDER lpsf=NULL; //IShellFolder接口
LPITEMIDLIST lpi=NULL; //ITERMIDLSIT结构体指针
HRESULT hr;
TV_ITEM tvi;
CImageList m_Image;//记录的是与树型控件关联的图像列表
SHFILEINFO sfi;//存放文件信息的结构
HIMAGELIST sys_small_icon;
sys_small_icon = (HIMAGELIST)SHGetFileInfo(NULL,0,&sfi,sizeof(sfi),
SHGFI_SYSICONINDEX|SHGFI_SMALLICON);
m_Image.Attach(sys_small_icon);
Tree.SetImageList(&m_Image,TVSIL_NORMAL);//将系统图像列表设为树控件的图象列表
m_Image.Detach ();
// 得到指向“桌面”的指针
hr=SHGetDesktopFolder(&lpsf);
SHGetSpecialFolderLocation(NULL,CSIDL_DESKTOP,&lpi);
if (SUCCEEDED(hr))
{
Tree.DeleteAllItems();
char szBuff[MAX_PATH];//存放显示名称的缓冲区
TV_INSERTSTRUCT tvis; //向树型控件中插入节点时使用的结构
tvi.mask = TVIF_TEXT | TVIF_IMAGE |
TVIF_SELECTEDIMAGE | TVIF_CHILDREN ; //设置要插入的树节点信息
if(GetName(lpsf,lpi,SHGDN_NORMAL,szBuff)==FALSE)
return;
tvi.pszText = szBuff;//设置显示名称
GetNormalAndSelectedIcons(lpi, &tvi);
tvis.item = tvi;
tvis.hParent = TVI_ROOT;
hParent = GetTreeCtrl().InsertItem(&tvis);//插入根节点
// HTREEITEM hNext = GetTreeCtrl().GetNextItem(hParent,TVGN_NEXTVISIBLE);
// HTREEITEM hChild = GetTreeCtrl().GetNextItem(hNext,TVGN_NEXT);
// HTREEITEM hNext1 = GetTreeCtrl().GetNextItem(hNext1,TVGN_NEXT);
FillTreeView(lpsf, NULL, hParent);
GetTreeCtrl().Expand (hParent,TVE_EXPAND);//展开“桌面”节点
lpsf->Release ();
}
}
void DirTreeView::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult)
{
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;
}
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;// 这个就是要返回的
}
//树控件节点展开时,加入各个子节点的名称及图标
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();
}