用驱动器上的目录和文件填充树视图
Fill TreeView with directories and files on drives
我的win32 api项目中有一个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;
}
文件名的向量我用来先列出目录,然后再列出文件。
函数 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
函数中的第三个参数是什么?
有没有更简单的方法可以用目录填充树视图?提前谢谢大家!
通常,执行此操作的方式根本不是使用nLevel
参数,而是使用hItemParent
参数。
也就是说,当您调用AddItemToTree
时,您将向函数传递与父项对应的HTREEITEM
。当您插入新项目时,这将馈送到tvins.hParent
成员。
所以你目前有nLevel == 1
的地方,你会有AddItemToTree(hwndTree, "text", TVI_ROOT)
.
若要在子文件夹展开时填充子文件夹,需要一个监视TVN_ITEMEXPANDED
通知的WM_NOTIFY
处理程序。
当您收到此消息时,它会告诉您展开了哪个项目 - 这是您要传递给AddItemToTree
的参数。
case WM_NOTIFY:
if (((LPNMHDR)lParam)->code == TVN_ITEMEXPANDED)
{
// work out the path to read, and then ...
AddItemToTree(hwndTree, <path>, ((LPNMTREEVIEW)lParam)->itemNew.hItem);
}
相关文章:
- 用二进制文件填充结构
- 如何使用文件填充结构(下面附有的代码)?
- 用空格填充 2D 数组(从文件输入)
- 如何从文件中填充类中的结构
- 如何创建一个新的二进制文件并用常量值填充它?
- 如何将目录中的文件属性填充到结构向量中?
- 如何使用文件填充数组并将其与用户输入C 进行比较
- 有没有办法在不使用 set_buff() 的情况下从文件中读取并填充消息增益
- 使用.txt文件填充 STL 列表不起作用
- 从文件填充 2D 数组
- 在 Windows 上从文件填充多维矩阵很慢
- 如何创建一个ifstream对象的数组,以及如何使用编号的文本文件填充该数组
- 从文件填充对象的向量
- 从顺序文件填充二维数组
- 用驱动器上的目录和文件填充树视图
- 在检查现有元素时,从文件填充并行数组时出现问题
- 用于从文件填充类的词法分析器/解析器的语法规则
- 冒泡排序在结构化列表中,由csv文件填充
- 对通过外部文件填充的数组进行不正确的排序和/或搜索
- 从文件填充结构