问题
I'm trying to apply file's extension filters to the file's selection dialog.
This way works:
ofn.lpstrFilter =
"(*.exe) Windows Executable\0*.exe\0"
"(*.ini) Windows Initialization file \0*.ini\0"
"(*.dll) Dynamic Link Library \0*.dll\0"
"(*.lib) Windows Library file \0*.lib\0"
"(*.conf) Windows Configuration file \0*.conf\0";
But when I'm assigning extension filters dynamically, via parameters, it fails, filters don't appear in the combo box:
LPCSTR filter = (LPCSTR)extFilter; //Contains string "bmp"
stringstream s;
s << "(*.exe) Windows Executable\0" << "*." << filter << "\0";
string ffilter = s.str();
ofn.lpstrFilter = ffilter.c_str();
I'm assuming the problem is in strings conversion, but can't figure it out.
回答1:
This line:
s << "(*.exe) Windows Executable\0" << "*." << filter << "\0";
Is passing null-terminated char*
strings to operator<<()
, and thus is effectively behaving the same as this code at runtime:
s << "(*.exe) Windows Executable" << "*." << filter << "";
The nulls never make it into s
.
To insert the nulls correctly, you need to assign them to the stringstream
as individual char
values and not as char*
values:
s << "(*.exe) Windows Executable" << '\0' << "*." << filter << '\0';
Also, the fact that you are type-casting extFilter
is suspicious. If you have to do that to get rid of a compiler error then extFilter
is not a compatible data type to begin with, the type-cast is hiding a bug in your code. Get rid of the type-cast:
LPCSTR filter = extFilter; //Contains string "bmp"
If the code fails to compile then you are doing something wrong and need to fix it properly.
On the other hand, if extFilter
is a null-terminated char
string to begin with, you don't need to assign it to a variable before passing it to operator<<()
:
s << "(*.exe) Windows Executable" << '\0' << "*." << extFilter << '\0';
回答2:
You are using a pointer to some temporary string that, according to http://www.cplusplus.com/reference/string/string/c_str/, "may be invalidated by further calls to other member functions that modify the object."
回答3:
Finally found an answer:
const char * extensionFilter = myParamVar; //Contains "JPG" string
string sFilter;
sFilter.append("Format: ");
sFilter.append(extensionFilter);
sFilter.push_back('\0');
sFilter.append("*.");
sFilter.append(extensionFilter);
sFilter.push_back('\0');
//Current filter content --> Format: JPG\0*.JPG\0
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){
. . .
回答4:
A shorter version:
ofn.lpstrFilter = _T("Format: XML\0*.xml\0");
来源:https://stackoverflow.com/questions/34092427/winapi-getopenfilename-extension-filter-not-working