Thread: Unknown crash. LOGFONT, static, MSDN.

  1. #1
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465

    Unknown crash. LOGFONT, static, MSDN.

    I'm a little confused. I found this: http://msdn.microsoft.com/library/default..../usingmenus.asp

    And in the link it does this.

    Code:
    HFONT GetAFont(int fnFont) 
    { 
    	static LOGFONT lf;  // structure for font information  
     
    	// Get a handle to the ANSI fixed-pitch font, and copy 
    	// information about the font to a LOGFONT structure. 
     
    	GetObject(GetStockObject(ANSI_FIXED_FONT), sizeof(LOGFONT), 
    		&lf); 
     
    	// Set the font attributes, as appropriate.  
     
    	if (fnFont == BOLD) 
    		lf.lfWeight = FW_BOLD; 
    	else 
    		lf.lfWeight = FW_NORMAL; 
     
    	lf.lfItalic = (fnFont == ITALIC); 
    	lf.lfItalic = (fnFont == ULINE); 
     
    	// Create the font, and then return its handle.  
     
    	return CreateFont(lf.lfHeight, lf.lfWidth, 
    		lf.lfEscapement, lf.lfOrientation, lf.lfWeight, 
    		lf.lfItalic, lf.lfUnderline, lf.lfStrikeOut, lf.lfCharSet, 
    		lf.lfOutPrecision, lf.lfClipPrecision, lf.lfQuality, 
    		lf.lfPitchAndFamily, lf.lfFaceName); 
    }
    I was trying to do a similar thing in my own code.

    Code:
    		case WM_CREATE:
    		{
    			LOGFONT lFont;
    			HFONT   hFont;
    
    			::GetObject
    				(::GetStockObject(ANSI_FIXED_FONT), 
    				sizeof LOGFONT, 
    				&lFont);
    
    			_tcsncpy
    				(lFont.lfFaceName,
    				_T("Courier New"),
    				sizeof lFont.lfFaceName);
    
    			hFont = ::CreateFontIndirect(&lFont);
    			break;
    		}
    Doesn't do anything. But that's because, hey, it crashes! Before it hits the break, it calls some procedure that um, does some wierd stuff, and then crashes I think with an unhandled exception (that may have been raised in this procedure). Disassembly ends up like this yo.

    Code:
    0040118E   . 6A 40		PUSH 40
    00401190   . 8D4C24 38	        LEA ECX,DWORD PTR SS:[ESP+38]
    00401194   . 68 94814000	PUSH Dialog_T.00408194
    00401199   . 51			PUSH ECX
    0040119A   . E8 3C020000	CALL Dialog_T.004013DB
    0040119F   . 83C4 0C		ADD ESP,0C
    004011A2   . 8D5424 18	        LEA EDX,DWORD PTR SS:[ESP+18]
    004011A6   . 52			PUSH EDX
    004011A7   . FF15 04804000      CALL DWORD PTR DS:[<&GDI32.CreateFontInd>
    004011AD   . 5F			POP EDI
    004011AE   . 33C0		XOR EAX,EAX
    004011B0   . 5E		        POP ESI
    004011B1   . 8B4C24 6C	        MOV ECX,DWORD PTR SS:[ESP+6C]
    004011B5   . 33CC		XOR ECX,ESP
    004011B7   . E8 10020000	CALL Dialog_T.004013CC
    004011BC   . 83C4 70		ADD ESP,70
    004011BF   . C2 1000		RETN 10
    That CALL Dialog_T.004013CC there at the end does it. Um. Yeah, that CALL is made unconditionally, and I can't understand it. But the wierd part is, after being all mystified by the fact that it was crashing, I made my LOGFONT structure static, like in MSDN's code, and it did not crash. In fact, the disassembly does not contain that last call.

    Code:
    00401166   . 6A 40		PUSH 40
    00401168   . 68 94814000	PUSH Dialog_T.00408194
    0040116D   . 68 DCAC4000	PUSH Dialog_T.0040ACDC
    00401172   . E8 04020000	CALL Dialog_T.0040137B
    00401177   . 83C4 0C		ADD ESP,0C
    0040117A   . 68 C0AC4000	PUSH Dialog_T.0040ACC0
    0040117F   . FF15 04804000      CALL DWORD PTR DS:[<&GDI32.CreateFontInd>
    00401185   . 33C0		XOR EAX,EAX
    00401187   . 83C4 10		ADD ESP,10
    0040118A   . C2 1000		RETN 10
    See, not there. So, my question is:

    Why does my LOGFONT structure have to be static, and if possible, why did it crash in the first place? Nothing in the CreateFontIndirect/LOGFONT documentation about such craziness. All replies appreciated.

    http://msdn.microsoft.com/library/default....ontext_4rw4.asp
    http://msdn.microsoft.com/library/default....ontext_1wmq.asp
    Last edited by Tonto; 07-30-2006 at 01:51 PM.

  2. #2
    Registered User
    Join Date
    Mar 2005
    Posts
    135
    A static variable is created once during a programs lifetime and last until the program is terminated. Are you using the non-static LOGFONT variable outside your WM_CREATE handler?

  3. #3
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    Not at all. I do not do anything to it, I was going to use the HFONT from CreateFontIndirect, which uses the LOGFONT, but the documentation says nothing about it requiring to have static residence.

  4. #4
    Registered User
    Join Date
    May 2006
    Posts
    903
    I don't know, but that call to _tcsncpy seems quite weird to me even though I don't know what this function does. It's probably some kind of strcpy() alter-ego and well, you can juste make the pointer point to the string:
    Code:
    lFont.lfFaceName = "Courier New";
    Also, sizeof doesn't return the number of character, you need strlen() for that and its return value doesn't count the null terminator.

  5. #5
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    Quote Originally Posted by MSVC++ 2005
    1>.\main.cpp(128) : error C2440: '=' : cannot convert from 'const wchar_t [12]' to 'WCHAR [32]'
    1> There is no context in which this conversion is possible
    It's not a pointer, it's an array. WCHAR is a typedef for wchar_t.

    Code:
    WCHAR lfFaceName[LF_FACESIZE];
    I can't assign to the array like that outside of initialization. I could have used strlen (_tcslen) but sizeof works, if it isn't copying more than the sizeof the array, I can say that it's doing it's job.

  6. #6
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    The first thing to say is: Don't use strncpy, wcsncpy or _tcsncpy.

    If you need a safe string copy, use prefereably StringCchCopy (available in <strsafe.h>), lstrcpyn (available in <windows.h>) or for other platforms strlcpy.

    The reason for the crash is a buffer overrun. The cause is given in a prominent warning on the documentation page for lstrcpyn:
    Quote Originally Posted by MSDN
    Also, when copying an entire string, note that sizeof returns the number of bytes, which is incorrect for the Unicode version of this function. Instead, use sizeof(lpString2)/sizeof(TCHAR)

  7. #7
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    Wow. Thanks so much! I would have never guessed that that was the problem. Bleh.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How do i do this? (static structure inside class)
    By 39ster in forum C++ Programming
    Replies: 4
    Last Post: 11-17-2008, 03:14 AM
  2. Errors including <windows.h>
    By jw232 in forum Windows Programming
    Replies: 4
    Last Post: 07-29-2008, 01:29 PM
  3. get keyboard and mouse events
    By ratte in forum Linux Programming
    Replies: 10
    Last Post: 11-17-2007, 05:42 PM
  4. Please Help - Problem with Compilers
    By toonlover in forum C++ Programming
    Replies: 5
    Last Post: 07-23-2005, 10:03 AM
  5. UNICODE and GET_STATE
    By Registered in forum C++ Programming
    Replies: 1
    Last Post: 07-15-2002, 03:23 PM