MFC,OPENFILENAME结构:m_ofn.lpstrCustomFilter

时间:2016-08-24 18:09:15

标签: c++ windows c++11 mfc

我只想弄清楚如何在MFC&#39 {s} m_ofn.lpstrCustomFilter中使用CFileDialog

内部结构是OPENFILENAME

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

1 个答案:

答案 0 :(得分:3)

根据OPENFILENAME文档:

  

<强> lpstrCustomFilter
  键入: LPTSTR
  一个静态缓冲区,包含一对以null结尾的过滤器字符串,用于保留用户选择的过滤器模式。第一个字符串是描述自定义过滤器的显示字符串,第二个字符串是用户选择的过滤器模式。应用程序第一次创建对话框时,指定第一个字符串,可以是任何非空字符串。当用户选择文件时,该对话框将当前过滤器模式复制到第二个字符串。保留的过滤器模式可以是 lpstrFilter 缓冲区中指定的模式之一,也可以是用户键入的过滤器模式。系统在下次创建对话框时使用字符串初始化用户定义的文件过滤器。如果 nFilterIndex 成员为零,则对话框将使用自定义过滤器。

     

如果此成员 NULL ,则该对话框不会保留用户定义的过滤器模式。

     

如果此成员不是 NULL ,则 nMaxCustFilter 成员的值必须指定 lpstrCustomFilter 缓冲区的大小(以字符为单位)。

     

<强> nMaxCustFilter
  键入: DWORD
  由 lpstrCustomFilter 标识的缓冲区的大小(以字符为单位)。此缓冲区长度至少应为40个字符。如果 lpstrCustomFilter NULL 或指向 NULL 字符串,则会忽略此成员。

例如:

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指定的过滤器不同。如果用户随后选择/输入其他过滤器,则会更新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条目。