此文章,部分内容属于自己记录,部分转载。
转载部分详见:从Window消息的角度看窗口应用程序的运行过程
Windows消息详细内容可查找:Window Dev Center
一个典型的Win32窗口应用程序的框架是这样的:
程序入口点(WinMain函数)-->注册窗口类(调用Re GISterClass函数或RegisterClassEx函数)-->创建主窗口(调用CreateWindow函数或CreateWindowEx函数)-->显示主窗口(调用ShowWindow函数)-->更新主窗口(调用UpdateWindow函数)-->进入消息循环(GetMessage、TranslateMessage、DispatchMessage)并处理各种 Windows消息(窗口过程函数)-->程序出口点(WinMain返回)。就像下面这个例子一样:#include<Windows.h>
#include<tchar.h>
//窗口类名和窗口标题
TCHAR szWindowClass[]=_T("HELLOWINDOWS");
TCHAR szWindowTitle[]=_T("This is the MAIN window");
//窗口过程函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
//LogMessage(logfile,msg,wParam,lParam);//
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hWnd,msg,wParam,lParam);
}
}
int WINAPI _tWinMain( HINSTANCE hInstance,HINSTANCE,LPTSTR lpCmdLine,int nCmdShow)
{
//注册窗口类
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = NULL;
RegisterClassEx(&wcex);
//创建主窗口
HWND hWnd = CreateWindowEx(0,szWindowClass, szWindowTitle, WS_OVERLAPPEDWINDOW,
128, 96, 512, 480, HWND_DESKTOP, NULL, hInstance, NULL);
if (!hWnd)
return FALSE;
//显示并更新主窗口
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
// 进入消息循环
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
//程序退出
}
下面来看它的窗口过程WndProc,它只处理了一个消息:WM_DESTROY,其余的消息都交给了Windows去处理(调用DefWindowProc)。对于一个实际的Windows程序来说,要在窗口过程中处理的消息会很多;然而Windows消息成百上千,无论你处理多少消息,剩下的你还是得调用DefWindowProc交给Windows系统去处理。这次我们就来看看,从程序启动到退出,DefWindowProc到底要帮我们做多少的工作。
CreateWindow()
---------------------------
MSG SYSTEM_EVENT WPARAM LPARAM
36 WM_GETMINMAXINFO 0 3796740 (消息说明:当窗口的消息、位置即将发生改变时,发送消息给窗口。lParam指向MINMAXINFO结构体)
129 WM_NCCREATE 0 3796728 (消息说明:当窗口第一次被创建时,在WM_CREATE消息之前发送消息,lParam指向一个CREATESTRUCT结构体,可获取正在被创建的窗口的信息。)
131 WM_NCCALCSIZE 0 3796708 (消息说明:当一个窗口的客户区域的大小和位置必须被计算时,发送此消息。wParam、lParam消息都有用。)
1 WM_CREATE 0 3796728 (消息说明:当一个应用通过CreateWindowEx或CreateWindow函数创建窗口时,发送消息。lParam指向CREATESTRUCT结构体,可获取正在被创建的窗口的信息。)
---------------------------
UpdateWindow()
---------------------------
wndProc未收到任何消息
---------------------------
ShowWindow()
---------------------------
MSG SYSTEM_EVENT WPARAM LPARAM
24 WM_SHOWWINDOW 1 0 (消息说明:当窗口即将被隐藏或显示的时候,发送消息。)
70 WM_WINDOWPOSCHANGING 0 3797712 (消息说明:当窗口的大小、位置或Z值顺序即将改变,发送消息。lParam指向WINDOWPOS结构体,包含窗口新的大小及位置。)
窗口显示
28 WM_ACTIVATEAPP 1 61028 (消息说明:当应用的窗口被激活或反激活的时候,发送消息给应用。wParam,lParam详见Windows Dev Center-Desktop)
134 WM_NCACTIVATE 0 0 (消息说明:当窗口的非客户区需要被改变用于指明窗口状态,发送消息给窗口。wParam,lParam详见Windows Dev Center-Desktop)
127 WM_GETICON 2 0 (消息说明:当窗口获取大、小图标时,发送消息。wParam == 2,表示接受由应用提供的小图标。如果应用没有提供,则使用系统产生的图标。)
127 WM_GETICON 0 0 (消息说明:wParam == 0,表示接受由应用提供的大图标。大图标,在ALT+TAB窗口中展示。)
127 WM_GETICON 1 0 (消息说明:wParam == 1,表示接受由应用提供的小图标。)
6 WM_ACTIVATE 1 0 (消息说明:当窗口被激活或被反激活时,发送消息。wParam==1,表示通过某些方法激活窗口(不是通过鼠标点击激活))
641 WM_IME_SETCONTEXT 1 -1073741809(消息说明:当窗口被激活,发送给应用。wParam==1,表示窗口已经被激活。lParam内容详见Windows Dev Center-Desktop)
7 WM_SETFOCUS 0 0 (消息说明:当窗口获得键盘焦点,发送消息给窗口。wParam,表示失去键盘焦点的窗口句柄。)
133 WM_NCPAINT 1 0 (消息说明:当窗口的接口必须被绘制时,发送消息给窗口。wParam,表示要更新区域的窗口句柄。)
20 WM_ERASEBKGND 285285209 0 (消息说明:当窗口的背景必须被擦除时(例如窗口大小改变时),发送消息给窗口.wParam,表示设备上下文的句柄。)
71 WM_WINDOWPOSCHANGED 0 3797712 (消息说明:当窗口的大小、位置或Z值顺序即将改变,发送消息。lParam指向WINDOWPOS结构体,包含窗口新的大小及位置。)
5 WM_SIZE 0 36832016 (消息说明:当窗口的大小发生改变后,发送消息给窗口。wParam内容详见Windows Dev Center-Desktop)
3 WM_MOVE 0 19660088 (消息说明:当窗口被移动,发送消息给窗口。lParam表示客户区域的左上角的x、y坐标。)