windows基础应用程序编程(二):消息说明

本文探讨了Windows基础应用程序编程中重要的WM_DESTROY和WM_PAINT消息。当你运行程序并操作窗口时,如最小化、最大化或右键点击标题栏,系统会发送这些消息。WM_DESTROY用于窗口销毁前的处理,而WM_PAINT则涉及窗口的绘制更新。了解这些消息的分类和功能对于掌握Windows应用开发至关重要。

问题

    运行了上一篇文章中所讲的程序之后,我们会惊讶的发现,这个窗口有这着许多丰富的功能,我们可以对这个窗口进行窗口最小和最大化,在水平和垂直方向上随意的更改窗口的大小,并且还发现右键单击程序的标题栏,会弹出一个菜单,这个菜单我们称之为系统菜单。这些功能都是windows系统帮我们完成的。是不是很强大啊?系统菜单如下所示:


    我相信经过上一篇文章的认真学习。(如果还不是很明白,可以再仔细的看一遍,切记,学习是一个大量重复的过程,不能一蹴而就,欲速则不达啊!)但是,同时,我也明白在上一篇的程序中,仍然存在着许多小的细节没有讲述。比如,大家可能还不太明白WM_DESTROY的含义,(大家估计也猜到了,这是对关闭窗口消息的一个处理),以及在窗口创建的过程中,我们已经调用了ShowWindow()函数之后,为什么还要调用UpdateWindow()函数呢?那么在这一篇文章中,我相信你能找到你想要的答案。

WM_DESTROY

    首先我们来看一下WM_DESTROY是什么东东,WM意思是指:windows message。顾明思议,这是一个“windows消息”。之所以打引号,是因为在上一篇中我们曾经提到,windows消息是一个结构体,那么,如果WM_DESTROY如果是一个MSG结构体的变量,那么我们怎么能使用switch/case结构呢?我们一般case 后面对应的是一个整数或者一个字符。我们根据VS给我们提供的功能,在WM_DESTROY上单击右键,选择转到定义。会发现这是一个对应于一个数的宏,不错,这实际上是消息的ID,我们根据这个ID来区分Windows中的不同消息。
    那么这个WM_DESTROY是如何产生的呢?当我们单击窗口上的关闭按钮,或者在程序的系统菜单上选择Close时发生的。还记得在上一篇文章中,我们提到在消息循环中,当GetMessage函数收到WM_QUIT消息时,才退出消息循环,但是在我们的程序中并没有看到WM_QUIT消息的踪影,那么消息循环是怎么退出的呢?其实,在我们处理WM_DESTROY函数时,调用了PostQuitMessage(0),这个函数将会在程序的消息队列中插入一个WM_QUIT消息。括号里的值为退出标识,这个值传递给消息结构体的wParam变量,在消息循环体的后面,我们看到有这么一条语句:return (int)msg.wParam; 即将这个值返回,代表正常退出。

WM_PAINT

现在是不是对上一篇的代码有了更深刻的了解了?OK,接下来我们将介绍一下为什么在显示完窗口之后还需要更新窗口。在介绍这个知识点之前,我们需要介绍一下WM_PAINT消息。
在上面生成的窗口中,除了上面的标题栏和周围的框架,中间一块白色的区域,我们称之为客户区,信息将在这个区域中进行显示。当这个客户区的一部分或者全部变为“无效”时,以致于必须“刷新”时,将由这个消息通知应用程序。WM_PAINT消息是windows系统中一个非常重要的消息。
那么什么客户区“无效”呢?这是windows从效率出发,当我们把一个窗口最小化时,windows是不会保存客户区内的显示内容,因为这个数据量是非常大的。windows仅仅是另这个客户区“无效”,当我们再次恢复以前的窗口时,窗口过程将会接受一个WM_PAINT消息,通过对这个消息的处理,程序将自动恢复窗口的内容。
在我们最初创建一个窗口时,整个客户区都是无效的,那么第一个WM_PAINT消息就是由UpdateWindow函数来发出的。一般我们在程序中,在消息循环的初始化期间都要调用函数UpdateWindow函数。
我们一般以这样的结构来处理WM_PAINT消息
case WM_PAINT:
     hDC = BeginPaint( hwnd, &ps );
     // 使用GDI函数
     EndPaint( hwnd, &ps );
     break;

至于为什么这样,大家暂时先不用理会,有个印象即可,在下一篇文章中将给出详细说明。
现在相信大家对上一节的内容不再会有疑惑了吧!
当然,windows系统还有这许多消息,比较常见的有WM_CREATE消息,这是当调用CreateWindow函数时,windows系统所接收到的第一个消息,一般发生在窗口创建之后,显示之前,我们可以在该消息的处理里面做一些初始化的工作。以及WM_SIZE消息,这个消息发生在改变窗口大小时。等等,我们在此不再列举,当需要时,我们再加以说明。

消息分类

根据不同的分类,我们可以把消息分成许多类。一般我们根据是否进队来把消息区分为进队消息和不进队消息。我们知道,windows为每一个程序提供了一个消息队列,我们通过消息循环来取得队列中的每个消息并分配到窗口过程(即窗口处理函数)中进行处理(即消息循环中的DispathMessage函数,还记得吗?)。所谓进队消息就是指windows放入消息队列中的消息。而不进队消息是指那些windows直接发给窗口过程,而不进入消息队列的消息。可见,我们的窗口过程可以处理全部消息,包括进队消息和不进队消息。
进队消息基本上是用户输入的结果,包括鼠标、键盘等所产生的消息,另外时钟消息(WM_TIMER)、刷新消息(WM_PAINT)和退出消息(WM_QUIT)等也都是进队消息。
不进队消息主要是来自特定的windows函数,例如,前面所讲的CreateWindow函数就属于不进队消息,WM_SIZE消息也是不进队消息。
那么,对于windows系统中这么多的消息,我们如何去区分哪个是进队消息哪个不是呢?幸运的是,我们根本不需要这么去做,我们知道,所有的消息都要经过窗口处理函数来进行处理,那么也就是说,窗口过程为我们屏蔽了这些区别,我们只需要按部就班的去处理每一个消息即可。
了解到这里,大家可能也发现了,所谓的Windows编程主要就是对windows中产生的消息进行处理的过程,对的,这又被称为Windows的消息驱动机制。

OK!这一篇文章就先到这里,内容比较简单。在下一章中我们将学习一下windows的GDI(图像设备接口),从而能够在窗口上显示一些文字。革命尚未成功,同志仍需努力啊!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值