当前位置: 动力学知识库 > 问答 > 编程问答 >

c++ - Is there a workaround for the character limit on the Windows API function GetOpenFileName() when OFN_ALLOWMULTISELECT?

问题描述:

According to the MSDN documentation, the function GetOpenFileName() has no character limit with option OFN_ALLOWMULTISELECT when compiled for Unicode with Windows 2000 and greater. However, on Windows XP x64 SP2, I'm finding that the 32k ANSI limit is still in effect, despite the use of Unicode. I've seen other complaints of this problem on the web, but no solutions. Does anyone know a simple work-around for this?

To be complete, I'm using Visual Studio 2010, and coding in C++.

网友答案:

The documentation might be wrong. GetOpenFileName() is somewhat deprecated, and it no longer supports the latest Vista/Windows 7 features. What's even worse is that GetOpenFileName() pops up an Open dialog that looks like the one in Windows 95, at least when you try to customize the dialog with the LPOFNHOOKPROC feature on Vista or Windows 7.

Beginning with Vista and Windows Server 2008, the new recommended API is the IFileDialog interface: http://www.codeproject.com/KB/vista/VGFileDialogs.aspx?msg=2368264. Unfortunately this isn't available on XP, therefore you need to implement both APIs depending on the OS version. If you need to add a few custom controls to your Open dialog, you have no choice at all but to use IFileDialogCustomize anyway.

I realize that your question was regarding Windows XP, and my suggested workaround won't help you, but unfortunately IFileDialog is the only alternative to GetOpenFileName().

网友答案:

Possibly a late answer, but I too had to deal with this issue and wanted to present my solutions in case others encounter this in the future (my condolences if you do). For those that wonders why use legacy GetOpenFileName(), if you are stuck with legacy .NET 1.1 and due to restrictions (in a real world, there are times when the person or organizations that are paying you to do this requires it), we have no other choices but to be bound to it, so please leave the criticisms aside and stick with OP's question. Also, one nice feature (I'm sure people can correct me on this) is that this method does not actually open the file when ALLOWMULTISELECT is set, thus you can use it as an interface to choose multiple files without eating the resources of each files opened as streams (i.e. imagine multi-selecting 1000+ files and each had a stream opened for it! - NOTE: .NET's OpenFileDialog also can do this since you have to explicitly call OpenFile() method to open the resources, thus iteration of Filenames property is possible, though it may give "InvalidOperationException: Too many files selected" if you exceed the mystery limits I've no clue about).

Firstly, despite what https://msdn.microsoft.com/en-us/library/windows/desktop/ms646927%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396 says in the remarks as

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 

Whether you explicitly call the "GetOpenFileNameW()" or let it internally switch to it, there is a 32KB limit on Windows XP (as OP mentions as well). Though I've not time to investigate, on Win7 and Server 2012 (64-bits), the same API call will switch correctly (apparently) to Unicode mode and bypasses the 32KB limit.

I've discovered that after reading the MSDN article on https://msdn.microsoft.com/en-us/library/ms996463.aspx?f=255&MSPPError=-2147217396 , If I trap WM_NOTIFY for CDN_SELCHANGE, query then for CDM_GETSPEC with a buffer that is quite large (i.e. greater than 32KB), you can in fact capture file list/collections greater than the 32KB limit. My apologies that the solution described in the MSDN article is C# and not C++, but the end-result should be the same.

分享给朋友:
您可能感兴趣的文章:
随机阅读: