Click here to Skip to main content
Licence 
First Posted 18 Sep 2000
Views 67,189
Bookmarked 20 times

Dynamic DC

By | 18 Sep 2000 | Article
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.

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 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

About the Author

Craig Henderson

Other
Centrix Software
United Kingdom United Kingdom

Member

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

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralMy vote of 1 PinmemberJoeJiao19:50 11 Sep '09  
QuestionCan I use it if I want to draw inside the WM_PAINT? PinmemberTG_LGW22:49 13 Aug '07  
AnswerRe: Can I use it if I want to draw inside the WM_PAINT? PinmemberJoeJiao20:13 4 Sep '09  
GeneralQuestion Pinmembercharfeddine_ahmed9:49 12 Oct '06  
QuestionHow to change a window default dc Pinmemberbroadoceans16:26 21 Dec '03  
GeneralThanks Very Much!! PinmemberMatt Soler14:23 18 May '01  
QuestionRe: Do you have an example of this? PinmemberAnonymous13:20 31 Dec '00  
I'm kinda a newbie when it comes to programming in Win32, do you have an example project in how this class is used? If you do, it'd be very helpful, thanks.;)
QuestionHow is this different to Keith Rule's article? PinsussHerman13:18 3 Oct '00  
AnswerRe: How is this different to Keith Rule's article? PinsussCraig Henderson22:16 4 Oct '00  
GeneralRe: How is this different to Keith Rule's article? Pinmemberrahulagarwal3317:12 10 Jun '09  
QuestionWhat's about CWindowDC ? PinsussHolger Persch19:35 18 Sep '00  
AnswerRe: What's about CWindowDC ? PinsussCraig Henderson22:31 18 Sep '00  

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.

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