Текущая версия документации Windows API для Структура OPENFILENAME
гласит (выделено мной):
lpstrDefExt
Type:LPCTSTR
The default extension.
GetOpenFileName
andGetSaveFileName
append this extension to the file name if the user fails to type an extension. This string can be any length, but only the first three characters are appended. The string should not contain a period (.). If this member isNULL
and the user fails to type an extension, no extension is appended.
Это неверно, как показывает выполнение следующего MVCE в Windows 10 (сборка 17134.5):
#include <stdio.h>
#include <Windows.h>
int main()
{
wchar_t filename[256] = { 0 };
OPENFILENAMEW ofn =
{
.lStructSize = sizeof(OPENFILENAMEW),
.lpstrFilter = L"All Files\0*.*\0\0",
.lpstrFile = filename,
.nMaxFile = sizeof(filename),
.lpstrDefExt = L"xlsx"
};
BOOL ret = GetSaveFileNameW(&ofn);
if (ret != 0)
{
wprintf(L"%s\r\n", filename);
}
}
Ввод test
в диалоговом окне «Сохранить файл» дает C:\Users\...\Documents\test.xlsx
, а не C:\Users\...\Documents\test.xls
, как утверждается в документации.
Когда произошло это изменение, т.е. на каких целевых системах я могу полагаться на то, что lpstrDefExt
поддерживает более трех символов?
@CodeCaster: Спасибо, это очень актуально! "по крайней мере, с Vista ..." было бы идеально, так как мне нужно поддерживать Windows 7 / Server 2008 и выше.
В Vista и более поздних версиях Get(Open|Save)FileName()
являются оболочками для новых интерфейсов IFile(Open|Save)Dialog
(если вы не укажете флаг OFN_ENABLEHOOK
), которые не имеют многих из тех же ограничений, что и старые API.
Кроме того, начиная с Vista рекомендуется использовать Диалог обычных предметов, а не GetOpenFilename.
Это началось 25 лет назад, начиная с эмуляции имен файлов MS-Dos 8.3. Файл с именем longfilename.xlsx имеет дополнительную запись в каталоге, которая будет напоминать longfi ~ 1.xls. Что соответствует подстановочному знаку * .xls. Эту поддержку давно пора отключить, особенно для версий x64, которые больше не могут поддерживать 16-битный код, но сегодня все еще включены по умолчанию. Все, что вы можете с этим сделать, - это проверить имена, которые вы получите.
@RemyLebeau: Ради удовольствия, я просто попытался добавить крючок. Он по-прежнему поддерживает расширение длинного имени файла, но, вау, полученный диалог вернул 16-битную память: imgur.com/a/bEPtMTL
@theB: Хороший совет. В моем случае это не вариант, поскольку мы вызываем диалог из VBA, а эти диалоги не работают с VBA. Я только что создал программу C как MVCE.
@Heinzi Вы можете получить диалог Win95-XP с помощью ловушки, вам просто нужно включить флаг проводника, иначе вы получите стиль Windows 3.