CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11
  1. #1
    Join Date
    Aug 2011
    Location
    Poland
    Posts
    12

    SelectObject() doesn't work in non-static wndproc

    I have a base class for my window. All is working fine excluding SelectObject(). This function
    doesn't set font handle to device context, so text is painting using system font. Why? Because of different place in memory? Why other functions such as SetBkMode() work?

    P.S. Of course, always work, only one WM_PAINT. I typed two to show the essence of the problem.

    Code:
    // In this static function SelectObject() works, but not in non-static (NewWindowFunction):
    LRESULT CALLBACK CChildWnd::StaticWindowFunction(HWND hWnd, UINT uMsg, WPARAM wPar, LPARAM lPar)
    {
    	if (uMsg == WM_NCCREATE)
    		SetWindowLong(hWnd, GWL_USERDATA, (LONG) ((CREATESTRUCT *)lPar)->lpCreateParams);
    	CChildWnd *pSelf = (CChildWnd *)GetWindowLong(hWnd, GWL_USERDATA);
    
    	if (uMsg == WM_PAINT) // Only for test
    	{
    		PAINTSTRUCT ps;
    		HDC hDC;
    		HFONT hFont;
    		HFONT hOldFont;
    		RECT rect;
    
    		hDC = BeginPaint(hWnd, &ps);
    			hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
    			hOldFont = (HFONT)SelectObject(hDC, hFont); // Here it's ok!
    
    			GetClientRect(hWnd, &rect);
    			DrawTextExW(hDC, L"1111", 4, &rect, DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_INTERNAL, NULL);
    
    			SelectObject(hDC, hOldFont);
    		EndPaint(hWnd, &ps);
    
    		return (LRESULT) 1;
    	}
    
    	return pSelf->NewWindowFunction(hWnd, uMsg, wPar, lPar);
    }
    
    LRESULT CALLBACK CChildWnd::NewWindowFunction(HWND hWnd, UINT uMsg, WPARAM wPar, LPARAM lPar)
    {
    	PAINTSTRUCT ps;
    	HDC hDC;
    	HFONT hFont;
    	HFONT hOldFont;
    	RECT rect;
    
    	switch (uMsg)
    	{
    		case WM_PAINT:
    			hDC = BeginPaint(hWnd, &ps);
    			        hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
    				hOldFont = (HFONT)SelectObject(hDC, hFont); // Does not work.
    
    				GetClientRect(hWnd, &rect);
    				DrawTextExW(hDC, L"1111", 4, &rect, DT_LEFT | DT_NOPREFIX | DT_SINGLELINE | DT_INTERNAL, NULL);
    		
    				SelectObject(hDC, hOldFont);
    			EndPaint(hWnd, &ps);
    
    			return (LRESULT) 1;
    		break;
    		case WM_DESTROY:
    			PostQuitMessage(0);
    		break;
    		default:
    			return DefWindowProc(hWnd, uMsg, wPar, lPar);
    	}
    
    	return 0;
    }
    Last edited by Distrust; June 11th, 2012 at 04:37 PM.

  2. #2
    Join Date
    Oct 2006
    Location
    Sweden
    Posts
    3,654

    Re: SelectObject() doesn't work in non-static wndproc

    hFont is uninitialized in NewWindowFunction.
    Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible, you are, by
    definition, not smart enough to debug it.
    - Brian W. Kernighan

    To enhance your chance's of getting an answer be sure to read
    http://www.codeguru.com/forum/announ...nouncementid=6
    and http://www.codeguru.com/forum/showthread.php?t=366302 before posting

    Refresh your memory on formatting tags here
    http://www.codeguru.com/forum/misc.php?do=bbcode

    Get your free MS compiler here
    https://visualstudio.microsoft.com/vs

  3. #3
    Join Date
    Aug 2011
    Location
    Poland
    Posts
    12

    Re: SelectObject() doesn't work in non-static wndproc

    Only in this piece of code that I posted on forum. Sorry, i just fixed it. The problem still exists.

  4. #4
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: SelectObject() doesn't work in non-static wndproc

    If using MFC, try the scoping operator (double colons, "::"), to get out of MFC scope and into SDK scope:
    Code:
    hOldFont = (HFONT)::SelectObject(hDC, hFont); // Does not work.

  5. #5
    Join Date
    Aug 2011
    Location
    Poland
    Posts
    12

    Re: SelectObject() doesn't work in non-static wndproc

    I'm using only pure WinAPI and my own classes.

  6. #6
    Join Date
    Apr 1999
    Posts
    27,449

    Re: SelectObject() doesn't work in non-static wndproc

    Quote Originally Posted by Distrust View Post
    Only in this piece of code that I posted on forum. Sorry, i just fixed it. The problem still exists.
    Why are you not checking the return value of SelectObject? If SelectObject fails, the function returns an error. You should be checking for return values for all of those Windows API functions you're calling, and not assume they just work:

    http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx
    I'm using only pure WinAPI and my own classes.
    So how are we to know if your own classes are the cause for the failure?

    Regards,

    Paul McKenzie

  7. #7
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: SelectObject() doesn't work in non-static wndproc

    Quote Originally Posted by Distrust View Post
    Only in this piece of code that I posted on forum. Sorry, i just fixed it. The problem still exists.
    Is your NewWindowFunction ever called? For what messages?
    I don't see any way it could be called in the case of WM_PAINT
    Victor Nijegorodov

  8. #8
    Join Date
    Aug 2011
    Location
    Poland
    Posts
    12

    Re: SelectObject() doesn't work in non-static wndproc

    Quote Originally Posted by Paul McKenzie
    Why are you not checking the return value of SelectObject? If SelectObject fails, the function returns an error. You should be checking for return values for all of those Windows API functions you're calling, and not assume they just work:
    Yes, you're right. My mistake.

    Quote Originally Posted by Paul McKenzie
    So how are we to know if your own classes are the cause for the failure?
    I would have to show much more code. Rather, no one would like to read this. Anyway it is not a good idea.

    Quote Originally Posted by VictorN
    Is your NewWindowFunction ever called? For what messages?
    I don't see any way it could be called in the case of WM_PAINT
    For WM_DESTROY message.

    I found the problem source.

    If I create my font inside object constructor it is ok - hFont isn't NULL. Before calling SelectObject() I'm checking this variable again - it still isn't NULL. Return value of SelectObject() is NULL and text is drawing using system font. But if I create my font just before SelectObject() - everything goes fine - return value of SelectObject() isn't NULL and text is drawing using my font. Strange...

    I haven't any duplicates of hFont variable.

    By the way - does the SelectObject function use GetLastError function?

  9. #9
    Join Date
    Apr 1999
    Posts
    27,449

    Re: SelectObject() doesn't work in non-static wndproc

    Quote Originally Posted by Distrust View Post
    If I create my font inside object constructor it is ok - hFont isn't NULL. Before calling SelectObject() I'm checking this variable again - it still isn't NULL. Return value of SelectObject() is NULL and text is drawing using system font. But if I create my font just before SelectObject() - everything goes fine - return value of SelectObject() isn't NULL and text is drawing using my font. Strange...
    It doesn't matter if it's NULL or not, what is the value that is returned by GetStockObject inside the constructor?
    I haven't any duplicates of hFont variable.
    How about comparing the value of the hFont variable that you initialized in the constructor with the value returned by GetStockObject when you create the font before you call SelectObject? Are the values the same?

    Regards,

    Paul McKenzie

  10. #10
    Join Date
    Aug 2011
    Location
    Poland
    Posts
    12

    Re: SelectObject() doesn't work in non-static wndproc

    It's hard to say, because when i compare them just before I call SelectObject they aren't the same - first value is negative, second is positive (after casting them to int). But if I view the value of hFont variable in constructor immediately after GetStockObject for example through the MessageBox and then just before SelectObject it seems that they are the same.

  11. #11
    Join Date
    Apr 1999
    Posts
    27,449

    Re: SelectObject() doesn't work in non-static wndproc

    Quote Originally Posted by Distrust View Post
    It's hard to say, because when i compare them just before I call SelectObject they aren't the same - first value is negative, second is positive (after casting them to int). But if I view the value of hFont variable in constructor immediately after GetStockObject for example through the MessageBox and then just before SelectObject it seems that they are the same.
    Another question concerning your design -- should a constructor be doing all of this work? What if the font creation failed during construction? Do you throw an exception, or is your class created but unusable?

    I can see if you were assigning the constant DEFAULT_GUI_FONT to an int variable during construction, and then later on create the font based on the value of this int. But actually attempting to build the font during construction is IMO not what a constructor is supposed to do. Leave that for when you actually do need the font, i.e on WM_PAINT.

    Regards,

    Paul McKenzie

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured