当使用 OPENFILENAME 结构和 GetSaveFileName() 时,是不是有任何方法可以让 SOMETHING 自动将选定的文件扩展名添加到文件名?

Posted

技术标签:

【中文标题】当使用 OPENFILENAME 结构和 GetSaveFileName() 时,是不是有任何方法可以让 SOMETHING 自动将选定的文件扩展名添加到文件名?【英文标题】:Is there anyway to make SOMETHING automatically add selected file extension to filename, when OPENFILENAME struct and GetSaveFileName() are used?当使用 OPENFILENAME 结构和 GetSaveFileName() 时,是否有任何方法可以让 SOMETHING 自动将选定的文件扩展名添加到文件名? 【发布时间】:2013-12-01 08:19:04 【问题描述】:

我有这个功能:

void PickupFileAndSave(std::vector<unsigned char> file_data, int *error_code, char *file_mask = "All files (*.*)\0*.*\0\0")

    OPENFILENAMEA ofn;       // common dialog box structure
    char szFile[MAX_PATH];   // buffer for file name
    char initial_dir[MAX_PATH] =  0 ;
    GetStartupPath(initial_dir);

    // Initialize OPENFILENAME
    ZeroMemory(&ofn, sizeof(ofn));
    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = GetActiveWindow();
    ofn.lpstrFile = szFile;
    // Set lpstrFile[0] to '\0' so that GetOpenFileName does not 
    // use the contents of szFile to initialize itself.
    ofn.lpstrFile[0] = '\0';
    ofn.nMaxFile = sizeof(szFile);
    ofn.lpstrFilter = file_mask;
    ofn.nFilterIndex = 1;
    ofn.lpstrFileTitle = NULL;
    ofn.nMaxFileTitle = 0;
    ofn.lpstrInitialDir = initial_dir;
    ofn.Flags = OFN_PATHMUSTEXIST | OFN_EXPLORER;

    if (!GetSaveFileNameA(&ofn))
    
        *error_code = GetLastError();
        return;
    

    char err_msg[1024] =  0 ;
    std::string file_name = ofn.lpstrFile; //this stores path to file without extension
    file_name.append(".");
    file_name.append(ofn.lpstrDefExt); //this is NULL and fails to copy too
    WriteAllBytes(file_name.c_str(), &file_data[0], file_data.size(), &err_msg[0]);

    if (strlen(err_msg) > 0)
    
        *error_code = GetLastError();
        return;
           

我是这样称呼的:

int write_error = 0;
PickupFileAndSave(compressed, &write_error, "RLE compressed files (*.rle)\0*.rle\0\0");

当我选择文件时,它会显示在过滤器所需的扩展名中,但不要将其添加到 lpstrFile

任何想法为什么以及如何解决它?

【问题讨论】:

【参考方案1】:

您没有指定 lpstrDefExt,因此系统不会添加扩展名以防您忽略它。因此,您只需在显示对话框之前初始化该字段:

lpstrDefExt = "rle";

文档解释了这一点:

lpstrDefExt

默认扩展名。如果用户未能键入扩展名,则 GetOpenFileName 和 GetSaveFileName 将此扩展名附加到文件名中。此字符串可以是任意长度,但仅附加前三个字符。该字符串不应包含句点 (.)。如果此成员为 NULL 并且用户未能键入扩展名,则不附加任何扩展名。


问题中的代码尚不清楚,但您希望处理存在多个过滤器并且希望附加所选过滤器的扩展名的情况。

系统不会为您执行此操作,因此您必须这样做。显示对话框后阅读 nFilterIndex。这会告诉您用户选择了哪个过滤器。然后解析过滤器字符串以获得选择的扩展名,如果没有扩展名,则将其附加到文件名中。

【讨论】:

有没有办法只添加 SELECTED 扩展?我不需要默认扩展名。如果我添加更多过滤器和更多扩展,除了 rle 怎么办?我尝试使用 lpstrDefExt 只是因为希望至少在那里找到扩展名。 阅读你的问题,看看我为什么这样解释它!使用 lpstrDefExt 查看您的代码。您的过滤器中只有一个扩展名。这不回答你问的问题吗?也许你应该改变问题,问你真正想问的问题。或者,如果您在得到答案后对更改问题感到不快,请提出一个新问题。 很抱歉,如果这让您感到困惑。我解释了为什么我曾经为 lpstrDefExt 烦恼。我希望至少能找到任何可以添加到文件名的扩展名 >_ 只有一个分机。您的过滤器只有 .rle。 如果我添加更多扩展,但默认扩展设置为“rle”怎么办?然后...用户选择一些“.dsa”,但我的代码会添加“rle”?我需要添加选定的扩展程序。

以上是关于当使用 OPENFILENAME 结构和 GetSaveFileName() 时,是不是有任何方法可以让 SOMETHING 自动将选定的文件扩展名添加到文件名?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Windows 中更改 OPENFILENAME 对话框的位置?

C++ ( MS V S ) 获取OpenFileName

scanf() gets() fgets()使用注意事项

为啥 OPENFILENAME lpstrFileTitle 参数是 LPSTR 而不是 LPCSTR?

关于使用gets()函数的问题

如何使用gets()读取无符号字符数组?