1 - 文件选择对话框
#include <windows.h>
#include <stdio.h>
int main()
{
OPENFILENAME ofn;
static WCHAR szFile[256];
static WCHAR szFileTitle[256];
memset(&ofn, 0, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = GetConsoleWindow();// 得到cmd的句柄,低版本的VS可能不支持
// 下面这个语句的格式:
// 下拉框选项1:Picture File(*.bmp,*.jpg)
// \0
// 下拉框选项1 真正支持的格式 : *.bmp;*.jpg;,多个支持的格式间用;分隔
// \0
// 如果还需要在下拉框内添加选项,就继续按照上面的格式添加,这里是第二个下拉框选项:txt File(*.txt)
// \0
// 同上面的格式,这里是下拉框选项2 真正支持的格式 :*.txt
// \0
ofn.lpstrFilter = L"Picture File(*.bmp,*.jpg)\0*.bmp;*.jpg;\0txt File(*.txt)\0*.txt\0";
ofn.nFilterIndex = 1;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFileTitle = szFileTitle;
ofn.nMaxFileTitle = sizeof(szFileTitle);
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER;
//当按下确定按钮
if (GetOpenFileName(&ofn))
{
wprintf(szFile);
}
else
{
wprintf(L"cancel");
}
while(true);
return 0;
}
以上代码在VS2019编译通过。
如果需要打开保存文件的对话框,请将GetOpenFileName函数改为GetSaveFileName函数
最好使用下面这个封装好的:
简易封装:
#include <wchar.h>/* _wgetcwd函数所需头,用以得到本 */
// 选择文件
// isSave标志着是否为保存模式
const WCHAR* SelectFile(bool isSave = false)
{
OPENFILENAME ofn;
static WCHAR szFile[256];
static WCHAR szFileTitle[256];
memset(&ofn, 0, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = GetConsoleWindow();// 得到cmd的句柄,低版本的VS可能不支持
ofn.lpstrFilter = L"Redstone map File(*.rsp)\0*.rsp;\0All File(*.*)\0*.*;\0";
ofn.lpstrDefExt = L"rsp"; // 指向包含默认扩展名的缓冲。如果用户忘记输入扩展名,GetOpenFileName和GetSaveFileName附加这个扩展名到文件名中。
ofn.nFilterIndex = 1;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFileTitle = szFileTitle;
ofn.nMaxFileTitle = sizeof(szFileTitle);
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER;
wchar_t oldpath[1024] = { 0 };
_wgetcwd(oldpath, 1024);
if (isSave)
{
if (GetSaveFileName(&ofn))
{
SetCurrentDirectory(oldpath);
return szFile;
}
}
else
{
if (GetOpenFileName(&ofn))
{
SetCurrentDirectory(oldpath);
return szFile;
}
}
return L"";
}
由于GetSaveFileName和GetOpenFileName函数会改变程序自身目录,所以需要这一段
char oldpath[1024] = { 0 };
_getcwd(oldpath, 1024);
wchar_t woldpath[128] = { 0 };
MultiByteToWideChar(CP_ACP, 0, oldpath, -1, woldpath, 1024);
详见:
http://www.huidong.xyz/index.php?mode=2&id=173
对OPENFILENAME结构体的更多解释:https://blog.csdn.net/whatday/article/details/23286475
效果预览:
2 - 文件夹选择对话框
#include <Shlobj.h>
int main()
{
TCHAR szBuffer[MAX_PATH] = { 0 };
BROWSEINFO bi = { 0 };
bi.hwndOwner = NULL;//拥有着窗口句柄,为NULL表示对话框是非模态的,实际应用中一般都要有这个句柄
bi.pszDisplayName = szBuffer;//接收文件夹的缓冲区
bi.lpszTitle = TEXT("选择一个文件夹");//标题
bi.ulFlags = BIF_NEWDIALOGSTYLE;
LPITEMIDLIST idl = SHBrowseForFolder(&bi);
if (SHGetPathFromIDList(idl, szBuffer)) {
MessageBox(NULL, szBuffer, TEXT("你选择的文件夹"), 0);
}
else {
MessageBox(NULL, TEXT("请选择一个文件夹"), NULL, MB_ICONERROR);
}
return 0;
}
封装好的函数:
// 选择目录
// wnd:父窗口句柄
// title:选择文件夹对话框标题
wstring SelectFolder(HWND wnd = NULL, wstring title = L"选择一个文件夹")
{
TCHAR szBuffer[MAX_PATH] = { 0 };
BROWSEINFO bi = { 0 };
bi.hwndOwner = wnd; // 父窗口句柄,为NULL表示对话框是非模态的
bi.pszDisplayName = szBuffer; // 接收文件夹的缓冲区
bi.lpszTitle = title.c_str(); // 对话框标题
bi.ulFlags = BIF_NEWDIALOGSTYLE;
LPITEMIDLIST idl = SHBrowseForFolder(&bi);
if (SHGetPathFromIDList(idl, szBuffer)) {
return szBuffer;
}
else {
MessageBox(NULL, TEXT("请选择一个文件夹"), NULL, MB_ICONERROR);
return NULL;
}
}
VS2019编译通过,参考 https://blog.csdn.net/zuishikonghuan/article/details/47441163
效果: