引言:
主要是说TreeCtrl的运用 ,展现系统文件列表
完成图如下
主要步骤是
第一步:在界面中拖入树控件并完成设置
第二步: 设置初始出
构造函数调用该方法。
树控件每个项目关联数据 一个是文件路径,一个是当前是否展开。
//树初始化
void CTreeDemoDlg::TreeInit()
{
HTREEITEM hroot = m_Tree.InsertItem(L"我的电脑");
//获取逻辑盘字符
wchar_t driverBuffer[1024] = { 0 }; //逻辑盘的缓存
GetLogicalDriveStrings(1024,driverBuffer); //获得逻辑盘的字符
//取出来逻辑盘字符
wchar_t* tempstr = driverBuffer;
int length = wcslen(tempstr); //获得每次缓存字符的长度
while (length>0)
{
HTREEITEM htree = m_Tree.InsertItem(tempstr,hroot); //添加逻辑盘
//给树关联数据
TreeItemData* ItemData = new TreeItemData;
wcscpy_s(ItemData->filePath, tempstr);
ItemData->ISExpand = false;
m_Tree.SetItemData(htree,(DWORD_PTR)ItemData);
ExpandDirAndInsertTree(tempstr,htree); //展开添加
tempstr += length + 1; //移动位置
length = wcslen(tempstr); //重新获得长度
}
m_Tree.Expand(hroot,TVE_EXPAND); //树展开 hroot节点
}
第三步 展开文件夹并插入到树节点中
//展开数据并且插入数中 根据路径和父节点
void CTreeDemoDlg::ExpandDirAndInsertTree(CString path, HTREEITEM hparentRoot)
{
//文件查找 CFileFind
CString findPath = path += L"\\*.*"; //文件路径
CFileFind finder; //文件查找器
BOOL isfind = finder.FindFile(findPath); //是否可以查到文件
//如果查到了
while (isfind)
{
isfind = finder.FindNextFile(); //是否有下个文件
//文件过滤
//将节点插入到父节点下
if (finder.IsDots() || finder.IsHidden() || finder.IsSystem() || !finder.IsDirectory())
continue;
//正常的文件
//获得图标索引
int imageIndex = GetFileIconIndex(finder.GetFilePath());
//HTREEITEM hitem = m_Tree.InsertItem(finder.GetFileName(), hparentRoot);
HTREEITEM hitem = m_Tree.InsertItem(finder.GetFileName(), imageIndex, imageIndex ,hparentRoot);
//给树节点,关联数据
TreeItemData* pItemData = new TreeItemData;
wcscpy_s(pItemData->filePath, finder.GetFilePath().GetBuffer());
pItemData->ISExpand = false;
m_Tree.SetItemData(hitem, (DWORD_PTR)pItemData);
}
}
主要是应用CFileFind 文件查找的类 ,其方法如下:
第四步 展开文件夹并插入到树节点中
上面只是展开了一层并不能展开下一层。那就要用到,展开树的事件。类似有些博文写的递归,他们只不过是一次 展开,但是会太好事件。下面是判断该展开项,得到其子类,并添加到树中。
//树展开事件
void CTreeDemoDlg::OnTvnItemexpandedTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
*pResult = 0;
//获取当前展开的节点
TVITEMW hItem = pNMTreeView->itemNew;
//获得关联的数据
TreeItemData* itemData = (TreeItemData*)m_Tree.GetItemData(hItem.hItem);
if (itemData)
{
if (itemData->ISExpand) return;
itemData->ISExpand = true; //标明,该节点已被展开过
//获取节点下的所有孩子节点
if (m_Tree.ItemHasChildren(hItem.hItem))
{
HTREEITEM hNextItem;
HTREEITEM hChildItem = m_Tree.GetChildItem(hItem.hItem);
while (hChildItem != NULL)
{
//获取了孩子节点,尝试去展开孩子节点
TreeItemData* itemData = (TreeItemData*)m_Tree.GetItemData(hChildItem);
if (itemData)
{
ExpandDirAndInsertTree(itemData->filePath, hChildItem);
}
//获取下一个孩子节点
hNextItem = m_Tree.GetNextItem(hChildItem, TVGN_NEXT);
hChildItem = hNextItem;
}
}
}
}
第五步、添加系统的图表
首先在构造函数中,添加图标列表的设置
//给树关联图标列表 GetSystemMetrics 获取系统固定配置项
m_treeImageList.Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32
, 60, 20);
m_Tree.SetImageList(&m_treeImageList,TVSIL_NORMAL);
//获得图标的下标
int CTreeDemoDlg::GetFileIconIndex(CString filePath)
{
SHFILEINFO shfileInfo; //文件信息结构体
SHGetFileInfo(filePath, 0, &shfileInfo, sizeof(SHFILEINFO), SHGFI_ICON | SHGFI_SMALLICON);
int index = m_treeImageList.Add(shfileInfo.hIcon);
::DestroyIcon(shfileInfo.hIcon);
return index;
}