GetOpenFileName никогда не возвращается при компиляции в режиме отладки (VS2010) - PullRequest
3 голосов
/ 10 ноября 2011

Когда я компилирую свою программу в режиме отладки, GetOpenFileName(&ofn) никогда не возвращается.

Отлично работает в режиме релиза. Единственное отличие, которое я могу заметить, заключается в том, что многие вещи оптимизируются в режиме релиза.

OPENFILENAME ofn;
TCHAR szFile[MAX_PATH];

szFile[0] = '\0';
szFile[1] = '\0';

//Initialize OPENFILENAME
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
ofn.lpstrFile = szFile;
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFilter = TEXT("Images (*.jpg;*.png;*.bmp;*.tga;*.psd)\0*.jpg;*.png;*.bmp;*.tga;*.psd\0\0");
ofn.lpstrInitialDir = TEXT(".");
ofn.lpstrTitle = TEXT("Open 512x512 image");
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
...
GetOpenFileName(&ofn)

Я компилирую, используя набор символов Unicode.

Если я удаляю \0 из середины ofn.lpstrFilter, он работает в режиме отладки, но, очевидно, фильтр работает неправильно.

Вот так выглядит строка в памяти как в режиме отладки, так и в режиме выпуска вокруг точки \0:

...snip...
0x00364BB4  70 00  p.
0x00364BB6  73 00  s.
0x00364BB8  64 00  d.
0x00364BBA  29 00  ).
0x00364BBC  00 00  ..
0x00364BBE  2e 00  ..
0x00364BC0  6a 00  j.
0x00364BC2  70 00  p.
0x00364BC4  67 00  g.
0x00364BC6  3b 00  ;.
...snip...

Я, вероятно, делаю что-то глупое (у меня нет большого опыта в Winapi / w Unicode), но я не могу понять, что. Есть идеи?

РЕДАКТИРОВАТЬ: Обновлено с текущим кодом.

В основном

ofn.lpstrFilter = TEXT("Images (*.jpg;*.png;*.bmp;*.tga;*.psd)*.jpg;*.png;*.bmp;*.tga;*.psd\0");
                                                              ^

работает, но

ofn.lpstrFilter = TEXT("Images (*.jpg;*.png;*.bmp;*.tga;*.psd)\0*.jpg;*.png;*.bmp;*.tga;*.psd\0");
                                                              ^

нет.

EDIT: попытался воспроизвести ту же ошибку в свежем проекте Visual Studio, но я не смог. Оно работает. Сделал различия в настройках проекта, и нет никаких различий между мэрами.

Ответы [ 3 ]

3 голосов
/ 10 ноября 2011

1 ofn.lpstrFilter должен заканчиваться двумя нулями: \0\0.

2 Вы уверены, что ZeroMemory() действительно обнуляет содержимое ofn.Вместо этого вы можете попробовать SecureZeroMemory().

Ссылаясь на 2 a заметку из msdn :

Используйте эту функцию [SecureZeroMemory ()] вместо ZeroMemory, когда хотитечтобы гарантировать, что ваши данные будут быстро перезаписаны, так как некоторые компиляторы C ++ могут оптимизировать вызов ZeroMemory, удалив его полностью.

Я бы просто использовал memset().

2 голосов
/ 10 ноября 2011

Я, наконец, выделил единственную разницу между сборками:

Я использовал Visual Leak Detector в моей отладочной сборке.После удаления он начал работать.

Я постараюсь разобраться, почему это происходит, но я просто хотел поблагодарить всех, кто пытался мне помочь.Хотелось бы получить больше очков.

У некоторых людей, имеющих подобные проблемы:

2 голосов
/ 10 ноября 2011

Несколько вещей ...

1) Вы инициализируете lpstrFile дважды.

ofn.lpstrFile = szFile;
ofn.lpstrFile = TEXT('\0');

2) Вы должны инициализировать szFile (вероятно, ваше намерение в # 1):

TCHAR szFile[MAX_PATH];
szFile[0] = '\0';

3) nMaxFile должно быть максимальное количество символов, а не байтов. Итак, вы хотите либо MAX_PATH, либо sizeof(szFile) / sizeof(TCHAR).

4) В вашем фильтре файлов отсутствует '*': должно быть * .jpg

...