Re: Preventing memory and resource leaks with GDI Objects ???
"Joseph M. Newcomer" <newcomer@flounder.com> wrote in
message news:d142q554dl8oevri4hs3cim536l0gki78c@4ax.com...
See below...
On Tue, 16 Mar 2010 07:54:20 -0500, "Peter Olcott"
<NoSpam@OCR4Screen.com> wrote:
"Joseph M. Newcomer" <newcomer@flounder.com> wrote in
message news:hoetp55bqv7f9lm31e1rr5dgv41tk0rjde@4ax.com...
What part of "use RestoreDC()" did you miss? If you
simply RestoreDC() when you are done
with the font, you will revert to whatever the default
font was. Not a big deal. The
other common practice is to note that if you do
SelectObject() of a font, the result is a
CFont * that had been selected and you simply re-selecte
this. This technique generalizes
to all 30 or so parameters of an HDC (changing a
parameter
returns you the prvious
setting) but this means you have to keep variables
around
to know what value to
re-selected, and I find RestoreDC() to be a simpler
apprroach.
joe
Its not just Font its also CBitmap, and there is no
default
bitmap to restore.
***
Have you not been paying attention? THere is ALWAYS a
bitmap to restore, and it is the
one that is returned by SelectObject of the bitmap, OR the
one that is restored when you
call RestoreDC, which is a 1x1 monochrome bitmap. But you
didn't have to know about the
1x1 bitmap, just read about SelectObject OR about
RestoreDC, both of which state
explicitly what is going to happen! Your mistaken believe
that there is no default bitmap
is the heart of the problem, and it means you have ignored
everything we have been telling
you! If you ask questions in this forum and get answers,
you should pay attention to them
instead of insisting that it works differently than we are
telling you.
****
//
// Displays a Font Selection DialogBox with
// default "Times New Roman", Bold, Italic, 8 Point
//
inline void ScreenCaptureType::SelectFont() {
int PointSize = 8;
int FontHeight = -MulDiv(PointSize,
GetDeviceCaps(MemoryDC.m_hDC, LOGPIXELSY), 72);
LOGFONT LogFont = {FontHeight, 0, 0, 0, FW_BOLD, 1, 0, 0,
ANSI_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH |
FF_DONTCARE, L"Times New Roman"};
CFontDialog dlg(&LogFont);
CFont tempfont;
CFont *OldFont;
tempfont.CreateFontIndirect(&LogFont);
OldFont = this->MemoryDC.SelectObject(&tempfont);
OldFont->DeleteObject();
if (dlg.DoModal() == IDOK)
this->cfont.CreateFontIndirect(&LogFont);
this->MemoryDC.SelectObject(&cfont);
}
So basically the messy little five line block of code in the
middle is the cleanest way to implement my functional
requirements within the requirements of MS Windows resource
management?
A simpler way that could possibly work would be:
Get rid of the five line block and replace the last line
with these two lines:
CFont* OldFont = this->MemoryDC.SelectObject(&cfont);
OldFont->DeleteObject();
This would work if the MemoryDC maintains its own pointer
the original CFont object, and does not rely upon
this->cfont to retain it.
It looks like all of this may be moot
because DeleteObject() is confirming that the object is
being deleted while it is selected by its return value of
1,
so my code is already good the way that it is. I only
tested
this with VS 2008, but, it works on Windows 7 and XP.
***
That's a change in behavior from the documented and
measured past behavor. It would be
nice if someone from Microosoft could confirm what really
happens here.
joe
****
On Sun, 14 Mar 2010 12:29:29 -0500, "Peter Olcott"
<NoSpam@OCR4Screen.com> wrote:
The problem is that the only way that I know how to
unselect
a GDI object is to select another GDI object. I can't
select
another GDI object because I have to get rid of the
first
one to make room to create the second one. If there is
another way to unselect a GDI object besides selecting
another GDI object, then this would be easy.
Ideally I only want to have a single CFont and a single
CBitmap and a single MemoryDC that I use over and over.
These must all be stored as object members, and will
live
as
long as the app lives.
"Goran" <goran.pusic@gmail.com> wrote in message
news:06b6b099-4b40-4809-868b-982febcb6066@t23g2000yqt.googlegroups.com...
On Mar 14, 5:46 am, "Peter Olcott"
<NoS...@OCR4Screen.com>
wrote:
So what is an example of simple clean minimal syntax
for
making sure that a single set of GDI object member
variables
always does get properly deleted? The best that I
could
come up with is to duplicate everything such as CFont
cfont[2]; and toggle the subscript.
This seems like far too much of a kludge.
(I'll presume that you want to use multiple fonts to
draw
on
some DC).
If so, this works:
0. create any GDI objects (e.g. fonts)
1. (optional) create your DC ( or receive it in OnPaint
:-) )
2. select any font into DC, draw, un-select it
Rinse, repeat 2 (you can also "stack" what you do in 2
if
you wish so)
3. (optional) destroy DC (don't if it's not yours)
4. let all go out of scope (IOW, let your enclosing
class
be
destroyed).
Goran.
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm