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

假设我是 只有,用它们编写“普通”的 GUI 程序(没有 COM,没有 ActiveX,没什么特别的) ,那么我将看到 ATL 和 MFC 之间的根本区别是什么,以帮助我找出使用哪一个?


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

因为无论是直接的还是间接的,所有东西似乎都链接到上一页:

我有什么 currently observed(在过去的几天里,同时试图学习两者) :

  • ATL 基于模板或编译时多态性。
    • ATL 方法往往是非虚拟的,并且往往返回引用。
  • MFC 基于虚方法或运行时多态性。
    • MFC 方法往往是虚拟的,并且往往返回指针。

但是 他们之间似乎没有任何建筑上的差异:

  • 两者都使用消息映射(BEGIN_MSG_MAPBEGIN_MESSAGE_MAP... 大不了的)
  • 两者都将 Win32方法封装到类中
  • Both seem to have similar classes CWnd vs. CWindow

但是,如果除了编译时方面和运行时方面之外没有真正的区别,那么为什么它们都存在呢?一个还不够吗?

What am I missing here?

36455 次浏览

许多同时使用这两种方法的人告诉我,他们使用 ATL 的编程经验没有使用 MFC 那么痛苦。使用 ATL 编译的可执行文件也会小得多。

我推荐你 看看 WTL,因为它建立在 ATL 之上。

他们一直提到的“额外功能”是什么? 我需要吗?

如果您定义了自己的需求,那么如果可以避免使用 MFC,那么回答起来可能会更容易。不幸的是“没什么特别的”还不够。包含哪些特性可能更有帮助(哪些控件,哪些框架/技术/现有库,等等)。

But here's 描述 MFC 中一些 WTL/ATL 不直接支持的特性的文章。

MFC 还发展到支持许多令人满意的特性,比如 MAPI、对其他 Windows 徽标需求的支持、套接字、文档(如果您喜欢和/或使用这种模式)以及复合文档文件。WTL 有很多很酷的特性,但是 MFC 是明显的特性冠军。这两个环境都支持框架化的主窗口架构(具有单独视图窗口的框架窗口)、 SDI 和 MDI 应用程序、分割窗口、基于对话框的应用程序以及各种基于 COM 的类以支持 COM。

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

The short answer is, if you are not doing anything "fancy", use ATL. It's great for simple user interfaces with COM thrown in.

长话短说: MFC 构建于90年代早期,目的是尝试这种称为 C + + 的新语言,并将其应用于 Windows。当操作系统还没有这些特性的时候,它使得 Office 就像开发社区可以使用的特性一样。

[编辑修饰: 我没有在微软工作,所以我不知道 Office 是否曾经建立在 MFC 上,但我认为答案是否定的。回到 Win 3.1,Win 95天,Office UI 团队将发明新的控件,并将它们打包到库中,然后 Windows 和 MFC 团队将使用可再发布的 dls 将包装器和 API 合并到这些控件中。我猜这些团队之间有一些协作和代码共享。最终,这些控件将进入服务包或下一个 Windows 版本的基础操作系统。这种模式一直延续到 Office Ribbon,在 Office 发布之后,它作为一个附加组件被添加到 Windows 中,现在已经成为 Windows 操作系统的一部分。]

当时这个库还很原始,因为 C + + 语言和编译器都是新的,而且微软随着 Office 的发展逐渐建立起来。

Because of this history, MFC:

  1. 设计相当笨重。它最初是围绕 Windows API 的一个轻量级包装器,但后来逐渐发展起来。因为编译器和语言不支持它们,所以必须发明一些小的“特性”。没有模板,他们发明了一个字符串类,他们发明了列表类,他们设计了自己的运行时类型识别,等等。
  2. 封装了20年来 Office 和 Windows 的发展,其中包括一大堆你可能永远都不会用到的东西: 单文档和多文档界面、 dDE、 COM、 COM + 、 DCOM、文档链接和嵌入(如果你愿意,你可以在你的应用中嵌入文档)、 ActiveX 控件(网络对象嵌入的发展!)结构性文件存储、序列化和版本控制、自动化(从 VBA 早期开始) ,当然还有 MVC。最新版本支持 VisualStudio 样式的窗口对接和 Office 色带。基本上雷德蒙德20年内的所有技术都在里面。太大了!
  3. 有大量的小陷阱,错误,变通方案,假设,支持仍然存在的东西,你永远不会使用,他们造成的问题。您需要非常熟悉许多类的实现,以及它们是如何交互的,以便在一个规模不错的项目中使用它。在调试期间深入研究 MFC 源代码是很常见的。在某个指针上发现一个15年前的技术备忘录是空的,导致崩溃仍然会发生。假设初始化古代文档嵌入内容会以奇怪的方式影响您的应用程序。在 MFC 中没有抽象这种东西,您需要每天使用它的特性和内部结构,它不会隐藏任何东西。别让我提到班级魔法师。

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

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

编辑修饰: 在 ATL 创建的时候,微软的技术路线图主要集中在“文档管理”上。苹果正在桌面出版业务中扼杀他们。Office 的“文档链接和嵌入”是增强 Office 的“文档管理”功能的主要组成部分,从而在这一领域展开竞争。COM 是为应用集成而发明的核心技术,而文档嵌入 API 是基于 COM 的。MFC 很难在这个用例中使用。ATL 是一个很好的解决方案,使这种特殊的技术更容易为第三方实现 COM 和利用文档嵌入功能。]

这些小小的改进使 ATL 在一个简单的应用程序上非常容易处理,这个应用程序不需要像 MFC 那样的所有 Office 特性。一些简单的用户界面和一些办公室套装软件比较的东西。它体积小,速度快,编译时间有限,为您节省了大量的时间和麻烦。MFC 有一个庞大的类库,这些类可能很笨重,而且很难使用。

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

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

MFC 的巨大足迹使它们不可能转储,因此它仍然在缓慢发展。模板已经重新合并到库中,以及其他语言和 API 增强。(我没有听说过 WTL,直到我看到这个问题。:)

归根结底,使用哪一个只是一个偏好的问题。您需要的大多数特性都在基本 OS API 中,如果库中没有合适的包装器,您可以直接从任何一个库中调用这些特性。

多年使用 MFC 的经验告诉我,我现在每天都在使用它。当 ATL 首次在几个项目上发布时,我涉足了几年。在那些日子里,这是一种新鲜的空气,但从来没有真正去任何地方。然后网络出现了,我把它忘得一干二净。


编辑: 这个答案有着惊人的长久性。由于它总是出现在我的堆栈溢出页面中,我想我应该对原来的答案加一些修饰,我认为这是缺乏的。

ATL is a set of classes meant to simplify the implementation of COM objects.

您可以不使用 MFC 使用它。在我的工作中,我们使用 ATL 向计算代码公开 COM 接口。这里没有图形用户界面的参与,它是为了我们能够调用这个计算代码从例如。Excel VBA.

查看一些 COM 指南/教程,看看它的摘要。

MFC is just a set of GUI wrapper classes to the Win32 API. Look at some Win32 API tutorial to see what it abstracts.