遍历文件信息

来源:互联网 发布:淘宝直通车显示原价 编辑:程序博客网 时间:2024/04/30 17:25
/*******************************************************************************/
/**********操作.CPP***************************************************************/
/*******************************************************************************/  

#include "stdafx.h"
#include "FileControlExample.h"
#include "FileControl.h"
#include <Commctrl.h>
#include <Shlobj.h> // 文件夹选择
#include <Uxtheme.h> // 扩展样式相关API
#pragma comment(lib,"UxTheme.lib")
#include <shlwapi.h> // 路径相关API
#pragma comment(lib,"shlwapi.lib")
typedef struct _TREE_ITEM 
{
    HTREEITEM hTreeItem;
    WCHAR     szFilePath[MAX_PATH];
}TREE_ITEM,*PTREE_ITEM;
typedef struct _LIST_ITEM 
{
    int   nItemIndex;
    WCHAR szFilePath[MAX_PATH];
}LIST_ITEM,*PLIST_ITEM;
#define MAX_LOADSTRING 100
// 全局变量:
HINSTANCE hInst;                                // 当前实例
TCHAR szTitle[MAX_LOADSTRING];                    // 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING];            // 主窗口类名
list<TREE_ITEM> g_lstTreeInfo;
list<LIST_ITEM> g_lstListInfo;
//HTREEITEM        g_hParent;
//TreeView_GetSelection
// 此代码模块中包含的函数的前向声明:
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HTREEITEM AddItemToTree(HWND hTree, LPWSTR lpItemName, HTREEITEM hParent, BOOL bFolder);
BOOL      AddItemToList(HWND hWnd,FILE_INFO stcInfo, DWORD dwIndex);
VOID      UpdataControl(HWND hWnd, LPWSTR lpPath, HTREEITEM hParent);
VOID      DeleteTreeItemListNode(HTREEITEM hItem);
BOOL      SelectFolder(HWND hWnd, LPWSTR lpszFolder);
VOID      InitList(HWND hWnd);
VOID Tree_LButtonDown(HWND hWnd);
VOID List_RButtonDown(HWND hWnd);
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPTSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    DialogBox(hInstance,LPTSTR(IDD_DIALOG),0,(DLGPROC)WndProc);
    return 0;
}
//
//  函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的: 处理主窗口的消息。
//
//  WM_COMMAND    - 处理应用程序菜单
//  WM_PAINT    - 绘制主窗口
//  WM_DESTROY    - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;
    switch (message)
    {
    case WM_INITDIALOG:{
        InitList(hWnd);
        break;}
    case WM_NOTIFY:
        {
            // 1. 判断是否为左键单击消息,并且消息消息来自树控件
            if (   NM_CLICK==((LPNMHDR)lParam)->code
                && IDC_TREE==((LPNMHDR)lParam)->idFrom )
            {
                Tree_LButtonDown(hWnd);
            }
            // 2. 判断是否为右键单击消息,并且消息消息来自列表框控件
            else if ( NM_RCLICK==((LPNMHDR)lParam)->code
                   && IDC_LIST==((LPNMHDR)lParam)->idFrom  )
            {
                List_RButtonDown(hWnd);
            }
            break;
        }
    case WM_COMMAND:
        wmId    = LOWORD(wParam);
        wmEvent = HIWORD(wParam);
        // 分析菜单选择:
        switch (wmId)
        {
        case BTN_SELETE:
            WCHAR szPath[MAX_PATH];
            SelectFolder(hWnd, szPath);
            UpdataControl(hWnd, szPath, NULL);
            break;
        case ID__32771:
            {
                UINT nSeleteItem = ListView_GetSelectionMark(GetDlgItem(hWnd,IDC_LIST));
                for (list<LIST_ITEM>::iterator i=g_lstListInfo.begin(); 
                    i!=g_lstListInfo.end();
                    i++)
                {
                    if ( i->nItemIndex != nSeleteItem ) continue;
                    CFileControl obj;
                    obj.SetFileIsHidden(i->szFilePath);
                    break;
                }
                break;
            }
        case ID__32772:
            {
                UINT nSeleteItem = ListView_GetSelectionMark(GetDlgItem(hWnd,IDC_LIST));
                for (list<LIST_ITEM>::iterator i=g_lstListInfo.begin(); 
                    i!=g_lstListInfo.end();
                    i++)
                {
                    if ( i->nItemIndex != nSeleteItem ) continue;
                    CFileControl obj;
                    obj.SetFileIsOnlyRead(i->szFilePath);
                    break;
                }
                break;
            }
        case IDCANCEL:
            PostQuitMessage(0);
        default:
            return FALSE;
        }
        break;
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        // TODO: 在此添加任意绘图代码...
        EndPaint(hWnd, &ps);
        break;
    case WM_CLOSE: // 重点
        PostQuitMessage(0);
    default:
        return FALSE;
    }
    return FALSE;
}
HTREEITEM AddItemToTree(HWND hTree, LPWSTR lpItemName, HTREEITEM hParent, BOOL bFolder)
{
    TVITEM            tvi   = {0};    // 树节点项属性信息
    TVINSERTSTRUCT    tvins = {0};    // 树形控件的节点信息
    tvi.mask = TVIF_TEXT|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_PARAM;
    tvi.pszText = lpItemName;
    tvi.cchTextMax = wcslen(lpItemName)+sizeof(TCHAR);
    if ( bFolder )
    {
        tvi.iImage = 1;
        tvi.iSelectedImage = 2;
        tvi.cChildren = I_CHILDRENCALLBACK;
    }
    else
    {
        tvi.iImage = 3;
        tvi.iSelectedImage = 3;
        tvi.cChildren = 0;
    }
    tvins.item = tvi;               // 插入点的属性信息
    tvins.hInsertAfter = TVI_SORT;    // 插入位置
    if ( NULL == hParent )          // 父节点的句柄
        tvins.hParent = TVI_ROOT;
    else
        tvins.hParent = hParent;
    return TreeView_InsertItem(hTree,&tvins);
}
VOID UpdataControl(HWND hWnd, LPWSTR lpPath, HTREEITEM hParent)
{
    HWND hTreeWnd = GetDlgItem(hWnd,IDC_TREE);
    // 1. 清空Tree的子节点
    if ( hParent )
    {
        // 1.1 获取其子节点,如果有的话则循环删除其子节点,否则跳过此步骤
        HTREEITEM hNext_A = TreeView_GetNextItem(hTreeWnd,hParent,TVGN_CHILD);
        if ( hNext_A )
        {
            // 1.1.1 获取其子节点的下一个节点
            HTREEITEM hNext_B = TreeView_GetNextItem(hTreeWnd,hNext_A,TVGN_NEXT);
            // 1.1.2 删除第一个子节点
            TreeView_DeleteItem(hTreeWnd,hNext_A);
            DeleteTreeItemListNode(hNext_A);
            // 1.1.3 将第二个节点hNext_B的句柄值赋值给第一个节点hNext_A
            hNext_A = hNext_B;
            // 1.1.4 如此往复删除剩余节点
            while ( hNext_B = TreeView_GetNextItem(hTreeWnd,hNext_A,TVGN_NEXT) )
            {
                TreeView_DeleteItem(hTreeWnd,hNext_A);
                DeleteTreeItemListNode(hNext_A);
                hNext_A = hNext_B;
            }
            // 1.1.5 删除最后一个节点
            if ( hNext_A )
            {
                TreeView_DeleteItem(hTreeWnd,hNext_A);
                DeleteTreeItemListNode(hNext_A);
            }
        }
    }
    
    // 2. 获取此目录下的所有文件列表,并清除列表框中的所有内容
    CFileControl objFile;
    list<FILE_INFO>  lstFileInfo;
    objFile.GetFileList(lpPath,lstFileInfo);
    ListView_DeleteAllItems(GetDlgItem(hWnd,IDC_LIST)); // 清空列表框
    g_lstListInfo.clear();                              // 情况列表框信息链表
    // 3. 将目录添加到Tree控件中
    DWORD dwIndex = 0;
    for (list<FILE_INFO>::iterator i=lstFileInfo.begin(); i!=lstFileInfo.end(); i++)
    {
        TREE_ITEM strTreeItem = {0};
        if ( i->bIsFolder )
        {
            // 3.1 将目录添加到Tree控件中,并将此节点信息加入链表
            strTreeItem.hTreeItem = AddItemToTree(hTreeWnd, i->szFilePath, hParent, TRUE);
            StringCbPrintf(strTreeItem.szFilePath, MAX_PATH, L"%s\\%s", lpPath, i->szFilePath);
            g_lstTreeInfo.push_back(strTreeItem);
            continue;
        }
        // 3.2 将文件添加到List控件中并将此节点信息加入链表
        AddItemToList(hWnd,*i,dwIndex);
        LIST_ITEM stcListItem = {0};
        stcListItem.nItemIndex = dwIndex;
        StringCbCopy(stcListItem.szFilePath,MAX_PATH,i->szFilePath);
        g_lstListInfo.push_back(stcListItem);
        dwIndex++;
    }
    lstFileInfo.clear();
}
VOID DeleteTreeItemListNode(HTREEITEM hItem)
{
    for ( list<TREE_ITEM>::iterator i = g_lstTreeInfo.begin();
        i != g_lstTreeInfo.end();
        i++)
    {
        if ( i->hTreeItem != hItem )  continue;
        g_lstTreeInfo.erase(i);
        break;
    }
}
BOOL AddItemToList(HWND hWnd,FILE_INFO stcInfo, DWORD dwIndex)
{
    HWND hListWnd = GetDlgItem(hWnd,IDC_LIST);
    LVITEM lvItem = {0};
    lvItem.mask    = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
    lvItem.state     = 0; // 子项的状态
    lvItem.stateMask = 0; // 状态有效的屏蔽位
    lvItem.iImage     = 0; // 与列表框关联的指定图像的索引值
    lvItem.iSubItem  = 0; // 子项的索引值(可以视为列号)
    WCHAR szInfo[64] = {0};
    lvItem.iItem    = dwIndex;
    lvItem.pszText  = PathFindFileName(stcInfo.szFilePath);
    lvItem.cchTextMax = wcslen(lvItem.pszText)+sizeof(TCHAR);
    ListView_InsertItem(hListWnd, &lvItem);
    wsprintf(szInfo,L"%I64d KB",stcInfo.qwFileSize/1024);
    ListView_SetItemText(hListWnd, lvItem.iItem, 1, szInfo);
    wsprintf(szInfo,L"%4d年%.2d月%#02d日,%.2d:%.2d:%.2d",
        stcInfo.stcCreatTime.wYear,
        stcInfo.stcCreatTime.wMonth,
        stcInfo.stcCreatTime.wDay,
        stcInfo.stcCreatTime.wHour,
        stcInfo.stcCreatTime.wMinute,
        stcInfo.stcCreatTime.wSecond);
    ListView_SetItemText(hListWnd, lvItem.iItem, 2, szInfo);
    wsprintf(szInfo,L"%4d年%.2d月%#02d日,%.2d:%.2d:%.2d",
        stcInfo.stcLastWriteTime.wYear,
        stcInfo.stcLastWriteTime.wMonth,
        stcInfo.stcLastWriteTime.wDay,
        stcInfo.stcLastWriteTime.wHour,
        stcInfo.stcLastWriteTime.wMinute,
        stcInfo.stcLastWriteTime.wSecond);
    ListView_SetItemText(hListWnd, lvItem.iItem, 3, szInfo);
    wsprintf(szInfo,L"%4d年%.2d月%#02d日,%.2d:%.2d:%.2d",
        stcInfo.stcLastAccessTime.wYear,
        stcInfo.stcLastAccessTime.wMonth,
        stcInfo.stcLastAccessTime.wDay,
        stcInfo.stcLastAccessTime.wHour,
        stcInfo.stcLastAccessTime.wMinute,
        stcInfo.stcLastAccessTime.wSecond);
    ListView_SetItemText(hListWnd, lvItem.iItem, 4, szInfo);
    return TRUE;
}
BOOL SelectFolder(HWND hWnd, LPWSTR lpszFolder)
{
    BROWSEINFO  bi = {0}; 
    ITEMIDLIST *pidl; 
    TCHAR       szPath[MAX_PATH];
    bi.hwndOwner      = hWnd; 
    bi.pszDisplayName = szPath; 
    bi.lpszTitle      = TEXT("Please select a folder"); 
    bi.ulFlags        = BIF_RETURNONLYFSDIRS; 
    if( pidl=SHBrowseForFolder(&bi) )
    {
        SHGetPathFromIDList( pidl, lpszFolder );
        return TRUE;
    }
    return FALSE;    
}
VOID InitList(HWND hWnd)
{
    // 1. 设置列表框样式为“可整行选择”、“有网格”
    ListView_SetExtendedListViewStyle( GetDlgItem(hWnd,IDC_LIST),
        LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_AUTOCHECKSELECT );
    // 2. 初始化列表框内容
    LVCOLUMN lvc = {0};
    lvc.mask   = LVCF_WIDTH|LVCF_TEXT;  // 列表框样式
    lvc.iImage = 1;                     // 与列表框关联的指定图像的索引值
    lvc.fmt    = LVCFMT_LEFT;            // 列的对齐方式
    lvc.pszText  = L"文件名";
    lvc.cx       = 128;
    lvc.iSubItem = 0;
    ListView_InsertColumn(GetDlgItem(hWnd,IDC_LIST), lvc.iSubItem, &lvc);
    lvc.pszText  = L"文件大小";
    lvc.cx       = 88;
    lvc.iSubItem = 1;
    ListView_InsertColumn(GetDlgItem(hWnd,IDC_LIST), lvc.iSubItem, &lvc);
    lvc.pszText  = L"创建时间";
    lvc.cx       = 88;
    lvc.iSubItem = 2;
    ListView_InsertColumn(GetDlgItem(hWnd,IDC_LIST), lvc.iSubItem, &lvc);
    lvc.pszText  = L"修改时间";
    lvc.cx       = 88;
    lvc.iSubItem = 3;
    ListView_InsertColumn(GetDlgItem(hWnd,IDC_LIST), lvc.iSubItem, &lvc);
    lvc.pszText  = L"访问时间";
    lvc.cx       = 88;
    lvc.iSubItem = 4;
    ListView_InsertColumn(GetDlgItem(hWnd,IDC_LIST), lvc.iSubItem, &lvc);
}
VOID Tree_LButtonDown(HWND hWnd)
{
    // 1. 初始化必要的信息
    POINT stcPoint = {0};                       // 发生此消息时的鼠标坐标
    HWND  hTreeWnd = GetDlgItem(hWnd,IDC_TREE); // 树形控件HEND
    GetCursorPos(&stcPoint);
    // 2. 将鼠标位置转换为相对坐标
    HTREEITEM     hTreeItem;
    TVHITTESTINFO thti;
    ScreenToClient(hTreeWnd,&stcPoint);
    thti.pt    = stcPoint;
    thti.flags = LVHT_EX_GROUP_BACKGROUND;
    // 3. 如果选中的列表框中的某一项,则更新树控件内容
    if ( hTreeItem  = TreeView_HitTest(hTreeWnd,&thti) )
    {
        for ( list<TREE_ITEM>::iterator i = g_lstTreeInfo.begin();
            i != g_lstTreeInfo.end();
            i++)
        {
            if ( i->hTreeItem != hTreeItem )
                continue;
            UpdataControl(hWnd,i->szFilePath,hTreeItem);
            break;
        }
    }
}
VOID List_RButtonDown(HWND hWnd)
{
    POINT stcPoint = {0};                       // 发生此消息时的鼠标坐标
    HWND  hListWnd = GetDlgItem(hWnd,IDC_LIST); // 列表框的HWND
    // 1. 将鼠标位置转换为相对坐标,然后测试是否选中的列表框中的某一项
    int           nListItemIndex;
    LVHITTESTINFO thti;
    GetCursorPos(&stcPoint);
    // 2. 判断是否点击了列表项的头结点
    ScreenToClient(hListWnd,&stcPoint);
    thti.pt        = stcPoint;
    thti.flags     = LVHT_EX_GROUP_HEADER;
    nListItemIndex = ListView_HitTestEx(hListWnd,&thti);
    if ( -1 != nListItemIndex )
    {
        // 2.1 加载菜单资源
        HMENU hMenu  = LoadMenu(NULL, MAKEINTRESOURCE(IDR_MENU1));
        HMENU hPopup = GetSubMenu(hMenu, 0);
        if ( !hMenu || !hPopup )  return;
        // 2.2 将相对坐标转换为原鼠标位置
        ClientToScreen(hListWnd,&stcPoint);
        // 2.3 弹出菜单
        TrackPopupMenuEx(hPopup, TPM_LEFTALIGN|TPM_RIGHTBUTTON, stcPoint.x, stcPoint.y, hWnd, NULL); 
        // 2.4 释放相关资源
        DestroyMenu(hMenu);
    }
}
/*******************************************************************************/
/*****************文件类.h**********************************************************/
/*******************************************************************************/  

#include <Strsafe.h>
#include <list>
using std::list;
typedef struct _FILE_INFO 
{
    WCHAR      szFilePath[MAX_PATH];       // 文件路径
    BOOL       bIsFolder;                  // 是否为文件夹
    DWORD64    qwFileSize;                 // 文件大小
    DWORD      dwAttribute;                // 文件属性
    WCHAR      szAttributeDescription[16]; // 文件属性描述
    SYSTEMTIME stcCreatTime;               // 创建时间
    SYSTEMTIME stcLastAccessTime;          // 最后访问时间
    SYSTEMTIME stcLastWriteTime;           // 最后写入时间
}FILE_INFO,*PFILE_INFO;
class CFileControl
{
public:
    CFileControl(void);
    CFileControl(LPCTSTR lpFileName);
    ~CFileControl(void);
public:
    DWORD GetMyProcessDir(LPWSTR &lpDirPath);                // 获取本进程当前目录
    BOOL  SetMyProcessDir(LPWSTR lpNewDir);                  // 设置程序的当前目录
    DWORD GetMyProcessImagePath(LPWSTR &lpPath);             // 获取本进程映像路径
    DWORD GetProcessImagePath(LPWSTR lpName,LPWSTR &lpPath); // 根据进程名获取映像路径
    BOOL  SetFileIsOnlyRead(LPWSTR lpPath); // 设置文件为只读
    BOOL  SetFileIsHidden(LPWSTR lpPath);   // 设置文件为隐藏
    BOOL  GetFileAttribute(LPWSTR lpPath, FILE_INFO &stcFileInfo);  // 将文件属性压入队列
    BOOL  GetFileList(LPWSTR lpName, list<FILE_INFO> &lstFileInfo); // 获取当前目录下文件列表
    DWORD GetFileTree(LPWSTR lpName, DWORD dwLeve=1);               // 获取文件树
private:
    HANDLE          m_hFile;
    list<FILE_INFO> m_lstFileInfo;
};

/*******************************************************************************/
/*****************文件类.cpp**********************************************************/
/*******************************************************************************/  

#include "stdafx.h"
#include "FileControl.h"
CFileControl::CFileControl(void){}
CFileControl::CFileControl(LPCTSTR lpFileName)
{
    m_hFile = CreateFile(
        lpFileName,                       // 文件名
        GENERIC_ALL,                      // 存取方式
        FILE_SHARE_WRITE|FILE_SHARE_READ, // 共享方式
        NULL,                             // 文件句柄继承属性
        CREATE_ALWAYS,                    // 操作模式
        FILE_ATTRIBUTE_ARCHIVE,           // 文件属性/标志
        NULL);                            // 模板文件句柄,一般为NULL
}
CFileControl::~CFileControl(void){}
DWORD CFileControl::GetMyProcessDir(LPWSTR &lpDirPath)
{
    return GetCurrentDirectory(MAX_PATH,lpDirPath);
}
BOOL CFileControl::SetMyProcessDir(LPWSTR lpNewDir)
{
    return SetCurrentDirectory(lpNewDir);
}
DWORD CFileControl::GetMyProcessImagePath(LPWSTR &lpDirPath)
{
    return GetModuleFileName(NULL,lpDirPath,MAX_PATH);
}
DWORD CFileControl::GetProcessImagePath(LPWSTR lpName,LPWSTR &lpPath)
{
    return GetModuleFileName(GetModuleHandle(lpName), lpPath, MAX_PATH);
}
BOOL CFileControl::SetFileIsOnlyRead(LPWSTR lpPath)
{
    // 1. 获取原来的文件属性
    DWORD dwFileAttributes = GetFileAttributes(lpPath);
    // 2. 将只读属性附加到原来的文件属性上
    dwFileAttributes |= FILE_ATTRIBUTE_READONLY;
    // 3. 设置文件属性
    return SetFileAttributes(lpPath, dwFileAttributes);
}
BOOL CFileControl::SetFileIsHidden(LPWSTR lpPath)
{
    // 1. 获取原来的文件属性
    DWORD dwFileAttributes = GetFileAttributes(lpPath);
    // 2. 将隐藏属性附加到原来的文件属性上
    dwFileAttributes |= FILE_ATTRIBUTE_HIDDEN;
    // 3. 设置文件属性
    return SetFileAttributes(lpPath, dwFileAttributes);
}
BOOL CFileControl::GetFileAttribute(LPWSTR lpPath, FILE_INFO &stcFileInfo)
{
    // 1. 文件路径
    wcscpy_s(stcFileInfo.szFilePath, lpPath);
    // 2. 获取时间信息
    WIN32_FILE_ATTRIBUTE_DATA wfad;
    GetFileAttributesEx( lpPath, GetFileExInfoStandard, &wfad);
    // 2.1 获取创建时间
    FILETIME ftLocal;
    FileTimeToLocalFileTime( &wfad.ftCreationTime, &ftLocal );        // 调整为系统所在时区的时间
    FileTimeToSystemTime( &ftLocal, &stcFileInfo.stcCreatTime );      // 转换为SYSTEMTIME格式
    // 2.2 获取最后访问时间
    FileTimeToLocalFileTime( &wfad.ftLastAccessTime, &ftLocal );      // 调整为系统所在时区的时间
    FileTimeToSystemTime( &ftLocal, &stcFileInfo.stcLastAccessTime ); // 转换为SYSTEMTIME格式
    // 2.3 获取最后修改时间
    FileTimeToLocalFileTime( &wfad.ftLastWriteTime, &ftLocal );       // 调整为系统所在时区的时间
    FileTimeToSystemTime( &ftLocal, &stcFileInfo.stcLastWriteTime );  // 转换为SYSTEMTIME格式
    // 3. 获取文件大小
    stcFileInfo.qwFileSize =   wfad.nFileSizeHigh;
    stcFileInfo.qwFileSize <<= sizeof(DWORD)*8;
    stcFileInfo.qwFileSize +=  wfad.nFileSizeLow;
    // 4. 文件属性
    stcFileInfo.dwAttribute = wfad.dwFileAttributes;
    if(stcFileInfo.dwAttribute&FILE_ATTRIBUTE_ARCHIVE)
        wcscpy_s(stcFileInfo.szAttributeDescription, L"<ARCHIVE> ");
    if(stcFileInfo.dwAttribute&FILE_ATTRIBUTE_COMPRESSED)
        wcscpy_s(stcFileInfo.szAttributeDescription, L"<压缩> ");
    if(stcFileInfo.dwAttribute&FILE_ATTRIBUTE_DIRECTORY)
        wcscpy_s(stcFileInfo.szAttributeDescription, L"<目录> ");
    if(stcFileInfo.dwAttribute&FILE_ATTRIBUTE_ENCRYPTED)
        wcscpy_s(stcFileInfo.szAttributeDescription, L"<加密> ");
    if(stcFileInfo.dwAttribute&FILE_ATTRIBUTE_HIDDEN)
        wcscpy_s(stcFileInfo.szAttributeDescription, L"<隐藏> ");
    if(stcFileInfo.dwAttribute&FILE_ATTRIBUTE_NORMAL)
        wcscpy_s(stcFileInfo.szAttributeDescription, L"<NORMAL> ");
    if(stcFileInfo.dwAttribute&FILE_ATTRIBUTE_OFFLINE)
        wcscpy_s(stcFileInfo.szAttributeDescription, L"<OFFLINE> ");
    if(stcFileInfo.dwAttribute&FILE_ATTRIBUTE_READONLY)
        wcscpy_s(stcFileInfo.szAttributeDescription, L"<只读> ");
    if(stcFileInfo.dwAttribute&FILE_ATTRIBUTE_SPARSE_FILE)
        wcscpy_s(stcFileInfo.szAttributeDescription, L"<SPARSE> ");
    if(stcFileInfo.dwAttribute&FILE_ATTRIBUTE_SYSTEM)
        wcscpy_s(stcFileInfo.szAttributeDescription, L"<系统文件> ");
    if(stcFileInfo.dwAttribute&FILE_ATTRIBUTE_TEMPORARY)
        wcscpy_s(stcFileInfo.szAttributeDescription, L"<临时文件> ");
    return TRUE;
}
BOOL CFileControl::GetFileList(LPWSTR lpName, list<FILE_INFO> &lstFileInfo)
{
    // 1. 构造代表子目录和文件夹路径的字符串,使用通配符“*”
    WCHAR szFilePath[MAX_PATH];
    StringCbCopy(szFilePath, MAX_PATH, lpName);
    StringCbCat(szFilePath, MAX_PATH, L"\\*");
    // 2. 获取第一个文件/目录,并获得查找句柄
    WIN32_FIND_DATA FindFileData;
    HANDLE hListFile = FindFirstFile(szFilePath,&FindFileData);
    int n = GetLastError();
    if ( INVALID_HANDLE_VALUE == hListFile )
        return FALSE;
    // 3. 开始循环遍历获取文件名
    do 
    {
        FILE_INFO stcInfo = {0};
        // 3.1 判断是否是本级目录或上级目录的名称,是的话则结束本次循环
        if (   !lstrcmp(FindFileData.cFileName, L".") 
            || !lstrcmp(FindFileData.cFileName, L"..") )
        {
            continue;
        }
        // 3.2 将获取到的文件名保存在结构体中
        wcscpy_s(stcInfo.szFilePath, FindFileData.cFileName);
        // 3.3 获取完整路径名
        WCHAR szFullPath[MAX_PATH];
        StringCbPrintf(szFullPath, MAX_PATH, L"%s\\%s", lpName, FindFileData.cFileName);
        // 3.4 如果不是目录,则获取详细信息
        if(FindFileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
            stcInfo.bIsFolder = TRUE;
        else
            GetFileAttribute(szFullPath, stcInfo); 
        // 3.5 将获取到的文件信息压入到链表中
        lstFileInfo.push_back(stcInfo);
    } while ( FindNextFile(hListFile, &FindFileData) );
    return TRUE;
}
DWORD CFileControl::GetFileTree(LPWSTR lpName, DWORD dwLeve)
{
    // 1. 如果层级是为0则返回,否则将层级-1后继续
    if ( !dwLeve-- )  return 0;
    // 2. 构造代表子目录和文件夹路径的字符串,使用通配符“*”
    WCHAR szFilePath[MAX_PATH];
    StringCbCopy(szFilePath, MAX_PATH, lpName);
    StringCbCat(szFilePath, MAX_PATH, L"\\*");
    // 3. 获取第一个文件/目录,并获得查找句柄
    WIN32_FIND_DATA FindFileData;
    HANDLE hListFile = FindFirstFile(szFilePath,&FindFileData);
    if ( INVALID_HANDLE_VALUE == hListFile )   return 0;
    // 4. 开始循环遍历获取文件名
    DWORD dwFileCount = 0;
    do 
    {
        // 4.1 判断是否是本级目录或上级目录的名称,是的话则结束本次循环
        if (   !lstrcmp(FindFileData.cFileName, L".") 
            || !lstrcmp(FindFileData.cFileName, L"..") )
        {
            continue;
        }
        // 4.2 获取完整路径名
        WCHAR szFullPath[MAX_PATH];
        StringCbPrintf(szFullPath, MAX_PATH, L"%s\\%s", lpName, FindFileData.cFileName);
        // 4.3 如果是目录,则递归调用,列举下级目录
        if(FindFileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
            dwFileCount += GetFileTree(szFullPath,dwLeve);
        // 4.4 将文件数量+1
        dwFileCount++;
    } while ( FindNextFile(hListFile, &FindFileData) );
    // 5. 返回本次遍历到的文件总数
    return dwFileCount;

}  


0 0
原创粉丝点击