当OFN_ALLOWMULTISELECT时,是否有针对Windows API函数GetOpenFileName()的字符限制的解决方法?

时间:2010-11-05 16:06:45

标签: c++ windows visual-studio-2010 user-interface getopenfilename

根据MSDN文档,当使用Windows 2000及更高版本编译Unicode时,函数GetOpenFileName()没有使用选项OFN_ALLOWMULTISELECT的字符限制。但是,在Windows XP x64 SP2上,我发现尽管使用了Unicode,32k ANSI限制仍然有效。我在网上看到过关于这个问题的其他抱怨,但没有解决方案。有没有人知道一个简单的解决办法呢?

要完成,我正在使用Visual Studio 2010,并使用C ++进行编码。

2 个答案:

答案 0 :(得分:4)

文档可能有误。 GetOpenFileName()有些不推荐使用,它不再支持最新的Vista / Windows 7功能。更糟糕的是,GetOpenFileName()会弹出一个类似于Windows 95中的Open对话框,至少当您尝试在Vista或Windows 7上使用LPOFNHOOKPROC功能自定义对话框时。

从Vista和Windows Server 2008开始,新推荐的API是IFileDialog界面:http://www.codeproject.com/KB/vista/VGFileDialogs.aspx?msg=2368264。不幸的是,这在XP上不可用,因此您需要根据操作系统版本实现这两个API。如果您需要在“打开”对话框中添加一些自定义控件,那么除了使用IFileDialogCustomize之外别无选择。

我意识到您的问题与Windows XP有关,我建议的解决方法对您没有帮助,但不幸的是,IFileDialog是GetOpenFileName()的唯一选择。

答案 1 :(得分:1)

可能是一个迟到的答案,但我也不得不处理这个问题,并希望提出我的解决方案以防其他人在未来遇到这个问题(如果你这样做,我表示哀悼)。对于那些想知道为什么要使用遗留GetOpenFileName()的人来说,如果你遇到遗留的.NET 1.1并且由于限制(在现实世界中,有时候支付你的人或组织需要它),我们别无选择,只能受其约束,所以请把批评放在一边,坚持OP的问题。此外,一个很好的功能(我确信人们可以纠正我)是这个方法实际上并没有设置ALLOWMULTISELECT打开文件,因此你可以使用它作为一个界面来选择多个文件而不吃资源每个文件作为流打开(即想象多选1000+文件,每个文件都有一个流为它打开! - 注意:.NET的OpenFileDialog也可以这样做,因为你必须显式调用OpenFile()方法打开资源,因此Filenames属性的迭代是可能的,虽然它可能会给出" InvalidOperationException:选择了太多的文件"如果你超出神秘限制,我就不知道了。

首先,尽管https://msdn.microsoft.com/en-us/library/windows/desktop/ms646927%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396在评论中说的是

Note, when selecting multiple files, the total character limit for the file names depends on the version of the function.
    • ANSI: 32k limit
    • Unicode: no restriction 

是否明确调用" GetOpenFileNameW()"或者让它在内部切换到它,Windows XP有32KB的限制(也提到OP)。虽然我没有时间调查,但在Win7和Server 2012(64位)上,相同的API调用将正确(显然)切换到Unicode模式并绕过32KB限制。

我在https://msdn.microsoft.com/en-us/library/ms996463.aspx?f=255&MSPPError=-2147217396上阅读MSDN文章之后发现,如果我为CDN_SELCHANGE捕获WM_NOTIFY,那么查询CDM_GETSPEC的缓冲区是非常大的(即大于32KB),你可以在事实上捕获文件列表/集合大于32KB的限制。我很抱歉MSDN文章中描述的解决方案是C#而不是C ++,但最终结果应该是相同的。