创建文件夹浏览器

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; 

以上是关于创建文件夹浏览器的主要内容,如果未能解决你的问题,请参考以下文章

如何为系统驱动器、文件夹和文件创建浏览器

创建文件夹浏览器

如何创建类似资源管理器的文件夹浏览器控件?

循环浏览本地文件夹并动态创建元素

防止 Visual Studio 创建浏览信息 (.ncb) 文件

无法删除由于 Selenium Grid 而创建的 %temp% 文件