<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-88  評論-77  文章-48  trackbacks-0
    在編程時,經常有一些針對目錄的操作,如打開目錄對話框選擇一個目錄,直接創建多級目錄,直接刪除多級目錄,判斷某個目錄是否存在等。本文就這些問題給出編程實現方法,并給出詳細的程序代碼,供各位編程愛好者參考。

    一、判斷目錄是否存在:

    ??C++ Builder中提供了檢查文件是否存在的函數FileExists,但沒有提供檢查目錄是否存在的函數,我們可以用Windows API函數FindFirstFile實現這個功能。程序實現如下:

    設char *Dir為帶判斷的目錄
    bool Exist;????????????????????????????????????????????// 最后結果,表示目錄是否存在
    if(Dir[strlen(Dir)]=='\\')Dir[strlen(Dir)-1]='\0';????// 先刪除最后的“\”
    WIN32_FIND_DATA wfd;??????????????????????????????????// 查找
    HANDLE hFind=FindFirstFile(Dir,&wfd);??????????????????
    if(hFind==INVALID_HANDLE_VALUE)Exist=false;????????????// 沒有找到配備,目錄肯定不存在
    else
    {
    ????if(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) // 檢查找到的結果是否目錄
    ????????Exist=true;??????????????????????????????????????// 是目錄,目錄存在
    ????else
    ????????Exist=false;????????????????????????????????????// 是目錄,目錄不存在
    ????FindClose(hFind);
    }

    二、打開目錄選擇對話框選擇一個目錄:

    ??大多專業軟件在要求輸入目錄的編輯框旁都放了一個按鈕,點擊后打開一個目錄窗口,很多編程愛好者也希望能掌握這個方法。實現這個功能要調用Windows API函數SHBrowseForFolder,完整聲明為WINSHELLAPI LPITEMIDLIST WINAPI SHBrowseForFolder(LPBROWSEINFO lpbi),返回一個ITEMIDLIST類型的指針,通過這個指針調用函數SHGetPathFromIDList可以確定所選擇的目錄的全名稱。入參為BROWSEINFO結構的指針,這個結構較為復雜,成員如下所示:

    HWND hwndOwner;????????// 擁有對話框的窗口,可以設置為Application->Handle
    LPCITEMIDLIST pidlRoot; // ITEMIDLIST類型的指針,表示在哪個路徑下選擇,一般可以設置為NULL
    LPSTR pszDisplayName;??// 選擇后,所選目錄的名稱(不包含父級目錄)被拷貝到這個指針指向的位置
    LPCSTR lpszTitle;??????// 作為標題顯示在對話框中目錄樹的上面,可以根據實際情況設置
    UINT ulFlags;??????????// 標志位,有點復雜,一般設置為BIF_RETURNONLYFSDIRS
    BFFCALLBACK lpfn;??????// 回調函數,一般不用,設置為NULL
    LPARAM lParam;??????????// 預定義的對話框傳遞給回調函數的值
    int iImage;????????????// 與所選目錄相關聯的圖標在系統圖標集合中的索引
    可以看出,使用函數SHBrowseForFolder還真麻煩,普通愛好者掌握它確實有一定的難度,現給出完整程序段如下:
    #include <shlobj.h>????????????????????// 必須包含的頭文件
    char SelectedDir[MAX_PATH];??????????????// 最終結果
    BROWSEINFO bi;??????????????????????????// 入參
    char FolderName[MAX_PATH];??????????????// 所選目錄名稱,例如選擇C:\Windows\Font,則為Font
    LPITEMIDLIST ItemID;????????????????????// 所選目錄的系統標志指針

    memset(SelectedDir, 0, MAX_PATH);??????????????// 初始化最終結果
    memset(&bi, 0, sizeof(BROWSEINFO));????// 初始化入參所有數據
    bi.hwndOwner = Application->Handle;
    bi.pszDisplayName = FolderName;
    bi.lpszTitle = "請選擇目錄";????????????// 改成自己希望的
    bi.ulFlags=BIF_RETURNONLYFSDIRS;
    ItemID = SHBrowseForFolder(&bi);??????// 調用函數,打開目錄選擇對話框
    if(ItemID)
    {
    ????SHGetPathFromIDList(ItemID, SelectedDir);??????// 獲取所選目錄的全名
    ????GlobalFree(ItemID);??????????????????????// 返回的ItemID占用了系統資源,不要忘了釋放
    }

    三、直接建立多級目錄:

    ??Windows API提供了建立目錄的函數CreateDirectory,但是調用前要保證父目錄必須存在,否則會失敗。其實,有時越級建立多級目錄很有用,因為在建立目錄特別是建立多層目錄時,層層加以判斷會大大地增加程序的復雜程度。如何實現這個功能呢?本人用遞歸方法設計了一個可以直接建立多級目錄的函數,現說明如下,供各位朋友參考。

    bool MakeDirectoryEx(const AnsiString &P)??// 入參為打算創建的目錄名,根據操作結果返回"true"或"false"
    {
    ????if(P.IsEmpty())return false;
    ????int len=P.Length();
    ????char *Path=P.c_str();
    ????if(Path[len-1]=='\\')
    ????{
    ????????len--;
    ????????Path[len]='\0';
    ????}??????????????????????????????????????// 刪除末尾的"\"
    ????AnsiString Dir=Path;
    ????// 分開父目錄和本身目錄名稱
    ????AnsiString Parent;
    ????for(int i=len-1;i>0;i--)
    ????{
    ????????if(Dir.IsPathDelimiter(i))
    ????????{
    ????????????Parent=Dir.SubString(0,i);
    ????????????break;
    ????????}
    ????}
    ????if(Parent.IsEmpty())return false; // 目錄名稱錯誤
    ????bool Ret=true;
    ????if(Parent.Length()>3)??????????// 如果長度小于3,表示為磁盤根目錄
    ????????Ret=DirectoryExistEx(Parent.c_str());// 檢查父目錄是否存在
    ????if(!Ret)Ret=MakeDirectoryEx(Parent);??// 父目錄不存在,遞歸調用創建父目錄
    ????if(Ret)????????????????????????????????????????// 父目錄存在,直接創建目錄
    ????{
    ????????SECURITY_ATTRIBUTES sa;
    ????????sa.nLength=sizeof(SECURITY_ATTRIBUTES);
    ????????sa.lpSecurityDescriptor=NULL;
    ????????sa.bInheritHandle=0;
    ????????Ret=CreateDirectory(Path,&sa);
    ????}
    ????return Ret;
    }
    ????可以看出基本方法是:
    先檢查父目錄是否存在,這里用到的函數DirectoryExistEx可以按照前面介紹的方法設計;
    如果父目錄存在,則直接創建目錄,否則自我調用創建父目錄。


    四、直接刪除整個目錄:

    ??在DOS下有一個Deltree命令,用來刪除整個目錄,這是一個很有用的功能,可惜,Windows API提供的函數RemoveDirectory只能刪除控目錄,就像DOS的RD命令一樣。編程實現這個功能同樣需要遞歸方法,基本流程是:

    查找目錄下的所有文件和目錄,即調用API函數FindFirstFile、FindNextFile(*.*)
    如果找到文件,則強制刪除。所謂強制刪除,即刪除前先調用SetFileAttributes把它的屬性設置為Normal,然后調用DeleteFile刪除它。
    如果找到目錄,則進行自我調用,即開始遞歸過程。
    如果沒有找到目錄,即表示為控目錄,調用RemoveDirectory直接刪除。
    具體程序代碼如下:

    bool DeleteDirectoryEx(const AnsiString &P)
    {
    ????if(P.IsEmpty() || P.Length()<4)return false;????????// 參數長度必須大于3,即不能為磁盤根目錄或空白
    ????int len=P.Length();
    ????char *Path=P.c_str();
    ????AnsiString Dir=Path;
    ????if(Path[len-1]!='\\')Dir=Dir+'\\';
    ????AnsiString Files=Dir+"*.*";
    ????WIN32_FIND_DATA wfd;
    ????HANDLE hFind=FindFirstFile(Files.c_str(),&wfd);
    ????bool Ret=true;
    ????AnsiString Tmp;
    ????if(hFind!=INVALID_HANDLE_VALUE)
    ????{
    ????????bool bFind=true;
    ????????while(bFind)
    ????????{
    ????????????if(wfd.cFileName[0]!='.') // . ..
    ????????????{
    ????????????????Tmp=Dir+wfd.cFileName;
    ????????????????if(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
    ????????????????{ // 刪除所有子目錄
    ????????????????????Ret=Ret&&DeleteDirectoryEx(Tmp.c_str(),false);
    ????????????????}else
    ????????????????{ // 刪除所有文件
    ????????????????????SetFileAttributes(Tmp.c_str(),FILE_ATTRIBUTE_NORMAL);
    ????????????????????Ret=Ret&&DeleteFile(Tmp.c_str());
    ????????????????}
    ????????????}
    ????????????bFind=FindNextFile(hFind,&wfd);
    ????????}
    ????????FindClose(hFind);
    ????}
    ????if(Ret)return RemoveDirectory(Path);
    ????return false;
    }
    posted on 2006-04-29 20:46 崛起的程序員 閱讀(309) 評論(0)  編輯  收藏 所屬分類: c/c++
    主站蜘蛛池模板: 精品福利一区二区三区免费视频| 岛国精品一区免费视频在线观看| 最近中文字幕大全免费视频| 亚洲av无码成h人动漫无遮挡| 久久99久久成人免费播放| 国产亚洲一区区二区在线| 久久99精品免费一区二区| 亚洲国产精品无码久久久蜜芽| AAAAA级少妇高潮大片免费看| 亚洲综合日韩久久成人AV| 中文字幕免费人成乱码中国| 亚洲av最新在线网址| 国产精品偷伦视频观看免费| 精品国产亚洲AV麻豆| 在线观看视频免费国语| 苍井空亚洲精品AA片在线播放 | 国产一区二区三区免费| 久久久久亚洲av无码专区蜜芽| 日韩中文字幕免费视频| 亚洲av无码专区在线| 日本免费电影一区| 色多多A级毛片免费看| 中文字幕亚洲不卡在线亚瑟| 一个人免费视频在线观看www| 亚洲视频一区在线播放| sss日本免费完整版在线观看| 亚洲欧洲美洲无码精品VA| 日本在线看片免费人成视频1000| 亚洲人成毛片线播放| 日本一区免费电影| EEUSS影院WWW在线观看免费| 午夜亚洲www湿好大| 一个人在线观看视频免费| 日韩a毛片免费观看| 国产人成免费视频| 免费无码又爽又刺激网站直播| 自怕偷自怕亚洲精品| 国产精品无码一二区免费| 久久精品国产免费一区| 亚洲kkk4444在线观看| 亚洲日韩v无码中文字幕|