Qual é a diferença fundamental entre MFC e ATL?

110

Supondo que eu os esteja usando apenas para programas GUI "normais" (sem COM, sem ActiveX, nada extravagante), qual é a diferença fundamental que verei entre ATL e MFC, para me ajudar a descobrir qual usar?


Eu fiz algumas pesquisas na web, mas no final das contas nenhuma das respostas realmente respondeu minha pergunta:

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

    • "ATL é uma maneira rápida e fácil de criar um componente COM em C ++ e manter uma pequena área ocupada. Use ATL para criar um controle se você não precisar de todas as funcionalidades internas que o MFC fornece automaticamente."

      Realmente não responde minha pergunta, porque:

      • Não estou trabalhando com COM.

      • Isso significa que o MFC não é rápido? Porque como?

    • "O MFC permite criar aplicativos completos, controles ActiveX e documentos ativos. Se você já criou um controle com o MFC, talvez queira continuar o desenvolvimento no MFC. Ao criar um novo controle, considere usar ATL se não precisar todas as funcionalidades internas do MFC. "

      Também não responde à minha pergunta, porque:

      • Eu nem mesmo sei o que é ActiveX em primeiro lugar.

      • Parece que a Microsoft está desencorajando o uso do MFC, mas não consigo descobrir por quê.

      • O que exatamente é a "funcionalidade interna" do MFC que o ATL não oferece?

    • Em geral, isso não responde à minha pergunta porque não explica as desvantagens e as razões por trás delas.

porque direta ou indiretamente, tudo parece estar vinculado à página anterior:

O que tenho observado atualmente (nos últimos dias, enquanto tento aprender ambos):

  • ATL é baseado em modelos ou polimorfismo de tempo de compilação.
    • Os métodos ATL tendem a ser não virtuais e tendem a retornar referências.
  • MFC é baseado em métodos virtuais ou polimorfismo de tempo de execução.
    • Métodos MFC tendem a ser virtuais e tendem a retornar ponteiros.

Mas não parece haver nenhuma diferença arquitetônica entre eles :

  • Ambos usam mapas de mensagens ( BEGIN_MSG_MAPvs. BEGIN_MESSAGE_MAP... grande coisa)
  • Ambos envolvem métodos Win32 em classes
  • Ambos parecem ter classes semelhantes CWndvs.CWindow

Mas então, se não há diferença real, exceto para o aspecto do tempo de compilação vs. tempo de execução, então por que ambos existem? Não deveria um deles ser suficiente?

O que estou perdendo aqui?

user541686
fonte
3
Posso estar errado, mas sei que o MFC requer uma DLL de tempo de execução um tanto robusta, enquanto acho que o ATL é compilado em um único exe. ATL é mais leve em geral. Além disso, confira WTL
Merlyn Morgan-Graham
@Merlyn: Certo, mas por que ele precisa de uma DLL de runtime robusta? Qual é a diferença fundamental que causa isso?
user541686
1
A mesma diferença entre herdar classes pré-compiladas vinculadas de uma DLL e herdar modelos vinculados por inclusão de código-fonte / instanciação de modelo. Os modelos são geralmente bibliotecas "apenas de cabeçalho". Minha resposta está incompleta, portanto, nos comentários :) MFC ainda existe devido à grande adoção e compatibilidade com versões anteriores. Caso contrário, a MS teria jogado fora quando criaram novos wrappers win32. Eles tendem a ter contratos de suporte longos em seu software (variando, mas até 10 anos). O suporte não é incompatível com a depreciação, embora.
Merlyn Morgan-Graham
@Merlyn: O que estou entendendo é que não devo usar o MFC? O que é essa "funcionalidade extra" que eles vivem mencionando? Eu preciso disso?
user541686
2
@Merlyn: Já ouviu falar de ATL.DLL? Já ouviu falar do termo "Usar MFC como biblioteca estática"?
Ajay

Respostas:

179

Acho que a resposta à sua pergunta é principalmente histórica, se você olhar para trás e ver como as duas bibliotecas se originaram e evoluíram ao longo do tempo.

A resposta curta é, se você não está fazendo nada "extravagante", use ATL. É ótimo para interfaces de usuário simples com COM incluído.

A longa resposta: o MFC foi criado no início dos anos 90 para testar essa nova linguagem chamada C ++ e aplicá-la ao Windows. Ele disponibilizou recursos semelhantes aos do Office para a comunidade de desenvolvimento quando o sistema operacional ainda não os tinha.

[Editar enfeite: eu não trabalhei na Microsoft, então não sei se o Office já foi construído no MFC, mas acho que a resposta é não. De volta ao Win 3.1, Win 95 dias, a equipe de IU do Office inventaria novos controles, empacotaria-os em bibliotecas e, em seguida, as equipes do Windows e MFC incorporariam wrappers e API a esses controles com dlls redistribuíveis. Eu acho que houve um pouco de colaboração e compartilhamento de código entre essas equipes. Eventualmente, esses controles chegariam ao sistema operacional de base em service packs ou na próxima versão do Windows. Esse padrão continuou com a Faixa de Opções do Office, que foi adicionada ao Windows como um componente complementar bem depois do lançamento do Office e agora faz parte do sistema operacional Windows.]

Naquela época, a biblioteca era bastante primitiva, tanto por causa da linguagem C ++ e do compilador serem novos, quanto pela Microsoft construí-la ao longo do tempo conforme o Office evoluía.

Por causa dessa história, MFC:

  1. Tem um design bastante desajeitado. Tudo começou como um envoltório leve em torno da API do Windows, mas cresceu. Há um monte de pequenos 'recursos' que tiveram que ser inventados porque o compilador e a linguagem simplesmente não os suportavam. Não havia modelos, eles inventaram uma classe de string, eles inventaram classes de lista, eles projetaram sua própria identificação de tipo de tempo de execução, etc.
  2. Encapsula 20 anos de evolução do Office e do Windows, que inclui um monte de coisas que você provavelmente nunca usará: interfaces de documentos únicos e múltiplos, DDE, COM, COM +, DCOM, vinculação e incorporação de documentos (para que você possa incorporar um documento do Word em seu aplicativo se você quiser), controles ActiveX (evolução da incorporação de objetos para a web!), Armazenamento de documentos estruturados, serialização e controle de versão, automação (desde os primeiros anos do VBA) e, claro, MVC. As versões mais recentes têm suporte para encaixe de janela no estilo Visual Studio e a faixa de opções do Office. Basicamente, toda tecnologia de Redmond em 20 anos está lá em algum lugar. É simplesmente ENORME!
  3. Tem uma tonelada de pequenas pegadinhas, bugs, soluções alternativas, suposições, suporte para coisas que ainda estão lá e que você nunca usará e que causam problemas. Você precisa estar intimamente familiarizado com a implementação de muitas classes e como elas interagem para usá-la em um projeto de tamanho decente. Explorar o código-fonte do MFC durante a depuração é comum. Ainda acontece encontrar uma nota técnica de 15 anos em algum ponteiro sendo nulo, causando um travamento. Suposições sobre a inicialização de material de incorporação de documentos antigos podem afetar seu aplicativo de maneiras estranhas. Não existe abstração no MFC, você precisa trabalhar com suas peculiaridades e detalhes internos diariamente, não esconde nada. E não me fale sobre o assistente de classe.

ATL foi inventado com a evolução da linguagem C ++ e os modelos chegaram. ATL foi uma demonstração de como usar modelos para evitar os problemas de tempo de execução da biblioteca MFC:

  1. Mapas de mensagens: como são baseados em modelos, os tipos são verificados e, se você bagunçar a função vinculada, ela não será compilada. No MFC, os mapas de mensagens são baseados em macro e vinculados ao tempo de execução. Isso pode causar bugs estranhos, mensagem direcionada para a janela errada, um travamento se você tiver uma função ou macro definida incorretamente, ou simplesmente não funcionar porque algo não está conectado corretamente. Muito mais difícil de depurar e mais fácil de quebrar sem perceber.
  2. COM / automação: semelhante aos mapas de mensagem, o COM era originalmente vinculado ao tempo de execução usando macros, exigindo muitos erros de tratamento e causando problemas estranhos. ATL o tornou baseado em modelo, com limite de tempo de compilação e muito, muito mais fácil de lidar.

[Editar enfeite: na época em que o ATL foi criado, o roteiro técnico da Microsoft estava focado principalmente em 'Gerenciamento de documentos'. A Apple os estava matando no mercado de editoração eletrônica. A 'vinculação e incorporação de documentos' do Office foi um componente principal para aprimorar os recursos de 'Gerenciamento de documentos' do Office para competir neste espaço. COM foi uma tecnologia central inventada para integração de aplicativos, e as APIs de incorporação de documentos foram baseadas em COM. O MFC era difícil de usar neste caso de uso. ATL foi uma boa solução para tornar esta tecnologia específica mais fácil para terceiros implementarem COM e utilizarem recursos de incorporação de documentos.]

Essas pequenas melhorias tornam o ATL extremamente mais fácil de lidar em um aplicativo simples que não precisa de todos os recursos do Office like do MFC. Algo com uma interface de usuário simples e alguma automação de escritório incluída. É pequeno, é rápido e tem limite de tempo de compilação economizando muito tempo e dor de cabeça. O MFC tem uma enorme biblioteca de classes que podem ser desajeitadas e difíceis de trabalhar.

Infelizmente, o ATL estagnou. Ele tinha wrappers para a API do Windows e suporte COM, mas nunca foi além disso. Quando a Web decolou, todas essas coisas foram meio que esquecidas como notícias antigas.

[Editar enfeite: a Microsoft percebeu que essa 'Coisa da Internet' seria grande. Seu roteiro técnico mudou drasticamente para se concentrar no Internet Explorer, Windows Server, IIS, ASP, SQL Server, COM / DCOM no Distributed Transaction Server. Portanto, a vinculação e incorporação de documentos não era mais uma prioridade alta.]

A grande pegada do MFC tornou impossível para eles fazerem o dump, então ele ainda evolui lentamente. Os modelos foram incorporados de volta à biblioteca, bem como outros aprimoramentos de linguagem e API. (Eu não tinha ouvido falar do WTL até ver esta pergunta. :)

No final das contas, qual deles usar é simplesmente uma questão de preferência. A maioria dos recursos de que você precisa está na API do sistema operacional base, que pode ser chamada diretamente de qualquer uma das bibliotecas, se não houver um wrapper adequado na biblioteca.

Apenas meus 2 centavos com base no uso do MFC por muitos anos, e agora o uso diariamente. Eu me interessei pelo ATL quando ele foi lançado pela primeira vez em alguns projetos por alguns anos. Era uma lufada de ar fresco naquela época, mas nunca foi realmente a lugar nenhum. E então a Web apareceu e eu esqueci completamente dela.


Edit: Esta resposta tem uma longevidade surpreendente. Como ele continua aparecendo em minha página de estouro de pilha, pensei em adicionar um pouco de enfeite à resposta original que achei que estava faltando.

Jay
fonte
39
1 Eu gostaria de poder +10 isso. Obrigado pela excelente descrição da história - é muito bem escrita e informativa! :)
user541686
3
Só queria mencionar ... Usei o MFC por alguns dias, depois mudei para ATL / WTL, que uso há algum tempo. E é incrível. Nunca mais vou olhar para o MFC de novo, provavelmente.
user541686
1
Portanto, a Microsoft cria novos programas usando os dois ou decidiu usar um em vez do outro?
The Muffin Man
1
Eu pensei que sabia a diferença ... mas nunca tinha visto uma explicação tão bonita e elaborada ... Humilha
Muito obrigado
1
A melhor resposta que já li sobre este tópico; você deve fazer um artigo com ele incluindo WTL
Pat de
20

Muitas pessoas que usaram os dois me disseram que sua experiência de programação foi menos dolorosa com ATL do que com MFC. Seu executável compilado também será muito menor com ATL.

Recomendo que você dê uma olhada no WTL , pois ele se baseia no ATL.

O que é essa "funcionalidade extra" que eles vivem mencionando? Eu preciso disso?

Se você definir seus requisitos, pode ser mais fácil responder se você puder evitar o uso do MFC. Infelizmente, "nada sofisticado" não é exclusivo o suficiente. Incluir quais recursos você pretende usar pode ser mais útil (quais controles, quais estruturas / tecnologias / bibliotecas existentes você deseja usar, etc).

Mas aqui está um artigo que descreve alguns recursos do MFC que não são diretamente suportados pelo WTL / ATL.

O MFC também evoluiu a ponto de oferecer suporte a muitos recursos desejáveis, como MAPI, suporte para os outros requisitos de logotipo do Windows, soquetes, documentos (se desejar e / ou usar esse padrão) e arquivos de documentos compostos. WTL tem sua cota de recursos interessantes, mas MFC é o campeão de recursos. Ambos os ambientes oferecem suporte a arquiteturas de janela principal em frame (janela de frame com janela de visualização separada), aplicativos SDI e MDI, janelas divididas, aplicativos baseados em diálogo e várias classes baseadas em COM para suporte COM.

Merlyn Morgan-Graham
fonte
3
A resposta de Jay tem essa batida. Deixando isso para o link do artigo que explica algumas das diferenças.
Merlyn Morgan-Graham
9

ATL é um conjunto de classes destinadas a simplificar a implementação de objetos COM.

Você pode usá-lo sem MFC. No meu trabalho, usamos ATL para expor interfaces COM ao código computacional. Não há GUI envolvida, cabe a nós sermos capazes de chamar este código computacional de, por exemplo. Excel VBA.

Veja algum guia / tutorial COM para ver o que ele resume.

MFC é apenas um conjunto de classes de wrapper GUI para a API Win32. Dê uma olhada em algum tutorial da API Win32 para ver o que ele abstrai.

Alexandre C.
fonte
ATL também pode ser usado sem nenhum COM envolvido. Muitas classes nele não têm relação com COM, o que fica ainda mais pronunciado quando se olha para WTL.
0xC0000022L
1
@ 0xC0000022L: Eu não conhecia CWindowImple amigos quando escrevi isso. Agora que tenho mais experiência com ATL, poderia tentar reescrever esta resposta. Em particular, ATL / WTL pode substituir virtualmente todo o MFC.
Alexandre C.