windows游戏编程了解消息事件模型
本系列文章由jadeshu编写,转载请注明出处。http://blog.csdn.net/jadeshu/article/details/22309265
作者:jadeshu 邮箱: jadeshu@qq.com 欢迎邮件交流
熟悉了DOS编程的朋友会更加深了解过程化模型,在DOS环境下,应用程序是一句一句逐个执行的。程序员思考问题的方式和机器的执行顺序是一样的。不需要考虑消息,不需要考虑多线程,一切都是顺其自然。然而在Windows环境下,它使用的是事件驱动的编程模型,应用程序通过处理操作系统发送来的消息来响应事件。事件可能是用户的一次鼠标移动,键盘敲击,或者是系统要求窗口重绘的消息,程序员所需要做的事就是处理应用程序感兴趣的消息。
WinMain函数是整个Windows程序的入口,在这个函数中会创建窗口,设定窗口过程,并进入消息循环。如下图:
从上图可以看出,Windows程序运行的源动力来自于消息队列,WinMain函数通过消息循环从消息队列中提取消息,然后把它提交给窗口过程处理,在窗口过程中,程序员编写自己的消息处理程序,对自己感兴趣的消息进行处理。对于不感兴趣的消息,就交给系统默认的消息处理函数DefWindowProc去处理。DefWindowProc定义了Windows应用程序的许多默认的行为特性,比如单击关闭按钮应用程序会退出,拖动标题栏窗口会移动等行为。如果程序员想要改变这些行为特性,那么就可以在窗口过程中拦截这些消息,对它们进行非默认的处理。
下面来具体介绍下消息
typedef struct tagMSG { HWND hwnd; //32位的窗口句柄。窗口可以是任何类型的屏幕对象,因为Win32能够维护大多数可视对象的句柄(窗口、对话框、按钮、编辑框等)。 UINT message; //用于区别其他消息的常量值 WPARAM wParam; //通常是一个与消息有关的常量值,也可能是窗口或控件的句柄。 LPARAM lParam; //通常是一个与消息有关的常量值,也可能是窗口或控件的句柄。 DWORD time; //消息时间 POINT pt; //鼠标坐标 } MSG;
Windows的消息系统是由3个部分组成的:
- 消息队列。Windows能够为所有的应用程序维护一个消息队列。应用程序必须从消息队列中获取消息,然后分派给某个窗口。
- 消息循环。通过这个循环机制应用程序从消息队列中检索消息,再把它分派给适当的窗口,然后继续从消息队列中检索下一条消息,再分派给适 当的窗口,一次进行。
- 窗口过程。每个窗口都有一个窗口过程来接收传递给窗口的消息,它的任务就是获取消息然后响应它。窗口过程是一个回调函数,处理了一个消息后,它通常要返回一个值给Windows。
一个消息从产生到被一个窗口响应,其中有5个步骤:
1) 系统中发生了某个事件。
2) Windows把这个事件翻译为消息,然后把它放到消息队列中。
3) 应用程序从消息队列中接收到这个消息,把它存放在TMsg记录中。
4) 应用程序把消息传递给一个适当的窗口的窗口过程。
5) 窗口过程响应这个消息并进行处理。- 其中步骤3和4构成了应用程序的消息循环。消息循环往往是Windows应用程序的核心,因为消息循环使一个应用程序能够响应外部的事件。消息循环的任务就是从消息队列中检索消息,然后把消息传递给适当的窗口。如果消息队列中没有消息,Windows就允许其他应用程序处理它们的消息。
windows是一个消息驱动的系统,它使用两种方式把各种事件通知给应用程序:
1、把消息放在应用程序的消息队列中
2、向适当的窗口过程直接发消息