天天看点

CPaintDC, CClientDC,CWindowDC详解

1.CPaintDC

MFC中的CPaintDC类响应WM_PAINT消息,允许在窗口客户区绘图,但是只能在OnPaint处理程序中,而不能在其它地方使用,WM_PAINT消息在一个很重要的的方面不同于其他Windows消息,如果处理程序调用Windows的::BeginPaint和EndPaint函数失败或者等价于这两个函数;那么不管又多少绘图工作,都不能将该消息从消息队列中删除。因此,应用程序一边又一遍的处理同一个WM_PAINT消息而陷入死循环。而通过CPaintDC的构造函数和析构函数调用::BeginPaint和::EndPaint,CPaintDC能保证这种情况不会发生;

2.CClientDC和CWindowDC

Windows程序不是总将绘图限制在OnPaint上;古国编写这样一个程序,只要一单机鼠标,应用程序就会在屏幕上画一个圆圈。那么你可能希望在接收到该按钮单击消息时立刻画圆,而不必等到WM_PAINT

这就需要CClientDC创建可在OnPaint外使用的用户区域设备描述表。下面的消息处理程序使用了CClientDC和两个CDC成员函数来完成在鼠标左键单机时画一个X连接窗口客户区的四角的功能;

void CMainWindow::OnLButtonDown(UINT nFlag,CPoint point)

{

CRect rect;

GetClientRect(rect);

CClientDC dc(this);

dc.MoveTo(rect.left,rect.top);

dc.LineTo(rect.right,rect.bottom);

dc.MoveTo(rect.right,rect.top);

dc.LineTo(rect.left,rect.bottom);

}

3.CWindowDC

CWindowDC还可以使用非客户区,CWindowDC与CClientDC相类似,但它代表的设备描述表包含了窗口边框之内的所有类容,CWindowDC一般不常用,有时可以创造特殊效果,例如用户自己绘制标题栏和带圆角的窗口。如果想在窗口非客户区作图,可以借助OnNcPaint处理程序捕捉WM_NCPAINT消息,确定非客户区需要绘制的时间,与OnPaint不同OnNcPaint处理程序不需要(也不应当调用)BeginPaint和EndPaint;,更少见的情况时程序需要全屏幕访问权。因此可创建CClientDC或者CWindowDC对象,并给其构造函数传一个NULL指针,语句:

CClientDC dc(NULL);

dc.Ellipse(0,0,100,100);

将在屏幕左上角画一个圆,屏幕截取程序经常使用全屏DC访问整个屏幕,很显然,除非有特殊原因,否则在自己的窗口外画图是件很不友好的事情;