作业的内容是编写一个基于对话框的应用程序,可以打开一个文件并浏览该文件下面的所有文件(树型控件)显示.
文件的代码如下:
1. 利用shell打开系统的文件资源代码
BROWSEINFO bi;
bi.hwndOwner=NULL;
bi.pidlRoot=NULL;
bi.pszDisplayName=NULL;
bi.lpszTitle=NULL;
bi.ulFlags=0;
bi.lpfn =NULL;
bi.iImage =0;
LPCITEMIDLIST pidl=SHBrowseForFolder(&bi);
if(!pidl)
return;
char FilePath[MAX_PATH];
SHGetPathFromIDList(pidl,FilePath);
m_Path=FilePath;
UpdateData(FALSE);
该文件名字被保存在 m_Path中,接着树型控件的文件遍历,可以采用msdn中的代码稍微改写即可.
void CMmDlg::Recurse(CString FilePath,CString FileName ,HTREEITEM hParent)
{
TV_ITEM tvItem;
TV_INSERTSTRUCT tvInsert;
tvItem.mask=TVIF_TEXT|TVIF_PARAM;
tvItem.pszText=(LPSTR)(LPCSTR)FileName;
tvInsert.hParent=hParent;
tvInsert.hInsertAfter=TVI_LAST;
tvInsert.item=tvItem;
HTREEITEM hNewParent=m_FileTree.InsertItem(&tvInsert);
CFileFind finder;
CString strWildcard(FilePath);
strWildcard+=_T(\"\\\\*.*\");
BOOL bWorking=finder.FindFile(strWildcard);
while (bWorking)
{
bWorking=finder.FindNextFile();
if (finder.IsDots())
{
continue;
}
if (finder.IsDirectory())
{
CString str = finder.GetFilePath();
CString theFileName = finder.GetFileName();
Recurse(str,theFileName,hNewParent);
}
else
{
CString str=finder.GetFileName();
TV_ITEM FiletvItem;
TV_INSERTSTRUCT FiletvInsert;
FiletvItem.mask=TVIF_TEXT|TVIF_PARAM;
FiletvItem.pszText=(LPSTR)(LPCSTR)str;
FiletvInsert.hParent=hNewParent;
FiletvInsert.hInsertAfter=TVI_LAST;
FiletvInsert.item=FiletvItem;
m_FileTree.InsertItem(&FiletvInsert);
}
}
finder.Close();
}
主消息代码,调用
m_FileTree.DeleteAllItems();
CString AdjustPath;
if(m_Path.GetLength()==3)
{
AdjustPath=m_Path.Left(2);
}
else
{
AdjustPath=m_Path;
}
Recurse(AdjustPath,AdjustPath,TVI_ROOT);
由此我们即可完成该功能.但是由于是递归,所以程序的性能将不怎么好,尤其是当搜索的目录比较大的时候,很有可能耗尽系统的堆寨,这里我们还得好好思考思考!因此可以将递归写成堆寨,这样效率能够提高,但是可读性就没有递归那么显而易见了