动态 DC






3.44/5 (5投票s)
一个设备上下文类,用于在 WM_PAINT 处理程序之外的窗口上绘图
引言
CDynamicDC
是一个非常小的类,它提供了一种简单而强大的方法,用于在 WM_PAINT
处理程序之外的窗口上绘图。该类的整个实现都是 inline
的,因为没有一个成员函数超过两行可执行代码!
为什么?
该类非常小,乍一看,人们可能会问它为什么有用。该类提供的关键优势是:
- 易于使用。只需使用窗口句柄实例化对象,并将其用作 DC
- 保证并自动释放系统 DC 资源。
- DC 资源在析构函数中释放,因此在堆栈上实例化对象,资源将始终被释放,即使生成了异常。
- 自动类型转换。该类的实例可以作为参数传递给任何期望 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);
}