65.9K
CodeProject 正在变化。 阅读更多。
Home

CAutoPen 类 - 正确销毁的 CPen

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.86/5 (7投票s)

1999年11月25日

viewsIcon

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
}

CAutoPenCAutoBrush 的源代码: <!-- 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

许可证

本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。

作者可能使用的许可证列表可以在此处找到。

© . All rights reserved.