MFC:以消息为基础的事件驱动系统和消息映射机制

以消息为基础的事件驱动系统和消息映射机制

(1)消息

A.What(什么是消息)

本质是一个数据结构,用于应用程序不同部分之间进行通信和交互

typedef struct tagMSG {HWND   hwnd;        // 接收该消息的窗口句柄UINT   message;     // 消息标识符(如 WM_CREATE、WM_SIZE 等)WPARAM wParam;      // 32 位消息的特定附加信息,确切含义依赖于消息值LPARAM lParam;      // 32 位消息的特定附加信息,确切含义也依赖于消息值DWORD  time;        // 消息创建时的时间POINT  pt;          // 消息创建时鼠标/光标在屏幕坐标系中的位置
} MSG;
  • hwnd:表示将要接收这个消息的窗口的句柄,也就是说谁将接收到这个消息
  • message:消息的类型标识符,指定了消息的类型,也就是说明了该消息是用来干什么的
  • wParam和lParam:这两个成员用于携带消息的附加参数,其具体含义取决于具体的消息类型
  • time:消息创建时的时间
  • pt:消息创建时鼠标/光标在屏幕坐标系中的位置

B.Which(有哪些类型的消息)

  • 窗口消息:

    与窗口内部运作有关的消息,如创建窗口(wm_create)、绘制窗口(wm_paint)、鼠标移动(wm_mousemove)、控件颜色(wm_ctlcolor)、水平滚动(wm_hscroll)等

  • 命令消息:

    当用户从菜单选中一个命令项目、按下一个快捷键或者点击工具栏上的一个按钮时,都将发送 wm_command 命令消息

    BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd) ON_COMMEND(IDD_BUTTON01, OnButton1LButtonDown) 
    END_MESSAGE_MAP() 
    

    上述代码表明:当点击控件IDD_BUTTON01时,将调用函数OnButton1LButtonDown()

  • 控件通知消息:

    当窗口内的子控件发生一些事件(通常由用户输入触发),需要通知父窗口时发送的消息。通知消息只适用于标准的窗口控件,如按钮、列表框、组合框、编辑框,以及 Windows 公共控件如树状视图、列表视图等

    BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd) ON_NOTIFY(LVN_KEYDOWN, IDC_LIST1, OnKeyDownList1)
    END_MESSAGE_MAP() 

    当列表控件 IDC_LIST1 发送 LVN_KEYDOWN 通知消息时,OnKeyDownList1 函数就会被调用,从而可以在该函数中进行相应的处理

  • 用户定义消息:

    step01:使用#define指令定义一个消息标识符 #define WM_MYMSG WM_USER + 8
    step02:在类声明中声明消息映射 DECLARE_MESSAGE_MAP()
    step03:在类中定义消息处理函数 afx_msg LRESULT MyMsgHandler(WPARAM wParam, LPARAM lParam);
    step04:实现消息映射

    BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd) ON_MESSAGE(WM_MYMSG, OnMyMsgHandler) 
    END_MESSAGE_MAP() 
    

(2)消息队列

A.What(什么是消息队列)

本质是一个存放MSG的队列数据结构,用于存放消息的队列

B.Which(MFC中有哪些消息队列)

系统消息队列:

主要接收来自硬件设备(如鼠标、键盘等)的输入消息,然后将这些消息分配到相应应用程序的线程消息队列中

线程消息队列:

存储与该线程相关的所有消息,包括系统发送的标准 Windows 消息(如 WM_CREATE、WM_SIZE 等)、用户自定义消息以及由其他线程或进程发送给本线程的消息

例如,当用户点击鼠标时,系统会产生一个鼠标点击消息,并将其放入系统消息队列。然后,Windows 会将这个消息传递到相应应用程序的线程消息队列中。应用程序的线程在消息循环中获取到这个消息后,根据消息的类型和参数进行相应的处理,比如调用相应的窗口过程函数。

C.Why(消息队列的作用)

支持事件驱动模型:

通过消息队列,应用程序能够根据不同的消息触发相应的处理逻辑,实现对用户操作和系统事件的响应

缓冲消息:

对于短时间内大量产生的消息,消息队列起到缓冲的作用,避免消息的丢失或处理混乱。它按照先进先出的原则存储消息,保证消息处理的顺序性

跨线程通信:

不同线程之间可以通过向特定线程的消息队列发送消息来进行通信,实现线程之间的协调和数据传递

D.Who(谁管理消息队列)

在MFC中,Window操作系统统一管理着所有的消息队列,包括系统消息队列和线程消息队列。

在一个多线程的应用程序中,不同线程的消息队列由操作系统统一管理,使得每个线程能够按照其自身的逻辑和优先级来处理接收到的消息,而不会出现混乱或冲突

E.How(如何使用消息队列)

  • 向消息队列中添加消息:PostMessage()和SendMessage()

    PostMessage(),将消息放入线程的消息队列后立即返回,不等待消息被处理;
    SendMessage(),直接调用窗口的窗口过程函数来处理消息,并等待处理完成后才返回

  • 从消息队列中取消息:GetMessage()和PeekMessage()

    GetMessage(),从线程的消息队列中取出一条消息,如果消息队列中没有消息,该函数会阻塞,直到有消息可用或者收到 WM_QUIT 消息
    PeekMessage(),与 GetMessage 不同的是,如果消息队列中没有消息,它不会阻塞,而是立即返回 FALSE

    消息分发的一般步骤:循环读取消息队列中的消息,并进行

    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {TranslateMessage(&msg); //翻译消息DispatchMessage(&msg); //分发消息
    }
    

    TranslateMessage函数会检查传入的消息,如果发现是WM_KEYDOWN和WM_KEYUP消息的组合,且对应的键可以被键盘驱动器映射为 ASCII 字符,它就会将其转换为一条WM_CHAR消息

    DispatchMessage函数将消息分发给相应的窗口过程进行处理,因为MSG中包含消息所接收的窗口句柄

(3)消息的处理过程

外部设备或窗口内部事件产生消息,产生的消息进入线程的消息队列中,而WIndow应用程序的主函数会不断调用GetMessage函数从消息列表中获取消息,并进行消息翻译和消息转发实现消息的处理。
在这里插入图片描述

(4)消息映射机制

A.What(什么是消息映射机制)

用于将 Windows 消息与类成员函数进行关联和处理的高效机制

B.Why(消息映射机制的作用)

将这些 Windows 消息与特定的类成员函数关联起来。这样,当特定的消息被发送到窗口时,MFC 框架能够根据消息映射找到对应的处理函数,并调用它来执行相应的操作

通过消息映射机制,开发者无需直接处理复杂的 Windows 消息循环和分发逻辑,而是可以专注于编写具体的消息处理代码

C.How(如何进行消息映射)

一般而言,针对不同的消息类型,使用不同的宏进行消息映射

  • 窗口消息:

    与窗口内部运作有关的消息,如创建窗口(wm_create)、绘制窗口(wm_paint)、鼠标移动(wm_mousemove)、控件颜色(wm_ctlcolor)、水平滚动(wm_hscroll)等

  • 命令消息:

    当用户从菜单选中一个命令项目、按下一个快捷键或者点击工具栏上的一个按钮时,都将发送 wm_command 命令消息

    BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd) ON_COMMEND(IDD_BUTTON01, OnButton1LButtonDown) 
    END_MESSAGE_MAP() 
    

    上述代码表明:当点击控件IDD_BUTTON01时,将调用函数OnButton1LButtonDown()

  • 控件通知消息:

    当窗口内的子控件发生一些事件(通常由用户输入触发),需要通知父窗口时发送的消息。通知消息只适用于标准的窗口控件,如按钮、列表框、组合框、编辑框,以及 Windows 公共控件如树状视图、列表视图等

    BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd) ON_NOTIFY(LVN_KEYDOWN, IDC_LIST1, OnKeyDownList1)
    END_MESSAGE_MAP() 

    当列表控件 IDC_LIST1 发送 LVN_KEYDOWN 通知消息时,OnKeyDownList1 函数就会被调用,从而可以在该函数中进行相应的处理

  • 用户定义消息:

    step01:使用#define指令定义一个消息标识符 #define WM_MYMSG WM_USER + 8
    step02:在类声明中声明消息映射 DECLARE_MESSAGE_MAP()
    step03:在类中定义消息处理函数 afx_msg LRESULT MyMsgHandler(WPARAM wParam, LPARAM lParam);
    step04:实现消息映射

    BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd) ON_MESSAGE(WM_MYMSG, OnMyMsgHandler) 
    END_MESSAGE_MAP() 
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/47807.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C语言】 利用栈完成十进制转二进制(分文件编译,堆区申请空间malloc)

利用栈先进后出的特性,在函数内部,进行除二取余的操作,把每次的余数存入栈内,最后输出刚好就是逆序输出,为二进制数 学习过程中,对存储栈进行堆区的内存申请时候,并不是很熟练,一开始…

双边性:构建神经网络的新方法

正如承诺的那样,这是最近我遇到的最有趣的想法之一的第二部分。如果你错过了,请务必观看本系列的第一部分 - 神经科学家对改进神经网络的看法 - 我们讨论了双边性的生物学基础以及我们大脑的不对称性质如何带来更高的性能。 在这篇文章中,我…

v-for 进行列表的 增删改查

通过对象下标替换属性值 但是通过实践此方法是错误的&#xff0c;Vue监听的是students这个对象&#xff0c;而不是这个对象里面的数组信息&#xff0c;也就是说&#xff0c;改变里面的值&#xff0c;并不能在页面上实现更新的功能 <!DOCTYPE html> <html lang"en…

通俗地理解主动元数据管理

元数据管理&#xff0c;是企业开展数据管理的核心基础&#xff0c;内容涉及元数据的创建&#xff0c;确定需要捕获哪些元数据&#xff0c;通过哪些工具和流程进行创建&#xff0c;继而将元数据妥善存储&#xff0c;保障安全性和可访问性&#xff0c;并不断更新维护&#xff0c;…

[渗透测试] 反序列化漏洞

反序列化漏洞 ​ 序列化&#xff1a;将对象的状态信息转换为可以传输或存储的形式的过程。简单的来说&#xff0c;就是将一个抽象的对象转换成可以传输的字符串 &#xff0c;以特定的形式在进行之间实现跨平台的传输。 序列化大多以字节流、字符串、json串的形式来传输。将对…

linux/windows wps node.js插件对PPT状态监听并且通知其他应用

需求背景 公司要求对Window系统&#xff0c;和国产操作系统&#xff08;UOS&#xff09;的wps 软件在 PPT开始播放 结束播放&#xff0c;和播放中翻页 上一页 下一页 等状态进行监听&#xff0c;并通知到我们桌面应用。 技术方案 开发WPS插件&#xff0c;使用node.JS 插件开…

系统架构设计师①:计算机组成与体系结构

系统架构设计师①&#xff1a;计算机组成与体系结构 计算机结构 计算机的组成结构可以概括为以下几个主要部分&#xff1a;中央处理器&#xff08;CPU&#xff09;、存储器&#xff08;包括主存和外存&#xff09;、输入设备、输出设备&#xff0c;以及控制器、运算器、总线和…

如何查看jvm资源占用情况

如何设置jar的内存 java -XX:MetaspaceSize256M -XX:MaxMetaspaceSize256M -XX:AlwaysPreTouch -XX:ReservedCodeCacheSize128m -XX:InitialCodeCacheSize128m -Xss512k -Xmx2g -Xms2g -XX:UseG1GC -XX:G1HeapRegionSize4M -jar your-application.jar以上配置为堆内存4G jar项…

使用puma部署ruby on rails的记录

之前写过一篇《记录一下我的Ruby On Rails的systemd服务脚本》的记录&#xff0c;现在补上一个比较政治正确的Ruby On Rails的生产环境部署记录。使用Puma部署项目。 创建文件 /usr/lib/systemd/system/puma.service [Unit] DescriptionPuma HTTP Server DocumentationRuby O…

[AWS]MSK调用,报错Access denied

背景&#xff1a;首先MSK就是配置一个AWS的托管 kafka&#xff0c;创建完成之后就交给开发进行使用&#xff0c;开发通常是从代码中&#xff0c;编写AWS的access_key 和secret_key进行调用。 但是开发在进行调用的时候&#xff0c;一直报错连接失败&#xff0c;其实问题很简单&…

Electron 企业级开发通信与本地存储实用解决方案

背景 之前写了一篇Electron通信的方式&#xff0c;讲述了一下三者之间的通信机制&#xff0c;比较恶心&#xff0c;后来发现有个electron/remote&#xff0c; Electron 渲染进程直接调用主进程的API库electron/remote引用讲解-CSDN博客文章浏览阅读58次。remote是个老库&…

蓝队黑名单IP解封提取脚本

应用场景&#xff1a;公司给蓝队人员一个解封IP列表&#xff0c;假如某个IP满足属于某某C段&#xff0c;则对该IP进行解封。该脚本则是进行批量筛选出符合条件的白名单IP 实操如下&#xff1a;公司给了一个已经封禁了的黑名单IP列表如下&#xff08;black&#xff09; 公司要求…

高清视频,无损音频,LDR6023——打造极致视听与高效充电的双重享受!

Type-C PD&#xff08;Power Delivery&#xff09;芯片是一种支持USB Type-C接口规范的电源管理单元&#xff0c;其主要功能包括&#xff1a; 快速充电&#xff1a;Type-C PD芯片支持高功率传输&#xff0c;能够提供更快的充电速度&#xff0c;使电子设备在短时间内充满电&…

微信小程序:多图片显示及图片点击放大,多视频显示

微信小程序&#xff1a;多图片显示及图片点击放大&#xff0c;多视频显示 01 多图片显示及图片点击放大02 多视频03 全部代码 01 多图片显示及图片点击放大 <view><view class"title">图片&#xff1a;</view><block wx:if"{{photoUrlList…

源码搭建国内微短剧系统(APP+小程序)云存储配置流程

国内微短剧系统很多人不知道云存储和配置的操作流程&#xff0c;我整理了一份非常详细的操作文档流程&#xff0c;给大家介绍短剧系统云存储配置的详细操作流程。顺便推荐一下国内微短剧系统。 推荐下他们的开源地址&#xff1a;https://gitee.com/nymaite_com_2878868888/tjg…

CrowdStrike更新致850万Windows设备宕机,微软紧急救火!

7月18日&#xff0c;网络安全公司CrowdStrike发布了一次软件更新&#xff0c;导致全球大范围Windows系统宕机。 预估CrowdStrike的更新影响了将近850万台Windows设备&#xff0c;多行业服务因此停滞&#xff0c;全球打工人原地放假&#xff0c;坐等吃瓜&#xff0c;网络上爆梗…

适用于 Mac 或 MacBook 的最佳数据恢复软件

Apple 设计的电脑可靠且用户友好&#xff0c;但即使是最好的最新款 MacBook硬件也会出现故障。当您的存储出现问题时&#xff0c;数据恢复软件可以帮助您恢复丢失和损坏的文件。 数据丢失的另一个原因是有时会发生令人尴尬的错误。如果您不小心丢弃了所需的文件&#xff0c;然…

【RaspberryPi】树莓派Matlab/Simulink支持包安装与使用

官网支持与兼容性 Raspberry Pi Support from MATLAB - Hardware Support - MATLAB & Simulink Raspberry Pi Support from Simulink - Hardware Support - MATLAB & Simulink Matlab与树莓派兼容性 Simulink与树莓派兼容性 树莓派Matlab&Simulink RaspberryPi支…

本地部署 mistralai/Mistral-Nemo-Instruct-2407

本地部署 mistralai/Mistral-Nemo-Instruct-2407 1. 创建虚拟环境2. 安装 fschat3. 安装 transformers4. 安装 flash-attn5. 安装 pytorch6. 启动 controller7. 启动 mistralai/Mistral-Nemo-Instruct-24078. 启动 api9. 访问 mistralai/Mistral-Nemo-Instruct-2407 1. 创建虚拟…

240722视频识别红色物体

文章目录 1.实验目的2.实验思路3.实验代码4.实验结果展示1.实验目的 针对需求,拍摄视频并实时识别其中红色物体。 2.实验思路 针对HSV模型可以很好的区分色彩这一特性,所以我们可以很好的找到我们需要的ROI 3.实验代码 # @File: 13.2拍视频识别其中的红色物体.py # @Au…