无论如何,当使用OPENFILENAME struct和GetSaveFileName()时,SOMETHING会自动将所选文件扩展名添加到文件名中吗?

时间:2013-12-01 08:19:04

标签: winapi file-extension savefiledialog

我有这个功能:

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 个答案:

答案 0 :(得分:2)

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

lpstrDefExt = "rle";

文档解释了这一点:

  

<强> lpstrDefExt

     

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


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

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