微软MFC技术运行机制

news2024/11/28 14:11:19

我是荔园微风,作为一名在IT界整整25年的老兵,今天总结一下微软MFC技术运行机制。

很多初学者误以为VC++开发必须使用MFC,其实不一定的。MFC的使用只能是提高程序在某些情况下的开发效率,而不能替代整个Win32程序设计。我认为我们有必须再来好好讲讲MFC的本质、MFC中的消息是以何种形式存在、懂得MFC中消息的存储方式消息队列、明白MFC程序运行的原理消息响应、MFC运行流程。

我在上一篇关于MFC的文章中说过,MFC是微软公司提供的类库,它以C++的形式封装了Windows的接口函数API。类库中包含大量的Windows句柄类、Windows控件类、Windows组件类。

直接使用Windows的API函数来开发产品,对于程序员来说很困难。因为API函数的数量十分多,而且名称上有时很难看出来是什么意思。如果用win32开发一个窗口至少也得100多行的代码,而一个软件系统做出来后,那代码量更是大的惊人。本质上来说,MFC就是win32开发与Application framework的组合。这个组合为程序员创建了程序的一般框架模型,减少了应用程序开发程序员的工作量。

为了方便大家理解MFC,现在我们做一个比喻。我们把MFC程序比喻为空调。

首先,威利斯·开利发明了世界上第一台空调,是下图这个样子的,于是空调的整个设计思想和原理被固定下来,形成了第一代空调,相当于我们这里的Win32的Application framework。

而最新的空调就是在第一代空调的基础上不断迭代发展而来。现代空调是在第一代空调的基础上不断完善而来,增加入不少新的技术,这种增加的新技术类似于我们这里的各类Windows的接口函数API,然后对第一代空调的设计思想原理结合后来的新技术进行了一次次的融合,而且更加模块化组件化,形成了现代空调产品,也就是我们这里的MFC。如下图这些工业用空调。

MFC的实质就是对Win32程序的封装,第一台空调与后来各种技术的结合 就是现代空调发展的一个模板,Win32的Application framework与函数API的结合 就是MFC框架。

你如果想在现代空调上加入新技术,就必须了解空调的原理。对于程序员来说,也必须了解MFC架构。MFC程序的结构一般是由一个CWinApp类对象和几个从MFC派生的类组成。

我们以一个基于单文档的MFC工程为例进行讲解,工程名为KongTiao。我们一建立KongTiao就会有如下图几个类,其中常用的是CMainFrame、CKongTiaoApp、CKongTiaoDoc、CKongTiaoView这4个类。

1.应用程序类CKongTiaoApp
先在KongTiao.h通过下面代码定议CKongTiaoApp类

class CKongTiaoApp : public CWinApp //派生类:public 基类
{
 public:
       CKongTiaoApp(); //构造函数,用于初始化
 public:
       virtual BOOL InitInstance(); //实例化虚函数
       afx_msg void OnAppAbout(); //函数声明
       DECLARE MESSAGE_MAP()

从第01行可看出它是从CWinApp类派生,它有且只有一个应用程序对象,负责应用程序的初始化、运行和结束。

2.文档类CKongTiaoDoc
先在KongTiaoDoc.h通过下面代码定义CKongTiaoDoc类

class CKongTiaoDoc : public CDocument  //派生类:public基类
  {  
  protected:        //以下为保护成员函数
      CKongTiaoDoc();    //构造函数,用于初始化
      DECLARE DYNCREATE(CMessageDoc)
  ...
  public:
  virtual ~CKongTiaoDoc();    //析构函数
  ...
  };

从它的第01行可看出它是从CDocument类派生,用来管理数据,实现数据的变化、存取。

3.视图类CMessageView
同时文档类还可以和视图类合作,访问和更新数据。先在KongTiaoView.h通过下面代码定义4-3是CKongTiaoView视图类的定义。

class CKongTiaoview : public CView    //派生类:public基类
{
  protected:      //以下为保护成员函数
      CKongTiaoView();  //构造函数,用于初始化
      DECLARE DYNCREATE(CKongTiaoview)
  ...
  public:
      virtual void OnDraw(CDC* pDC);  //画视图
      virtual BOOL PreCreateWindow(CREATESTRUCT& cs);  //创建窗口
  ...
  public:
      virtual ~CKongTiaoView();  //析构函数
  ...
  protected:
      DECLARE MESSAGE MAP()
  public:
      afx msg void OnMouseMove(UINT nFlags, CPoint point);  //鼠标移动的消息函数
};

从第01行可看出它是从CView类派生。视图和文档联系在一起,在文档和用户之间起中介作用,即:在屏幕上显示文档的内容,并把用户输入转换成对文档的操作。

4.主框架窗口类CMainFrame

代码MainFrm.h是CMainFrame框类的定义。
 

class CMainFrame : public CFrameWnd      //派生类:public基类
{
  protected:    //以下为保护成员函数
      CMainFrame();    //构造函数,用于初始化
      DECLARE DYNCREATE(CMainFrame)
  ...
  public:
      virtual BOOL PreCreateWindow(CREATESTRUCT& cs);   //创建窗口
  public:
      virtual ~CMainFrame();    //析构函数
  ...
  protected:
      CStatusBar m_wndStatusBar;     //声明一个状态栏对象
       CToolBar m_wndToolBar;     //声明一个工具栏对象
  protected:
      afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);    //用于创建窗口各种属性
      DECLARE_MESSAGE MAP()
  };

从第01行可看出它是从CFrameWnd类派生,负责创建和控制菜单、工具栏、状态栏等界面元素。

5.MFC类的底部派生关系

前面大家已经看到很多类的派生关系,这4个默认生成的类都是从CWinApp、CDocument 等类派生而来,这就需要大家了解MFC类的底部派生关系,如图所示。


第 1行的 CObject 类是大多数 MFC 类的根类或基类。 CObject派生出CCmdTarget。类 CCmdTarget 是MFC类库中消息映射体系的一个基类,是MFC处理命令消息的基础核心。而CCmdTarget类又派生出了如图中所示4种不同的类,即CWinThread、CDocTemplate、 CDocument、CWnd。

 

作者简介:荔园微风,1981年生,高级工程师,浙大工学硕士,软件工程项目主管,做过程序员、软件设计师、系统架构师,早期的Windows程序员,Visual Studio忠实用户,C/C++使用者,是一位在计算机界学习、拼搏、奋斗了25年的老将,经历了UNIX时代、桌面WIN32时代、Web应用时代、云计算时代、手机安卓时代、大数据时代、ICT时代、AI深度学习时代、智能机器时代,我不知道未来还会有什么时代,只记得这一路走来,充满着艰辛与收获,愿同大家一起走下去,充满希望的走下去。

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

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

相关文章

python grpc使用示例

1. grpc简介 1.1 概述 gRPC是搭建分布式应用接口和客户端的框架。在 gRPC 中,客户端应用程序可以直接调用不同机器上的服务器应用程序上的方法,就像它是本地对象一样,可以更容易创建分布式应用程序和服务。与许多 RPC 系统一样,gR…

AI绘画MidJourney 酷炫艺术风格效果,总有一款你喜欢

文 / 高扬 今天六一儿童节,祝各位大朋友节日快乐。 这次以儿童为主题,看看MidJourney的绘画风格,在这里,我使用的默认V5.1版本。 图画场景是一个男孩和一个女孩在田野玩耍,对应的英文是:A boy and a girl a…

使用PyQT实现模拟表盘时钟的显示效果

代码 class clockThread(QThread):update_ui_signal pyqtSignal(str)def __init__(self, window):super(clockThread, self).__init__()# 信号绑定槽函数self.update_ui_signal.connect(self.draw_time)self.hour 0self.minute 0self.second 0self.window windowself.win…

数据结构与算法·第6章【树】

基本操作 树的相关定义 树的深度(高度):树中叶子结点所在的最大层次 森林: m m m棵互不相交的树的集合 二叉树 二叉树或为空树,或是由一个根结点加上两棵分别称为左子树和右子树的、互不交的二叉树组成。 性质 二…

JavaCV音视频开发宝典:使用JavaCV读取海康平台或海康网络摄像头sdk回调视频TS码流并解析预览图像

《JavaCV音视频开发宝典》专栏目录导航 《JavaCV音视频开发宝典》专栏介绍和目录 ​ 前言 两年前博主写了如何利用JavaCV解析各种h264裸流,《JavaCV音视频开发宝典:使用javacv读取GB28181、海康大华平台和网络摄像头sdk回调视频码流并解析预览图像》,但是随着时间变化,各…

企业邮箱如何设置邮件审核

有的时候对外给客户或合作伙伴等发送邮件需要领导审核后再发,以前都是先发给领导,领导审核以后再重新发给客户, 这样的流程太过繁琐。 新的邮件审核功能既能满足审核需求,又避免了重复发信,可以极大提高工作效率。 设…

使用VitePress静态网站生成器创建组件库文档网站并部署到GitHub

Vue3TSVite开发组件库并发布到npm 网站在线预览: Vue Amazing UI | Amazing UI Components LibraryAmazing UI 组件库https://themusecatcher.github.io/vue-amazing-ui/参考文档: VitePress 目录 一、安装依赖及配置 1、安装 vitepress 2、在 p…

想要精通算法和SQL的成长之路 - 反转链表

想要精通算法和SQL的成长之路 - 反转链表 前言一. 反转链表 前言 想要精通算法和SQL的成长之路 - 系列导航 一. 反转链表 原题链接 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 思路如下: 我们可以通过一次遍历&#xff…

该怎么用设计测试用例测网上银行转账?

目录 前言 1、网上银行转账是怎么测的,设计一下测试用例。 回答思路: 2、测试工作的流程?缺陷状态有什么?设计测试用例有几种方法? 修改完以后,有两种处理情况: 3、在项目中找到的经典BUG是什么? 4、定期…

kali系统渗透

用kali远程ssh时,如果不能的话 按照以下方法 ┌──(root㉿kali)-[~]└─# mkdir ~/.ssh┌──(root㉿kali)-[~]└─# vim ~/.ssh/configHost *HostkeyAlgorithms ssh-rsaPubkeyAcceptedKeyTypes ssh-rsa msfconlole -q //进入马上发不显示内容,所以加…

编程实现人脸识别

1.更改url 用翔云平台下的人脸识别的API文档 把他贴到url中: 2.定义参数 (根据平台给定的这些串口接收参数来定义) key和secret在这里找: 3.指定post内容 把这部分定义成一个postString 4.字符串的拼接 sprintf函数调用的主…

使用粒子群优化算法(PSO)辨识锂电池二阶RC模型参数(附MATLAB代码)

目录 一、原理部分 二、代码详解部分 三、结果及分析 一、原理部分 PSO算法由美国学者于 1995 年提出,因其算法简单、效果良好,而在很多领域得到了广泛应用。该算法的起源是模拟鸟群的觅食过程,形成一种群体智能搜索算法。 其核心是&#…

使用Flask高效构建Web应用

1、聊聊Flask框架 Flask官方文档 Flask是Armin ronacher基于Python开发的微型Web框架,诞生于2010年,它依赖于jinja2模板和Werkzeug WSGI服务。Flask的核心简单易于扩展,它不会替你做出太多决策比如使用何种数据库或模板引擎,这些都…

抖音seo矩阵系统源码解析

抖音SEO矩阵系统源码是一种用于优化抖音视频内容的工具,可以帮助用户提高抖音视频的搜索排名和流量,从而增加视频曝光和转化率。该系统包括两部分,即数据收集和分析模块以及SEO策略和实施模块。 数据收集和分析模块主要负责从抖音平台上收集…

认识功能安全

01、什么是功能安全 1-背景简介 由于汽车的复杂性,整个行业正在致力于提供符合安全要求的零部件系统。比如,线控油门系统,当驾驶员踩下油门踏板,踏板上的传感器向控制器发送信号时,控制器会综合分析如发动机转速、车…

ERP系统实施,8个需要了解的关键绩效指标

实施ERP系统是一项复杂的、耗时的工作,但它也代表了企业重新思考其战略、目标和流程的绝佳机会。成功的ERP实施可以激发创新,改善企业的所有领域。例如,通过集中企业各部门不断增长的财务和业务数据,所有的决策者都在同一个页面上…

非煤矿山电子封条系统算法方案 opencv

非煤矿山电子封条系统算法部署方案是基于pythonopencv网络模型Ai视频图像识别技术,非煤矿山电子封条系统算法部署方案对出入井人员、人员变化及非煤矿山生产作业状态等状况,及时发现处理异常动态将自动发出警报。OpenCV的全称是Open Source Computer Vis…

亲身经历告诉你,0基础转行学Python,毕业就能15000

对生活现状的不满,对自己浑浑噩噩的厌恶,以及对互联网行业的憧憬,让我下定决心选择去黑马程序员开启转行之旅。 学科 | Python大数据开发 薪资 | 15000 时间总是在你回忆往事时才会觉得短暂,来黑马之前觉得六个月将是一段很漫长…

操作系统原理 —— 内存动态分区分配算法(二十一)

在上一个章节我们讲了内存连续分配的几种方式,有单一、固定、动态这三种,在固定、动态这种里面,操作系统会记录空闲分区表,这个表是用来记录当前空闲的内存。 那么在之后有新的进程装入内存,需要从空闲分区表中找到一…

从零手写操作系统之RVOS内存管理模块简单实现-02

从零手写操作系统之RVOS内存管理模块简单实现-02 内存管理分类内存映射表(Memory Map)Linker Script 链接脚本语法基于符号定义获取程序运行时内存分布 基于 Page 实现动态内存分配代码讲解调试 扩展 本系列参考: 学习开发一个RISC-V上的操作系统 - 汪辰 - 2021春 整…