以前在玩C编程的时候完全么有见过这么多参数的程序,Windows程序就是参数多,都不知道都是干些什么的。虽然有些参数可以简单的设定成NULL或者0,但是还是很麻烦就是了。那么就一句句分析好了。
前天说过了这个程序的结构,因为第一部分致使一些函数的调用,后面的才是关键,我就整理一下书上的内容好了。我实在搞不懂书上那个程序,只好以VC++的为准了。
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/1327ab569c1ae82736693a50b8e33378.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
来来来,一个个来,先看看这个,从数目上面看这里是最难的,参数多。不过一个个看就不这么难了。
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/1327ab569c1ae82736693a50b8e33378.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
下面就是函数: InitInstance(HANDLE, int)了:
//
// 函数: InitInstance(HANDLE, int)
//
// 目的: 保存实例句柄并创建主窗口
//
// 注释:
//
// 在此函数中,我们在全局变量中保存实例句柄并
// 创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // 将实例句柄存储在全局变量中
hWnd = CreateWindow(
szWindowClass, // Windows类别名称
szTitle, /* Windows窗口名称,不要和上面那个搞混了!不一样的,上面的只是起指示作用,这个才会真正地显示出来。 */
WS_OVERLAPPEDWINDOW, // 风格
CW_USEDEFAULT, // 指定了窗口左上角相对于屏幕左上角的初始位置,这里是默认的迭代方式
0 ,
CW_USEDEFAULT, // 制定窗口大小,这里使用默认设定
0 ,
NULL, // 父窗口句柄,这里使直接建立一个窗口,所以不用
NULL, // 窗口菜单句柄,按道理这里应该是有菜单的,就不知道为什么这里没有了
hInstance, // 「程序执行实体句柄」设定为执行实体句柄,它是作为WinMain的参数传递给这个程序的。
NULL); // 「建立参数」指标设定为NULL,可以用这个参数存取稍后程序中可能引用到的数据。不知道怎么用。。。。
if ( ! hWnd)
{
return FALSE; // 建立失败
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
// 函数: InitInstance(HANDLE, int)
//
// 目的: 保存实例句柄并创建主窗口
//
// 注释:
//
// 在此函数中,我们在全局变量中保存实例句柄并
// 创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // 将实例句柄存储在全局变量中
hWnd = CreateWindow(
szWindowClass, // Windows类别名称
szTitle, /* Windows窗口名称,不要和上面那个搞混了!不一样的,上面的只是起指示作用,这个才会真正地显示出来。 */
WS_OVERLAPPEDWINDOW, // 风格
CW_USEDEFAULT, // 指定了窗口左上角相对于屏幕左上角的初始位置,这里是默认的迭代方式
0 ,
CW_USEDEFAULT, // 制定窗口大小,这里使用默认设定
0 ,
NULL, // 父窗口句柄,这里使直接建立一个窗口,所以不用
NULL, // 窗口菜单句柄,按道理这里应该是有菜单的,就不知道为什么这里没有了
hInstance, // 「程序执行实体句柄」设定为执行实体句柄,它是作为WinMain的参数传递给这个程序的。
NULL); // 「建立参数」指标设定为NULL,可以用这个参数存取稍后程序中可能引用到的数据。不知道怎么用。。。。
if ( ! hWnd)
{
return FALSE; // 建立失败
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
主消息循环:
while (GetMessage( & msg, NULL, 0 , 0 )) // 从消息队列中取出一个消息,传给Windows一个指标,指向名为msg的MSG结构。
{
if ( ! TranslateAccelerator(msg.hwnd, hAccelTable, & msg))
{
TranslateMessage( & msg); // 将msg结构传给Windows,进行一些键盘转换。
DispatchMessage( & msg); // 将msg结构回传给Windows。然后,Windows将该消息发送给适当的窗口消息处理程序,让它进行处理。
}
}
return ( int ) msg.wParam;
}
while (GetMessage( & msg, NULL, 0 , 0 )) // 从消息队列中取出一个消息,传给Windows一个指标,指向名为msg的MSG结构。
{
if ( ! TranslateAccelerator(msg.hwnd, hAccelTable, & msg))
{
TranslateMessage( & msg); // 将msg结构传给Windows,进行一些键盘转换。
DispatchMessage( & msg); // 将msg结构回传给Windows。然后,Windows将该消息发送给适当的窗口消息处理程序,让它进行处理。
}
}
return ( int ) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
/* 窗口消息处理程序的四个参数与MSG结构的前四个字段是相同的。第一个参数hwnd是接收消息的窗口的句柄,它与CreateWindow函数的传回值相同。对于与HELLOWIN相似的程序(只建立一个窗口),这个参数是程序所知道的唯一窗口句柄。如果程序是依据同一窗口类别(同时也是同一窗口消息处理程序)建立多个窗口,则hwnd标识接收消息的特定窗口。 */
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
RECT rect;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 分析菜单选择:
// 这个地方书上是没有的,因为人家的没有菜单咯,那就不管先:)
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_PAINT: // 处理WM_PAINT消息
hdc = BeginPaint(hWnd, & ps);
// TODO: 在此添加任意绘图代码:
MessageBox(NULL,TEXT ( " 我重绘窗口了! " ),TEXT ( " Hei here " ), 0 );
/* 开始的时候绘制,大小改变的时候绘制,甚至有东西覆盖也要重新绘制。运行一下就知道了。 */
GetClientRect (hWnd, & rect) ;
DrawText (hdc, TEXT ( " Hello, Windows 98! " ), - 1 , & rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
EndPaint(hWnd, & ps);
break ;
case WM_DESTROY: // 处理WM_DESTROY消息
MessageBox(NULL,TEXT ( " 我退出了! " ),TEXT ( " Hei here " ), 0 ); // 窗口关闭
PostQuitMessage( 0 );
break ;
default :
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0 ;
}
/* 窗口消息处理程序的四个参数与MSG结构的前四个字段是相同的。第一个参数hwnd是接收消息的窗口的句柄,它与CreateWindow函数的传回值相同。对于与HELLOWIN相似的程序(只建立一个窗口),这个参数是程序所知道的唯一窗口句柄。如果程序是依据同一窗口类别(同时也是同一窗口消息处理程序)建立多个窗口,则hwnd标识接收消息的特定窗口。 */
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
RECT rect;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 分析菜单选择:
// 这个地方书上是没有的,因为人家的没有菜单咯,那就不管先:)
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_PAINT: // 处理WM_PAINT消息
hdc = BeginPaint(hWnd, & ps);
// TODO: 在此添加任意绘图代码:
MessageBox(NULL,TEXT ( " 我重绘窗口了! " ),TEXT ( " Hei here " ), 0 );
/* 开始的时候绘制,大小改变的时候绘制,甚至有东西覆盖也要重新绘制。运行一下就知道了。 */
GetClientRect (hWnd, & rect) ;
DrawText (hdc, TEXT ( " Hello, Windows 98! " ), - 1 , & rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
EndPaint(hWnd, & ps);
break ;
case WM_DESTROY: // 处理WM_DESTROY消息
MessageBox(NULL,TEXT ( " 我退出了! " ),TEXT ( " Hei here " ), 0 ); // 窗口关闭
PostQuitMessage( 0 );
break ;
default :
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0 ;
}
好了,基本就这么多了,写了前面的我就已经头大了,所以后面基本上就抄书上的了,我在消息处理函数那里加入了一些MessageBox,这样在运行的时候就可以知道什么时候会调用这个消息了。
-----------------------------------------------
我发现的一个问题:一开始我老找不到
TCHAR szTitle[MAX_LOADSTRING];
//
标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
这个在怎么地方被定义成了HELLOWIN,其实这个在下面这个函数中真正被定义了:
//
初始化全局字符串
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_HELLOWIN, szWindowClass, MAX_LOADSTRING);
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_HELLOWIN, szWindowClass, MAX_LOADSTRING);
那么我看呀看,终于在资源列表里面发现了IDS_APP_TITLE和IDC_HELLOWIN的踪影,看图:
就是这了,进去以后你会发现这样的好处是方便集中修改,不过要以后才用得到了。。。。。