Windows消息传递机制详解

所属分类: 软件编程 / C 语言 阅读数: 109
收藏 0 赞 0 分享

对于windows程序设计,这里有几个关键词需要注意:消息,消息循环,窗口过程。
 
所谓的Windows消息传递机制就类似于生活中的物流公司。当寄件人(例如鼠标、键盘)将包裹(消息)交给物流公司(Windows系统)时,物流公司(Windows系统)会进行整理并且派发(整理及派发主要由消息循环完成),交给相应的快递员(窗口过程)来处理。快递员(窗口过程)拿到包裹(消息)后则有多种方式来处理,如立马交给收件人,等一天交给收件人,或转交给其他快递派发,这就需要在窗口过程中用swich/case来区分。
 
消息循环:

当初始化完成后,WinMain主函数就进入消息循环:

While(GetMessage(&msg,...))
{
TranslateMessage(&msg);//转换键盘消息
DispatchMessage(&msg);//分派消息
}

窗口过程:

LRESULT CALLBACK WndProc(...)
{
...
switch( msg )
{
case 1:
...
case 2:
...
Default:
...
}
return 0;
}

下面以两个问题的方式进行具体概要。
 
问题1:消息有哪几种分类方法?
(1) 队列消息和非队列消息
队列消息会被送到系统消息队列,然后到线程消息队列。Windows维护一个系统消息队列,每个GUI线程也有一个线程消息队列。其中包括键盘鼠标消息,WM_PAINT、WM_TIMER、WM_QUIT。
这些队列消息以外的消息绝大多数都是非队列消息。

此处注意:消息队列中放置的消息是以MSG结构的形式存在,MSG包括:窗口句柄、消息标识、消息的两个参数(WPARAM和LPARAM)、消息发送(POST)的时间以及鼠标的位置。此外,可以利用::GetMessage函数和::PeekMessage函数来保存获得的消息信息。
非队列消息直接送给目的窗口过程。

(2) 系统消息和应用程序消息
系统消息ID范围 0X8000~0XBFFF
应用程序消ID范围0XC000~0XFFFF
为了应用程序消息的ID唯一性,可以使用::RegisterWindowMessage来得到特定的ID。 

问题2:消息是如何进行传递、接收、处理的?
Windows应用程序的输入由Windows系统以消息的形式发送给应用程序的窗口,这些窗口通过窗口过程来接收和处理消息,然后把控制返还给Windows。

此处注意:非队列消息直接送给目的窗口的窗口过程,队列消息由::DispatchMessage派发给目的窗口的窗口过程。窗口过程被调用时接收四个参数:窗口句柄、消息标识、两个32位的消息参数。在窗口过程里,用switch/case分支处理语句来识别和处理消息。

每个GDI应用程序在主窗口创建之后,都会进入消息循环,接受用户输入、解释和处理消息。消息循环从消息队列中得到消息,如果不是快捷键消息或对话框消息,就进行消息转换和派发,让目的窗口的窗口过程来处理。当得到消息WM_QUIT,或者::GetMessage出错时,退出消息循环。

更多精彩内容其他人还在看

用标准c++实现string与各种类型之间的转换

这个类在头文件中定义, < sstream>库定义了三种类:istringstream、ostringstream和stringstream,分别用来进行流的输入、输出和输入输出操作。另外,每个类都有一个对应的宽字符集版本
收藏 0 赞 0 分享

C++如何通过ostringstream实现任意类型转string

再使用整型转string的时候感觉有点棘手,因为itoa不是标准C里面的,而且即便是有itoa,其他类型转string不是很方便。后来去网上找了一下,发现有一个好方法
收藏 0 赞 0 分享

C/C++指针小结

要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区
收藏 0 赞 0 分享

C++ 类的静态成员深入解析

在C++中类的静态成员变量和静态成员函数是个容易出错的地方,本文先通过几个例子来总结静态成员变量和成员函数使用规则,再给出一个实例来加深印象
收藏 0 赞 0 分享

C++类的静态成员初始化详细讲解

通常静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域操作符来指出静态成员所属的类.但如果静态成员是整型或是枚举型const,则可以在类声明中初始化
收藏 0 赞 0 分享

C++类静态成员与类静态成员函数详解

静态成员不可在类体内进行赋值,因为它是被所有该类的对象所共享的。你在一个对象里给它赋值,其他对象里的该成员也会发生变化。为了避免混乱,所以不可在类体内进行赋值
收藏 0 赞 0 分享

C++中的friend友元函数详细解析

友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类。友元函数的特点是能够访问类中的私有成员的非成员函数。友元函数从语法上看,它与普通函数一样,即在定义上和调用上与普通函数一样
收藏 0 赞 0 分享

static全局变量与普通的全局变量的区别详细解析

以下是对static全局变量与普通的全局变量的区别进行了详细的分析介绍,需要的朋友可以过来参考下,希望对大家有所帮助
收藏 0 赞 0 分享

C++ explicit关键字的应用方法详细讲解

C++ explicit关键字用来修饰类的构造函数,表明该构造函数是显式的,既然有"显式"那么必然就有"隐式",那么什么是显示而什么又是隐式的呢?下面就让我们一起来看看这方面的知识吧
收藏 0 赞 0 分享

教你5分钟轻松搞定内存字节对齐

随便google一下,人家就可以跟你解释的,一大堆的道理,我们没怎么多时间,讨论为何要对齐.直入主题,怎么判断内存对齐规则,sizeof的结果怎么来的,请牢记以下3条原则
收藏 0 赞 0 分享
查看更多