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

动态 DC

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.44/5 (5投票s)

2000年9月19日

CPOL
viewsIcon

89150

一个设备上下文类,用于在 WM_PAINT 处理程序之外的窗口上绘图

引言

CDynamicDC 是一个非常小的类,它提供了一种简单而强大的方法,用于在 WM_PAINT 处理程序之外的窗口上绘图。该类的整个实现都是 inline 的,因为没有一个成员函数超过两行可执行代码!

为什么?

该类非常小,乍一看,人们可能会问它为什么有用。该类提供的关键优势是:

  1. 易于使用。只需使用窗口句柄实例化对象,并将其用作 DC
  2. 保证并自动释放系统 DC 资源。
  3. DC 资源在析构函数中释放,因此在堆栈上实例化对象,资源将始终被释放,即使生成了异常。
  4. 自动类型转换。该类的实例可以作为参数传递给任何期望 HDC、CDC* 或 CDC& 参数类型的函数

示例

将设备上下文用作 Win32 HDC。

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

将设备上下文用作指向 MFC CDC 类的指针。

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

将设备上下文用作对 MFC CDC 类的引用。

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

代码

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);
}
© . All rights reserved.