Click here to Skip to main content
Click here to Skip to main content

Dynamic DC

, 18 Sep 2000 CPOL
Rate this:
Please Sign up or sign in to vote.
A Device Context class to draw on a window outside of a WM_PAINT handler.
<!-- Main HTML starts here -->

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.

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

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

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

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

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

The Code

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)

Share

About the Author

Craig Henderson
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.
Follow on   Twitter

Comments and Discussions

 
GeneralMy vote of 1 PinmemberJoeJiao11-Sep-09 20:50 
QuestionCan I use it if I want to draw inside the WM_PAINT&#65311; PinmemberTG_LGW13-Aug-07 23:49 
AnswerRe: Can I use it if I want to draw inside the WM_PAINT? PinmemberJoeJiao4-Sep-09 21:13 
GeneralQuestion Pinmembercharfeddine_ahmed12-Oct-06 10:49 
QuestionHow to change a window default dc Pinmemberbroadoceans21-Dec-03 17:26 
GeneralThanks Very Much!! PinmemberMatt Soler18-May-01 15:23 
QuestionRe: Do you have an example of this? PinmemberAnonymous31-Dec-00 14:20 
QuestionHow is this different to Keith Rule's article? PinsussHerman3-Oct-00 14:18 
AnswerRe: How is this different to Keith Rule's article? PinsussCraig Henderson4-Oct-00 23:16 
GeneralRe: How is this different to Keith Rule's article? Pinmemberrahulagarwal3310-Jun-09 18:12 
QuestionWhat's about CWindowDC ? PinsussHolger Persch18-Sep-00 20:35 
AnswerRe: What's about CWindowDC ? PinsussCraig Henderson18-Sep-00 23:31 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.141223.1 | Last Updated 19 Sep 2000
Article Copyright 2000 by Craig Henderson
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid