我认为你问题的答案主要是历史性的,如果你回顾一下这两个库是如何起源并随时间演变的。
简短的答案是,如果你没有进行任何“高级”的操作,请使用ATL。它非常适合带有COM的简单用户界面。
长答案:
MFC是在90年代初建立的,用于尝试这种名为C++的新语言,并将其应用于Windows。当操作系统还没有这些功能时,它使Office类似的功能可供开发社区使用。
[编辑装饰:我没有在微软工作,所以不知道Office是否曾经建立在MFC上,但我认为答案是否定的。在Win 3.1、Win 95时代,Office UI团队会发明新的控件,将它们打包成库,然后Windows和MFC团队会通过可重新分发的dll包装器和API将这些控件整合到一起。我想这些团队之间有一些协作和代码共享。最终,这些控件会在服务包或下一个Windows版本中成为基础操作系统的一部分。办公室缘带被添加到Windows作为插件组件,其后才成为Windows操作系统的一部分。]
那时,该库相当原始,既因为C++语言和编译器是新的,又因为Microsoft随着Office的演变而逐步建立了它。
由于这个历史,MFC:
- 设计相对臃肿。它最初只是Windows API的一个轻量级包装器,但逐渐壮大。由于编译器和语言本身不支持一些小的“功能”,所以必须发明一些东西。例如没有模板,他们发明了字符串类、列表类,设计了自己的运行时类型识别等。
- 封装了20年的Office和Windows演变,其中包括许多你可能永远不会使用的东西:单文档和多文档接口、DDE、COM、COM+、DCOM、文档链接和嵌入(这样你就可以将Word文档嵌入到你的应用程序中),ActiveX控件(Web对象嵌入的演变!)、结构化文档存储、序列化和版本控制、自动化(来自早期的VBA年代)以及MVC。最新版本支持Visual Studio风格的窗口停靠和Office功能区。基本上,20年里Redmond的所有技术都在其中。简直太庞大了!
- 有很多小问题、错误、解决方法、假设、支持那些你永远不会使用的东西,它们会引起问题。你需要非常熟悉许多类的实现方式以及它们之间的交互才能在一个相当大的项目中使用它。在调试过程中深入MFC源代码是很常见的。仍然会出现找到15年前某个指针为空导致崩溃的技术注释。对古老文档嵌入的初始化假设可能以奇怪的方式影响你的应用程序。在MFC中不存在抽象,你需要每天处理它的怪癖和内部机制,它不会隐藏任何东西。而且别让我再谈类向导了。
随着C++语言的发展和模板的引入,ATL被发明出来了。 ATL展示了如何使用模板避免MFC库的运行时问题:
- 消息映射:由于它们是基于模板的,类型是经过检查的,如果绑定函数出错,它就不会构建。在MFC中,消息映射是基于宏的,并且是运行时绑定的。这可能会导致奇怪的错误,例如将消息路由到错误的窗口、如果你定义的函数或宏不正确则崩溃,或者只是因为某些东西没有正确连接而无法工作。更难调试,更容易不注意就破坏了。
- COM/自动化:与消息映射类似,最初使用宏进行运行时绑定,需要大量的错误处理,会导致奇怪的问题。ATL使其基于模板、编译时绑定,并且更加容易处理。
在ATL创建时,微软的技术路线主要集中在“文档管理”上。苹果在桌面出版业务方面表现出色,而Office的“文档链接和嵌入”是提高Office“文档管理”功能以在该领域竞争的主要组成部分。COM是为应用程序集成发明的核心技术,文档嵌入API基于COM。MFC对于此用例来说很难使用。ATL是使第三方实现COM并利用文档嵌入功能更容易的好解决方案。
这些小改进使ATL在简单应用程序上处理起来非常容易,这些应用程序不需要MFC的所有Office样式功能。一些简单的UI和一些Office自动化。它很小,很快,编译时间绑定可以节省您很多时间和头痛。MFC有一个庞大的类库,可能会很笨拙且难以使用。
不幸的是,ATL停滞了。它具有Windows API和COM支持的包装器,然后就没有超越这一点。当Web开始流行时,所有这些东西都被遗忘了。
微软意识到这个“互联网事物”将会变得很大,他们的技术路线发生了巨大变化,专注于Internet Explorer,Windows Server,IIS,ASP,SQL Server,COM / DCOM在分布式事务服务器中。因此,文档链接和嵌入不再是高优先级。
MFC的巨大占用空间使它们无法丢弃,因此它仍然缓慢发展。模板已经并入库中,以及其他语言和API增强功能。(在看到这个问题之前,我从未听说过WTL。:)
最终,使用哪个库只是个人偏好问题。您所需的大多数功能都在基本操作系统API中,如果库中没有适当的包装器,则可以直接从任一库中调用。
根据我多年使用MFC的经验(我现在每天都在使用),我认为这只是我的2美分。ATL发布时,我曾在几个项目中涉足过ATL,并且在那些日子里它是一股清新的空气,但从来没有真正走得很远。然后Web出现了,我忘记了所有这些。
AtlModuleInit
。 - Ajay