您的位置:首页 > 其它

一点关于最简单的Win32应用程序的研究

2017-02-03 16:58 176 查看
这里有一个最简单的Win32应用程序,下面是对他的分析,也就是调用全过程,代码来自Windows程序设计第三版(人民邮电出版社)

#include<windows.h>
// 窗口函数的函数原形
LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR     lpCmdLine,
int       nCmdShow)
{
char szClassName[] = "MainWClass";
WNDCLASSEX wndclass;
// 用描述主窗口的参数填充WNDCLASSEX结构
wndclass.cbSize = sizeof(wndclass); // 结构的大小
wndclass.style = CS_HREDRAW|CS_VREDRAW; // 指定如果大小改变就重画
wndclass.lpfnWndProc = MainWndProc; // 窗口函数指针
wndclass.cbClsExtra = 0;        // 没有额外的类内存
wndclass.cbWndExtra = 0;        // 没有额外的窗口内存
wndclass.hInstance = hInstance;     // 实例句柄
wndclass.hIcon = ::LoadIcon(NULL,
IDI_APPLICATION);   // 使用预定义图标
wndclass.hCursor = ::LoadCursor(NULL,
IDC_ARROW);     // 使用预定义的光标
wndclass.hbrBackground = (HBRUSH)
::GetStockObject(WHITE_BRUSH);  // 使用白色背景画刷
wndclass.lpszMenuName = NULL;       // 不指定菜单
wndclass.lpszClassName = szClassName ;  // 窗口类的名称
wndclass.hIconSm = NULL;        // 没有类的小图标
// 注册这个窗口类
::RegisterClassEx(&wndclass);
// 创建主窗口
HWND hwnd = ::CreateWindowEx(
0,          // dwExStyle,扩展样式
szClassName,        // lpClassName,类名
"My first Window!", // lpWindowName,标题
WS_OVERLAPPEDWINDOW,    // dwStyle,窗口风格
CW_USEDEFAULT,      // X,初始 X 坐标
CW_USEDEFAULT,      // Y,初始 Y 坐标
CW_USEDEFAULT,      // nWidth,宽度
CW_USEDEFAULT,      // nHeight,高度
NULL,           // hWndParent,父窗口句柄
NULL,           // hMenu,菜单句柄
hInstance,      // hlnstance,程序实例句柄
NULL) ;         // lpParam,用户数据
if(hwnd == NULL)
{
::MessageBox(NULL, "创建窗口出错!", "error", MB_OK);
return -1;
}
// 显示窗口,刷新窗口客户区
::ShowWindow(hwnd, nCmdShow);
::UpdateWindow(hwnd);
// 从消息堆中取出消息
MSG msg;
while(::GetMessage(&msg, NULL, 0, 0))
{
// 转化键盘消息
::TranslateMessage(&msg);
// 将消息发送到相应的窗口函数
::DispatchMessage(&msg);
}
// 当GetMessage返回0时程序结束
return msg.wParam;
}
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
char szText[] = "最简单的窗口程序!";
switch (message)
{
case WM_PAINT: // 窗口客户区需要重画
{
HDC hdc;
PAINTSTRUCT ps;
// 使无效的客户区变的有效,并取得设备环境句柄
hdc = ::BeginPaint (hwnd, &ps) ;
// 显示文字
::TextOut(hdc, 10, 10, szText, strlen(szText));
::EndPaint(hwnd, &ps);
return 0;
}
case WM_DESTROY: // 正在销毁窗口
// 向消息队列投递一个WM_QUIT消息,促使GetMessage函数返回0,结束消息循环
::PostQuitMessage(0) ;
return 0 ;
}
// 将我们不处理的消息交给系统做默认处理
return ::DefWindowProc(hwnd, message, wParam, lParam);
}


以下是其运行日志:

创建窗口结构体

指定结构大小

指定如果大小改变就重画

指定窗口函数指针

指定没有额外的类内存

指定没有额外的窗口内存

指定实例句柄

指定预定义图标

指定预定义的光标

指定白色背景画刷

不指定菜单

指定窗口类的名称

指定没有类的小图标

调用RegisterClassEx

窗口注册完成

创建窗口

MainWndProc()第0次调用

调用Windows的默认消息处理函数DefWindowProc(),消息:

36:WM_GETMINMAXINFO

MainWndProc()第1次调用

调用Windows的默认消息处理函数DefWindowProc(),消息:

129:WM_NCCREATE

MainWndProc()第2次调用

调用Windows的默认消息处理函数DefWindowProc(),消息:

131:WM_NCCALCSIZE

MainWndProc()第3次调用

调用Windows的默认消息处理函数DefWindowProc(),消息:

1:WM_CREATE

窗口创建完成

调用ShowWindow()

MainWndProc()第4次调用

调用Windows的默认消息处理函数DefWindowProc(),消息:

24:WM_SHOWWINDOW

MainWndProc()第5次调用

调用Windows的默认消息处理函数DefWindowProc(),消息:

70:WM_WINDOWPOSCHANGING

MainWndProc()第6次调用

调用Windows的默认消息处理函数DefWindowProc(),消息:

70:WM_WINDOWPOSCHANGING

MainWndProc()第7次调用

调用Windows的默认消息处理函数DefWindowProc(),消息:

28:WM_ACTIVATEAPP

MainWndProc()第8次
a85d
调用

MainWndProc()第9次调用

调用Windows的默认消息处理函数DefWindowProc(),消息:

127:WM_GETICON

MainWndProc()第10次调用

调用Windows的默认消息处理函数DefWindowProc(),消息:

127:WM_GETICON

MainWndProc()第11次调用

调用Windows的默认消息处理函数DefWindowProc(),消息:

127:WM_GETICON

调用Windows的默认消息处理函数DefWindowProc(),消息:

134:WM_NCACTIVATE

MainWndProc()第12次调用

MainWndProc()第13次调用

MainWndProc()第14次调用

调用Windows的默认消息处理函数DefWindowProc(),消息:

642:WM_IME_NOTIFY

调用Windows的默认消息处理函数DefWindowProc(),消息:

641:WM_IME_SETCONTEXT

MainWndProc()第15次调用

调用Windows的默认消息处理函数DefWindowProc(),消息:

7:PBT_APMRESUMESUSPEND

调用Windows的默认消息处理函数DefWindowProc(),消息:

6:PBT_APMRESUMECRITICAL

MainWndProc()第16次调用

调用Windows的默认消息处理函数DefWindowProc(),消息:

133:WM_NCPAINT

MainWndProc()第17次调用

调用Windows的默认消息处理函数DefWindowProc(),消息:

20:WM_ERASEBKGND

MainWndProc()第18次调用

调用Windows的默认消息处理函数DefWindowProc(),消息:

71:WM_WINDOWPOSCHANGED

MainWndProc()第19次调用

调用Windows的默认消息处理函数DefWindowProc(),消息:

5:WM_SIZE

MainWndProc()第20次调用

调用Windows的默认消息处理函数DefWindowProc(),消息:

3:WM_MOVE

调用UpdateWindow

MainWndProc()第21次调用

创建设备图形句柄

创建画布结构

调用TextOutW

调用EndPaint()

绘画完成

创建MSG实例句柄

调用GetMessgae()

MainWndProc()第21次调用

调用Windows的默认消息处理函数DefWindowProc(),消息:

136:WM_SYNCPAINT

MainWndProc()第22次调用

调用Windows的默认消息处理函数DefWindowProc(),消息:

127:WM_GETICON

MainWndProc()第23次调用

调用Windows的默认消息处理函数DefWindowProc(),消息:

127:WM_GETICON

MainWndProc()第24次调用

调用Windows的默认消息处理函数DefWindowProc(),消息:

127:WM_GETICON

调用TranslateMessage

调用DispatchMessage

MainWndProc()第25次调用

调用Windows的默认消息处理函数DefWindowProc(),消息:

799:WM_DWMNCRENDERINGCHANGED

调用PostQuitMessage()

调用TranslateMessage

调用DispatchMessage

MainWndProc()第26次调用

调用Windows的默认消息处理函数DefWindowProc(),消息:

49338

调用PostQuitMessage()

调用TranslateMessage

调用DispatchMessage

调用PostQuitMessage()

调用TranslateMessage

调用DispatchMessage

调用PostQuitMessage()

WinMain调用结束

从上面的运行日志我们可以看出:

MainWindowsProc函数从创建好窗口之后就被Windows一直调用,而且调用过程及每一步做过什么都可以看的很清楚。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Win32-API