WinMain()调用完ShowWindow后,还需要调用函数UpdateWindow,最终把窗口显示了出来。调用函数UpdateWindow将产生一个WM_PAINT消息,这个消息将使窗口重画,即使窗口得到更新.—这是程序第一次调用了这条消息。
为重新显示非法区域,Windows就发送WM_PAINT消息实现。要求Windows发送WM_PAINT的情况有改变窗口大小,对话框关闭,使用了UpdateWindows和ScrollWindow函数等。这里注意,Windows并非是消息WM_PAINT的唯一来源,使用InvalidateRect或InvalidateRgn函数也可以产生绘图窗口的WM_PAINT消息……
通常情况下用BeginPaint()来响应WM_PAINT消息。如果要在没有WM_PAINT的情况下重画窗口,必须使用GetDC函数得到显示缓冲区的句柄。这里面不再扩展。详细见MDSN。
这个BeginPaint函数会执行准备绘画所需的所有步骤,包括返回你用于输入的句柄。结束则是以EndPaint();
在调用完BeginPaint之后,WndProc接着调用GetClientRect:
GetClientRect(hwnd,&rect);
第一个参数是程序窗口的句柄。第二个参数是一个指针,指向一个RECT类型的结构。查MSDN,可看到这个结构有四个成员。
WndProc做了一件事,他把这个RECT结构的指针传送给了DrawText的第四个参数。函数DrawText的目的就是在窗口上显示一行字—-“你好,欢迎你来到VC之路!”,有关这个函数的具体用法这里也没必要说了吧。
关于WM_DESTROY这个消息要比WM_PAINT消息容易处理得多:只要用户关闭窗口,就会发送WM_DESTROY消息(在窗口从屏幕上移去后)。
程序通过调用PostQuitMessage以标准方式响应WM_DESTROY消息:
PostQuitMessage (0) ;
这个函数在程序的消息队列中插入一个WM_QUIT消息。在(四)创建消息循环中我们曾有这么一段话:
消息循环以GetMessage调用开始,它从消息队列中取出一个消息:
在接收到除WM_QUIT之外的任何一个消息后,GetMessage()都返回TRUE。如果GetMessage收到一个WM_QUIT消息,则返回FALSE,如收到其他消息,则返回TRUE。因此,在接收到WM_QUIT之前,带有GetMessage()的消息循环可以一直循环下去。只有当收到的消息是WM_QUIT时,GetMessage才返回FALSE,结束消息循环,从而终止应用程序。
Win32 API主消息循环的两种处理方法主要介绍了Win32 API主消息循环的两种处理方法:使用GetMessage方法构造主消息循环、使用PeekMessage方法构造主消息循环。
使用GetMessage方法构造主消息循环一般应用程序都使用用GetMessage方法构造主消息循环,该方法是获得一条线程 的消息。对于VS2005自动生成的Win32 Windows程序上面有些不足。
因为VS2005生成的主消息循环如下;
简单看看的确没有问题,但是当我们去查阅MSDN文档看到GetMessage消息时候可以看到这样一段
If there is an error, the return value is -1.所以我们应该把上面这个主循环修改为下面这样的形式,增加一个临死变量。
// Main message loop: BOOL bRet;//临时变量,存储GetMessage方法返回值 // Main message loop: while ((bRet = GetMessage(&msg, NULL, 0, 0))!=0) { if(bRet==-1) { //表示GetMessage获得的信息有错误 } else { TranslateMessage(&msg); DispatchMessage(&msg); } }(2)使用PeekMessage方法构造主消息循环
PeekMessage常常用于Windows开发游戏中,PeekMessage在处理获得消息时候和GetMessage一样,关键不同的是PeekMessage在没有消息处理的时候还会继续保持循环激活状态,并且继续占用资源。
1:Win32是个多任务抢占式操作系统,每运行一个程序(可执行文件),操作系统就创建一个进程和主线程,把程序的代码和数据映射到该进程地址空间,并为每个线程分配了一个时间片,一个线程放弃CPU的处理权有、可以是时间片完了,I/O请求,还有就是程序自己要求放弃处理权,而GetMessage函数是一个阻塞函数,也就是你调用他就相当于主动放弃了CPU,引起线程上下文切换,从而其他线程可以得到CPU,但该函数会在有消息的时间激活而继续执行。如果你是获取消息用PeekMessage函数,那么你打开任务管理器,才知道什么叫做真正的浪费资源;
2:
while(1) { id=getMessage(...); if(id == quit) break; translateMessage(...); }