创建文件夹浏览器
Posted skdev
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了创建文件夹浏览器相关的知识,希望对你有一定的参考价值。
一 实例
二 思路
1 GetLocalDeviceString 可获得当前电脑的盘符,即c:d:e:,盘符之间以’/0’相隔。
2 GetFileAttributes 用来判断是否文件夹。
dwFileAttributes==FILE_ATTRIBUTE_DIRECTORY&&strcmp(cFileName,".")!=0&&strcmp(cFileName,"..")!=0 即表示该文件为文件夹。
3 FindFirstFile 查找指定路径的第一个文件。
4 FindNextFile 查找下一个文件。
5 hTreeItem=(HTREEITEM)SendMessage(hTree,TVM_GETNEXTITEM,TVGN_PARENT , (LPARAM)tvi.hItem); 获取当前结点的父结点,用以获得所选择结点的路径。
6 hTreeItem=(HTREEITEM)SendMessage(hwTree,TVM_GETNEXTITEM,TVGN_CHILD , (LPARAM)hTItem); 获取当前结点目录的子文件,用以获取第一个子目录。
7 hTreeItem=(HTREEITEM)SendMessage(hwTree,TVM_GETNEXTITEM,TVGN_NEXT , (LPARAM)hTItem); 获取当前结点的下一个结点,用以列出子目录。
8 思路描述
由于遍历电脑的所有文件夹既浪费时间,影响性能,也没必要。我们只需展示当前目录的所有子目录,而子目录只需用+来表示是否包有子目录,而+只要检测到该目录包有一个子目录即可。所以只需搜索当前层和下一层的第一个文件夹即可。每次展开一个文件夹之后,下次就不需再检测了,因而性能相对来说好多了。
第一次显示,只搜索第一个文件夹,使其有+或-;当点击该目录时,搜索当前目录的子目录,若搜索到第一个子目录,则用+表示。
如何对所选择文件夹进行展开?① 选取当前目录;② 对该目录按上面规则展开。
展开全部和展开局部:展开全部指展开当前目录的所有子目录;展开局部指展开当前目录的一两个子目录。当点击某个目录时,然后展开当前目录的全部和展开所有子目录的局部。
如何对已存在的目录不再展开?如果已存在的项<=2,则删除已打开,再展开全部;否则不处理。
三 代码
folder.h///
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include "resource.h"
#pragma comment(lib,"comctl32.lib")
int
InitTreeView(HWND hwndTree,HINSTANCE hInstance);
int
FindDir(HTREEITEM hTItem,char dir[]);
int
ExpandAll(HTREEITEM hTItem,char dir[]);
int
IsItemExist(HTREEITEM hTItem,char dir[]);
/folder.cpp/
#include "folder.h"
HWND
hwTree;
HTREEITEM hTreeItem[10];
/*树形列表
名称:InitTreeView
功能:初始化树形控件
参数:hwndTree 为树形列表控件句柄,hInstance为程序句柄
*/
int InitTreeView(HWND hwndTree,HINSTANCE hInstance)
{
int tx=0,i,len;
char Driver[50],p[20],dir[200];
TV_INSERTSTRUCT tvs;
TV_ITEM tvi;
hwTree=hwndTree;
HIMAGELIST himgl;
himgl=ImageList_Create(16,16,ILC_COLOR16,1,10);
i=ImageList_AddIcon(himgl,LoadIcon(hInstance,(LPCTSTR)IDI_FCLOSE));
i=ImageList_AddIcon(himgl,LoadIcon(hInstance,(LPCTSTR)IDI_FIXED));
i=ImageList_AddIcon(himgl,LoadIcon(hInstance,(LPCTSTR)IDI_COMPUTER));
i=ImageList_AddIcon(himgl,LoadIcon(hInstance,(LPCTSTR)IDI_FOPEN));
himgl=TreeView_SetImageList(hwndTree,himgl,TVSIL_NORMAL);
tvi.mask=TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_TEXT;
tvi.pszText ="我的电脑";
tvi.iImage=2;
tvi.iSelectedImage=2;
tvs.hInsertAfter=TVI_LAST;
tvs.hParent=TVI_ROOT;
tvs.item =tvi;
hTreeItem[0]=TreeView_InsertItem(hwndTree,&tvs);
///以下为分为盘符C:D:等的功能
GetLogicalDriveStrings(50,Driver);
i=0;
while(1)
{
len=strlen(&Driver[i]);
if(len==0)
break;
sprintf(dir,"%s*",&Driver[i]);
Driver[i+len-1]='/0';
sprintf(p,"%s",&Driver[i]);
tx=0;
tvs.hParent=hTreeItem[tx];
tvi.pszText=p;
tvi.cchTextMax=strlen(tvi.pszText);
tvi.iImage=1;
tvi.iSelectedImage=1;
tvs.item=tvi;
tx++;
hTreeItem[tx]=TreeView_InsertItem(hwndTree,&tvs);
FindDir(hTreeItem[tx],dir);
i+=len+1;
}
SendMessage(hwndTree,TVM_EXPAND,TVE_EXPAND|TVE_EXPANDPARTIAL,(LPARAM)hTreeItem[0]);
return 1;
}
/*名称:FinDir
功能:展开局部,即展为子目录的第一个或第二个目录
参数:hTItem当前目录的句柄,dir 当前目录的路径
*/
int FindDir(HTREEITEM hTItem,char dir[])
{
TV_INSERTSTRUCT tvs;
TV_ITEM tvi;
WIN32_FIND_DATA fdata;
HANDLE hF=NULL;
tvs.hParent=hTItem;
hF=FindFirstFile (dir,&fdata);
if (hF == INVALID_HANDLE_VALUE)
{
FindClose(hF);
return 0;
}
else if(fdata.dwFileAttributes==FILE_ATTRIBUTE_DIRECTORY&&strcmp(fdata.cFileName,".")!=0&&strcmp(fdata.cFileName,"..")!=0)
{
tvi.mask=TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_TEXT;
tvs.hInsertAfter=TVI_LAST;
tvi.pszText=fdata.cFileName;
tvi.cchTextMax=strlen(tvi.pszText);
tvi.iImage=0;
tvi.iSelectedImage=3;
tvs.item=tvi;
TreeView_InsertItem(hwTree,&tvs);
}
while(FindNextFile(hF,&fdata)!=0)
{
if(fdata.dwFileAttributes==FILE_ATTRIBUTE_DIRECTORY&&strcmp(fdata.cFileName,".")!=0&&strcmp(fdata.cFileName,"..")!=0)
{
tvi.mask=TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_TEXT;
tvs.hInsertAfter=TVI_LAST;
tvi.pszText=fdata.cFileName;
tvi.cchTextMax=strlen(tvi.pszText);
tvi.iImage=0;
tvi.iSelectedImage=3;
tvs.item=tvi;
TreeView_InsertItem(hwTree,&tvs);
break;
}
}
FindClose(hF);
return 1;
}
/*名称:ExpandAll
功能:展开全部,展开当前的所有子目录
参数:hTItem当前目录句柄,dir为当前目录的路径
*/
int ExpandAll(HTREEITEM hTItem,char dir[])
{
char path[200];
TV_INSERTSTRUCT tvs;
TV_ITEM tvi;
WIN32_FIND_DATA fdata;
HANDLE hF=NULL;
HTREEITEM hexpanitem;
tvs.hParent=hTItem;
sprintf(path,"%s//*",dir);
hF=FindFirstFile (path,&fdata);
if (hF == INVALID_HANDLE_VALUE)
{
FindClose(hF);
return 0;
}
else if(fdata.dwFileAttributes==FILE_ATTRIBUTE_DIRECTORY&&strcmp(fdata.cFileName,".")!=0&&strcmp(fdata.cFileName,"..")!=0)
{
tvi.mask=TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_TEXT;
tvs.hInsertAfter=TVI_LAST;
tvi.pszText=fdata.cFileName;
tvi.cchTextMax=strlen(tvi.pszText);
tvi.iImage=0;
tvi.iSelectedImage=3;
tvs.item=tvi;
hexpanitem=TreeView_InsertItem(hwTree,&tvs);
sprintf(path,"%s//%s//*",dir,fdata.cFileName);
FindDir(hexpanitem,path);
}
while(FindNextFile(hF,&fdata)!=0)
{
if(fdata.dwFileAttributes==FILE_ATTRIBUTE_DIRECTORY&&strcmp(fdata.cFileName,".")!=0&&strcmp(fdata.cFileName,"..")!=0)
{
tvi.mask=TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_TEXT;
tvs.hInsertAfter=TVI_LAST;
tvi.pszText=fdata.cFileName;
tvi.cchTextMax=strlen(tvi.pszText);
tvi.iImage=0;
tvi.iSelectedImage=3;
tvs.item=tvi;
hexpanitem=TreeView_InsertItem(hwTree,&tvs);
sprintf(path,"%s//%s//*",dir,fdata.cFileName);
FindDir(hexpanitem,path);
}
}
FindClose(hF);
return 1;
}
/*名称:IsItemExist
功能:判断当前目录是否已全部展开,用以判断若是展开则不必再展开全部
参数:hTItem为当前目录句柄,dir为当前目录的路径
*/
int IsItemExist(HTREEITEM hTItem,char dir[])
{
HTREEITEM hTreeItemtemp;
int count;
hTreeItemtemp=(HTREEITEM)SendMessage(hwTree,TVM_GETNEXTITEM,TVGN_CHILD,(LPARAM)hTItem);
if(hTreeItemtemp==NULL)
return 0;
hTItem=hTreeItemtemp;
count=1;
while(1)
{
hTreeItemtemp=(HTREEITEM)SendMessage(hwTree,TVM_GETNEXTITEM,TVGN_NEXT,(LPARAM)hTItem);
if(hTreeItemtemp==NULL)
break;
hTItem=hTreeItemtemp;
count++;
if(count>=3)
return 1;
}
while(1)
{
hTreeItemtemp=(HTREEITEM)SendMessage(hwTree,TVM_GETNEXTITEM,TVGN_PREVIOUS,(LPARAM)hTItem);
SendMessage(hwTree,TVM_DELETEITEM,0,(LPARAM)hTItem);
if(hTreeItemtemp==NULL)
return 0;
hTItem=hTreeItemtemp;
}
return 1;
}
/main.cpp///
HWND
hTree;
LPNM_TREEVIEW
pnmtv;
char
buff[50];
char
buffPath[MAX_PATH],tempPath[MAX_PATH];
TV_ITEM
tvi;
HTREEITEM
hTreeItemtemp;
case WM_NOTIFY:
pnmtv=(NM_TREEVIEW FAR *)lParam;
if(pnmtv->hdr.code==TVN_SELCHANGED||pnmtv->hdr.code==TVN_ITEMEXPANDING)
{
tvi.mask=TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_TEXT;
tvi.hItem=pnmtv->itemNew.hItem;
tvi.pszText=buff;
tvi.cchTextMax=50;
hTree=GetDlgItem(hDlg,ID_TREE_FOLDER);
SendMessage(hTree,TVM_GETITEM,0,(LPARAM)(TV_ITEM FAR*)&tvi);
if(strcmp(buff,"我的电脑")==0)
return 0;
sprintf(buffPath,"%s",buff);
strcpy(tempPath,buffPath);
while(1)
{
hTreeItemtemp=(HTREEITEM)SendMessage(hTree,TVM_GETNEXTITEM,TVGN_PARENT,(LPARAM)tvi.hItem);
tvi.mask=TVIF_TEXT;
tvi.hItem=hTreeItemtemp;
tvi.pszText=buff;
tvi.cchTextMax=50;
SendMessage(hTree,TVM_GETITEM,0,(LPARAM)(TV_ITEM FAR*)&tvi);
if(strcmp(buff,"我的电脑")==0)
break;
sprintf(buffPath,"%s//%s",buff,tempPath);
strcpy(tempPath,buffPath);
}
SetDlgItemText(hDlg,ID_SRCPATH,buffPath);
if(!IsItemExist(pnmtv->itemNew.hItem,buffPath))
ExpandAll(pnmtv->itemNew.hItem,buffPath);
}
break;
以上是关于创建文件夹浏览器的主要内容,如果未能解决你的问题,请参考以下文章