Windows编程_Lesson004_项目预备_重新认识MFC

2024-06-06 12:18

本文主要是介绍Windows编程_Lesson004_项目预备_重新认识MFC,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

MFC本质

MFC本质上就是一套开发框架,它可以帮助我们快速开发。MFC是以类的方式重新将Windows API进行了归类,MFC层次结构图链接。一提到类,相信对于了解C++或者其它比较高级一点的开发语言的同学肯定就不会感到那么恐惧MFC了。MFC既然是一套,所以你就不一定非得在VS环境下编译,它可以在任何支持C++的编译器下面进行编译,但是这些编译器必须是在Windows下的,因为它所使用的大多数API都是Windows下的,和Linux或者Unix是不兼容的。虽然说可以在任何编译器下进行编译MFC这套框架,但是我们还是最好在VS下面进行MFC的编译和开发,因为VS对MFC的支持是最好的。
下面是MFC层次结构图,看到这些图,我们对MFC是不是了解更加清晰了呢?
它就是一层一层的继承,和C++的继承是一模一样的。
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
上面所述的目的就是我们(主要是刚接触MFC的同学)不要觉得MFC有多难多复杂,它其实就是一个一个的类,一步一步的看这个类是从哪儿继承过来的,然后我们就知道这个类中都有什么函数(接口)可供我们使用了,用到什么函数,直接就去这个类里面查找就OK了!这么一解释,MFC是不是变得不是那么难了呢?

Dialog创建过程

XXX代表的数创建的对话框工程的名字。
MFC的对话框创建完成后,存放代码的有两个类,一个是XXXApp的类,另一个是XXXDlg的类。我们需要注意一下几个点:

第一个点,在XXXApp类中,有这样的一个虚函数:

virtual BOOL InitInstance();

这个函数在程序启动的时候被被动的调用。

第二个点,在XXXDlg类中,有这样的一个函数:

BOOL OnInitDialog() override;

注意:所有的OnXXX函数,代表的意思都是被被动的调用,意思就是当发生某些消息的时候就会调用OnXXX函数!

特别需要注意的是:
XXXDlg类是完成界面功能的,而XXXApp类是主要实现程序逻辑的功能的。
在MFC这套框架中,程序和窗口是分开的。窗口只是响应一些界面的消息,它一定不是来完成逻辑的,XXXApp才是来完成逻辑的。

详细的执行过程是这样的,XXXApp类会生成唯一的一个全局对象theApp,这个theApp会执行它的InitInstance()函数,而 InitInstance()函数里面会生成XXXDlg类的对象dlg,dlg调用它的函数DoModal(),DoModal()再调用BOOL OnInitDialog() override,此时,一个对话框界面就活生生的展现在我们的面前了,我们可以在对话框界面上做一些事情,当这个对话框关闭的时候,它也会返回一个值,我们可以根据返回值,也可以做一些相应的收尾工作。

这里写图片描述

这就是MFC的对话框创建和销毁的全部过程,是不是很简单呢?

对话框的使用

这里写图片描述

这里写图片描述

这里写图片描述
如果按照上面进行添加对话框标题,会弹出下面的错误
这里写图片描述

当我们单步调试,进入SetWindowText函数,如下图所示:
这里写图片描述
我们可以看到hWnd是一个空指针,所以就会出现崩溃。那么有的同学就会产生疑问,我们的对话框对象不是已经创建出来了吗?那么为什么不能调用SetWindowText函数呢?这是因为SetWindowText函数是针对于窗口来进行操作的,而窗口是属于内核对象,也就是意味着,有没有类,跟我内核对象是一点关系都没有的,也就是说,只要你有窗口,我就能做窗口相关的事情。
总的来说就是对话框对象是我们自己程序的对象,我们的程序对象维护了一个窗口内核对象,注意:我们只是维护一个窗口内核对象,它是不属于我们自己程序的,应该说,所有的内核对象都是不属于程序的,它们是属于操作系统的,我们能做的是,我们需要什么,操作系统帮我们拿出来我们需要的东西,然后在确保拿过来这个东西的时候,我们再对它们进行相关操作。,所以我们当前的对话框对象并没有拿到内核对象,因为必须在DoModal之后,才能拿到窗口内核对象,也就是说,DoModal函数里面才能拿到窗口内核对象。
我们的对话框类严格来说是一个窗口管理类,我们的窗口是一个内核对象,而窗口内核对象是通过操作系统来分配的,所以我们的窗口管理类唯一能做的是向操作系统要一个窗口内核对象(起到一个通知的作用),然后再让这些窗口对象做一些相应的改变,比如通过SetWindowText函数来修改对话框标题等。
这里写图片描述

那么问题又来了,SetWindowText函数只能在DoModal函数之后才能起作用,但是DoModal函数是一个阻塞函数,SetWindowText函数是不能被执行到的呀!!!这该怎么办呢?如果我们使用的是非模态对话框,那么在Create函数之后,是可以进行SetWindowText函数来修改标题的。
那么对于模态对话框,我们就没有办法解决这个问题了吗?办法是有的,比如我们可以对DoMoDal函数进行改造。我们可以想象一下DoModal函数里面做的事情:

可定CreateWindow -> 发送WM_CREATE消息 -> OnInitialDialog函数里面可以做初始化操作

所以我们可以重写OnInitialDialog函数,在OnInitialDialog函数中,我们首先可以调用父类里面的CDialogEx::OnInitialDialog函数,然后再做窗口设置操作,调用SetWindowText函数,来更改对话框标题,重写的OnInitialDialog函数如下所示:

这里写图片描述

此时,我们再看一下执行效果:

这里写图片描述

我们只重写OnInitialDialog函数,就解决了程序崩溃的问题,原来的调用没有任何一点儿改变:
这里写图片描述

从上面的例子可以看出,MFC实际上是以C++的方式对Windows里面的很多特性进行了一层一层的封装,然后对Windows中的每一个消息都相应的产生一个On…的函数,所以我们可以利用C++里面的特性,来对MFC进行各种各样的填充、扩充以及修改。

我们如果想正儿八经使用MFC这套框架的话,把MFC写的与众不同一些的话,我们更多的是对MFC的类进行继承,然后对特定的消息进行特定的操作。

下面介绍三种方式来定制MFC

1. 构造函数接收参数修改对话框风格的例子
2. 重载一个接收参数的DoModal函数
3. 设置一个方法

1. 构造函数接收参数例子
增加一个带参数的构造函数
这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

上面的方式虽然可以,但是并不推荐。我们应该使用一个enum来枚举一些对话框风格
这里写图片描述

这里写图片描述

这里写图片描述

2. 重载接收参数的DoModal函数修改对话框风格的例子

这里写图片描述

这里写图片描述

3.设置一个方法改对话框风格的例子就不再举例子了

DoModal函数的返回值

当我们点击对话框上面的×号关闭对话框时,DoModal函数会返回2,它代表是IDCANCEL消息,然后就将对话框关闭掉了,如果我们想使用自己的按钮来关闭对话框,该如何实现呢?
那么这样实现我们的关闭按钮函数,可以将对话框关闭掉吗?

这里写图片描述

我们也不知道OnClose函数里面到底做了什么事情,调试一下!!!

这里写图片描述
这里写图片描述
这里写图片描述
从上面可以看出OnClose函数什么事情都没有做,所以这个按钮是不能将对话框关闭掉的。

如果我们调用父类的OnClose函数,效果会怎样呢?

这里写图片描述
通过调试,可以看出,跟调用本类中的OnClose函数是一模一样的。

那么我们该如何才能自己将对话框关闭呢?很简单,自己重载一个OnClose函数,让OnClose函数调用CloseWindow函数,就可以将对话框关闭。
这里写图片描述
这里写图片描述

MFC的按钮约定俗成的一些按钮。
这里写图片描述

我们还可以使用EndDialog函数,根据传入的不同的参数,来决定DoModal函数的返回值。
这里写图片描述
这里写图片描述
从上面可以看出,如果我们传入的是IDCANCEL,那么DoModal函数的返回值就是2了。

这篇关于Windows编程_Lesson004_项目预备_重新认识MFC的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1036083

相关文章

深度解析Java项目中包和包之间的联系

《深度解析Java项目中包和包之间的联系》文章浏览阅读850次,点赞13次,收藏8次。本文详细介绍了Java分层架构中的几个关键包:DTO、Controller、Service和Mapper。_jav... 目录前言一、各大包1.DTO1.1、DTO的核心用途1.2. DTO与实体类(Entity)的区别1

Go语言数据库编程GORM 的基本使用详解

《Go语言数据库编程GORM的基本使用详解》GORM是Go语言流行的ORM框架,封装database/sql,支持自动迁移、关联、事务等,提供CRUD、条件查询、钩子函数、日志等功能,简化数据库操作... 目录一、安装与初始化1. 安装 GORM 及数据库驱动2. 建立数据库连接二、定义模型结构体三、自动迁

如何在Spring Boot项目中集成MQTT协议

《如何在SpringBoot项目中集成MQTT协议》本文介绍在SpringBoot中集成MQTT的步骤,包括安装Broker、添加EclipsePaho依赖、配置连接参数、实现消息发布订阅、测试接口... 目录1. 准备工作2. 引入依赖3. 配置MQTT连接4. 创建MQTT配置类5. 实现消息发布与订阅

springboot项目打jar制作成镜像并指定配置文件位置方式

《springboot项目打jar制作成镜像并指定配置文件位置方式》:本文主要介绍springboot项目打jar制作成镜像并指定配置文件位置方式,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录一、上传jar到服务器二、编写dockerfile三、新建对应配置文件所存放的数据卷目录四、将配置文

怎么用idea创建一个SpringBoot项目

《怎么用idea创建一个SpringBoot项目》本文介绍了在IDEA中创建SpringBoot项目的步骤,包括环境准备(JDK1.8+、Maven3.2.5+)、使用SpringInitializr... 目录如何在idea中创建一个SpringBoot项目环境准备1.1打开IDEA,点击New新建一个项

基于Python开发Windows屏幕控制工具

《基于Python开发Windows屏幕控制工具》在数字化办公时代,屏幕管理已成为提升工作效率和保护眼睛健康的重要环节,本文将分享一个基于Python和PySide6开发的Windows屏幕控制工具,... 目录概述功能亮点界面展示实现步骤详解1. 环境准备2. 亮度控制模块3. 息屏功能实现4. 息屏时间

springboot项目中整合高德地图的实践

《springboot项目中整合高德地图的实践》:本文主要介绍springboot项目中整合高德地图的实践,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一:高德开放平台的使用二:创建数据库(我是用的是mysql)三:Springboot所需的依赖(根据你的需求再

在Windows上使用qemu安装ubuntu24.04服务器的详细指南

《在Windows上使用qemu安装ubuntu24.04服务器的详细指南》本文介绍了在Windows上使用QEMU安装Ubuntu24.04的全流程:安装QEMU、准备ISO镜像、创建虚拟磁盘、配置... 目录1. 安装QEMU环境2. 准备Ubuntu 24.04镜像3. 启动QEMU安装Ubuntu4

Windows下C++使用SQLitede的操作过程

《Windows下C++使用SQLitede的操作过程》本文介绍了Windows下C++使用SQLite的安装配置、CppSQLite库封装优势、核心功能(如数据库连接、事务管理)、跨平台支持及性能优... 目录Windows下C++使用SQLite1、安装2、代码示例CppSQLite:C++轻松操作SQ

一文详解如何在idea中快速搭建一个Spring Boot项目

《一文详解如何在idea中快速搭建一个SpringBoot项目》IntelliJIDEA作为Java开发者的‌首选IDE‌,深度集成SpringBoot支持,可一键生成项目骨架、智能配置依赖,这篇文... 目录前言1、创建项目名称2、勾选需要的依赖3、在setting中检查maven4、编写数据源5、开启热