我只想弄清楚如何在MFC&#39 {s} m_ofn.lpstrCustomFilter
中使用CFileDialog
。
内部结构是OPENFILENAME
。
我需要一个实际的例子,因为我发现的所有例子都是将lpstrCustomFilter
设置为NULL。
答案 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开始的索引。然后,当对话框关闭时,使用lpstrFile
和nFileExtension
提取用户的实际所选文件扩展名并保存,以便稍后初始化custom filter
条目。