1.在使用者移动视窗或显示视窗时,视窗中先前被隐藏的区域重新可见。
2.使用者改变视窗的大小(如果视窗类别样式有著CS_HREDRAW 和CS_VREDRAW位元旗标的设定)。
3.程式使用ScrollWindow 或ScrollDC 函式滚动显示区域的一部分。
4.程式使用InvalidateRect或InvalidateRgn函式刻意产生WM_PAINT讯息。
在某些情况下,显示区域的一部分被临时覆盖,Windows 试图保存一个显示区域,并在以後恢复它,但这不一定能成功。在以下情况下,Windows 可能发送WM_PAINT 讯息:
1.Windows 擦除覆盖了部分视窗的对话方块或讯息方块。
2.功能表下拉出来,然後被释放。
3.显示工具提示讯息。
而滑鼠游标穿越显示区域或者图示拖过显示区域时windows总是能够保存成功,故而不会产生WM_PAINT 讯息。
Windows之所以会产生WM_PAINT 消息是由于系统或者程序设计者在一些条件下需要重新绘制一部分或者全部,需要重新绘制的这部分就称为无效区域,保存在一个矩形结构中。为提高绘制效率窗口值保存一个无效矩形,不需要每次更新一小块,通常在消息队列中存在WM_PAINT时,再次发送WM_PAINT消息只更新无效矩形而不会再次插入一条WM_PAINT消息。并需要在处理WM_PAINT消息时把无效区域设为有效。
与其他windows系统的API一样绘制接口并不会直接操作设备对象,而且操作设备句柄。更新界面时就使用绘图句柄,在指定的区域上绘制图形或文字。windows为每一个窗体保存了一个绘图结构:
typedef struct tagPAINTSTRUCT
{
HDC hdc ; //绘图句柄
BOOL fErase ; //是否擦除背景
RECT rcPaint ; //无效矩形
BOOL fRestore ; //系统内部使用
BOOL fIncUpdate ; //系统内部使用
BYTE rgbReserved[32] ; //系统内部使用
}PAINTSTRUCT ;
其中fErase指定是否擦除背景,若擦除则用wndclass.hbrBackground指定的画刷刷新背景或者在处理WM_ERASEBKGND消息时自定义背景擦除动作。是否擦除一般由函数InvalidateRect的最后一个参数决定。无效矩形只在绘图是有意义,获取和使用hdc的方法有两个:
//1.在处理WM_PAINT消息时
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
//使用GDI 函式
EndPaint (hwnd, &ps) ;
return 0 ;
//2.非WM_PAINT消息中
hdc = GetDC (hwnd) ;
//使用GDI 函式
ReleaseDC (hwnd, hdc) ;
方法1中的ps,即为PAINTSTRUCT结构的对象,故在处理WM_PAINT消息时可以获得无效矩形的大小,而方法2的获得的矩形为整个客户区的大小。并BeginPaint,EndPaint和GetDC,ReleaseDC必须成对出现,既使用完一个DC之后必须释放它。
输出文字为最简单的绘图方式:
/*-----------------------------------------------
SYSMETS.H -- System metrics display structure
-----------------------------------------------*/
#define NUMLINES ((int) (sizeof sysmetrics / sizeof sysmetrics [0]))
struct
{
int iIndex ;
TCHAR * szLabel ;
TCHAR * szDesc ;
}
sysmetrics [] =
{
SM_CXSCREEN, TEXT ("SM_CXSCREEN"),
TEXT ("Screen width in pixels"),
SM_CYSCREEN, TEXT ("SM_CYSCREEN"),
TEXT ("Screen height in pixels"),
SM_CXVSCROLL, TEXT ("SM_CXVSCROLL"),
TEXT ("Vertical scroll width"),
SM_CYHSCROLL, TEXT ("SM_CYHSCROLL"),
TEXT ("Horizontal scroll height"),
SM_CYCAPTION, TEXT ("SM_CYCAPTION"),
TEXT ("Caption bar height"),
SM_CXBORDER, TEXT ("SM_CXBORDER"),
TEXT ("Window border width"),
SM_CYBORDER, TEXT ("SM_CYBORDER"),
TEXT ("Window border height"),
SM_CXFIXEDFRAME, TEXT ("SM_CXFIXEDFRAME"),
TEXT ("Dialog window frame width"),
SM_CYFIXEDFRAME, TEXT ("SM_CYFIXEDFRAME"),
TEXT ("Dialog window frame height"),
SM_CYVTHUMB, TEXT ("SM_CYVTHUMB"),
TEXT ("Vertical scroll thumb height"),
SM_CXHTHUMB, TEXT ("SM_CXHTHUMB"),
TEXT ("Horizontal scroll thumb width"),
SM_CXICON, TEXT ("SM_CXICON"),
TEXT ("Icon width"),
SM_CYICON, TEXT ("SM_CYICON"),
TEXT ("Icon height"),
SM_CXCURSOR, TEXT ("SM_CXCURSOR"),
TEXT ("Cursor width"),
SM_CYCURSOR, TEXT ("SM_CYCURSOR"),
TEXT ("Cursor height"),
SM_CYMENU, TEXT ("SM_CYMENU"),
TEXT ("Menu bar height"),
SM_CXFULLSCREEN, TEXT ("SM_CXFULLSCREEN"),
TEXT ("Full screen client area width"),
SM_CYFULLSCREEN, TEXT ("SM_CYFULLSCREEN"),
TEXT ("Full screen client area height"),
SM_CYKANJIWINDOW, TEXT ("SM_CYKANJIWINDOW"),
TEXT ("Kanji window height"),
SM_MOUSEPRESENT, TEXT ("SM_MOUSEPRESENT"),
TEXT ("Mouse present flag"),
SM_CYVSCROLL, TEXT ("SM_CYVSCROLL"),
TEXT ("Vertical scroll arrow height"),
SM_CXHSCROLL, TEXT ("SM_CXHSCROLL"),
TEXT ("Horizontal scroll arrow width"),
SM_DEBUG, TEXT ("SM_DEBUG"),
TEXT ("Debug version flag"),
SM_SWAPBUTTON, TEXT ("SM_SWAPBUTTON"),
TEXT ("Mouse buttons swapped flag"),
SM_CXMIN, TEXT ("SM_CXMIN"),
TEXT ("Minimum window width"),
SM_CYMIN, TEXT ("SM_CYMIN"),
TEXT ("Minimum window height"),
SM_CXSIZE, TEXT ("SM_CXSIZE"),
TEXT ("Min/Max/Close button width"),
SM_CYSIZE, TEXT ("SM_CYSIZE"),
TEXT ("Min/Max/Close button height"),
SM_CXSIZEFRAME, TEXT ("SM_