Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

CAutoPen Class - A CPen that IS Correctly Destroyed

0.00/5 (No votes)
24 Nov 1999 1  
CAutoPen Class - a CPen that is correctly destroyed

If you create a temporary CPen object on the stack with one of the one-step CPen constructors, you can easily forget to deselect the pen from the device context before it goes out of scope. In that case, although stepping through the code and running BoundsChecker will make you believe otherwise, this causes a serious GDI resource leak. The CAutoPen class overcomes this flaw and also selects the pen into the device context in the constructors. MFC is a much too thin wrapper around Win32!!!

Example of the usage of a CAutoPen (and a 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
}

Source code of CAutoPen and 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

License

This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below.

A list of licenses authors might use can be found here.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here