I found a bug in the Windows API function "GetOpenFileName()" that have fallen through cracks of many generations of Windows. The same problem exists in Windows NT, 2k and XP. Please take a look at the simple code below.
The code below creates an Open common dialog box that lets the user specify multiple files to open. The code executes fine if the user selects two or more files. However, if the user selects only one file, the API function "GetOpenFileName()" always fails and the error code indicates that the buffer is too small for the filename specified by the user, which is simply not true. But if I decrease the buffer size by 1 (i.e. change it from 0x20000 to 0x1FFFF), then the code will execute without any problem. I compiled the code using both Visual C++ and Borland C++, and both executables have the same behavior. Therefore this is not a compiler problem.
| const int size =
0x20000; LPSTR buffer = new char[size]; buffer[0]=0; OPENFILENAME ofn; ZeroMemory(&ofn, sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = GetActiveWindow(); ofn.lpstrFilter = "Any File (*.*)\0*.*\0\0"; ofn.lpstrFile = buffer; ofn.nMaxFile = size; ofn.Flags = OFN_EXPLORER|OFN_ALLOWMULTISELECT|OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST; if (!GetOpenFileName(&ofn)) { if (CommDlgExtendedError() == FNERR_BUFFERTOOSMALL) ; // show error message "Buffer is too small!" else ; // show other error messages } delete[] buffer; |
According to the help files that come with the compilers (as well as the online help at msdn.microsoft.com), the filename is stored differently in the buffer when the user selects only one file compared to the case where the user selects multiple files. My guess is, whoever wrote the API code for handling the case where the user selects only one file (when she is allowed to select multiple files), checks only the lower word of the buffer size instead of the whole double word.
Fortunately it is easy to go around this bug.
| Go to top |
This page was last modified on 02/29/2004.