我的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中的所有目录和文件需要很长时间。
所以我认为它可以这样工作:
但问题来了,如何在某个地方插入一些物品?我的意思是AddItemToTree
函数中的第三个参数是什么?
有没有更简单的方法用目录填充TreeView? 谢谢大家!
答案 0 :(得分:1)
通常,您执行此操作的方式根本不是nLevel
参数,而是hItemParent
参数。
也就是说,当您致电AddItemToTree
时,您将传递与父项对应的HTREEITEM
函数。当您插入新项目时,这会被送到tvins.hParent
成员。
因此,您目前拥有nLevel == 1
,{+ 1}}。
要在展开子文件夹时填充子文件夹,您需要一个AddItemToTree(hwndTree, "text", TVI_ROOT)
处理程序来监视TVN_ITEMEXPANDED
通知。
当您收到此消息时,它会告诉您哪个项目已展开 - 这是您传递给WM_NOTIFY
的参数。
AddItemToTree