GetSaveFileName () как обновить расширение файла в элементе управления Имя файла:?

У меня есть следующий код (отрывок) для отображения диалогового окна «Сохранить как»:

char FileName[MAX_PATH] = "TestImage.jpg"

...

lpofn.lStructSize = sizeof(OPENFILENAME);
lpofn.hwndOwner = hWnd;
lpofn.hInstance = GetWindowInstance (hWnd);
lpofn.lpstrFilter = "JPG - JPEG File\0*.JPG\0TIF - TIFF File\0*.TIF\0PNG File\0*.PNG\0BMP - Bitmat File\0*.BMP\0";
lpofn.lpstrCustomFilter = NULL;
lpofn.nMaxCustFilter = NULL;
lpofn.nFilterIndex = 0;
lpofn.lpstrFile = FileName;
lpofn.nMaxFile = MAX_PATH;
lpofn.lpstrFileTitle = NULL;
lpofn.nMaxFileTitle = NULL;
lpofn.lpstrInitialDir = NULL;
lpofn.lpstrTitle = NULL;
lpofn.Flags = OFN_HIDEREADONLY | OFN_ENABLEHOOK | OFN_EXPLORER;
lpofn.nFileOffset = 0;
lpofn.nFileExtension = 0;
lpofn.lpstrDefExt = NULL;
lpofn.lCustData = NULL;
lpofn.lpfnHook = &UpdateFilename;
lpofn.lpTemplateName = NULL;
if(!GetSaveFileName(&lpofn)) return;

...

например. - Пользователь сохраняет как, имя файла по умолчанию = "TestImage.jpg", тип файлов по умолчанию = JPG - Пользователь меняет тип файлов на PNG, для управления именем файла остается "TestImage.jpg" вместо изменения на "TestImage.png"

Я делаю что-то неправильно? Можно ли указать GetSaveFileName () изменить расширение, или мне нужно иметь настраиваемый диалог сохранения как (какие-либо примеры?)

Я использую Win32 API, VC6.

Обновление: вот функция перехвата:

UINT CALLBACK UpdateFilename(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uiMsg)
    {
         case WM_NOTIFY:
          // Check for CDN_TYPECHANGE etc
              return FALSE;
    }

    return FALSE;
}

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


person user1998558    schedule 21.01.2013    source источник


Ответы (2)


Чтобы обновить диалоговое окно, пока оно все еще запущено, вам необходимо предоставить указатель на обратный вызов lpfnHook в структуре OPENFILENAME и обработать обработчик обратного вызова _ 3_ уведомление. Он может отправить диалоговое окно CDM_GETFILEPATH или _ 5_ сообщение, чтобы получить текущее имя файла, настроить его при необходимости, а затем отправить _ 6_, чтобы обновить поле редактирования (идентификатор поля редактирования имени файла - 0x442) новое значение.

Обновление: в вашем коде ловушки все в порядке. GetSaveFileName() устарел, начиная с Windows Vista, заменен (и становится оболочкой) Common Диалог элемента. Пользовательский интерфейс диалога GSFN не изменяется ловушкой в ​​XP, поэтому вы должны использовать Vista +, и в этом случае включение ловушки просто заставляет оболочку использовать другие настройки при внутреннем вызове CID. Многие новые функции CID основаны на IShellItem, а не на строках имен файлов. , поэтому оболочка удаляет все, что не может быть представлено как имя файла в старом стиле, и делает диалог похожим на диалог GSFN старого стиля в XP и ранее. Итак, вы видите нормальное поведение для GetSaveFileName() под Vista +! Если вам это не нравится, не используйте больше GetSaveFileName(). Вместо этого используйте новый интерфейс IFileSaveDialog. Фактически, он изначально изменяет расширение файла для вас, если вы настраиваете несколько типов файлов, назначаете один из них как расширение по умолчанию, а затем устанавливаете начальное имя файла, которое соответствует расширению по умолчанию. Но при желании можно также реализовать интерфейс IFileDialogEvents в своем код для получения уведомлений OnTypeChange, а затем использовать _ 15_, чтобы обновить отображаемое имя файла по мере необходимости.

person Remy Lebeau    schedule 22.01.2013
comment
Спасибо, я реализовал ловушку, но внешний вид диалога полностью изменился? Не слишком уверен, как объяснить, но он меняется со стандартного диалогового окна «Сохранить как» на урезанную версию. Я попробовал как OFNHookProcOldStyle, так и OFNHookProc, оба выглядели по-разному, но дали аналогичный урезанный диалог. Можно ли реализовать хук и сохранить стандартный вид? - person user1998558; 22.01.2013
comment
Можете ли вы обновить свой вопрос, указав фактический код ловушки, который вы используете? - person Remy Lebeau; 22.01.2013
comment
Готово, обратите внимание, что я намеренно не продолжал обрабатывать CDN_TYPECHANGE, пока не изменится внешний вид диалогового окна. Также спасибо, что сообщили мне о CDN_TYPECHANGE, это был хороший указатель. Кроме того, поскольку я на самом деле не обрабатываю сообщение, я вернул ЛОЖЬ вместо ИСТИНА. - person user1998558; 23.01.2013

Используйте буфер для предложенного имени файла, а не статическую строку.

char szFile[MAX_PATH]; 
szFile[0] = '\0';
lpofn.lpstrFile= szFile; 
lpofn.nMaxFile = sizeof(szFile)/ sizeof(*szFile);

Кроме того, это стандартное поведение Windows, восходящее ко временам Win95. Поскольку вы используете VS6.0, у вас все еще есть эти библиотеки DLL. Что я тогда сделал, так это использовать:

lpofn.lpstrDefExt = (LPSTR)NULL

Это предотвращает добавление любого расширения. Затем по возвращении я проверил lpofn.nFileExtension, чтобы узнать, какое расширение было выбрано.

if (lpofn.nFileExtension == 0)
{
// add default extension, no extension was selected/entered by user
}
else
{
 // there is an extension, save as entered.
}
person Flot2011    schedule 22.01.2013
comment
Спасибо, это похоже на то, что я делаю сейчас. Я не знал, что это поведение по умолчанию. - person user1998558; 22.01.2013