CAutoPen 类 - 正确销毁的 CPen






4.86/5 (7投票s)
1999年11月25日

62710
CAutoPen 类 - 一个正确销毁的 CPen
如果你在堆栈上使用单步 CPen
构造函数创建了一个临时 CPen
对象,很容易忘记在它超出作用域之前从设备上下文中取消选择该画笔。在这种情况下,即使逐步调试代码并运行 BoundsChecker
也会让你相信并非如此,但这会导致严重的 GDI 资源泄漏。CAutoPen
类克服了此缺陷,并在构造函数中将画笔选择到设备上下文中。MFC 对 Win32 的封装也太薄了!!!
CAutoPen
(和 CAutoBrush
)的使用示例: <!-- start a block of source code -->
void CMyView::OnDraw(CDC* pDC)
{
// make red pen
CAutoPen NewPen(pDC, PS_SOLID, 1, RGB(255,0,0));
// make green brush
CAutoBrush NewBrush(pDC, RGB(0, 255, 0));
// draw rectangle
CRect rect(10, 10, 110, 110);
pDC->Rectangle(&rect);
// and automatic cleanup done
}
CAutoPen
和 CAutoBrush
的源代码: <!-- start a block of source code -->
// Filename: AutoPen.h
// Programmer: Anneke Sicherer-Roetman - a.sicherer@noldus.nl
// Noldus Information Technology, Wageningen, Netherlands
// Revision Date: 1999-04-09
// Description: Classes CAutoPen & CAutoBrush
#if !defined AUTOPEN_H
#define AUTOPEN_H
class CAutoPen : public CPen
{
public:
// 1st constructor, see CPen docs
CAutoPen(CDC *pDC, int nPenStyle, int nWidth, COLORREF crColor) :
CPen(nPenStyle, nWidth, crColor), m_pDC(pDC), m_pOldGdi(NULL)
{
Initialize();
}
// 2nd constructor, see CPen docs
CAutoPen(CDC *pDC, int nPenStyle, int nWidth, const LOGBRUSH *pLogBrush,
int nStyleCount = 0, const DWORD *lpStyle = NULL) :
CPen(nPenStyle, nWidth, pLogBrush, nStyleCount, lpStyle), m_pDC(pDC), m_pOldGdi(NULL)
{
Initialize();
}
// destructor, deselects pen from device context
virtual ~CAutoPen()
{
ASSERT_VALID(m_pOldGdi);
ASSERT_VALID(m_pDC);
m_pDC->SelectObject(m_pOldGdi);
}
private:
CDC *m_pDC; // remembers device context
CGdiObject *m_pOldGdi; // remembers previous pen
CAutoPen() { } // default constructor cannot be called
// selects pen into device context
void Initialize()
{
m_pOldGdi = m_pDC->SelectObject(this);
ASSERT_VALID(m_pOldGdi);
}
};
class CAutoBrush : public CBrush
{
public:
// 1st constructor, see CBrush docs
CAutoBrush(CDC *pDC, COLORREF crColor) :
CBrush(crColor), m_pDC(pDC), m_pOldGdi(NULL)
{
Initialize();
}
// 2nd constructor, see CBrush docs
CAutoBrush(CDC *pDC, int nIndex, COLORREF crColor) :
CBrush(nIndex, crColor), m_pDC(pDC), m_pOldGdi(NULL)
{
Initialize();
}
// 3rd constructor, see CBrush docs
CAutoBrush(CDC *pDC, CBitmap* pBitmap) :
CBrush(pBitmap), m_pDC(pDC), m_pOldGdi(NULL)
{
Initialize();
}
// destructor, deselects brush from device context
virtual ~CAutoBrush()
{
ASSERT_VALID(m_pOldGdi);
ASSERT_VALID(m_pDC);
m_pDC->SelectObject(m_pOldGdi);
}
private:
CDC *m_pDC; // remembers device context
CGdiObject *m_pOldGdi; // remembers previous pen
CAutoBrush() { } // default constructor cannot be called
// selects brush into device context
void Initialize()
{
m_pOldGdi = m_pDC->SelectObject(this);
ASSERT_VALID(m_pOldGdi);
}
};
#endif
许可证
本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。
作者可能使用的许可证列表可以在此处找到。