-
June 11th, 2012, 11:58 AM
#1
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.
-
June 11th, 2012, 12:20 PM
#2
Re: SelectObject() doesn't work in non-static wndproc
hFont is uninitialized in NewWindowFunction.
-
June 11th, 2012, 03:22 PM
#3
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.
-
June 11th, 2012, 05:16 PM
#4
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.
-
June 11th, 2012, 06:12 PM
#5
Re: SelectObject() doesn't work in non-static wndproc
I'm using only pure WinAPI and my own classes.
-
June 12th, 2012, 02:02 AM
#6
Re: SelectObject() doesn't work in non-static wndproc
Originally Posted by Distrust
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
-
June 12th, 2012, 05:33 AM
#7
Re: SelectObject() doesn't work in non-static wndproc
Originally Posted by Distrust
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
-
June 12th, 2012, 08:35 AM
#8
Re: SelectObject() doesn't work in non-static wndproc
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.
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.
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?
-
June 12th, 2012, 09:38 AM
#9
Re: SelectObject() doesn't work in non-static wndproc
Originally Posted by Distrust
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
-
June 12th, 2012, 10:19 AM
#10
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.
-
June 12th, 2012, 04:08 PM
#11
Re: SelectObject() doesn't work in non-static wndproc
Originally Posted by Distrust
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|