c - GetSaveFileName()如何更新 "File name:"控件中的文件扩展名?

标签 c winapi visual-c++-6

我有以下代码(摘录)来显示“另存为”对话框:

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。

更新:这是 Hook 函数:

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

请注意, Hook 函数确实会在断点处停止。我故意不继续处理 CDN_TYPECHANGE,直到我弄清楚为什么在启用 Hook 时对话框的外观会发生变化以及如何修复它。

最佳答案

使用缓冲区作为建议的文件名,而不是静态字符串。

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.
}

关于c - GetSaveFileName()如何更新 "File name:"控件中的文件扩展名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14449280/

相关文章:

winapi - 使用 Win32 查看文件夹

command-line - 为 VC 6 构建命令行?

c++ - 在 Visual Studio 6 中从 VB 调用 VS2010 C++ dll

c - 为什么 EOF 在 fgets 和 read 中的行为不同

winapi - RTLCopyMemory 在 Vista 中工作吗?

c++ - 获取控件周围的 "padding"

c++ - 在 Visual C++ 6.0 MFC 中,是否可以将 CString 安全地视为简单类型而不是类?

c - 32 位字的镜像位

c - 使用 C 的插入排序

c - 我应该怎么做,如果用户输入我不想要的东西,它会在 C 中触发一条消息?