Microsoft Knowledge Base Email Alertz

(131462) - When an application uses the Open File common dialog with the OFN_ALLOWMULTISELECT flag, there is a danger that the buffer passed to the common dialog in the OPENFILENAME.lpstrFile field will be too small. In this situation, GetOpenFileName() will...

Search KbAlertz

Advanced Search

Receive Microsoft Knowledge Base articles by E-Mail?

Every night we scan the Microsoft Knowledge Base. If technologies you're interested in are updated, we'll send you an e-mail. You only get one e-mail a day, and only when new articles are added.

Click here to create a
FREE account
Already have an account?
[Click here to Login]











Microsoft Knowledge Base Article

This article contents is Microsoft Copyrighted material.
©2005-©2007 Microsoft Corporation. All rights reserved. Terms of Use | Trademarks

Article ID: 131462 - Last Review: November 21, 2006 - Revision: 4.3

How To Handle FNERR_BUFFERTOOSMALL in Windows

This article was previously published under Q131462

SUMMARY

When an application uses the Open File common dialog with the OFN_ALLOWMULTISELECT flag, there is a danger that the buffer passed to the common dialog in the OPENFILENAME.lpstrFile field will be too small. In this situation, GetOpenFileName() will return an error value and CommDlgExtendedError() will return FNERR_BUFFERTOOSMALL.

MORE INFORMATION

When you install a hook on the Open File common dialog using the OPENFILENAME.lpfnHook member, the dialog you are hooking is a child of the main Open File dialog. In CDN_SELCHANGE, you should check to see if the buffer originally allocated is large enough to handle all the files selected. You should reallocate the buffer if neccessary and free the previous allocated buffer to prevent memory leaks.

Here is an example of the subclass procedure:
extern "C"
{
WNDPROC* g_lpfnDialogProc =NULL;


unsigned int CALLBACK DialogHook(HWND hwnd, UINT uMsg, WPARAM wParam,
                          LPARAM lParam)
{
	static HWND hwndParentDialog;
	LPOFNOTIFY lpofn;
	int cbLength;
	static LPTSTR lpsz;
	static int LastLen;
	
	switch (uMsg)
	{
	case WM_INITDIALOG:
          // You need to use a copy of the OPENFILENAME struct used to
          // create this dialog. You can store a pointer to the
          // OPENFILENAME struct in the ofn.lCustData so you can
          // retrieve it here in the lParam. Once you have it, you
          // need to hang on to it. Using window properties provides a
          // good thread safe solution to using a global variable.

          if(!SetProp(GetParent(hwnd), "OFN", (void *) lParam))
	  MessageBox(NULL, "SET PRop Failed", "ERROR", MB_OK);
          return (0);

	  case WM_COMMAND:
		  {
			OutputDebugString("command\n");
		  }
		  break;
      case WM_NOTIFY:
          // The OFNOTIFY struct is passed in the lParam of this
          // message.

          lpofn = (LPOFNOTIFY) lParam;

          switch (lpofn->hdr.code)
          {
 	  	case CDN_SELCHANGE:
			  
		LPOPENFILENAME lpofn;
		cbLength = CommDlg_OpenSave_GetSpec(GetParent(hwnd), NULL, 0);
		  
		cbLength += _MAX_PATH;
		
   	     // The OFN struct is stored in a property of dialog window
			  		  
		lpofn = (LPOPENFILENAME) GetProp(GetParent(hwnd),
						  "OFN");
			
		if (lpofn->nMaxFile < cbLength)  

		{
			  // Free the previously allocated buffer.
			  if(lpsz)
				  HeapFree(GetProcessHeap(),
							0,
 				 	                lpsz);
  			 // Allocate a new buffer
			  lpsz = (LPTSTR) HeapAlloc(GetProcessHeap(),
						HEAP_ZERO_MEMORY,
						cbLength);
			  if (lpsz)
			  {
					  
				  lpofn->lpstrFile = lpsz;
				  lpofn->nMaxFile  = cbLength;
			  }
		  }
		  break;
			  
         }
          return (0);

      case WM_DESTROY:

          // Also need to free the property with the OPENFILENAME
          // struct.
          RemoveProp(GetParent(hwnd), "OFN");
          return (0);
  }
  return (0);
} 
				
Finally, this technique only works for 32-bit applications that are using the Explorer-type common dialogs.

Windows 95/98: For 32-bit applications that do not use the OFN_EXPLORER flag, it thunks to the 16-bit common dialog and the hook function only gets a copy of the OPENFILENAME structure.

Windows NT/2000: Applications should use Unicode version of the Open file Common dialog. For example, use OPENFILENAMEW structure and call GetOpenFileNameW API. This workaround will not work for Ansi version of open file Common dialog.

APPLIES TO
  • Microsoft Win32 Application Programming Interface, when used with:
    • Microsoft Windows 95
    • Microsoft Windows 98 Standard Edition
    • Microsoft Windows NT 4.0
    • Microsoft Windows 2000 Standard Edition
Keywords: 
kbcmndlgfileo kbhowto KB131462
       

Community Feedback System

Very often, it takes hours to solve a problem. Very often, you've looked high and low, and have tried a lot of solutions. When you finally found it, chances are, it was because someone else helped you. Here's your chance to give back. Use our community feedback tool to let others know what worked for you and what didn't.

Please also understand that the community feedback system is not warranted to be correct, it's simply a system that we've built to let people try and help each other. If something in a feedback response doesn't make sense to you, or you're not comfortable making changes that the feedback talks about (like registry edits), please consult a professional.

Thank you for using kbAlertz.com Feedback System.

-- Scott Cate

sapphire - sapphire Report As Irrelevant  
Written: 4/12/2005 4:08 AM
...but how do i fire the file ok event in this case?