http://www.pconline.com.cn/pcedu/empolder/gj/c/0506/651420.html
Windows内部为每个窗口都保留了一个绘图结构(PAINTSTRUCT),它包含了包围无效区域的最小矩形的坐标和一些其它信息,需要注意的是当窗口消息处理函数在处理WM_PAINT消息之前显示区域中出现了另一个无效区域,那么Windows会计算出一个包围两个无效区域的新无效区域,并把这种变化保存在绘图结构(PAINTSTRUCT)中,Windows是不会同时把多个WM_PAINT消息同时放到消息队列中的。
窗口消息处理函数是通过调用InvalidateRect函数使窗口显示区域内的矩形变为无效的,如果消息队列中已经存在一个WM_PAINT消息,那么Windows将计算出新的无效矩形,在接收到WM_PAINT消息的时候,窗口消息处理函数可以获得无效矩形的座标,通过调用GetUpdateRect,可以在任何时候获得这些坐标。
GetDC 和 BeginPaint 获取HDC的区别:
1. 使用BeginPaint和Endpaint函数
通常是在应用程序接收到WM_PAINT消息,也就是需要更新窗口的显示区域的时候调用BeginPaint函数获取设备描述表句柄的,使用完后调用Endpaint函数释放设备描述表句柄。
他们的函数原型为:
HDC BeginPaint(
HWND hwnd,, // handle to window
LPPAINTSTRUCT pPaint // paint information
);
BOOL EndPaint(
HWND hWnd, // handle to window
CONST PAINTSTRUCT *pPaint // paint data
);
2. 使用GetDC和ReleaseDC函数
在很多情况下我们可能需要在接收到非WM_PAINT消息的时候获取设备描述表句柄,通过调用GetDC函数我们可以获得设备描述表句柄,因为程序作者可能要使用设备描述表句柄完成其它工作,例如获得设备描述表属性,或者修改设备描述表属性值等,在最后我们与第一种方法一样要释放句柄,通过调用ReleaseDC函数完成工作。
他们的函数原型为:
HDC GetDC(
HWND hWnd // handle to window
);
int ReleaseDC(
HWND hWnd, // handle to window
HDC hDC // handle to DC
);
两种方法的区别:
<1> 使用BeginPaint函数获得的的操作区域是显示区域中的无效矩形区域,接下来绘图操作只能在窗口的无效区域范围内进行,无效区域以外的区域将被忽略不能进行操作,而GetDC函数获得的操作区域则是整个窗口的显示区域,之后的操作可以在任何部分进行,而不只限制在无效区域。
<2> BeginPaint函数会自动把无效区域变成有效的区域,而GetDC函数则不会将任何无效区域变得有效,必须强行调用ValidateRect函数,并把第二个参数设置为NULL来完成。