匯東網


使用 Win32 API 调用系统文件选择、文件夹选择对话框。

[編輯] [转简体]
|
作者:huidong | 分類:【編程】Win32
[ 18 瀏覽 0 評論 4 贊 4 踩 ]

概要

正文

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 


效果预览:

图片.png

图片.png


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


效果:

图片.png

图片.png


[ 4] [ 4]


 評論區  0 條評論

+ 添加評論