MFC框架机制详解

本文详细探讨了MFC框架下的Windows消息机制,包括窗口过程、消息类型、MessageMAP的形成、消息处理流程,以及系统和线程消息队列的工作原理。通过讲解消息的发送、接收和处理,阐述了消息死锁问题及其解决方案,同时概述了MFC的执行期类型识别和动态创建,以及Win32运行机制。
摘要由CSDN通过智能技术生成

MFC框架机制详解

1.1 Windows消息机制要点

1.1.1 窗口过程

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

1.1.2 消息类型
  • 1. 系统定义消息(System-Defined Messages)

    在SDK中事先定义好的消息,非用户定义的,其范围在[0x0000, 0x03ff]之间 (1024),

    可以分为以下三类:

    1. 窗口消息(Windows Message)

      与窗口的内部运作有关,如创建窗口,绘制窗口,销毁窗口等。可以是一般的窗口,也可以是Dialog,控件等。所有派生自CWnd 的类才有资格接收标准消息。

      第一个消息是:WM_NULL = $0000;

      最后一个消息是:WM_DDE_LAST = WM_DDE_FIRST ( 03E0)+8= 03E8=1000;

      中间有几个地方并不连续;

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

    2. 命令消息(Command Message)

      与处理用户请求有关, 如单击菜单项或工具栏或控件时, 就会产生命令消息。WM_COMMAND=$0111, LOWORD(wParam)表示菜单项,工具栏按钮或控件的ID。如果是控件, HIWORD(wParam)表示控件消息类型。

      所有派生自CCmdTarget 的类都有能力接收WM_COMMAND消息。

    3. 控件通知(Notify Message)

      控件通知消息, 这是最灵活的消息格式, 其Message, wParam, lParam分别为:WM_NOTIFY= $004E, 控件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直

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值