Windows消息机制要点

1. 窗口过程每个窗口会有一个称为窗口过程的回调函数(WndProc),它带有四个参数,分别为:窗口句柄(Window Handle),消息ID(Message ID),和两个消息参数(wParam, lParam), 当窗口收到消息时系统就会调用此窗口过程来处理消息。(所以叫回调函数)

    2消息类型

    1)系统定义消息(System-Defined Messages)

    在SDK中事先定义好的消息,非用户定义的,其范围在[0x0000, 0x03ff]之间, 可以分为以下三类:

    1>窗口消息(Windows Message)

    与窗口的内部运作有关,如创建窗口,绘制窗口,销毁窗口等。可以是一般的窗口,也可以是Dialog,控件等。

    如:WM_CREATE, WM_PAINT, WM_MOUSEMOVE, WM_CTLCOLOR, WM_HSCROLL...

    2>命令消息(Command Message)

    与处理用户请求有关, 如单击菜单项或工具栏或控件时, 就会产生命令消息。

    WM_COMMAND, LOWORD(wParam)表示菜单项,工具栏按钮或控件的ID。如果是控件, HIWORD(wParam)表示控件消息类型

    3>控件通知(Notify Message)

    控件通知消息, 这是最灵活的消息格式, 其Message, wParam, lParam分别为:WM_NOTIFY, 控件ID,指向NMHDR的指针。NMHDR包含控件通知的内容, 可以任意扩展。

    2)程序定义消息(Application-Defined Messages)

    用户自定义的消息, 对于其范围有如下规定:WM_USER: 0x0400-0x7FFF    (ex. WM_USER+10) WM_APP(winver>4.0): 0x8000-0xBFFF (ex.WM_APP+4)

    RegisterWindowMessage: 0xC000-0xFFFF

    3消息队列(Message Queues)

    Windows中有两种类型的消息队列

    1)系统消息队列(System Message Queue)

    这是一个系统唯一的Queue,设备驱动(mouse, keyboard)会把操作输入转化成消息存在系统队列中,然后系统会把此消息放到目标窗口所在的线程的消息队列(thread-specific message queue)中等待处理

    2)线程消息队列(Thread-specific Message Queue)

    每一个GUI线程都会维护这样一个线程消息队列。(这个队列只有在线程调用GDI函数时才会创建,默认不创建)。然后线程消息队列中的消息会被送到相应的窗口过程(WndProc)处理.注意: 线程消息队列中WM_PAINT,WM_TIMER只有在Queue中没有其他消息的时候才会被处理,WM_PAINT消息还会被合并以提高效率。其他所有消息以先进先出(FIFO)的方式被处理。

    4队列消息(Queued Messages)和非队列消息(Non-Queued Messages)

    1)队列消息(Queued Messages)

    消息会先保存在消息队列中,消息循环会从此队列中取消息并分发到各窗口处理如鼠标,键盘消息。

    2)非队列消息(NonQueued Messages)

    消息会绕过系统消息队列和线程消息队列直接发送到窗口过程被处理

    如: WM_ACTIVATE, WM_SETFOCUS, WM_SETCURSOR, WM_WINDOWPOSCHANGED注意: postMessage发送的消息是队列消息,它会把消息Post到消息队列中; SendMessage发送的消息是非队列消息, 被直接送到窗口过程处理

    5 PostMessage(PostThreadMessage), SendMessage PostMessage:把消息放到指定窗口所在的线程消息队列中后立即返回。 PostThreadMessage:把消息放

到指定线程的消息队列中后立即返回。

 

    SendMessage:直接把消息送到窗口过程处理, 处理完了才返回。

    6 GetMessage, PeekMessage

    PeekMessage会立即返回可以保留消息

    GetMessage在有消息时返回会删除消息

    7 TranslateMessage, TranslateAccelerator TranslateMessage: 把一个virtual-key消息转化成字符消息(character message),并放到当前线程的消息队列中,消息循环下一次取出处理。

    TranslateAccelerator: 将快捷键对应到相应的菜单命令。它会把WM_KEYDOWN 或 WM_SYSKEYDOWN转化成快捷键表中相应的WM_COMMAND 或WM_SYSCOMMAND消息, 然后把转化后的 WM_COMMAND或WM_SYSCOMMAND直接发送到窗口过程处理, 处理完后才会返回。

    8(消息死锁( Message Deadlocks)

    假设有线程A和B, 现在有以下下步骤1) 线程A SendMessage给线程B, A等待消息在线程B中处理后返回2) 线程B收到了线程A发来的消息,并进行处理, 在处理过程中,B也向线程A SendMessgae,然后等待从A返回。

    因为此时, 线程A正等待从线程B返回, 无法处理B发来的消息, 从而导致了线程A,B相互等待, 形成死锁。多个线程也可以形成环形死锁。

    可以使用 SendNotifyMessage或SendMessageTimeout来避免出现死锁。

    9 BroadcastSystemMessage

    我们一般所接触到的消息都是发送给窗口的, 其实, 消息的接收者可以是多种多样的,它可以是应用程序(applications), 可安装驱动(installable drivers), 网络设备(network drivers), 系统级设备驱动(system-level device drivers)等,BroadcastSystemMessage这个API可以对以上系统组件发送消息。

时间: 2024-12-29 11:22:43

Windows消息机制要点的相关文章

Windows 消息机制

Windows 消息机制 Windows是一个消息驱动的操作系统.如绘制窗口的消息 WM_PAINT. 结构体定义: 消息分类-发送途径 队列消息.Windows为每个运行中的程序维护一个消息队列,由应用程序自己取出,如WM_TIMER. 非队列消息.此类消息来自特定的Windows函数,如UpdateWindow()函数直接向窗口处理函数发送WM_PAINT重绘消息. 消息分类-发送者 系统消息.是预定义的UINT常量. 用户消息.通过RegisterWindowMessage()函数申请.

windows 消息机制、窗口过程与线程间消息传递

按照自己的理解好好整理一遍 消息机制 windows是一个消息驱动的系统,会有一个总的系统消息的队列,鼠标.键盘等等都会流入到这个队列中,同时会为每个线程维护一个消息队列(注意默认是有GUI调用的线程才有,对于没有GUI或者窗口的线程,只有当在线程内调用get/peek message 才会自动创建一个消息队列),线程是容纳消息队列的基本单元,系统会把属于不同线程的消息投递到属于线程的消息队列中 当线程调用get/peek message时会从系统的消息队列中取出一个本线程内的消息.(get方法

Qt之进程间通信(Windows消息)

简述 通过上一节的了解,我们可以看出进程通信的方式很多,今天分享下如何利用Windows消息机制来进行不同进程间的通信. 简述 效果 发送消息 自定义类型与接收窗体 发送数据 接收消息 设置标题 重写nativeEvent 效果 发送消息 自定义类型与接收窗体 包含所需库,定义发送的自定义类型.接收消息的窗体标题.自定义类型可以处理消息过多情况下,对消息的区分,如果不需要也可以去掉. #ifdef Q_OS_WIN #pragma comment(lib, "user32.lib")

从SetTimer看Windows消息处理机制

本文说明两个问题:    1.windows的消息处理机制:    2.怎么往SetTimer的回调函数传递参数.    首先看第一个问题,我们都知道windows是消 息驱动的,windows呈现给用户的任何可以看到听到的东西几乎都是消息驱动的,在底层windows为每个线程准备了一个消息队列,如果用户线程注册 了某个消息,那么在适当的时候windows就会将消息投递到该线程的消息队列中,然后由该线程取出队列中的消息,然后处理之,这个过程有两个参与者,一 个是windows系统,它主要负责投递

iOS开发系列--通知与消息机制详解_IOS

概述 在多数移动应用中任何时候都只能有一个应用程序处于活跃状态,如果其他应用此刻发生了一些用户感兴趣的那么通过通知机制就可以告诉用户此时发生的事情.iOS中通知机制又叫消息机制,其包括两类:一类是本地通知:另一类是推送通知,也叫远程通知.两种通知在iOS中的表现一致,可以通过横幅或者弹出提醒两种形式告诉用户,并且点击通知可以会打开应用程序,但是实现原理却完全不同.今天就和大家一块去看一下如何在iOS中实现这两种机制,并且在文章后面会补充通知中心的内容避免初学者对两种概念的混淆. 本地通知 本地通

Windows消息传递机制详解_C 语言

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

iOS开发系列--通知与消息机制

概述 在多数移动应用中任何时候都只能有一个应用程序处于活跃状态,如果其他应用此刻发生了一些用户感兴趣的那么通过通知机制就可以告诉用户此时发生的事情.iOS中通知机制又叫消息机制,其包括两类:一类是本地通知:另一类是推送通知,也叫远程通知.两种通知在iOS中的表现一致,可以通过横幅或者弹出提醒两种形式告诉用户,并且点击通知可以会打开应用程序,但是实现原理却完全不同.今天就和大家一块去看一下如何在iOS中实现这两种机制,并且在文章后面会补充通知中心的内容避免初学者对两种概念的混淆. 本地通知 推送通

如何捕获VCL没有处理的Windows消息

---- C++ Builer的VCL提供了对大多数Windows消息的处理机制,这对于一般应用程序是足够了,但VCL也不是无所不包的,对于那些VCL没有处理的Windows消息,在需要时如何进行捕获呢?C++ Builder采用了消息映像表机制,通过消息映像表将特定的Windows消息与代码中的函数联系起来,当窗口捕获到消息时就会调用这个函数,这其实和事件句柄非常相似. ---- C++ Builder消息映像表定义形式如下: BEGIN_MESSAGE_MAP MESSAGE_HANDLER

深入VCL理解BCB的消息机制1

本文所谈及的技术内容都来自于Internet的公开信息.由CKER在闲暇之际整理后,贴出来以飴网友,姑且妄称原创. 『每次在国外网站上找到精彩文章的时候,心中都会暗自叹息为什么在中文网站难以觅得这类文章呢?其实原因大家都明白.』 时至今日,学习Windows编程的兄弟们都知道消息机制的重要性.所以理解消息机制也成了不可或缺的功课. 大家都知道,Borland的C++ Builder以及Delphi的核心是VCL.作为Win32平台上的开发工具,封装Windows的消息机制当然也是必不可少的. 那