From: Paul N on
My code seems to be working, but I am worried that it may be very
wasteful. The actual code is a bit complicated, but here is a working
cut-down example that (I think) illustrates the point:

void makeitalic(HDC hdc) {
LOGFONT lf;
HGDIOBJ hgdiobj;
HFONT hfont;

hgdiobj = GetCurrentObject(hdc, OBJ_FONT);
GetObject(hgdiobj, sizeof lf, &lf);
lf.lfItalic = TRUE;
hfont = CreateFontIndirect(&lf);
SelectObject(hdc, hfont);
}

(in WndProc)

case WM_PAINT:
PAINTSTRUCT ps;
HDC hdc;

hdc = BeginPaint (hWnd, &ps);
TextOut(hdc, 10, 10, _TEXT("Test"), 4);
makeitalic(hdc);
TextOut(hdc, 10, 30, _TEXT("Italic"), 6);
EndPaint (hWnd, &ps);
break;

This shows text, in both normal and italic. But I am worried that it
may be filling up memory by creating a new font every time a window is
displayed. Should I be saving the results somewhere and reusing them?
Or deleting them promptly after use? Is there any discussion of this
point that I could read up on?

Thanks for any help.
Paul.
From: ScottMcP [MVP] on
On Apr 9, 7:04 am, Paul N <gw7...(a)aol.com> wrote:
> My code seems to be working, but I am worried that it may be very
> wasteful. The actual code is a bit complicated, but here is a working
> cut-down example that (I think) illustrates the point:
>
> void makeitalic(HDC hdc) {
> LOGFONT lf;
> HGDIOBJ hgdiobj;
> HFONT hfont;
>
> hgdiobj = GetCurrentObject(hdc, OBJ_FONT);
> GetObject(hgdiobj, sizeof lf, &lf);
> lf.lfItalic = TRUE;
> hfont = CreateFontIndirect(&lf);
> SelectObject(hdc, hfont);
>
> }
>
> (in WndProc)
>
>         case WM_PAINT:
>                 PAINTSTRUCT ps;
>                 HDC hdc;
>
>                 hdc = BeginPaint (hWnd, &ps);
>                 TextOut(hdc, 10, 10, _TEXT("Test"), 4);
>                 makeitalic(hdc);
>                 TextOut(hdc, 10, 30, _TEXT("Italic"), 6);
>                 EndPaint (hWnd, &ps);
>                 break;
>
> This shows text, in both normal and italic. But I am worried that it
> may be filling up memory by creating a new font every time a window is
> displayed. Should I be saving the results somewhere and reusing them?
> Or deleting them promptly after use? Is there any discussion of this
> point that I could read up on?
>
> Thanks for any help.
> Paul.

You are right to worry. It is leaking the font handle and after a
while it will probably cause messed up painting.

When you use SelectObject (with any type of GDI object) you are
obligated to later restore the state of the HDC to what it was. This
can be done by saving the return from the SelectObject call, and later
selecting the returned object back in to the HDC. Or it can be done
with SaveDC and RestoreDC.

When you create a font you are obligated to later use DeleteObject to
free it. And, you can't delete it if it is still selected into DC!
So you have a double boo boo here with basic painting rules.

And finally, for the sake of efficiency it makes more sense to create
the font one time only, outside of the WM_PAINT handler. Keep the
font handle in memory.
From: Matti Vuori on
Paul N <gw7rib(a)aol.com> wrote in news:282089d1-6cf8-447f-87f6-
7a223fcd0b41(a)u22g2000yqf.googlegroups.com:
> This shows text, in both normal and italic. But I am worried that it
> may be filling up memory by creating a new font every time a window is
> displayed. Should I be saving the results somewhere and reusing them?
> Or deleting them promptly after use? Is there any discussion of this
> point that I could read up on?

The logical fonts that you create with CreateFontIndirect() are objects
like anything else and you must keep track of them and delete them at
some point with DeleteObject().

In this case, you probably should create a variable that stays alive
during the window messages, but the easiest way is to delete the italic
font and reselect the old font.

Your naming convention could also perhaps be made cleare to help in not
making errors later on. In this case many people might name the font
variables:
HFONT oldfont (not HGDIOBJ... use a cast; oldfont = (HFONT)
GetCurrentObject() )
HFONT italic_font (currently hfont)

So, when done with the font, at the end of WMM_PAINT:
SelectObject(oldfont);
DeleteObject(italic_font);


From: Paul N on
On 9 Apr, 14:21, "ScottMcP [MVP]" <scott...(a)mvps.org> wrote:
> You are right to worry.  It is leaking the font handle and after a
> while it will probably cause messed up painting.
>
> When you use SelectObject (with any type of GDI object) you are
> obligated to later restore the state of the HDC to what it was.  This
> can be done by saving the return from the SelectObject call, and later
> selecting the returned object back in to the HDC.  Or it can be done
> with SaveDC and RestoreDC.
>
> When you create a font you are obligated to later use DeleteObject to
> free it.  And, you can't delete it if it is still selected into DC!
> So you have a double boo boo here with basic painting rules.
>
> And finally, for the sake of efficiency it makes more sense to create
> the font one time only, outside of the WM_PAINT handler.  Keep the
> font handle in memory.

Thanks Scott and Matti. I thinbk I shall have to do some planning here
but you have pointed me in the right direction.

Just one quick question - is there a value for HFONT which is
guaranteed not to actually be a font? Such as 0? (Like the way a NULL
pointer is used to show that malloc has failed.) This would be handy
as a way to keep track of which fonts I've actually generated.

Thanks again.
Paul.
From: Arny on
On 09.04.2010 16:32, Paul N wrote:
> On 9 Apr, 14:21, "ScottMcP [MVP]"<scott...(a)mvps.org> wrote:
>> You are right to worry. It is leaking the font handle and after a
>> while it will probably cause messed up painting.
>>
>> When you use SelectObject (with any type of GDI object) you are
>> obligated to later restore the state of the HDC to what it was. This
>> can be done by saving the return from the SelectObject call, and later
>> selecting the returned object back in to the HDC. Or it can be done
>> with SaveDC and RestoreDC.
>>
>> When you create a font you are obligated to later use DeleteObject to
>> free it. And, you can't delete it if it is still selected into DC!
>> So you have a double boo boo here with basic painting rules.
>>
>> And finally, for the sake of efficiency it makes more sense to create
>> the font one time only, outside of the WM_PAINT handler. Keep the
>> font handle in memory.
>
> Thanks Scott and Matti. I thinbk I shall have to do some planning here
> but you have pointed me in the right direction.
>
> Just one quick question - is there a value for HFONT which is
> guaranteed not to actually be a font? Such as 0? (Like the way a NULL
> pointer is used to show that malloc has failed.) This would be handy
> as a way to keep track of which fonts I've actually generated.
>
> Thanks again.
> Paul.

Yes. 0 is an invalid handle value. HFONT is a pointer actually.

Take care.

- RaZ