Winapi GetOpenFileName Extension Filter not working

可紊 提交于 2019-12-11 17:58:12

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!