我只是想弄清楚如何在MFC的m_ofn.lpstrCustomFilter中使用CFileDialog

内部结构是OPENFILENAME

我需要一个实际的示例,因为我发现的所有示例都将lpstrCustomFilter设置为NULL。

最佳答案

根据 OPENFILENAME 文档:



例如:

TCHAR szfilter[256] = TEXT("custom filter\0*.ext\0");

...

m_ofn.lpstrCustomFilter = szFilter;
m_ofn.nMaxCustFilter = 256;
m_ofn.nFilterIndex = 0;

该文档暗示,当第一次显示该对话框且nFilterIndex为0时,即使lpstrCustomFilter指定的初始筛选器与lpstrFilter指定的初始筛选器不同,初始筛选器仍处于 Activity 状态。如果用户随后选择/输入其他过滤器,则szfilter将更新为包含用户选择的过滤器。这样可以保存szFilter,以便下次显示对话框时,可以根据需要使用用户最后选择的过滤器来初始化对话框。

并且在实践中,这在XP和更早版本中可以正常工作。

在Windows 7(可能是Vista)和更高版本中,无论GetOpenFileName()的配置如何,OPENFILENAME 都不再像这样。 GetOpenFileName()只是忽略lpstrCustomFilter,从不应用初始的自定义过滤器,也从不覆盖szFilter缓冲区。这意味着lpstrCustomFilter现在已被弃用,不再使用,并且设置nFilterIndex=0会被静默提升为nFilterIndex=1。也许可以解释为什么所有示例都将lpstrCustomFilter设置为NULL

行为发生这种变化的原因是因为不推荐使用GetOpenFileName(),现在它成为 IFileOpenDialog 的包装,以向后兼容旧代码。 IFileOpenDialog不支持保留用户指定的过滤器,它仅与应用程序定义的过滤器一起使用。较新的对话框中没有用于设置或检索用户指定的过滤器的API,因此Microsoft显然没有使GetOpenFileName()包装程序尝试在较新的对话框中模拟旧的lpstrCustomFilter功能。

您可以尝试通过使用lpstrCustomFilter来手动模拟旧的lpstrFilter行为。为custom filter创建一个额外的条目。如果用户以前选择了文件,请使用所选文件的扩展名初始化该条目,并将nFilterIndex设置为该条目的从1开始的索引。然后,当对话框关闭时,使用lpstrFilenFileExtension提取用户实际选择的文件扩展名并保存,以便以后可以初始化custom filter条目。

10-08 19:22