Winapi GetOpenFileName 扩展过滤器不工作

Winapi GetOpenFileName Extension Filter not working

我正在尝试将文件的扩展名过滤器应用于文件的选择对话框。

这种方式可行:

ofn.lpstrFilter =   
"(*.exe) Windows Executable[=10=]*.exe[=10=]"
"(*.ini) Windows Initialization file [=10=]*.ini[=10=]"
"(*.dll) Dynamic Link Library [=10=]*.dll[=10=]"
"(*.lib) Windows Library file [=10=]*.lib[=10=]"
"(*.conf) Windows Configuration file [=10=]*.conf[=10=]";

但是当我通过参数动态分配扩展过滤器时,它失败了,过滤器没有出现在组合框中:

LPCSTR filter = (LPCSTR)extFilter; //Contains string "bmp"

stringstream s;
s << "(*.exe) Windows Executable[=11=]" << "*." << filter << "[=11=]";
string ffilter = s.str();
ofn.lpstrFilter = ffilter.c_str();

我假设问题出在字符串转换中,但无法弄清楚。

您正在使用指向某个临时字符串的指针,根据 http://www.cplusplus.com/reference/string/string/c_str/、"may be invalidated by further calls to other member functions that modify the object."

这一行:

s << "(*.exe) Windows Executable[=10=]" << "*." << filter << "[=10=]";

正在将以 null 结尾的 char* 字符串传递给 operator<<(),因此在运行时的行为实际上与以下代码相同:

s << "(*.exe) Windows Executable" << "*." << filter << "";

空值永远不会进入 s

要正确插入空值,您需要将它们作为单独的 char 值分配给 stringstream,而不是作为 char* 值:

s << "(*.exe) Windows Executable" << '[=12=]' << "*." << filter << '[=12=]';

此外,您进行类型转换的事实 extFilter 值得怀疑。如果您必须这样做才能消除编译器错误,那么 extFilter 不是一个兼容的数据类型,类型转换在您的代码中隐藏了一个错误。摆脱类型转换:

LPCSTR filter = extFilter; //Contains string "bmp"

如果代码无法编译,那么你做错了什么,需要正确修复它。

另一方面,如果 extFilter 是一个以 null 结尾的 char 字符串开头,则在将其传递给 [=16= 之前不需要将其分配给变量]:

s << "(*.exe) Windows Executable" << '[=14=]' << "*." << extFilter << '[=14=]';

终于找到答案了:

const char * extensionFilter = myParamVar; //Contains "JPG" string

string sFilter;
sFilter.append("Format: ");
sFilter.append(extensionFilter);
sFilter.push_back('[=10=]');
sFilter.append("*.");
sFilter.append(extensionFilter);
sFilter.push_back('[=10=]');

//Current filter content --> Format: JPG[=10=]*.JPG[=10=]

const char * filter = sFilter.c_str(); //Char string conversion
ofn.lpstrFilter = filter; //Set the filter to the sctructure's member.

//Opens the dialog and it successfully applies the filter.
if (GetOpenFileName(&ofn)==TRUE){
. . .

更短的版本:

ofn.lpstrFilter = _T("Format: XML[=10=]*.xml[=10=]");