MFC综合实验二学习记录

文章目录

    • 如何确定消息映射宏中命令对应的菜单项资源
    • 虚函数和纯虚函数的区别?
    • MFC中什么是UPDATE_COMMAND_UI 消息
    • 如何查看控件对应的成员变量
    • 模态对话框的理解
    • HGDIOBJ" 类型的值不能用于初始化 "CBrush *" 类型的实体错误
    • MFC编程中CDC类型和HDC类型有什么区别?
    • 关于WIDING和ALTERNATE填充方式的问题

如何确定消息映射宏中命令对应的菜单项资源

这是MFC中CdcdrawView函数中的消息映射宏,我的问题是如何找到ID_SET对应的是什么菜单项资源


在这里插入图片描述


最后的解决方案比较简单,只需要使用 Ctrl + F,然后输入 ID_SET 来搜索,注意到要调整搜索范围为当前项目,就可以找到对应的文件了!


在这里插入图片描述
在这里插入图片描述


注意要点击查找全部,可以看到搜索到的结果完美的符合要求, ID_SET是设置菜单项对应的ID。


在这里插入图片描述


虚函数和纯虚函数的区别?

虚函数(Virtual Function)

定义:虚函数是在基类中使用关键字 virtual 声明的函数。它可以在派生类中被重写(Override)。

实现:虚函数在基类中通常有具体的实现。这意味着即使派生类没有重写这个函数,也可以使用基类中的实现。

目的:虚函数的主要目的是允许在派生类中对基类方法进行扩展或修改,同时使用基类指针或引用来实现多态。

示例

class Base {
public:virtual void display() {std::cout << "Display of Base" << std::endl;}
};

多态:通过基类指针或引用调用虚函数时,会根据对象的实际类型来调用相应的函数实现,实现多态。

纯虚函数(Pure Virtual Function)

定义:纯虚函数是在基类中使用 virtual 关键字声明的,但没有提供任何实现,并以 = 0 结尾。例如,virtual void display() = 0;

实现:纯虚函数在基类中没有实现,派生类必须重写这个函数,除非派生类也是抽象类。

目的:纯虚函数的主要目的是定义一个接口,强制派生类实现特定的函数。这是创建抽象基类(即不能直接实例化的类)的一种方式。

示例

class Base {
public:virtual void display() = 0; // 纯虚函数
};

抽象类:包含至少一个纯虚函数的类称为抽象类。不能创建抽象类的实例。这是因为抽象类定义了一个尚未完全实现的接口。

总结

虚函数允许在基类中有一个默认实现,而派生类可以选择是否提供新的实现。

纯虚函数不在基类中提供实现,强制派生类提供自己的实现。包含纯虚函数的类成为抽象类,无法实例化。


MFC中什么是UPDATE_COMMAND_UI 消息


在这里插入图片描述

在 MFC (Microsoft Foundation Classes) 应用程序中,UPDATE_COMMAND_UI 消息是一种用于实时更新用户界面元素状态的机制。它不是由用户直接操作触发的,而是由框架在特定时刻自动发送,用于查询命令(如菜单项、工具栏按钮等)的当前状态。这允许程序动态地调整用户界面元素,以反映当前的应用程序逻辑和数据状态。

作用
UPDATE_COMMAND_UI 消息的主要作用是维护用户界面的一致性和正确性。例如,根据当前文档的状态,一个菜单项可能需要被启用或禁用,或者一个工具栏按钮可能需要显示为被选中或未选中状态。

如何工作
当 MFC 应用程序的主消息循环运行时,框架会定期发送 UPDATE_COMMAND_UI 消息给所有的用户界面元素(如菜单项和工具栏按钮)。接收到这个消息的用户界面元素需要决定自己的显示状态。这通常涉及以下几个方面:

是否启用:元素是否可用或灰显(禁用)。
是否选中:例如,切换按钮的选中/未选中状态。
其他视觉状态:如文本标签的变更等。

示例
假设您的应用程序有一个 “保存” 菜单项,您希望在文档被修改后启用它,在文档未修改时禁用它。您可以添加一个处理 UPDATE_COMMAND_UI 消息的函数来实现这一点:

void CMyApp::OnUpdateFileSave(CCmdUI* pCmdUI)
{// 检查文档是否已修改bool isModified = /* 获取文档状态 */;// 根据文档的修改状态启用或禁用 "保存" 菜单项pCmdUI->Enable(isModified);
}

在这个例子中,每当用户界面需要更新时(例如,当用户编辑文档时),这个函数会根据文档的当前修改状态来启用或禁用 “保存” 菜单项。



如何查看控件对应的成员变量


打开类向导中的对话框类对,可以看到成员变量和对应的控件ID。


在这里插入图片描述

模态对话框的理解

HGDIOBJ" 类型的值不能用于初始化 “CBrush *” 类型的实体错误

在CGraph类的绘制函数中,在选中画笔画刷的过程中出现了一点小问题,错误是

严重性 代码 说明 项目 文件 行 禁止显示状态
错误(活动) E0144 “HGDIOBJ” 类型的值不能用于初始化 “CBrush *” 类型的实体 dcdraw E:\LearningMaterial\大四上\OO报告\综合实验二\202000800341_XXX_综合2_1\CGraph.cpp 448

	//选中画笔画刷CPen* pOldpen=pDC->SelectObject(&bpen);if (bfill) { //填充CBrush* pOldBrush=pDC->SelectObject(&br);}else{CBrush* pOldBrush= pDC->SelectObject(GetStockObject(NULL_BRUSH));}

可以看到上下两行的画刷选中代码几乎一致,为什么会出现这样的问题呢?

在 MFC 中,CDC::SelectObject 方法期望一个与设备上下文相关的对象(例如 CBrushCPen 等),但是 GetStockObject 函数返回的是一个 HGDIOBJ一个更通用的GDI对象句柄)。HGDIOBJ 是 Windows API 中的一个术语,是 “Handle to a GDI Object” 的缩写。

因此,从 HGDIOBJ 转换到 CBrush* 需要显式的类型转换,而不是隐式的。修改成如下的形式,即没有问题。

//选中画笔画刷CPen* pOldpen=pDC->SelectObject(&bpen);if (bfill) { //填充CBrush* pOldBrush=pDC->SelectObject(&br);}else{CBrush* pOldBrush= (CBrush*)pDC->SelectObject(GetStockObject(NULL_BRUSH));}

MFC编程中CDC类型和HDC类型有什么区别?

在Windows编程中,CDC 和 HDC 是两种不同的,但相关的概念,它们都用于图形绘制,但在不同层面上提供功能:

  1. HDC (Handle to Device Context):
  • HDC 是一个指向设备上下文的句柄。在Windows API(特别是在底层的C或C++编程中)中使用。
  • 它是一个低层次的图形绘制接口,提供了直接访问GDI(图形设备接口)的功能。
  • HDC 可以用于屏幕、内存位图、打印机等多种绘图表面。
  • 使用 HDC 通常涉及直接的Windows API调用,例如 MoveToEx, LineTo, TextOut, Ellipse 等。
  1. CDC (Class for Device Context):
  • CDC 是MFC(Microsoft Foundation Classes)框架中的一个类,它封装了 HDC。
  • 它是一个更高层次的、面向对象的接口,使得在使用MFC编写的C++程序中绘图变得更简单和更直观。
  • CDC 提供了更多的安全性和易用性,因为它自动管理资源,如选择和取消选择GDI对象(例如画笔、字体)。
  • CDC 类包含了多个用于绘图的成员函数,这些函数实际上是对 HDC 函数的封装。例如,CDC::LineTo 是 LineTo 的封装。

简而言之,HDC 是一个更接近于Windows底层的、基于句柄的设备上下文表示,而 CDC 是MFC框架中的一个类,它提供了一个更高级别和更面向对象的接口来处理设备上下文。在MFC程序中,通常使用 CDC 而不是直接操作 HDC,因为它简化了代码并提高了安全性。但在底层的WinAPI编程中,HDC 是必不可少的。


关于WIDING和ALTERNATE填充方式的问题

这个问题其实并不重要,但是没想到随便一搜迟迟难以找到答案,给我精神造成了极大的打击,务必要记录下来。

  1. ALTERANATE:从左到右水平扫描!系统只填充每个扫描行的多边行的奇数边到偶数边的部分,不填充偶数边到奇数边的部分;
    在这里插入图片描述

MSDN中的原话如下:

When the fill mode is ALTERNATE, GDI fills the area between odd-numbered and even-numbered polygon sides on each scan line. That is, GDI fills the area between the first and second side, between the third and fourth side, and so on.

水平扫描

就是显示器上的从左到右一行一行的水平扫描,假如你客户区大小是 500 × 600 500\times600 500×600,那就是从 ( 0 , 0 ) (0,0) (0,0) ( 500 , 0 ) (500,0) (500,0) 这是第一次水平扫描,…一直到 ( 0 , 600 ) (0,600) (0,600) ( 500 , 600 ) (500,600) (500,600)。共扫描了600次就扫描完了客户

奇数边和偶数边

这里说的奇数和偶数边完全是相对而言的啊,只是我们便于理解的一种方法,就是说在水平扫描一行时,第一次遇到对线就把它定义为第一条边(注意:同一条线的话在不同的扫描行上相对的边可能不是一样的,这点一定要注意思了),第二次遇到的线就是第二条边,以此类推;那么对于一个矩形( 就单单一个矩形),左是第一条边,右是第二条边,上下它就什么都不是了,不会存在第三条边和第四条边的.

  1. WINDING模式下:填充奇数边到偶数边和ALTERANATE模式一样,但填充偶数边到奇数边的部分就不同了,你必须记主画线的方向,你可以取一个方向为正向,用一个计数器 cnt = 0,当线经过正向时cnt就加1,反向时cnt就减1,如果最后cnt为0就填充这个区域,不为0就不填充!

MSDN中的原话如下:

When the fill mode is WINDING, GDI fills any region that has a nonzero winding value. This value is defined as the number of times a pen used to draw the polygon would go around the region. The direction of each edge of the polygon is important.

在这里插入图片描述
这是WIDING模式下的填充结果,可以看到存在奇数边到偶数边问题的只有4和5。

  • 我们首先观察4,根据从区域4得到的射线,设定正方向为顺时针,经过的第一条边-1,第二条边+1, cnt = 0,所以区域4不填充
  • 接着从区域5观察,设定正方向为顺时针,经过的第一条边+1,第二条边+1,所以区域5填充

一种简单的理解方式是看能不能环绕成功,能环绕成功则可以填充,下图五角星是一笔画绘制的,可以自己思考一下

在这里插入图片描述

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

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

相关文章

TOP 9 安卓手机系统和应用程序修复工具,可修复各种Android 系统问题

您的新 Android 手机可能因其令人兴奋的性能而印象深刻。然而&#xff0c;随着时间的推移&#xff0c;您可能会发现系统有些地方与以前不太一样。您可能会遇到屏幕无响应、 Android应用程序崩溃、连接问题、电池耗尽等现象。 好吧&#xff0c;在这些情况下您不必感到不安&…

centos通过yum安装redis

1. 安装yum添加epel源(此步根据环境&#xff0c;如果有源则可跳过&#xff0c;在阿里去可跳过&#xff09; yum install epel-release 2 使用yum安装Redis yum install redis 出现如下图所示的内容&#xff0c;默认的安装路径是在 /usr/bin目录下&#xff1a; 文件安装路径…

uniapp 微信小程序跳转至其他小程序

一、背景&#xff1a; 需要在目前的小程序中跳转到另一个小程序&#xff0c;跳转的目标小程序需要已经发布上线了 二、具体实现 使用uni.navigateToMiniProgram打开另一个小程序 官网指引&#x1f449;&#xff1a;uni.navigateToMiniProgram(OBJECT) | uni-app官网 <t…

iview 选择框远程搜索 指定筛选的参数

问题&#xff1a;开启了filterable之后&#xff0c;选择框是允许键盘输入的&#xff0c;但是会对选择列表进行过滤&#xff0c;如果不想使用再次过滤&#xff0c;可以试下下面这个方法。 场景&#xff1a;输入加密前的关键字筛选&#xff0c;选择框显示加密后的数据 说明一&a…

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK实现相机的高速图像保存(C++)

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK实现相机的高速图像保存&#xff08;C&#xff09;&#xff09; Baumer工业相机Baumer工业相机的图像高速保存的技术背景Baumer工业相机通过NEOAPI SDK函数图像高速保存在NEOAPI SDK里实现线程高速图像保存&#xff1a;工业相机高…

rke2 offline install kubernetes v1.26

文章目录 1. 准备2. 安装 ansible3. 基础配置3.1 配置 hosts3.2 安装软件包3.3 内核参数3.4 连接数限制3.5 关闭swap 、selinux、防火墙3.6 时间同步 4. RKE2 安装4.1 下载安装4.2 配置其他管理节点4.3 新增 worker 节点 1. 准备 7 台主机 主机名ipcpu内存diskos角色user密码…

11.3编写Linux串口驱动

编写串口驱动主要步骤 构建并初始化 struct console 对象&#xff0c;若串口无需支持 console 可省略此步骤 //UART驱动的console static struct uart_driver virt_uart_drv; static struct console virt_uart_console {//console 的名称&#xff0c;配合index字段使用&…

unity C#中Array、Stack、Queue、Dictionary、HashSet优缺点和使用场景总结

文章目录 数组 (Array)列表 (List<T>)栈 (Stack<T>)队列 (Queue<T>)链表 (LinkedList<T>)哈希表 (Dictionary<TKey, TValue>) 或 HashSet<T>集合 (Collection<T>) 数组 (Array) 优点&#xff1a; 高效访问&#xff1a;通过索引可以…

1-04C语言执行过程

一、概述 本小节主要讲解一个C程序从源代码到最终执行的过程&#xff0c;这个过程又可以细分为两部分&#xff1a; 源代码到可执行文件的过程可执行文件在内存中执行 本小节是C语言基础当中&#xff0c;比较容易被初学者忽视的知识点。而实际上&#xff1a; 熟悉C程序从源文…

前端超好玩的小游戏合集来啦--周末两天用html5做一个3D飞行兔子萝卜小游戏

文章目录 💖飞行兔子萝卜小游戏💟效果展示💟代码展示源码获取💖飞行兔子萝卜小游戏 💟效果展示 💟代码展示 <body> <script src=

如何选猫粮:买主食冻干猫粮需要注意什么?

随着养猫的人越来越多&#xff0c;铲屎官们对猫咪的饮食也越来越注重。除了猫粮&#xff0c;很多铲屎官还会给猫咪准备小零食。那么&#xff0c;猫咪是不是除了猫粮就没有其他可吃的了呢&#xff1f;答案当然不是。猫咪还有猫冻干、冻干猫粮、猫条等可以选择。每个铲屎官都希望…

【MySQL】索引基础

文章目录 1. 索引介绍2. 创建索引 create index…on…2.1 explain2.2 创建索引create index … on…2.3 删除索引 drop index … on 表名 3. 查看索引 show indexes in …4. 前缀索引4.1 确定最佳前缀长度&#xff1a;索引的选择性 5. 全文索引5.1 创建全文索引 create fulltex…

Vue3.4更新 “Slam Dunk“发布!!!

Announcing Vue 3.4 | The Vue Point. vue3.4更新官方文档 在vue2即将结束更新的时候&#xff0c;vue3迎来了一个重要的更新。代号为“&#x1f3c0; Slam Dunk”&#xff0c;即"灌篮高手"。这个版本进行了很多显著的内部改进&#xff0c;最重要的是模版解析的底层逻…

Github 2024-01-08开源项目周报 Top14

根据Github Trendings的统计&#xff0c;本周(2024-01-08统计)共有14个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量Python项目5TypeScript项目3C项目2Dart项目1QML项目1Go项目1Shell项目1Rust项目1JavaScript项目1C#项目1 免费…

IO进程线程Day5

1> 将互斥机制代码重新实现一遍 #include<myhead.h>char buf[128]; //临界资源pthread_mutex_t mutex; //创建锁资源//分支线程 void* task(void* arg) {while(1){//获取锁资源pthread_mutex_lock(&mutex);printf("这里是分支线程:%s\n",buf);st…

多线程模板应用实现(实践学习笔记)

出处&#xff1a;B站码出名企路 个人笔记&#xff1a;因为是跟着b站的教学视频以及文档初步学习&#xff0c;可能存在诸多的理解有误&#xff0c;对大家仅供借鉴&#xff0c;参考&#xff0c;然后是B站up阳哥的视频&#xff0c;我是跟着他学。大家有兴趣的可以到b站搜索。加油…

CAD安装教程

CAD安装教程 目录 一&#xff0e; 下载CAD二&#xff0e; 安装CAD 一&#xff0e; 下载CAD 如果需要CAD安装包请私信。 二&#xff0e; 安装CAD 解压压缩包AutoCAD2022中文版&#xff0c;以管理员身份运行AutoCAD_2022_Simplified_Chinese_Win_64bit_dlm.sfx。 选择解压路径。…

【sklearn练习】datasets的使用

一、数据集分类 1、fetch类的数据集&#xff1a; 以 "fetch" 开头的数据集&#xff0c;这些数据集通常不包含在 scikit-learn 的标准安装中&#xff0c;需要从远程服务器上下载。这些数据集通常比标准数据集更大&#xff0c;因此在使用它们之前&#xff0c;需要通过…

Spring MVC中@ExceptionHandler注解的智能处理机制——无需显示指定异常类型

概述 在深入探讨Spring MVC框架时&#xff0c;我们经常会遇到异常处理的相关场景。其中&#xff0c;ExceptionHandler注解是一个非常重要的工具&#xff0c;它允许我们声明一个方法来专门处理特定类型的异常。有趣的是&#xff0c;Spring容器具备智能化的异常类型关联功能&…

自动驾驶:低阶可部署的单目测距算法-基于YOLO与透视变换

一、开发环境 部署平台&#xff1a;英伟达的Jetson Nano 环境&#xff1a;Linux ROS 语言&#xff1a;C 设备&#xff1a;1920*1080像素的摄像头、开发板。 模型&#xff1a;yolo-v8s 二、单目测距实现思路 0、标定相机和车辆&#xff08;假设已经标定完成&#xff09; 1、通…