消息
1、WM_NCCREATE:调用CreateWindow函数的时候,会首先发送WM_NCCREATE消息给窗口过程函数,即NC,也就是No-Client(标题栏、窗体边框、最大化按钮、最小化按钮、滚动条等输入No-Client区域)。如果应用程序需要处理这个消息,那么需要返回TRUE来继续往下创建窗口。如果WM_NCCREATE返回FALSE的话,窗口创建将被终止,直接返回一个NULL句柄。
#define WM NCCREATE Ox0081
wParam中 此参数未使用。
lParam的 指向CREATESTRUCT结构的指针,其中包含有关正在创建的窗口的信息。
2、WM_CREATE:创建窗口的消息,发送完WM_NCCREATE消息并返回TRUE的情况下,会发送WM_CREATE消息给窗口过程函数。在窗口对用户可见之前,窗口过程函数会接收到消息。所以说,可以在这里创建控件、子窗口、初始化滚动条等操作
#define WM_CREATE 0x0001
wParam:此参数未使用。
lParam的指向CREATESTRUCT结构的指针,其中包含有关正在创建的窗口的信息。
CREATESTRUCT结构体的定义如下:
typedef struct tagCREATESTRUCTW {
LPVOID lpCreateParams;//创建窗口的基本参数
HINSTANCE hInstance;//拥有将创建窗口的模块实例句柄
HMENU hMenu;//新窗口的菜单句柄
HWND hwndParent;//新窗口的父窗口句柄
int cy;//新窗口的高度
int cx;//新窗口的宽度
int y;//新窗口的左上角y坐标
int x;//新窗口的右上角x坐标
LONG style;//新窗口的样式
LPCWSTR lpszName;//窗口标题名称
LPCWSTR lpszClass;//窗口类名称
DWORD dwExStyle;//窗口扩展样式
} CREATESTRUCTW, *LPCREATESTRUCTW;
以下为WM_NCCREATE和WM_CREATE消息具体案例,WM_NCCREATE返回TRUE。
case WM_NCCREATE:
{
CREATESTRUCT* p = (CREATESTRUCT*)lParam;
return TRUE;
}
case WM_CREATE:
{
CREATESTRUCT* p = (CREATESTRUCT*)lParam;
return 0;
}
3、WM_CLOSE:用户点击关闭按钮的时候依次发送WM_CLOSE、WM_DESTROY和WM_NCDESTROY消息来销毁窗口。此刻窗口消息并未退出,为了使程序彻底退出,应该在WM_DESTROY调用PostQuitMessage(0)函数来发送WM_QUIT消息并退出消息循环,具体可参考如下代码:
case WM_CLOSE:
{
WriteFile("WM_CLOSE");
return DefWindowProc(hwnd, message, wParam, lParam);
}
case WM_NCDESTROY:
{
WriteFile("WM_NCDESTROY");
return DefWindowProc(hwnd, message, wParam, lParam);
}
case WM_DESTROY:
{
WriteFile("WM_DESTROY");
PostQuitMessage(0);
break;
}
4、WM_PAINT:以下操作会触发操作系统的重绘消息
4.1、程序启动时,UpdateWindow函数会发送一个WM_PAINT消息来更新指定窗口的客户区域。
4.2、鼠标调整窗口大小的时候,会连续触发。
4.3、最小化的时候不会触发,但是从最小化到正常化的时候,会触发。
4.4、最大化的时候会触发。
4.5、当向屏幕外面拖拽的时候不会触发,但是当从屏幕外面拖拽到屏幕里面的时候,会连续触发。
4.6、调用InvalidateRect函数的时候会触发。
注意:仅仅覆盖或者移动窗口的是 不会触发,因为窗口的大小并未发生变化。
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);//使窗口无效区域变得有效,从而不在发送WM_PAINT消息。
EndPaint(hwnd, &ps);//和BeginPaint成双结对使用,必须同时调用。
return 0;
}
typedef struct tagPAINTSTRUCT {
HDC hdc;//用于绘图的显示器DC
BOOL fErase;//是否擦除背景
RECT rcPaint;//指定客户区的矩形
BOOL fRestore;//系统保留
BOOL fIncUpdate;//系统保留
BYTE rgbReserved[32];//系统保留
} PAINTSTRUCT, *PPAINTSTRUCT, *NPPAINTSTRUCT, *LPPAINTSTRUCT;
5、WM_ERASEBKGND:当窗体大小发生变化,必须擦除背景的时候,发送WM_ERASEBKGND消息。默认情况下,windows使用WNDCLASS中hbrBackground对背景进行擦除。如果程序处理WM_ERASEBKGND返回非0值表示不需要进一步擦除。返回0代表需要进一步擦除,PAINTSTRUCT
结构体中的fErase
将会编程true。
7、UpdateWindow、InvalidateRect、RedrawWindow三个函数的区别
UpdateWindow:如果窗口的更新区域不是空的,则UpdateWindow函数立即向窗口发送。WM_PAINT消息来更新指定窗口的客户区。
InvalidateRect:只增加一个无效区域在更新区域中,并不立刻进行重绘,直到发生下一个WM_PAINT消息时处理该区域是才重绘。如果希望立即刷新无效区域,可以在调用InvalidateRect之后调用UpdateWindow。
RedrawWindow()则是具有Invalidate()和UpdateWindow()的双特性。声明窗口的状态为无效,并立即更新窗口,立即调用WM_PAINT消息处理。