一、从Windows消息机制说起

摘要:
例如,当用户单击鼠标或键时,Windows系统将发送相应的消息。
 
 

一,消息

      消息(Message)指的就是Windows 操作系统发给应用程序的一个通知,它告诉应用程序某个特定的事件发生了。比如,用户单击鼠标或按键都会引发Windows 系统发送相应的消息。最终处理消息的是应用程序的窗口函数,如果程序没处理的话操作系统有默认函数将会作出处理。
     从数据结构的角度来说,消息是一个结构体,它包含了消息的类型标识符以及其他的一些附加信息。系统定义的结构体MSG用于表示消息,MSG 具有如下定义形式:
typedef struct MSG
{
     HWND hwnd;                    //hwnd 是窗口的句柄,这个参数将决定由哪个窗口过程函数对消息进行处理 
     UINT message;                  //message是一个消息常量,用来表示消息的类型 
     WPARAM wParam;            //32 位的附加信息,具体表示什么内容,要视消息的类型而定 
     LPARAM lParam;               //32 位的附加信息,具体表示什么内容,要视消息的类型而定 
     DWORD time;                   //time 是消息发送的时间 
     POINT pt;                         //消息发送时鼠标所在的位置 
}
 
二,Windows编程原理
     Windows 是一消息(Message)驱动式系统,Windows 消息提供了应用程序与应用程序之间、应用程序与Windows 系统之间进行通讯的手段。应用程序要实现的功能由消息来触发,并靠对消息的响应和处理来完成。Windows 系统中有两种消息队列,一种是系统消息队列,另一种是应用程序消息队列。计算机的所有输入设备由 Windows 监控,当一个事件发生时,Windows 先将输入的消息放入系统消息队列中,然后再将输入的消息拷贝到相应的应用程序队列中,应用程序中的消息循环从它的消息队列中检索每一个消息并发送给相应的窗口函数中。
       一、从Windows消息机制说起第1张
     箭头1 说明操作系统能够操纵输入输出设备,例如让打印机打印;
     箭头2 说明操作系统能够感知输入输出设备的状态变化,如鼠标单击,按键按下等,这就是操作系统和计算机硬件之间的交互关系
     箭头3 是应用程序通知操作系统执行某个具体的操作,这是通过调用操作系统的API 来实现的;
     箭头4 操作系统能够感知硬件的状态变化,但是并不决定如何处理,而是把这种变化封装成消息转交给应用程序,由应用程序决定如何处理,箭头4说明了这种转交情况。
 
三,Windows消息循环
     消息循环是Windows 应用程序存在的根本,应用程序通过消息循环获取各种消息,并通过相应的窗口过程函数,对消息加以处理;正是这个消息循环使得一个应用程序能够响应外部的各种事件。
     一、从Windows消息机制说起第2张
     Windows 操作系统为每个线程维持一个消息队列,当事件产生时,操作系统感知这一事件的发生,并包装成消息发送到消息队列,应用程序通过GetMessage()函数取得消息并存于一个消息结构体中,然后通过一个TranslateMessage()和DispatchMessage()解释和分发消息,下面的代码描述了Windows 的消息循环。

while(GetMessage (&msg, NULL, 0, 0))
{
     TranslateMessage (&msg) ;
     DispatchMessage (&msg) ;
}
TranslateMessage(&msg)对于大多数消息而言不起作用,但是有些消息,比如键盘按键按下和弹起(分别对于KeyDown 和KeyUp 消息),却需要通过它解释,产生一个WM_CHAR消息。DispatchMessage(&msg)负责把消息分发到消息结构体中对应的窗口,交由窗口过程函数处理。GetMessage()在取得WM_QUIT 之前的返回值都为TRUE,也就是说只有获取到WM_QUIT 消息才返回FALSE,才能跳出消息循环。

     对一个Windows窗体程序而言,在Program.cs文件中的Main函数中,有如下的代码:
     Application.Run(new Form1());
     这行代码的意思就是在当前线程上开始运行标准应用程序消息循环,并使指定窗体可见。实际上就是启动了一个GetMessage的无限循环。而这个响应Windows消息的线程就被称做Windows窗体程序的UI线程
 
四,主要函数的区别
SendMessage()与PostMessage()是用于向应用程序发送消息的。SendMessage()将消息直接加入到应用程序的消息队列中,在应用程序处理完此消息后,它才返回。PostMessagex()将消息直接加入到应用程序的消息队列中,不等程序返回就退出。
PeekMessage和GetMessage用来从消息队列中取出数据,GetMessage从消息队列里取得一个消息并将其放于指定的结构,获取消息成功后,线程将从消息队列中删除该消息。GetMessage函数会一直等待直到有消息到来才有返回值。PeekMessage函数检查消息队列,并将该消息(如果存在)放于指定的结构,然后返回,不会等待。

免责声明:文章转载自《一、从Windows消息机制说起》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Visual Studio 2013发布Cloud Service至Azure ChinaUnity3D Shader入门指南(一)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

JavaScript初学指南

目录: 包含与引入(Embedding,including) write 和 writeln 文档对象(document object) bgColor 和 fgColor 消息框(Message Box) 变量(Variables)和条件(Conditions) 函数(Function) onClick onLoad onUnload 表单(Form)...

WebSphere MQ几个特性的应用

IBM WebSphere MQ消息中间件有很多的特性和优点,使用IBM WebSphere MQ可以简化和优化消息通讯的应用设计。为了满足用户各种不同的应用的通讯需求,IBM WebSphere MQ采用了大量业界领先的技术,并拥有许多先进的功能,其中很多是其他厂商所无能为力的。将这些技术和功能应用到客户的通讯系统之中,可以简化应用逻辑,优化系统架构,从...

Java虚拟机:十八、Java对象大小、对象内存布局及锁状态变化

一个对象占多少字节? 关于对象的大小,对于C/C++来说,都是有sizeof函数可以直接获取的,但是Java似乎没有这样的方法。不过还好,在JDK1.5之后引入了Instrumentation类,这个类提供了计算对象内存占用量的方法。至于具体Instrumentation类怎么用就不说了,可以参看这篇文章如何精确地测量java对象的大小。 不过有一点不同的...

QT5 Thread线程

QT5 Thread线程继承QThread方式 一.首先分析一下 QTimer Class与 Sleep()函数之间的秘密 QTimer *t = new QTimer(*parent); //创建QTimer 对象 t->start(_time); //计时开始每隔_time时间自动触发&QTimer::timeout信号 t->st...

Linux基础(15)多线程编程

Linux的内核中没有thread的概念,线程是第三方库libpthread实现的, 和vfork(轻量级进程,只有部分copy)有点像(进程的创建fork会完全copy主进程资源 ,而线程会共享资源,子线程创建新资源时其作用域只在当前子线程,而子线程非新新创建的资源会和创建前的主线程共享这些资源) , 线程和进程的创建在内核里都是系统调用copy_proc...

Java多线程2

线程的生命周期 与人有生老病死一样,线程也同样要经历开始(等待)、运行、挂起和停止四种不同的状态。这四种状态都可以通过Thread类中的方法进行控制。下面给出了Thread类中和这四种状态相关的方法。 1 // 开始线程 2 public void start( ); 3 public void run( ); 4 5 // 挂...