在編寫應用程序時,有時須要用戶選擇某個文件,以供應用程序使用,好比在某些管理程序中須要打開某一個進程,這個時候須要彈出一個對話框來將文件路徑以樹形圖的形式表示出來,以圖形化的方式供用戶選擇文件路徑,而不是須要用戶本身輸入文件路徑。windows
在MFC中可以彈出對話框供用戶選擇文件路徑的類是CFileDialog,可是這個類的主要問題是當用戶選擇文件路徑後,會打開相關的文件,與咱們的要求不符,在Windows平臺下有兩個函數SHBrowseForFolder、SHGetPathFromIDList。這兩個函數的說明以下:函數
LPITEMIDLIST WINAPI SHBrowseForFolder(
LPBROWSEINFO lpbi
);
該函數的主要做用是彈出一個對話框,便於用戶選擇文件的路徑,傳遞的參數是一個LPBROWSEINFO的結構體,這個結構體的原型以下:spa
typedef struct _browseinfo { HWND hwndOwner;//該對話框的屬主窗口句柄 LPCITEMIDLIST pidlRoot;//對話框中顯示的最上層目錄 LPTSTR pszDisplayName;//指向一個緩衝區,用於返回用戶選擇的文件名 LPCTSTR lpszTitle;//文件對話框的標題 UINT ulFlags;//文件對話框相關標誌 BFFCALLBACK lpfn;//文件對話框對應的回調函數的地址 LPARAM lParam;//附加參數 int iImage;//返回用戶選中的圖片的索引 } BROWSEINFO, *PBROWSEINFO, *LPBROWSEINFO;
其中最主要的參數是pszDisplayName,這個參數指向一個緩衝區,用於存儲用戶選擇的文件名(只是文件名不包括具體的路徑);lpszTitle這個參數表示的是對話框的具體名稱,這兩個參數有一個沒有給則會形成程序的錯誤,主要是對話框不能出來。另外的是標誌的變量,通常使用的是BIF_BROWSEINCLUDEFILES(容許用戶選擇文件)、BIF_RETURNONLYFSDIRS(只能選擇目錄,不能選擇文件)指針
在用戶選擇了相關的文件並點擊對話框中的肯定時,會返回一個LPITEMIDLIST的指針,這個結構表示的是文件系統的相關信息,接下來就是利用函數SHGetPathFromIDList來真正獲取用戶選擇的文件路徑,該函數的原型以下:code
WINSHELLAPI BOOL WINAPI SHGetPathFromIDList(
LPCITEMIDLIST pidl,
LPSTR pszPath
);
該函數主要利用pidl對應的文件系統的相關信息,經過第二個參數返回文件的路徑,下面是具體的例子:blog
#include <windows.h> #include <Shlobj.h> #include <tchar.h> #include <Commctrl.h> #pragma comment(lib, "comctl32.lib") int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { LPITEMIDLIST pil = NULL; INITCOMMONCONTROLSEX InitCtrls = {0}; TCHAR szBuf[4096] = {0}; BROWSEINFO bi = {0}; bi.hwndOwner = NULL; bi.iImage = 0; bi.lParam = NULL; bi.lpfn = NULL; bi.lpszTitle = _T("請選擇文件路徑"); bi.pszDisplayName = szBuf; bi.ulFlags = BIF_BROWSEINCLUDEFILES; InitCommonControlsEx(&InitCtrls);//在調用函數SHBrowseForFolder以前須要調用該函數初始化相關環境 pil = SHBrowseForFolder(&bi); if (NULL != pil)//若函數執行成功,而且用戶選擇問件路徑並點擊肯定 { SHGetPathFromIDList(pil, szBuf);//獲取用戶選擇的文件路徑 wprintf_s(_T("%s"), szBuf); } return 0; }