SaveDC.h
Collapse
Copy
Code
class CSaveDC {
public:
CSaveDC(CDC & dc) { sdc = &dc; saved = dc.SaveDC(); }
CSaveDC(CDC * dc) { sdc = dc; saved = dc->SaveDC(); }
virtual ~CSaveDC() { sdc->RestoreDC(saved); }
protected:
CDC * sdc;
int saved;
};
That's all
there is to
it! Note
that it has
two
constructors,
one if you
have a
CDC *
and one if
you have a
CDC
or
CDC &
.
All you do
is declare a
dummy
variable.
But there's
an important
trick,
illustrated
below.
Collapse
Copy
Code
void CMyView::OnPaint()
{
CPaintDC dc(this);
CFont f;
f.CreateFont(...); {
CSaveDC sdc(dc);
dc.SelectObject(&f);
dc.TextOut(...); }
}
Note that
the save
context you
create by
using the
CSaveDC
class must
be in a
scope that
is smaller
than the
objects
selected
into the DC.
Thus the
/*
save context
*/
block
guarantees
that the
CSaveDC
destructor
is
guaranteed
to be called
before the
destructor
for the
font. All
you have to
do is
declare your
fonts, pens,
brushes, and
regions
outside the
block and
you can be
guaranteed
that their
destructors
will be
called in a
context
where they
are not
selected
into the
active DC.
Note that
CSaveDC
s
can nest
(because the
::SaveDC
can nest).
The nesting
can be
static or
dynamic. For
example
Collapse
Copy
Code
void CMyView::OnPaint()
{
CPaintDC dc(this);
CFont f;
f.CreateFont(12,...); {
CSaveDC sdc(dc);
dc.SelectObject(&f);
drawboxes(dc);
dc.TextOut(...); }
void CMyView::drawboxes(CDC & dc)
{
CPen RedPen(PS_SOLID, 0, RGB(255, 0, 0));
CBrush GreenBrush(RGB(0, 255, 0);
CFont f;
f.CreateFont(6, ...); {
dc.SelectObject(&RedPen);
dc.SelectObject(&GreenBrush);
dc.SetBkMode(TRANSPARENT);
dc.SetTextColor(::GetSysColor(COLOR_GRAYTEXT);
...
}
}