MFC程序设计中的BeginPaint/EndPaint和GetDC/ReleaseDC的使用

1. 绘图/写字一般在WM_PAINT消息中处理。而在响应WM_PAINT消息时,需要成对调用下面两个接口:

  HDC BeginPaint(_In_  HWND hwnd, _Out_  LPPAINTSTRUCT lpPaint);

  BOOL EndPaint(_In_  HWND hWnd, _In_  const PAINTSTRUCT *lpPaint);

(1)BeginPaint只重画需要更新的区域(称为“无效区域”)。
(2)更新区域由Invalidate,InvalidateRect或者InvalidateRgn函数设置,或者在窗口发生大小改变、移动、创建、滚动等影响客户区的操作之后由系统设置。
(3)假如更新区域被标记为擦除,则BeginPaint会给窗口发送WM_ERASEBKGND消息。
(4)BeginPaint只能用在WM_PAINT消息响应中,不能用在别的地方。
(5)BeginPaint要与EndPaint配对使用。

2. GetDC与ReleaseDC

  HDC GetDC (HWND hWnd);

  HRESULT ReleaseDC (HDC hDC);

  GetDC 可以用在任何需要DC的地方, 他不会使得无效区域变得有效,所以不停的发送WM_PAINT消息导致屏幕闪烁。

 

BeginPaint/EndPaint 会删除消息队列中的WM_PAINT ,并使无效区域有效。也就是它会告诉系统这个窗口需要重画的地方已经重画完了,这样系统不会再重发WM_PAINT ;而

GetDC/ReleaseDC 并不删除WM_PAINT ,也不能使无效区域有效。也就是GetDC 并没有告诉系统这个窗口需要重画的地方已经重画过,在WM_PAINT 消息处理函数返回后,无效区域仍然存在。

系统一直以为通知你的重画命令你还没有执行或者执行出错,所以在空闲时,它还会不断地发送WM_PAINT 催促你,于是程序不断处理WM_PAINT 消息,反复重画,造成闪烁。

BeginPaint/EndPaint是比较“被动”的,只在窗口新建和被摧残时才重画,而GetDC/ReleaseDC用于主动绘制,而且它不加判断就都画上去,无效区域跟它没关系。

开发者在有些情况下需要主动重画:比如一个定时更换外观的窗口,这时候就要在WM_TIMER处理函数中使用GetDC/ReleaseDC。

这时候用BeginPaint/EndPaint的话,会因为无效区域为空,所有绘画操作都将被过滤掉(除非调用InvalidateRect或InvalidateRgn)。

posted on 2014-12-17 10:34  eric.geoffrey  阅读(598)  评论(0编辑  收藏  举报

导航