MFC和ATL之间的根本区别是什么?

2024-02-14

假设我是only将它们用于“普通”GUI 程序(没有 COM,没有 ActiveX,没什么花哨的),我将看到 ATL 和 MFC 之间的根本区别是什么,以帮助我弄清楚使用哪一个?


我在网上做了一些搜索,但最终没有一个答案真正回答了我的问题:

  • http://msdn.microsoft.com/en-us/library/bk8ytxz5(v=vs.80).aspx http://msdn.microsoft.com/en-us/library/bk8ytxz5(v=vs.80).aspx:

    • “ATL 是一种快速、简单的方法,既可以用 C++ 创建 COM 组件,又可以保持较小的占用空间。如果不需要 MFC 自动提供的所有内置功能,可以使用 ATL 创建控件。”

      并没有真正回答我的问题,因为:

      • 我不使用 COM。

      • 这是否意味着MFCisn't快速地?为什么/如何?

    • “MFC 允许您创建完整的应用程序、ActiveX 控件和活动文档。如果您已经使用 MFC 创建了控件,您可能希望继续在 MFC 中进行开发。创建新控件时,如果不需要,请考虑使用 ATL MFC 的所有内置功能。”

      也没有回答我的问题,因为:

      • 我真的不知道什么是ActiveXis首先。

      • 看来微软不鼓励使用 MFC,但我不明白为什么。

      • 到底是什么isATL不提供MFC的“内置功能”?

    • 一般来说,这并不能回答我的问题,因为它没有解释缺点以及其背后的原因。

因为直接或间接,一切似乎都链接回上一页:

  • 如何决定新的 C++ 项目是使用 ATL、MFC、Win32 还是 CLR? https://stackoverflow.com/questions/821676/how-do-i-decide-whether-to-use-atl-mfc-win32-or-clr-for-a-new-c-project

    • “在 ATL 和 MFC 之间做出选择有些困难。[[别开玩笑!]]我会推荐你​​去MSDN 页面 http://msdn.microsoft.com/en-us/library/bk8ytxz5%28VS.80%29.aspx以便在他们之间做出选择。”

      明显地,这并不能回答我的问题。 :)

  • http://www.codeguru.com/forum/archive/index.php/t-64778.html http://www.codeguru.com/forum/archive/index.php/t-64778.html

  • etc.

我拥有的目前观察到的(在过去几天内,同时尝试学习两者):

  • ATL is based on templates, or compile-time polymorphism.
    • ATL 方法往往是非虚拟的,并且往往返回引用。
  • MFC is based on virtual methods, or run-time polymorphism.
    • MFC 方法往往是虚拟的,并且往往返回指针。

但有它们之间似乎没有任何架构差异:

  • 两者都使用消息映射(BEGIN_MSG_MAP vs. BEGIN_MESSAGE_MAP...大不了)
  • 两者都将 Win32 方法包装到类中
  • 两者似乎都有相似的课程CWnd vs. CWindow

但是,如果除了编译时与运行时方面之外没有真正的区别,那么为什么它们都存在呢?难道其中之一就够了吗?

我在这里缺少什么?


如果你回顾一下这两个图书馆是如何起源和随时间演变的,我认为你的问题的答案主要是历史性的。

简而言之,如果您不做任何“花哨”的事情,请使用 ATL。它非常适合带有 COM 的简单用户界面。

长答案: MFC 是在 90 年代初构建的,目的是尝试这种称为 C++ 的新语言并将其应用到 Windows。它使开发社区可以使用类似于 Office 的功能,而操作系统尚不具备这些功能。

[编辑点缀:我没有在微软工作过,所以我不知道Office是否曾经是基于MFC构建的,但我认为答案是否定的。回到 Win 3.1、Win 95 时代,Office UI 团队会发明新的控件,将它们打包到库中,然后 Windows 和 MFC 团队会将包装器和 API 合并到具有可再发行 dll 的这些控件中。我猜想这些团队之间有一些协作和代码共享。最终,这些控件将进入服务包或下一个 Windows 版本中的基本操作系统。 Office 功能区延续了这种模式,它在 Office 发布后作为附加组件添加到 Windows 中,现在已成为 Windows 操作系统的一部分。]

当时该库相当原始,因为 C++ 语言和编译器都是新的,而且 Microsoft 随着 Office 的发展而不断构建它。

由于这段历史,MFC:

  1. 有一个相当笨重的设计。它最初是作为 Windows API 的一个轻量级包装器,但后来不断发展。有许多小“功能”必须发明,因为编译器和语言不支持它们。没有模板,他们发明了字符串类,他们发明了列表类,他们设计了自己的运行时类型标识,等等。
  2. 概括了 Office 和 Windows 20 年的发展,其中包括一大堆你可能永远不会使用的东西:单文档和多文档接口、DDE、COM、COM+、DCOM、文档链接和嵌入(这样你就可以在您的应用程序(如果您愿意的话)、ActiveX 控件(Web 对象嵌入的演变!)、结构化文档存储、序列化和版本控制、自动化(从早期的 VBA 开始),当然还有 MVC。最新版本支持 Visual Studio 样式窗口停靠和 Office 功能区。基本上,雷蒙德 20 年来的所有技术都在某个地方。实在是太大了!
  3. 有大量的小陷阱、错误、解决方法、假设、对仍然存在但你永远不会使用的东西的支持,它们会导致问题。您需要非常熟悉许多类的实现以及它们如何交互才能在规模合适的项目中使用它。在调试过程中深入研究 MFC 源代码是很常见的。找到 15 年前的技术说明,其中一些指针为空导致崩溃仍然会发生。对古代文档嵌入内容初始化的假设可能会以奇怪的方式影响您的应用程序。 MFC 中不存在抽象这样的东西,您每天都需要处理它的怪癖和内部结构,它不会隐藏任何内容。不要让我开始使用类向导。

ATL 是随着 C++ 语言的发展而发明的,模板也随之出现。 ATL 展示了如何使用模板来避免 MFC 库的运行时问题:

  1. 消息映射:由于它们是基于模板的,因此会检查类型,如果你搞砸了绑定函数,它就不会构建。在 MFC 中,消息映射是基于宏的,并且受运行时限制。这可能会导致奇怪的错误,消息路由到错误的窗口,如果您的函数或宏定义不正确,则会导致崩溃,或者只是因为某些东西没有正确连接而无法工作。调试起来更加困难,而且更容易在不经意间被破坏。
  2. COM/自动化:与消息映射类似,COM 最初是使用宏在运行时绑定的,需要大量的错误处理并导致奇怪的问题。 ATL 使其基于模板,受编译时间限制,并且更容易处理。

[编辑补充:在创建 ATL 时,微软的技术路线图主要集中在“文档管理”上。苹果在桌面出版业务中正在扼杀他们。 Office“文档链接和嵌入”是增强 Office“文档管理”功能以在该领域竞争的主要组成部分。 COM是为应用程序集成而发明的核心技术,文档嵌入API就是基于COM的。 MFC 很难用于此用例。 ATL 是一个很好的解决方案,可以让第三方更轻松地实现这一特定技术并利用文档嵌入功能。]

这些小改进使得 ATL 在不需要 MFC 的所有 Office 功能的简单应用程序上更容易处理。具有简单的 UI 和一些 Office 自动化功能的东西。它很小,速度很快,编译时间有限,可以为您节省大量时间和头痛。 MFC 拥有庞大的类库,但这些类库可能很笨重且难以使用。

不幸的是ATL停滞不前。它有 Windows API 和 COM 支持的包装器,但它从未真正超越这一点。当网络兴起时,所有这些东西都像旧新闻一样被遗忘了。

[编辑修饰:微软意识到这个“互联网事物”将会变得很大。他们的技术路线图发生了巨大的变化,重点关注分布式事务服务器中的 Internet Explorer、Windows Server、IIS、ASP、SQL Server、COM/DCOM。因此文档链接和嵌入不再是一个高优先级。]

MFC巨大的足迹让他们无法倾倒,所以它仍然发展缓慢。模板以及其他语言和 API 增强功能已重新合并到库中。 (直到我看到这个问题,我才听说过 WTL。:)

最终,使用哪一个只是一个偏好问题。您需要的大部分功能都在基本操作系统 API 中,如果库中没有合适的包装器,您可以直接从任一库调用这些功能。

只是我的 2 美分,基于使用 MFC 多年,我现在每天都使用它。当 ATL 在几个项目上首次发布时,我已经涉足了几年。在那些日子里,这是一股新鲜空气,但从未真正去任何地方。然后网络出现了,我就忘记了它。


编辑:这个答案的寿命令人惊讶。由于它不断出现在我的堆栈溢出页面中,我想我应该为我认为缺乏的原始答案添加一些修饰。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MFC和ATL之间的根本区别是什么? 的相关文章

  • pthread_cond_timedwait() 和 pthread_cond_broadcast() 解释

    因此 我在堆栈溢出和其他资源上进行了大量搜索 但我无法理解有关上述函数的一些内容 具体来说 1 当pthread cond timedwait 因为定时器值用完而返回时 它如何自动重新获取互斥锁 互斥锁可能被锁定在其他地方 例如 在生产者
  • 如何避免情绪低落?

    我有一个实现状态模式每个状态处理从事件队列获取的事件 根据State因此类有一个纯虚方法void handleEvent const Event 事件继承基础Event类 但每个事件都包含其可以是不同类型的数据 例如 int string
  • 如何忽略“有符号和无符号整数表达式之间的比较”?

    谁能告诉我必须使用哪个标志才能使 gcc 忽略 有符号和无符号整数表达式之间的比较 警告消息 gcc Wno sign compare 但你确实应该修复它警告你的比较
  • 使闭包捕获的变量变得易失性

    闭包捕获的变量如何与不同线程交互 在下面的示例代码中 我想将totalEvents 声明为易失性的 但C 不允许这样做 是的 我知道这是错误的代码 这只是一个例子 private void WaitFor10Events volatile
  • 实时服务器上的 woff 字体 MIME 类型错误

    我有一个 asp net MVC 4 网站 我在其中使用 woff 字体 在 VS IIS 上运行时一切正常 然而 当我将 pate 上传到 1and1 托管 实时服务器 时 我得到以下信息 网络错误 404 未找到 http www co
  • Newtonsoft JSON PreserveReferences处理自定义等于用法

    我目前在使用 Newtonsoft Json 时遇到一些问题 我想要的很简单 将要序列化的对象与所有属性和子属性进行比较以确保相等 我现在尝试创建自己的 EqualityComparer 但它仅与父对象的属性进行比较 另外 我尝试编写自己的
  • 当 contains() 工作正常时,xpath 函数ends-with() 工作时出现问题

    我正在尝试获取具有以特定 id 结尾的属性的标签 like span 我想获取 id 以 国家 地区 结尾的跨度我尝试以下xpath span ends with id Country 但我得到以下异常 需要命名空间管理器或 XsltCon
  • C - 找到极限之间的所有友好数字

    首先是定义 一对友好的数字由两个不同的整数组成 其中 第一个整数的除数之和等于第二个整数 并且 第二个整数的除数之和等于第一个整数 完美数是等于其自身约数之和的数 我想做的是制作一个程序 询问用户一个下限和一个上限 然后向他 她提供这两个限
  • 如何将图像和 POST 数据上传到 Azure 移动服务 ApiController 终结点?

    我正在尝试上传图片and POST表单数据 尽管理想情况下我希望它是json 到我的端点Azure 移动服务应用 我有ApiController method HttpPost Route api upload databaseId sea
  • WPF TabControl,用C#代码更改TabItem的背景颜色

    嗨 我认为这是一个初学者的问题 我搜索了所有相关问题 但所有这些都由 xaml 回答 但是 我需要的是后台代码 我有一个 TabControl 我需要设置其项目的背景颜色 我需要在选择 取消选择和悬停时为项目设置不同的颜色 非常感谢你的帮助
  • vector 超出范围后不清除内存

    我遇到了以下问题 我不确定我是否错了或者它是一个非常奇怪的错误 我填充了一个巨大的字符串数组 并希望在某个点将其清除 这是一个最小的例子 include
  • for循环中计数器变量的范围是多少?

    我在 Visual Studio 2008 中收到以下错误 Error 1 A local variable named i cannot be declared in this scope because it would give a
  • 如何在 VBA 中声明接受 XlfOper (LPXLOPER) 类型参数的函数?

    我在之前的回答里发现了问题 https stackoverflow com q 19325258 159684一种无需注册即可调用 C xll 中定义的函数的方法 我之前使用 XLW 提供的注册基础结构 并且使用 XlfOper 类型在 V
  • 将 unsigned char * (uint8_t *) 转换为 const char *

    我有一个带有 uint8 t 参数的函数 uint8 t ihex decode uint8 t in size t len uint8 t out uint8 t i hn ln for i 0 i lt len i 2 hn in i
  • 将文本叠加在图像背景上并转换为 PDF

    使用 NET 我想以编程方式创建一个 PDF 它仅包含一个背景图像 其上有两个具有不同字体和位置的标签 我已阅读过有关现有 PDF 库的信息 但不知道 如果适用 哪一个对于如此简单的任务来说最简单 有人愿意指导我吗 P D 我不想使用生成的
  • 为什么我收到“找不到编译动态表达式所需的一种或多种类型。”?

    我有一个已更新的项目 NET 3 5 MVC v2 到 NET 4 0 MVC v3 当我尝试使用或设置时编译出现错误 ViewBag Title财产 找不到编译动态表达式所需的一种或多种类型 您是否缺少对 Microsoft CSharp
  • 如何使用 std::string 将所有出现的一个字符替换为两个字符?

    有没有一种简单的方法来替换所有出现的 in a std string with 转义 a 中的所有斜杠std string 完成此操作的最简单方法可能是boost字符串算法库 http www boost org doc libs 1 46
  • C 中的异或运算符

    在进行按位操作时 我在确定何时使用 XOR 运算符时遇到一些困难 按位与和或非常简单 当您想要屏蔽位时 请使用按位 AND 常见用例是 IP 寻址和子网掩码 当您想要打开位时 请使用包含或 然而 XOR 总是让我明白 我觉得如果在面试中被问
  • 如何在 C++ BOOST 中像图形一样加载 TIFF 图像

    我想要加载一个 tiff 图像 带有带有浮点值的像素的 GEOTIFF 例如 boost C 中的图形 我是 C 的新手 我的目标是使用从源 A 到目标 B 的双向 Dijkstra 来获得更高的性能 Boost GIL load tiif
  • 限制C#中的并行线程数

    我正在编写一个 C 程序来生成并通过 FTP 上传 50 万个文件 我想并行处理4个文件 因为机器有4个核心 文件生成需要更长的时间 是否可以将以下 Powershell 示例转换为 C 或者是否有更好的框架 例如 C 中的 Actor 框

随机推荐

  • 大整数的按位运算

    我正在实现 BER 压缩整数的解码 最近我发现了与大整数按位运算相关的奇怪 JavaScript 行为 E g var a 17516032 has 25 bits alert a lt lt 7 outputs 2052915200 al
  • 哪些 x86 C++ 编译器本身是多线程的?

    现在 几乎每个用户在台式机上 以及大量笔记本电脑上 都拥有 2 或 4 个核心 高级用户拥有 6 12 个 AMD 或 i7 核心 哪些 x86 x86 64 C C 编译器可以使用多个线程进行编译 已经有一个 make j N 类似的解决
  • 我使用的是哪个版本的 python time 模块

    如何确定安装了哪个版本的 python 模块 time 对于其他模块 version version or version 工作 但是时间上 这两种方法都会返回错误 模块 对象没有属性 version 或 版本 Module time内置于
  • Google Analytics Regex - 无负向前瞻的替代方案

    Google Analytics 分析 在其过滤器中不再允许负向前瞻 事实证明 创建仅包含我希望包含的链接的自定义报告非常困难 包含负向前瞻的正则表达式在启用时可以工作 test com index php s 这匹配 test com t
  • 聚合 MongoDB 中子文档的总计

    我有一个如下所示的文档 我本质上想为子文档中的项目生成一个聚合 本质上 每个文档都是一个销售记录 其中包含销售详细信息和包含每个商品销售数量的子文档 数组 我想生成所有已售商品的摘要 因此 一个示例集合是 non relevant 1 AB
  • 在训练期间评估模型会影响其性能 PyTorch

    In PyTorch 我想在验证集上评估我的模型eval step在训练期间 我写了这样的代码 def tune model loader train loader dev optimizer epochs eval step for ep
  • 防止 Spring WebFlow 应用程序中的跨站点请求伪造

    我正在寻找一种 希望是简单的 添加方法CSRF http www codinghorror com blog 2008 10 preventing csrf and xsrf attacks html对基于 Spring WebFlow 2
  • Spring的@Cacheable注释可以与注释方法的bean具有相同的作用域吗?

    有没有简单的方法来使用 Spring Cacheable使用非单例 例如会话范围 bean 进行注释并使缓存与所述 bean 具有相同的范围 Example import javax inject Inject import javax i
  • 如何在大事务下获得高性能(postgresql)

    我有 200 万条数据需要插入到 postgresql 中 但它却发挥了低效的表现 我可以通过将大事务分割成较小的事务来实现高性能插入器 实际上 我不想这样做 或者 还有其他明智的解决方案吗 不 更快的主要想法是在一个事务中完成所有插入 多
  • 为什么 CREATE VIEW 必须是批处理中的第一个语句? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 CREATE VIEW 必须是批处理中的第一个语句是否有任何逻辑原因 这样的设计背后的原理是什么 与其说它一定是first批处理中的声明 而是它
  • 处理 ARM 芯片的保留寄存器位

    我正在使用 ARM Cortex M3 的寄存器 在文档中 某些位可能是 保留的 我不清楚在寄存器上写入时应该如何处理这些保留位 这些保留位是否可写 我应该小心不要碰它们吗 如果我碰它们 会发生什么不好的事情吗 这是关于如何处理保留位的经典
  • 一次推送两条路由时不会调用 RouteAware didPushNext

    当同时推送两条路线到Navigator并使用RouteAware获取时 更新了当前状态 第一个路由的 didPopNext 没有 叫 似乎调用了 RouteObserver didPush 将调用 didPushNext 对于调用 Firs
  • 将图像 2 重叠在图像 1 上

    我们在网站中显示 image1 如下 现在我们提供上传 image2 的选项 我们想要上传的 image2 应该与现有的 image1 重叠 例如here http www dailyobjects com custom cases app
  • ABAP中的求值顺序

    ABAP 是否有明确的评估顺序 例如 在表达式中foo bar 是否可以保证哪种方法foo and bar 首先评估 执行 在 ABAP 关键字文档中找不到此类信息 ABAP 文档 arith exp 算术运算符 https help sa
  • 在哪里可以下载所有聚合物元素的 zip 文件?

    Polymer 1 0 最近发布了 我可以在elements polymer project org https elements polymer project org 网站 但我找不到一个简单的链接来下载一个大 zip 文件中的所有内容
  • #define 与运算符一起使用[重复]

    这个问题在这里已经有答案了 我知道 define具有以下语法 define SYMBOL string例如 如果我写 define ALPHA 2 1 define BETA ALPHA 2 then ALPHA 1 but BETA 0
  • 我应该如何在类和应用程序层之间传递数据?

    例如 如果我正在创建一个 3 层应用程序 数据 业务 UI 并且数据层正在抓取单个或多个记录 在发送到业务层之前 是否将数据层中的所有内容转换为通用列表 集合 发送数据表可以吗 将信息发送回数据层怎么样 如果我使用对象 列表 这些成员是数据
  • iPhone:如何拖动或移动 UIImage/UIButton,如下所示?

    我不知道如何在我的应用程序中获得以下类型的功能 如上图所示 用户可以滑动 拖动 不同的图像部分 并可以组合图像 谁能告诉我这是哪一个控件 或者有什么教程吗 查看 MoveMe 示例应用程序 它将向您展示如何通过触摸和拖动来移动子视图 然后
  • FileLocator.resolve(url) 的转义结果

    方法FileLocator resolve url 可用于翻译地址bundleentry something somewhere x txt到正确的文件 URL mnt foo somewhere x txt 然而 这也记录在https b
  • MFC和ATL之间的根本区别是什么?

    假设我是only将它们用于 普通 GUI 程序 没有 COM 没有 ActiveX 没什么花哨的 我将看到 ATL 和 MFC 之间的根本区别是什么 以帮助我弄清楚使用哪一个 我在网上做了一些搜索 但最终没有一个答案真正回答了我的问题 ht