基础篇-Windows消息机制
1在介绍Windows 消息运行机制之前,首先介绍一下消息的概念:
消息(Message)指的就是Windows 操作系统发给应用程序的一个通告[5],它告诉应用程序某个特定的事件发生了。比如,用户单击鼠标或按键都会引发Windows 系统发送相应的消息。最终处理消息的是应用程序的窗口函数,如果程序不负责处理的话系统将会作出默认处理。从数据结构的角度来说,消息是一个结构体,它包含了消息的类型标识符以及其他的一些附加信息。
2 Windows 编程原理
Windows 是一消息(Message)驱动式系统,Windows 消息提供了应用程序与应用程序之间、应用程序与Windows 系统之间进行通讯的手段。应用程序要实现的功能由消息来触
发,并靠对消息的响应和处理来完成。Windows 系统中有两种消息队列,一种是系统消息队列,另一种是应用程序消息队列。计算机的所有输入设备由 Windows 监控,当一个事件发生时,Windows 先将输入的消息放入系统消息队列中,然后再将输入的消息拷贝到相应的应用程序队列中,应用程序中的消息循环从它的消息队列中检索每一个消息并发送给相应的窗口函数中。一个事件的发生,到达处理它的窗口函数必须经历上述过程。所谓消息就是描述事件发生的信息,Windows 程序是事件驱动的,用这一方法编写程序避免了死板的操作模式,因为Windows 程序的执行顺序将取决于事件的发生顺序,具有不
可预知性。Windows 操作系统,计算机硬件,应用程序之间具有如图1 所示的关系

箭头1 说明操作系统能够操纵输入输出设备,例如让打印机打印;箭头2 说明操作系统能够感知输入输出设备的状态变化,如鼠标单击,按键按下等,这就是操作系统和计算机硬件之间的交互关系,应用程序开发者并不需要知道他们之间是如何做到的,我们需要了解的操作系统与应用程序之间如何交互。箭头3 是应用程序通知操作系统执行某个具体的操作,这是通过调用操作系统的API 来实现的;操作系统能够感知硬件的状态变化,但是并不决定如何处理,而是把这种变化转交给应用程序,由应用程序决定如何处理,向上的箭头4说明了这种转交情况,操作系统通过把每个事件都包装成一个称为消息结构体MSG 来实现这个过程,也就是消息响应,要理解消息响应,首先需要了解消息的概念和表示。
3 Windows 消息循环
消息循环[1]是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,才能跳出消息循环。
4 消息的处理
取得的消息将交由窗口处理函数进行处理,对于每个窗口类Windows 为我们预备了一个默认的窗口过程处理函数DefWindowProc(),这样做的好处是,我们可以着眼于我们感兴趣的消息,把其他不感兴趣的消息传递给默认窗口过程函数进行处理。每一个窗口类都有一个窗口过程函数,此函数是一个回调函数,它是由Windows 操作系统负责调用的,而应用程序本身不能调用它。以switch 语句开始,对于每条感兴趣的消息都以一个case 引出。
LRESULT CALLBACK WndProc
(
HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam
)
{
…
switch(uMsgId)
{
case WM_TIMER://对WM_TIMER 定时器消息的处理过程
return 0;
case WM_LBUTTONDOWN://对鼠标左键单击消息的处理过程
reurn 0;
. …
default:
return DefWindowProc(hwnd,uMsgId,wParam,lParam);
}
}
对于每条已经处理过的消息都必须返回0,否则消息将不停的重试下去;对于不感兴趣的消息,交给DefWindowProc()函数进行处理,并需要返回其处理值。
基础篇-Windows消息机制的更多相关文章
- Windows消息机制
Windows的消息系统是由3个部分组成的: · 消息队列.Windows能够为所有的应用程序维护一个消息队列.应用程序必须从消息队列中获取消息,然后分派给某个窗口.· 消息循环.通过这个循环机制应用 ...
- <Win32_1>深入浅出windows消息机制[转自crocodile_]
上学期学习了Java ,感觉Java写一个窗口真心简单,很易上手,也就难怪很多开发人员选择Java作为自己的开发编程语言.但是由于自身对windows的热爱,让我觉得c.c++语言才是我亲睐的编程语言 ...
- 收藏:Windows消息机制
百度百科介绍的windows消息机制也不错:http://baike.baidu.com/view/672379.htm Windows的应用程序一般包含窗口(Window),它主要为用户提供一种可视 ...
- 转:Windows消息机制要点
Windows消息机制要点 1. 窗口过程 每个窗口会有一个称为窗口过程的回调函数(WndProc),它带有四个参数,分别为:窗口句柄(Window Handle),消息ID(Message ...
- windows消息机制(转)
1. 引言Windows 在操作系统平台占有绝对统治地位,基于Windows 的编程和开发越来越广泛.Dos 是过程驱动的,而Windows 是事件驱动的[6],这种差别的存在使得很多Dos 程序员不 ...
- 我对windows消息机制的理解(参考深入浅出MFC,欢迎批评指正!!)
以消息为基础,以事件驱动之 程序的进行依靠外部消息来驱动,即:程序不断等待任何可能的输入,然后做判断,然后再做适当的处理. 消息输入:操作系统捕获,以消息形式进入程序.(操作系统通过其USERS模块中 ...
- 深入Delphi -- Windows 消息机制
http://www.txsz.net/xs/delphi/3/Windows%20%E6%B6%88%E6%81%AF%E6%9C%BA%E5%88%B6.htm Windows 消息机制 by m ...
- 深入理解windows 消息机制
深入理解Windows消息机制 今天我们来学一学Windows消息机制,我们知道在传统的C语音程序中,当我们需要打开一个文件时,我们可以调用fopen()函数,这个函数最后又会调用操作系统提供的函数以 ...
- windows消息机制框架原理【简单版本】
windows消息机制框架原理 结合两张图理解 窗口和窗口类 Windows UI 应用程序 (e) 具有一个主线程 (g).一个或多个窗口 (a) 和一个或多个子线程 (k) [工作线程或 UI 线 ...
随机推荐
- [Effective JavaScript 笔记]第65条:不要在计算时阻塞事件队列
第61条解释了异步API怎样帮助我们防止一段程序阻塞应用程序的事件队列.使用下面代码,可以很容易使一个应用程序陷入泥潭. while(true){} 而且它并不需要一个无限循环来写一个缓慢的程序.代码 ...
- IBM DB2 For Linux安装指南(转)
一.安装前准备工作: 1.对于Linux系统,需要安装以下软件包: 2.Linux内核设置: 编辑/etc/sysctl.conf文件,加入如下内容: 3.创建相应用户以及组: 官方文档给出必须创建三 ...
- android项目的结构和布局
一.res文件夹 1.res文件夹用于存放Android的资源.包括:动画.静态图片.字符串.菜单.布局.视频.文件等. 1.drawable-ldpi:低分辨率图形(120像素/英寸) 2.draw ...
- BooleanToVisibilityConverter.cs
//---------------------------------------------------------------------------- // // Copyright (C) M ...
- 使用IOS7原生API进行二维码条形码的扫描
使用IOS7原生API进行二维码条形码的扫描 IOS7之前,开发者进行扫码编程时,一般会借助第三方库.常用的是ZBarSDK,IOS7之后,系统的AVMetadataObject类中,为我们提供了解析 ...
- 内核编译选配(VMware篇)
出现这个错误的原因是相应的驱动程序没有编译进内核,所以在内核启动时,不认识分区. 一.磁盘驱动没编译进内核 VMware5.5.3 的磁盘有两种,一种是IDE的,一种是SCSI的:VMware 你在新 ...
- C++string中有关大小和容量的函数浅析
1.length()与size() length是因为沿用C语言的习惯而保留下来的,string类最初只有length,引入STL之后,为了兼容又加入了size,它是作为STL容器的属性存在的,便于符 ...
- RPM安装rabbitMQ
系统使用的是centos 7 - minimal 建立用户和组: # groupadd rabbitmq # useradd rabbitmq -g rabbitmq 在安装rabbitMQ之前需要先 ...
- iOS - Xcode 常用快捷键
Xcode 常用快捷键 1)文件: command + shift + n 新建项目 command + n 新建文件 command + control + n 新建空文件 command + o ...
- 学习mongo系列(三) update() save()
一.update()方法 >db.user.update({"name":"user1"},{$set:{"title":" ...