Thread: Mysterious crashes in common file dialog

  1. #1
    Registered User
    Join Date
    Feb 2010
    Posts
    44

    Mysterious crashes in common file dialog

    I get some mysterious crashes w/out any messages when working with Common File Dialogs. I have a Dialog Box with three edit controls and three buttons (IDC_BUTTON1, IDC_BUTTON2, IDC_BUTTON3) to browse for files. I want to fill the Edit controls with the file names. Usually when I am pushing the third button the application crashes without a warning. Below I give the code for one button in the Dialog procedure. The other two are identical except that ofn has to be replaced by ofn1 and ofn2, respectively. And szFileName is replaced by szFileName1 and szFileName2, respectively.

    Code:
    case IDC_BUTTON1:
    				{
    
    					ZeroMemory(&ofn, sizeof(ofn));
    					
    					ofn.lStructSize = sizeof(ofn);
    					ofn.hwndOwner = hwnd;
    					ofn.lpstrFilter = TEXT("Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0");
    					ofn.lpstrFile = szFileName;
    					ofn.nMaxFile = MAX_PATH;
    					ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
    					ofn.lpstrDefExt = TEXT("txt");
    
    					if(GetOpenFileName(&ofn))
    					{
    
    						ILength = lstrlen(szFileName);
    						buffer = (LPWSTR)GlobalAlloc(GPTR, ILength*sizeof(TCHAR));
    						if(buffer)
    						{
    							wsprintf(buffer, szFileName);
    							SetDlgItemText(hwnd, IDC_EDIT1, (LPWSTR) buffer);
    							GlobalFree((HANDLE)buffer);
    						}
    					}
    
    				}
    			break;
    And for completeness, the variables are as such:

    Code:
    	OPENFILENAME ofn, ofn1, ofn2;
    	wchar_t szFileName[MAX_PATH] = TEXT("");
    	wchar_t szFileName1[MAX_PATH] = TEXT("");
    	wchar_t szFileName2[MAX_PATH] = TEXT("");
    	int ILength;
    	LPWSTR buffer;
    Has anyone encountered this problem before? Thanx.

  2. #2
    Registered User
    Join Date
    Feb 2010
    Posts
    44
    Ok, never mind. I found the problem. I made the classic mistake of allocating a buffer with the same length as the outcome of lstrlen. This way there is no space for the null terminating characters (in case of wide characters) and the application crashes.

  3. #3
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    The filter should be double NULL terminated.

    Each file type is delimited by a NULL terminator and 2 in a row signals the end of the filter list.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  4. #4
    Registered User
    Join Date
    Feb 2010
    Posts
    44
    oh, I thought TEXT() was terminating the string with an extra '\0'. Are you sure about the extra '\0', because the problem seems to be solved by replacing ILength by ILength + 1 in the allocation of buffer.

  5. #5
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    AFAIK the TEXT() macro only 'converts' between UNICODE and ANSI depending on the define in the app, it does not add any terminators.

    Read MSDN on the format required for the 'Filter' param, it is quite clear that it needs two terminators (but may not crash this app or crash the app everytime, especially if you are only testing a debug version or within the IDE).
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Code:
    	ILength = lstrlen(szFileName);
    	buffer = (LPWSTR)GlobalAlloc(GPTR, ILength*sizeof(TCHAR));
    	if(buffer)
    	{
    		wsprintf(buffer, szFileName);
    1. Your length is short by 1 character. Starting with "abc", you get a length of 3, but you actually need 4 to store it (but I see you've fixed that one).
    2. do NOT USE wsprintf like that to simply copy a string. If szFileName has a % character, you're well and truly screwed.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    Quote Originally Posted by novacain View Post
    AFAIK the TEXT() macro only 'converts' between UNICODE and ANSI depending on the define in the app, it does not add any terminators.
    The fact that it's a string literal tells you it automatically ends in a null terminator, which in this case happens to be the second behind the explicit one.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    The TEXT macro is only defined as either:
    #define TEXT(x) x
    Or
    #define TEXT(x) L##x
    So, as you see, it adds no null terminator. It ONLY takes into account Unicode/ANSI string literals.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Quote Originally Posted by adeyblue View Post
    The fact that it's a string literal tells you it automatically ends in a null terminator, which in this case happens to be the second behind the explicit one.
    Yes of course. Opps.
    Last edited by novacain; 02-28-2010 at 11:52 PM.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can we have vector of vector?
    By ketu1 in forum C++ Programming
    Replies: 24
    Last Post: 01-03-2008, 05:02 AM
  2. C++ std routines
    By siavoshkc in forum C++ Programming
    Replies: 33
    Last Post: 07-28-2006, 12:13 AM
  3. Post...
    By maxorator in forum C++ Programming
    Replies: 12
    Last Post: 10-11-2005, 08:39 AM
  4. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  5. System
    By drdroid in forum C++ Programming
    Replies: 3
    Last Post: 06-28-2002, 10:12 PM