【发布时间】:2015-01-16 00:05:03
【问题描述】:
我的 win32 api 项目中有一个 TreeView。 我想用驱动器上的目录和文件填充 TreeView。使用一个函数我得到所有可用的驱动器,然后我用驱动器号作为参数调用这个函数:
bool ListDirectoryContents(const char *sDir)
{
WIN32_FIND_DATA fdFile;
HANDLE hFind = 0;
vector<string> FileNames;
char sPath[2048];
sprintf(sPath, "%s\\*.*", sDir);
if((hFind = FindFirstFile(sPath, &fdFile)) == INVALID_HANDLE_VALUE)
{
printf("Path not found: [%s]\n", sDir);
return false;
}
do
{
if(strcmp(fdFile.cFileName, ".") != 0 && strcmp(fdFile.cFileName, "..") != 0)
{
sprintf(sPath, "%s%s", sDir, fdFile.cFileName);
if((fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
if((fdFile.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) == 0)
{
// Directories
AddItemToTree(hwndTree, sPath, 2);
//FileNames.insert(sPath);
//ListDirectoryContents(sPath); // Recursion
}
}
else
{
if((fdFile.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) == 0)
{
//Files
//AddItemToTree(hwndTree, sPath, 2);
FileNames.push_back(sPath);
}
}
}
}
while(FindNextFile(hFind, &fdFile));
FindClose(hFind);
for(vector<string>::iterator FileName = FileNames.begin(); FileName != FileNames.end(); ++FileName)
{
AddItemToTree(hwndTree, (char*)FileName->c_str(), 2);
}
return true;
}
我用来首先列出目录和之后列出文件的 FileNames 向量。
AddItemToTree 函数:
HTREEITEM AddItemToTree(HWND hwndTree, char *text, int nLevel)
{
TVINSERTSTRUCT tvins;
static HTREEITEM hPrev = (HTREEITEM)TVI_FIRST;
static HTREEITEM hRootItem = NULL;
static HTREEITEM hPrevLev2Item = NULL;
//tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_PARAM;
tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIS_STATEIMAGEMASK;
tvi.iImage = AddIconToTree(hwndTree, text);
tvi.iSelectedImage = tvi.iImage;
tvi.pszText = GetFileNameFromPath(text);
tvins.hInsertAfter = hPrev;
tvins.item = tvi;
if(nLevel == 1)
{
tvins.hParent = TVI_ROOT;
}
else if(nLevel == 2)
{
tvins.hParent = hRootItem;
}
else
{
TVITEM tviSetup;
tviSetup.hItem = hPrev;
tviSetup.mask = TVIF_PARAM;
TVITEM * tviLocal = &tviSetup;
TreeView_GetItem(hwndTree, tviLocal);
if(nLevel > tviLocal->lParam)
{
tvins.hParent = hPrev;
}
else
{
HTREEITEM hPrevLocal = TreeView_GetParent(hwndTree, hPrev);
tviLocal->hItem = hPrevLocal;
TreeView_GetItem(hwndTree, tviLocal);
for(int i = nLevel; i <= tviLocal->lParam;)
{
HTREEITEM hPrevLocalTemp = TreeView_GetParent(hwndTree, hPrevLocal);
hPrevLocal = hPrevLocalTemp;
tviLocal->hItem = hPrevLocal;
TreeView_GetItem(hwndTree, tviLocal);
}
tviLocal->mask = TVIF_TEXT;
TreeView_GetItem(hwndTree, tviLocal);
tvins.hParent = hPrevLocal;
}
}
hPrev = (HTREEITEM)SendMessage(hwndTree, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins);
if(hPrev == 0)
{
return false;
}
if(nLevel == 1)
{
hRootItem = hPrev;
}
return hPrev;
}
问题是,如果我在 ListDirectoryContents 函数中使用递归调用,则需要很长时间才能填充 TreeView 中的所有目录和文件。
所以我认为它可以像这样工作:
- 首先我要添加根目录(所有驱动器,例如 C:\、D:\...)
- 我会找到驱动器中的所有子目录和文件,并将它们添加为驱动器根目录的子目录。
- 然后如果我展开根节点,它会找到之前找到的驱动器子目录的所有子目录,依此类推...
但是问题来了,我怎样才能在某个地方插入一些项目?我的意思是AddItemToTree 函数中的第三个参数是什么?
有没有更简单的方法来用目录填充 TreeView? 提前谢谢大家!
【问题讨论】:
标签: c++ winapi treeview directory subdirectory