2

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++.

Michael Repucci
  • 1,633
  • 2
  • 19
  • 35
  • Perhaps definitions of "no limit" differ. 32K is getting into "this buffer has an invalid size" long territory. The Ansi limit for single files was MAX_PATH or 260 characters iirc. – Chris Becke Nov 05 '10 at 16:24
  • AFAIK, the Unicode and ANSI limit for single file paths is MAX_PATH (260 on XP+). But I'm not sure what you're getting at with the "this buffer has an invalid size" territory. The size of the buffer in the OPENFILENAME structure (see http://msdn.microsoft.com/en-us/library/ms646839%28VS.85%29.aspx) passed to GetOpenFileName is a DWORD (unsigned long), so the limit should be much greater than 32k. – Michael Repucci Nov 05 '10 at 16:35
  • Strange question. Of course there's a workaround, use GetOpenFileNameW(). – Hans Passant Nov 05 '10 at 16:54
  • Strange answer. GetOpenFileNameW() is the function called when you use GetOpenFileName() and compile for Unicode. So that presents the same problem. – Michael Repucci Nov 08 '10 at 16:15
  • I mean that 32K is big enough that it might exceed an overly paranoid sanity check limit on the buffer. – Chris Becke Nov 09 '10 at 19:34
  • That would appear to be, at least approximately, what is happening. Mind you, the limit is not exactly 32K. In one particular case, the buffer contained around 31400 characters (wchar_t), and I've seen others report the same message for around 29K characters. So it's pretty unclear where this limit comes from, let alone how to circumvent it. – Michael Repucci Nov 10 '10 at 15:14
  • To clarify other's who thinks the 32KB limit is filepaths length, MSDN states "Note, when selecting multiple files, the total character limit for the file names depends on the version of the function" (as in, selecting multiple files, totaling to be more than 32KB - we're having issues when selecting 1260 files on XP). For the record, same API call to ComDlg32.dll on Win7 succeeds. I've ended up here because I was searching to find out what ComDlgExtendedError() returns. – HidekiAI May 14 '15 at 18:41

2 Answers2

4

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().

Tamas Demjen
  • 690
  • 1
  • 6
  • 8
1

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.

HidekiAI
  • 3,013
  • 3
  • 20
  • 22