在Windows中,用户程序可以调用系统的API函数,系统也会调用用户程序,这个调用时通过消息来进行的。
Windows程序设计是一种事件驱动方式的程序设计模式,主要基于消息。
【例】当用户在窗口中画图的时候,按下鼠标左键,操作系统就会感知到这一事件,于是将这个事件包装成一个消息,投递到应用程序的消息队列中,然后应用程序从消息队列中取出消息进行响应。在处理过程中,操作系统会给应用程序“发送消息”。“发送消息”实际上是指操作系统调用程序中一个专门负责处理消息的函数,这个函数称为窗口过程。
1.消息
在Windows中,消息是由MSG结构体表示的。MSG结构体定义如下:
typedef struct tagMSG { // msg HWND hwnd; //表示消息所属的窗口 UINT message; //指定消息的标识符 WPARAM wParam; LPARAM lParam; DWORD time; POINT pt; } MSG;
结构体中:
第一个成员变量hwnd表示消息所属窗口。我们通常开发的应用程序都是窗口应用程序,一个消息一般都是与某个窗口相关联的。
第二个成员变量message指定了消息的标识符。在windows中,消息是由一个数值来表示的,不同的消息对应不同的数值。为了便于记忆,windows将消息对应的数值定义为WM_XXX宏。如,鼠标左键按下的消息是WM_LBUTTONDOWN。键盘按下的消息是WM_KEYDOWN。字符消息WM_CHAR等等。
第三个、第四个成员变量wParam和lParam,用于指定消息的附加信息。用于指定消息的附加信息。例如,当我们收到一个自负消息的时候,message成员变量的值就是WM_CHAR,但用户到底输入的是什么字符,那么由wParam和lParam来说明。wParam、lParam表示的信息随消息的不同而不同。
最后两个变量分别表示消息投递到消息队列中的事件和鼠标的当前位置。
2.消息队列
每一个Windows应用程序开始执行后,系统都会为该程序创建一个消息队列,这个消息队列用来存放该程序创建的窗口消息。例如,当按下鼠标左键的时候,将会产生WM_LBUTTONDOWN消息,系统会将这个消息放到窗口所属的应用程序的消息队列中,等待应用程序的处理。Windows将产生的消息依次放到消息队列中,而应用程序则通过一个消息循环不断地从消息队列中取出消息,并且进行响应。
3.进队消息和不进队消息
进队消息将由系统放入到应用程序的消息队列中,然后由应用程序取出并发送。不进队消息在系统调用窗口过程时直接发给窗口。无论是进队消息还是不进队消息,最终都由调用窗口过程函数队消息进行处理。