一直以来,对于WM_PAINT和WM_ERASEBKGND消息不是很清楚,从书上和网上找了很多资料,大体上有以下几点说法:
1>WM_PAINT先产生,WM_ERASEBKGND后产生
2.WM_PAINT产生后,在调用BeginPaint时
hdc = BeginPaint(hWnd, &ps);
如果ps.fErase为true,则BeginPaint会产生WM_ERASEBKGND消息
3.BeginPaint函数用来擦除窗口背景
4.WM_ERASEBKGND用来绘制背景
经过调试、分析,发现上面的说法并不正确。以下是一些测试代码,代码后面附上一些分析。最后总结出几点,可以解释程序中出现的所有关于窗口重绘的问题。
如有不正确的地方,大家可以指正。
为了说明问题,在此不说WM_NCPAINT消息(非客户区消息),只说WM_ERASEBKGND消息和客户区的WM_PAINT消息
//此段代码摘自vc6应用程序向导自动生成的代码,并添加了一些测试代码
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_ERASEBKGND: //如果处理了这个消息,则默认消息处理函数不会调用,背景就不会绘制
{
static int iCount=0;
char ch[MAX_PATH];
sprintf(ch,"%d ---------WM_ERASEBKGND\n",iCount); //这个函数需要包含#include<stdio.h>
OutputDebugString(ch); //调试时便于观察
iCount++;
break;
}
case WM_PAINT:
{
OutputDebugString(" --