使用 Win32 API 调用系统文件选择、文件夹选择对话框。
[編輯] [转简体] (简体译文)
|
作者:huidong
| 分類:【編程】Win32
1 - 文件选择对话框
[
14 瀏覽
0 評論
1 贊
2 踩
]
概要
正文
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
效果: