2016-02-14 6 views
-1

Я использую OPENFILENAME, чтобы открыть диалоговое окно просмотра в приложении win32.null завершающий символ не распознается

Я хочу, чтобы иметь возможность использовать динамический файл фильтрации в соответствии с тем, что пользователю нужно, а не предопределены ко всем файлам

ofn.lpstrFilter = L"All Files\0*.*\0\0"; 

Я пытался изменить стандартный код с динамическим, но, кажется, что даже нулевой завершающим символ обрабатывается как строка в коде ниже

string UserChoice = "Exe Files\0*.exe\0\0"; 
wstring ChoiceTemp = s2ws(UserChoice); // convert string to lpcwstr 
LPCWSTR FilterByUser = ChoiceTemp.c_str(); 
ofn.lpstrFilter = FilterByUser; 

кажется, что \ 0 не признается в качестве нулевого символа в диалоге просмотра файлов и он не показывает каких-либо файлов на всех, мои знания на C++ находится на моих первых шагах, и я не могу сделать это w ork без какой-либо помощи по этой проблеме, и я искал в сети, но ничего не пригодилось.

Любое предложение о том, как заставить его работать?

+0

Зачем вам эти нуль-терминаторы? 'std :: string' не нуждается в них. Вы можете просто назначить ему строку, а нуль-терминатор будет добавлен автоматически – ForceBru

+0

@Force Они требуются спецификацией API OPENFILENAME. Символы-ограничители NUL используются как разделители. Конечно, вся строка с двойным NUL завершена, поэтому вы все равно можете использовать 'std :: string', потому что она поддерживает встроенные NUL. –

+0

Весь этот код, который у вас есть, довольно бессмыслен. Если вам нужна широкая строка, просто создайте ее: 'std :: wstring UserChoice = L" EXE Files \ 0 * .exe \ 0 "'. Обратите также внимание на то, что в строковых литералах всегда есть неявный символ терминатора NUL, поэтому двойной '\ 0 \ 0' в конце не нужен. Тогда вы просто сделаете 'ofn.lpstrFilter = UserChoice.c_str()'. –

ответ

0

lpstrFilter обычно постоянная строка, поэтому нет никакой необходимости в std::wstring. Просто определить постоянную строку:

const wchar_t* filter = 
    L"All files\0*.*\0" 
    L"Exe files\0*.exe\0"; 

Но это может быть сделано следующим образом, если это необходимо (я повторяю @Joachim Pileborg)

std::wstring filter = 
    L"All files|*.*|" 
    L"Exe files|*.exe|"; 
std::replace(filter.begin(), filter.end(), '|', '\0'); 
ofn.lpstrFilter = filter.data(); 

Использование filter.data() вместо c_str(). Чтобы выбрать конкретный фильтр, используйте nFilterIndex

wchar_t filename[MAX_PATH]; 
wcscpy_s(filename, L"c:\\test\\default file.txt"); 

OPENFILENAME ofn = { sizeof(OPENFILENAME) }; 
ofn.lpstrFile = filename; 
ofn.nMaxFile = MAX_PATH; 
ofn.lpstrFilter = filter; 
ofn.nFilterIndex = 2; //select "Exe files" 
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; 
4

Вы можете использовать std::string для строк со встроенными терминаторами, но для создания строки вы должны использовать правильный std::string constructor.

Более конкретно то, где вы явно указываете длину (номер 4 в ссылке связанного конструктора) или итератор начала и конца (номер 6). В этом случае первый из них лучше:

string UserChoice("Exe Files\0*.exe\0", 16); 
+0

спасибо за ссылку, но мои знания не так хороши, но я не записываю определение, определение Exe Files \ 0 * .exe происходит от ввода пользователем, который приходит как строка, и мне просто нужно ввести его как значение в ofn.lpstrFilter. Что-то я делаю неправильно, и он не понимает \ 0 – Nocs

+0

@Nocs * Как * вы получаете строку? Откуда? Не то чтобы это важно, потому что вам нужно найти истинный конец строки, тогда вы можете сделать это, например. 'std :: string s = std :: string (the_actual_string, length_of_the_actual_string)' –

+0

строка UserChoice - это фактически то, что пользователь вводит в качестве выбора для фильтрации файлов – Nocs