在编写应用程序时,有时须要用户选择某个文件,以供应用程序使用,好比在某些管理程序中须要打开某一个进程,这个时候须要弹出一个对话框来将文件路径以树形图的形式表示出来,以图形化的方式供用户选择文件路径,而不是须要用户本身输入文件路径。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; }