2016-08-24 21 views

回答

3

按照OPENFILENAME文档:

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

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

如果此部件是不NULL,所述nMaxCustFilter成员的值必须指定的大小,在字符,则lpstrCustomFilter缓冲液中。

nMaxCustFilter
类型:DWORD
大小,以字符,通过lpstrCustomFilter标识的缓冲液中。该缓冲区的长度至少应为40个字符。如果lpstrCustomFilterNULL或指向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。这可能解释了为什么所有示例只设置了lpstrCustomFilterNULL

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

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

+0

你做了一个惊人的解释。谢谢。 – basjak