Click here to Skip to main content
15,886,799 members
Articles / Desktop Programming / MFC

Dynamic DC

Rate me:
Please Sign up or sign in to vote.
3.44/5 (5 votes)
18 Sep 2000CPOL 87.3K   20   12
A Device Context class to draw on a window outside of a WM_PAINT handler

Introduction

CDynamicDC is a very small class that provides an easy and robust method for drawing on a window outside of the WM_PAINT handler. The entire implementation of the class is inline because no member function is more than two lines of executable code!

Why?

The class is so small that at first glance, one may ask why it is useful. The key advantages that the class provide are:

  1. Ease of use. Simply instantiate the object with a window handle and use it as a DC
  2. Guaranteed and Automatic release of system DC resource.
  3. The DC resource is freed in the destructor, so instantiate the object on the stack and the resource will always be freed even if an exception if generated
  4. Automatic type conversions. An instance of this class can be passed as a parameter to any function that is expecting HDC, CDC* or CDC& parameter types

Examples

Using the Device Context as a Win32 HDC.

C++
CDynamicDC dc(hWnd);
::MoveTo(dc, 10, 10, &ptOld);
::LineTo(dc, 100, 100);

Using the Device Context as a pointer to an MFC CDC class.

C++
CDynamicDC dc(hWnd);
dc->MoveTo(10, 10);
dc->LineTo(100, 100);

Using the Device Context as a reference to an MFC CDC class.

C++
CDynamicDC dcDynamic(hWnd);
CDC &dc(*dcDynamic);
dc.MoveTo(10, 10);
dc.LineTo(100, 100);

The Code

C++
class CDynamicDC
{
  private:
    HDC  m_hDC;
    HWND m_hWnd;

  public:
    CDynamicDC(CWnd *__pWnd);
    CDynamicDC(HWND __hWnd);
    virtual ~CDynamicDC();

    operator HDC();     // dynamic conversion to HDC
    CDC *operator->();  // dynamic conversion to CDC pointer
    operator CDC*();    // allow CDC pointer dereferencing
};

// constructor initialised with an MFC CWnd pointer
inline CDynamicDC::CDynamicDC(CWnd *__pWnd)
  : m_hDC(NULL),
    m_hWnd(NULL)
{
    ASSERT(__pWnd != NULL  &&  ::IsWindow(__pWnd->GetSafeHwnd()));
    m_hWnd = __pWnd->GetSafeHwnd();
    m_hDC  = ::GetDCEx(m_hWnd, NULL, DCX_CACHE);
}

// constructor initialised with a Win32 windows handle
inline CDynamicDC::CDynamicDC(HWND __hWnd)
  : m_hDC(NULL),
    m_hWnd(NULL)
{
    ASSERT(__hWnd != NULL  &&  ::IsWindow(__hWnd));
    m_hWnd = __hWnd;
    m_hDC  = ::GetDCEx(m_hWnd, NULL, DCX_CACHE);
}

// virtual destructor will free the DC
inline CDynamicDC::~CDynamicDC()
{
    if (m_hDC != NULL)
    {
        ASSERT(m_hWnd != NULL  &&  ::IsWindow(m_hWnd));
        ::ReleaseDC(m_hWnd, m_hDC);
    }
}

// this operator implements dynamic conversion to a Win32 HDC object so that
// an instance of this class can be used anywhere an HDC is expected
inline CDynamicDC::operator HDC()
{
    return m_hDC;
}

// this operator implements dynamic conversion to an MFC CDC object so that
// an instance of this class can be used anywhere a pointer to a CDC object
// is expected
inline CDC *CDynamicDC::operator->()
{
    return CDC::FromHandle(m_hDC);
}

// this operator enables an instance of this class to be dereferenced as if
// it were a pointer to an MFC CDC object, for example if a CDC reference
// is required
inline CDynamicDC::operator CDC*()
{
    return CDC::FromHandle(m_hDC);
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead
United Kingdom United Kingdom
Craig graduated with a B.SC. Honours in Computing for Real Time Systems from the University of the West of England, Bristol in 1995 after completing an HND in Computing in 1993.

Comments and Discussions

 
GeneralMy vote of 1 Pin
RickyJiao11-Sep-09 19:50
RickyJiao11-Sep-09 19:50 
QuestionCan I use it if I want to draw inside the WM_PAINT? Pin
TG_LGW13-Aug-07 22:49
TG_LGW13-Aug-07 22:49 
AnswerRe: Can I use it if I want to draw inside the WM_PAINT? Pin
RickyJiao4-Sep-09 20:13
RickyJiao4-Sep-09 20:13 
GeneralQuestion Pin
Ahmed Charfeddine12-Oct-06 9:49
Ahmed Charfeddine12-Oct-06 9:49 
QuestionHow to change a window default dc Pin
broadoceans21-Dec-03 16:26
broadoceans21-Dec-03 16:26 
GeneralThanks Very Much!! Pin
18-May-01 14:23
suss18-May-01 14:23 
QuestionRe: Do you have an example of this? Pin
31-Dec-00 13:20
suss31-Dec-00 13:20 
QuestionHow is this different to Keith Rule's article? Pin
Herman3-Oct-00 13:18
Herman3-Oct-00 13:18 
AnswerRe: How is this different to Keith Rule's article? Pin
Craig Henderson4-Oct-00 22:16
Craig Henderson4-Oct-00 22:16 
GeneralRe: How is this different to Keith Rule's article? Pin
rahulagarwal3310-Jun-09 17:12
rahulagarwal3310-Jun-09 17:12 
QuestionWhat's about CWindowDC ? Pin
HP18-Sep-00 19:35
HP18-Sep-00 19:35 
AnswerRe: What's about CWindowDC ? Pin
Craig Henderson18-Sep-00 22:31
Craig Henderson18-Sep-00 22:31 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.