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=]");
我正在尝试将文件的扩展名过滤器应用于文件的选择对话框。
这种方式可行:
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=]");