最近忙于一些相當無聊的事情,還沒忙完,不過,博客還是要寫的,不然我頭頂上會多了幾塊磚頭。
在上一篇博文中,我們瀏覽了文件,今天我們也瀏覽一下目錄,如何?
瀏覽目錄我們同樣有兩個規矩,用托管類庫的我就不說了,相信大家兩分鐘就能弄好。重點還是說說第二個規矩,用API方式。我們用到的是Shell函數,一提到Shell,可能有朋友會感到痛苦,因為它很多函數涉及到COM,不過,也沒什么了,反正我的哲學理念是立足于實戰。所以,我給大家總結了思路。
就拿今天我們要用到的SHBrowseForFolder函數來說吧,先說說這個函數的用途吧,一句話概括:顯示一個對話框,讓你可以選擇一個目錄。
COM對象需要先初始化,再用,用完了釋放,根據這個思路,大的步驟如下:
1、CoInitialize(NULL); //初始化。
2、調用函數。
3、CoUninitialize(); //釋放。
這個動作就好比你去租用商家的自行車去游玩,別人只是把資源(自行車)借給你用,你給押金(引用計數),等到你耍完了,再去把資源還給人家。
要調用SHBrowseForFolder函數,先初始化它的參數,也就是BROWSEINFO結構體,這個家伙初始化后,將地址傳給SHBrowseForFolder的lpbi參數。BROWSEINFO結構你得設置以下成員。
- PIDLIST_ABSOLUTE?pIDLIST;//函數返回的值存在這里??
- BROWSEINFO?brsInfo;??
- WCHAR?fdpath[MAX_PATH];?//接收選擇目錄的字符數組??
- ??
- 。。。。。。。。。。。。。。。。。。。??
- brsInfo.hwndOwner?=?hWnd;?//擁有者窗口??
- brsInfo.pidlRoot?=?NULL;?//根目錄為桌面??
- brsInfo.pszDisplayName?=?fdpath;?//返回的被選擇的路徑??
- brsInfo.lpszTitle?=?L"請選擇目錄";?//對話框標題??
- brsInfo.ulFlags=?BIF_RETURNONLYFSDIRS?|?BIF_DONTGOBELOWDOMAIN?|?BIF_NEWDIALOGSTYLE;?//不顯示網絡路徑??
- brsInfo.lpfn?=?NULL;?//沒有回調??
- brsInfo.lParam?=?NULL;?//沒有額外參數??
之后就可以調用函數了。
- //?初始化COM組件,用完后記得釋放??
- CoInitialize(NULL);??
- pIDLIST?=?SHBrowseForFolder(&brsInfo);??
- if(pIDLIST)??
- {??
- ????//取出對話框中用來顯示結果的控件??
- ????HWND?hStatic?=?GetDlgItem(hfDlg,?IDC_DISPLAY);??
- ????SendMessage(hStatic,WM_SETTEXT,?NULL,?(LPARAM)fdpath);??
- }??
- CoUninitialize();??
- //?釋放IDLIST??
- CoTaskMemFree((LPVOID)pIDLIST);??
由于PIDLIST也是COM對象資源,通過調用CoTaskMemFree函數將其釋放。
現在,運行一下應用程序。
?
?
聰明的你會發現,雖然我們得到了選擇的目錄名字,但不是完整路徑,通常我們是需要完整的路徑的。這個也不難,我們再請出另一個函數——SHGetPathFromIDList,它可以幫我們得出完整的路徑。
所以,我們把上面的代碼修改一下。
- if(pIDLIST)??
- {??
- ????//得到完整路徑??
- ????SHGetPathFromIDList(pIDLIST,?fullPath);??
- ????//取出對話框中用來顯示結果的控件??
- ????HWND?hStatic?=?GetDlgItem(hfDlg,?IDC_DISPLAY);??
- ????SendMessage(hStatic,?WM_SETTEXT,?NULL,?(LPARAM)fullPath);??
- ????//SendMessage(hStatic,WM_SETTEXT,?NULL,?(LPARAM)fdpath);??
- }??
現在再看看結果,這回你肯定滿意了。
?
-------------- 【C++ Code】 -------------------------
- LRESULT?CALLBACK?WndProc(HWND?hWnd,?UINT?message,?WPARAM?wParam,?LPARAM?lParam)??
- {??
- ????int?wmId,?wmEvent;??
- ????PAINTSTRUCT?ps;??
- ????HDC?hdc;??
- ??
- ????PIDLIST_ABSOLUTE?pIDLIST;//函數返回的值存在這里??
- ????BROWSEINFO?brsInfo;??
- ????WCHAR?fdpath[MAX_PATH];?//接收選擇目錄的字符數組??
- ????WCHAR?fullPath[MAX_PATH];?//完整路徑??
- ??
- ????static?HWND?hfDlg;??
- ??
- ????switch?(message)??
- ????{??
- ????case?WM_CREATE:??
- ????????hfDlg?=?CreateDialog(hInst,?MAKEINTRESOURCE(IDD_FORMVIEW),?hWnd,?NULL);??
- ????????ShowWindow(hfDlg,SW_SHOW);??
- ????????break;??
- ????case?WM_COMMAND:??
- ????????wmId????=?LOWORD(wParam);??
- ????????wmEvent?=?HIWORD(wParam);??
- ????????//?分析菜單選擇:??
- ????????switch?(wmId)??
- ????????{??
- ????????case?IDM_ABOUT:??
- ????????????DialogBox(hInst,?MAKEINTRESOURCE(IDD_ABOUTBOX),?hWnd,?About);??
- ????????????break;??
- ????????case?IDM_EXIT:??
- ????????????DestroyWindow(hWnd);??
- ????????????break;??
- ????????case?IDM_BROWSFOLDER:??
- ????????????brsInfo.hwndOwner?=?hWnd;?//擁有者窗口??
- ????????????brsInfo.pidlRoot?=?NULL;?//根目錄為桌面??
- ????????????brsInfo.pszDisplayName?=?fdpath;?//返回的被選擇的路徑??
- ????????????brsInfo.lpszTitle?=?L"請選擇目錄";?//對話框標題??
- ????????????brsInfo.ulFlags=?BIF_RETURNONLYFSDIRS?|?BIF_DONTGOBELOWDOMAIN?|?BIF_NEWDIALOGSTYLE;?//不顯示網絡路徑??
- ????????????brsInfo.lpfn?=?NULL;?//沒有回調??
- ????????????brsInfo.lParam?=?NULL;?//沒有額外參數??
- ????????????//?初始化COM組件,用完后記得釋放??
- ????????????CoInitialize(NULL);??
- ????????????pIDLIST?=?SHBrowseForFolder(&brsInfo);??
- ????????????if(pIDLIST)??
- ????????????{??
- ????????????????//得到完整路徑??
- ????????????????SHGetPathFromIDList(pIDLIST,?fullPath);??
- ????????????????//取出對話框中用來顯示結果的控件??
- ????????????????HWND?hStatic?=?GetDlgItem(hfDlg,?IDC_DISPLAY);??
- ????????????????SendMessage(hStatic,?WM_SETTEXT,?NULL,?(LPARAM)fullPath);??
- ????????????????//SendMessage(hStatic,WM_SETTEXT,?NULL,?(LPARAM)fdpath);??
- ????????????}??
- ????????????CoUninitialize();??
- ????????????//?釋放IDLIST??
- ????????????CoTaskMemFree((LPVOID)pIDLIST);??
- ????????????break;??
- ????????default:??
- ????????????return?DefWindowProc(hWnd,?message,?wParam,?lParam);??
- ????????}??
- ????????break;??
- ????case?WM_PAINT:??
- ????????hdc?=?BeginPaint(hWnd,?&ps);??
- ????????//?TODO:?在此添加任意繪圖代碼...??
- ????????EndPaint(hWnd,?&ps);??
- ????????break;??
- ????case?WM_DESTROY:??
- ????????PostQuitMessage(0);??
- ????????break;??
- ????default:??
- ????????return?DefWindowProc(hWnd,?message,?wParam,?lParam);??
- ????}??
- ????return?0;??
- }??