注:可能你看这些东西的时候有些乱,不过没关系,这很正常,多看几下MSDN就慢
慢明白了,有我写这个专题的时候,很多概念也太不清楚,不过等我查资料写下来
后,感觉渐渐有些东西也有了点眉目,因为这本身也是个进步的过程。 ---小朱
(七)处理消息
窗口过程处理消息通常以switch语句开始,对于它要处理的每一条消息ID都跟有一
条case语句。大多数windows proc都有具有下面形式的内部结构:
switch(uMsgId)
{
case WM_(something):
//这里此消息的处理过程
return 0;
case WM_(something else):
//这里是此消息的处理过程
ruturn 0;
default:
//其他消息由这个默认处理函数来处理
return DefWindowProc(hwnd,uMsgId,wParam,lParam);
}
在处理完消息后,要返回0,这很重要-----它会告诉Windows不必再重试了。对于那
些在程序中不准备处理的消息,窗口过程会把它们都扔给DefWindowProc进行缺省
处理,而且还要返回那个函数的返回值。在消息传递层次中,可以认为
DefWindowProc函数是最顶层的函数。这个函数发出WM_SYSCOMMAND消息,由系统执
行Windows环境中多数窗口所公用的各种通用操作,例如,画窗口的非用户区,更
新窗口的正文标题等等等等。
再提示一下,以WM_的消息在Windows头文件中都被定义成了常量,如
WM_QUIT=XXXXXXXXXXX,但我们没有必要记住这个数值,也不可能记得住,我们只要
知道WM_QUIT就OK了。
在第二只小板凳中我们只让窗口过程处理了两个消息:一个是WM_PAINT,另一个是
WM_DESTROY,先说说第一个消息---WM_PAINT.
关于WM_PAINT:
无论何时Windows要求重画当前窗口时,都会发该消息。也可以这样说:无论何时
窗口非法,都必须进行重画。 哎呀,什么又是"非法窗口"?什么又是重画啊?你
这人有没有完,嗯?
稍安勿燥,我比你还烦呢?我午饭到现在还没吃呢!你有点耐心,来点专业精神好
不好???我开始在MSDN里面找有关这个方面的内容了,别急,我找找看:
Platform SDK-->Graphics and Multimedia Services-->Windows GDI-->Painting
and Drawing-->Using the WM_PAINT Message-----终于找到了。
下面是一大套理论:
让我们把Windows的屏幕想像成一个桌面,把一个窗口想像成一张纸。当我们把一
张纸放到桌面上时,它会盖住其他的纸,这样被盖住的其他纸上的内容都看不到了
。但我们只要把这张纸移开,被盖住的其他纸上的内容就会显示出来了---这是一
个很简单的道理,谁都明白。
对于我们的屏幕来说,当一个窗口被另一窗口盖住时,被盖住的窗口的某些部分就
看不到了,我们要想看到被盖住的窗口的全部面貌,就要把另一个窗口移开,但是
当我们移开后,事情却起了变化-----很可能这个被盖住的窗口上的信息被擦除了
或是丢失了。当窗口中的数据丢失或过期时,窗口就变成非法的了---或者称为"无
效"。于是我们的任务就来了,我们必须考虑怎样在窗口的信息丢失时"重画窗口
"--使窗口恢复成以前的那个样子。这也就是我们在这第二只小板凳中调用
UpdateWindow的原因。
你忘记了吗?刚才我们在(三)显示和更新窗口中有下面的一些文字:
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,结束消息循环,从而终
止应用程序。
至此,第二支小板凳终于支解完毕!!