mdShow是系统传递给WinMain函数的参数。函数的第二个参数可以有多个不同的取值(具体情况请索引查看SDK文档),例如下面的代码将隐藏句柄hWnd指定的窗口。
::ShowWindow(hWnd,SW_HIDE); //nCmdShow参数的取值可以是SW_SHOW、SW_HIDE、SW_MINIMIZE等
4. 更新窗口客户区:
PS:
如果指定窗口的更新区域不为空的话,UpdateWindow函数通过向这个窗口发送一个WM_PAINT消息更新它的客户区。当窗口显示在屏幕上时,窗口的客户区被在WNDCLASSEX中指定的刷子擦去了,调用UpdateWindow函数将促使客户区重画,以显示其内容。
5. 进入无限的消息循环:
程序下面将进入无限的循环中。在调用UpdateWindow函数之后,整个窗口已经显示在桌面上,程序必须准备从用户接受键盘和鼠标输入了。Windows为每个线程维护了一个消息队列,每当有一个输入发生,Windows就把用户的输入翻译成消息放在消息队列中。利用GetMessage函数可以从调用线程的消息队列中取出一个消息来填充MSG结构。
1 ::GetMessage(&msg,NULL,0,0);
PS:
如果消息队列中没有消息(即没有用户输入),这个函数会一直等待下去,知道有消息进入到消息队列为止。msg是一个MSG结构类型的变量,这个结构定义了消息的所有属性。
typedef struct tagMSG { HWND hwnd; //消息要发送的窗口句柄
UINT message; //消息标识符,以WM_开头的预定义值(意为Window Message)
WPARAM wParam; //消息的参数之一
LPARAM lParam; //消息的参数之二
DWORD time //消息放入消息队列的时间
POINT pt; //这是一个POINT数据结构,表示消息放入消息队列时的鼠标位置
}MSG,*PMSG;
GetMessage函数从消息队列中取得的消息如果不是WM_QUIT,则返回非零值。一个WM_QUIT消息会促使GetMessage函数返回0,从而结束消息循环。
::TranslateMessage(&msg);
此调用把键盘输入翻译成为可传递的消息。
DispatchMessage函数分发一个消息到对应窗口的窗口函数。在上面的例子中,窗口函数是MainWndProc。MainWndProc处理消息后把控制权交给Windows,此时DispatchMessage函数仍然继续工作,当它返回时,消息循环队列从调用Getmessage函数开始进入下一轮循环。
*6. 处理消息:
消息处理函数接收到的所有消息都被标识为一个数字,这就是MainWndProc的第一个参数uMsg。这些数字在WINUSER.H文件中都是以WM_为前缀定义的。
通常Windows程序设计者用一个switch和case结构来决定消息处理函数收到了什么消息,以及如何处理这个消息。所有消息处理函数不处理的消息都必须传给一个名为DefWindowProc的函数让Windows做默认处理,从DefWindowProc函数返回的值也必须从消息处理函数返回。
1 switch(uMsg) 2 { 3 case WM_PAINT: 4 /*处理WM_PAINT消息*/
5 return 0; 6
7 case WM_DESTROY: 8 /*处理WM_DESTROY消息*/
9 return 0; 10
11 } 12 return ::DefWindowProc(hwnd,message,wParam,lParam);
PS:
必须要把所有不处理的消息交给DefWindowProc函数处理,也要把它的返回值返回给Windows,否则Windows就失去了与应用程序通信的途径,也就不能再控制窗口的行为了,这是不合法的。
WM_PAINT消息通知应用程序窗口客户区有一块或者全部变成无效,必须刷新。这意味着窗口客户区的内容必须被重画。客户区在以下情况会变成无效:
1)当窗口第一次被创建时,整个客户区是无效的,因为还没有向上面画任何东西。
第一个WM_PAINT消息被发送到窗口处理函数时,程序有机会向客户区画一些东西。
2)当改变窗口大小的时候,客户区编程无效。
用户在填写WNDCLASSEX结构的style成员时,将它设置为CS_HREDRAW和CS_VREDRAW,这就直接促成在改变窗口大小时Windows将整个窗口变为无效。
3)最小化窗口,再将它恢复到以前大小时,Windows没有保存整个客户区的内容。
在图形操作系统下,需要保存的数据太多了。同样地,Windows使这个窗口无效,窗口处理函数就会收到一个WM_PAINT消息,自己负责回复客户区内容。
4)当围着屏幕移动窗口,直到窗口被覆盖时,Windows并没有保存被覆盖的区域。
这个区域再次显示时,它就被标识为无效。窗口处理函数会收到一个WM_PAINT消息来重画窗口的内容。
处理WM_PAINT消息时总是以调用BeginPaint函数开始。
hdc=::BeginPaint(hwnd,&ps); //以一个EndPaint函数调用结束
::EndPaint(hwnd,&ps);
这两个函数中,第一个参数是窗口句柄,第二个参数是指向PAINTSTRUCT结构的指正,这个结构包含一些可以在重画客户区时使用的信息。
在调用BeginPaint函数的时候,如果客户区的背景还没有被擦掉的话,Windows将擦除它,擦除背景时使用的刷子由WNDCLASSEX结构的hbrBackground成员指定。对BeginPain函数的调用将使整个客户区有效,然后返回设备环境句柄。在窗口的客户区显示图形和文字时,需要使用这个设备环境句柄。EndPaint函数负责释放设备环境句柄,使它变得不在能使用。DefWindowProc函数会通过调用BeginPaint和EndPaint函数使客户区有效。
调用BeginPaint函数后,主程序中调用了TextOut函数。
1 ::TextOut(hdc,10,10,szText,strlen(szText));
此函数用于在hdc指定的设备(这里是 显示器)上显示文字。(10,10)为坐标位置,szText为要显示的文字,strlen(szText)语句计算出了文本占用的字节数。
每当客户区变成无效,消息处理函数WndProc都会收到一个洗呢WM_PAINT消息。响应此消息的代码取得设备环境句柄后,再一次将szText的内容显示在指定位置。
WM_DESTROY是窗口函数必须处理的消息。当用户关闭窗口,而且此窗口已经响应了用户的请求正在关闭时,消息处理函数就会收到一个WM_DESTROY消息。当接受到这个消息的时候,说明窗口正在销毁。MainWndProc函数调用PostQuitMessage函数来响应此消息。