2015-12-04 5 views
0

Я пытаюсь применить фильтры расширения файла к диалоговому окну файла.Winapi GetOpenFileName Extension Filter не работает

Этот способ работает:

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"; 

enter image description here

Но когда я задаю расширения фильтры динамически, с помощью параметров, это не удается, фильтры не появляются в поле со списком:

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(); 

enter image description here

Я принимаю Проблема заключается в преобразовании строк, но не может понять это.

+0

Не тестировался, я предположим, что разделитель '' \ 0'' может нанести вред 'stringstream'. Если да, то как насчет использования другого символа, такого как '$' как разделителя, и после завершения построения фильтра скопируйте строку в массив 'char' и преобразуйте' '' '' в '' \ 0''? – MikeCAT

+0

Пробовали ли вы смотреть на 'ffilter' в отладчике, чтобы увидеть, что он содержит? –

+0

Любые новости здесь? Люди ждут ... :) –

ответ

-1

Наконец нашел ответ :

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){ 
. . . 
0

Вы используете указатель на некоторую временную строку, которая, согласно http://www.cplusplus.com/reference/string/string/c_str/, «может быть признана недействительной дальнейшими вызовами других функций-членов, которые изменяют объект».

+0

«Любые дальнейшие вызовы методов» маловероятны, поскольку их может не быть.Скорее всего, что временный stringstream сам вышел из сферы действия и получил освобождение. – andlabs

+0

Временно не задействовано. Содержимое 'stringstream' присваивается переменной' string', которая остается в области действия до тех пор, пока диалог не будет отклонен. –

+0

@RemyLebeau - Это хорошая догадка, но я не вижу вызова диалога в опубликованном фрагменте. –

1

Эта линия:

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

проходит нуль завершающим char* строки в operator<<(), и, таким образом, эффективно вести себя так же, как этот код во время выполнения:

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

В обнуляет никогда не превратить его в s.

Чтобы правильно вставить аннулирует, вам необходимо назначить их stringstream как индивидуальные char ценности и не как char* значения:

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

Кроме того, тот факт, что вы типа литья extFilter подозрительна. Если вам нужно сделать это, чтобы избавиться от ошибки компилятора, то extFilter не является совместимым типом данных, чтобы начать с того, что тип-литье скрывает ошибку в вашем коде. Избавиться от типа отлитого:

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

Если код не компилировать, то вы делаете что-то неправильно, и нужно, чтобы исправить это правильно.

С другой стороны, если extFilter является завершающим нулем char строку, чтобы начать с того, что вам не нужно, чтобы присвоить его переменной перед передачей его operator<<():

s << "(*.exe) Windows Executable" << '\0' << "*." << extFilter << '\0'; 
0

Сокращенный вариант:

ofn.lpstrFilter = _T("Format: XML\0*.xml\0");