You are on page 1of 18

Começando a programar em C

++

Todas as semanas eu recebo a mesma pergunta pelo formulário de contato: "Quero começar a programar em C++ mas não sei como". Eu não fico aborrecido com isso, pelo contrário, fico bastante feliz. É muito bom saber que uma quantidade considerável de pessoas quer evoluir e passar para o lado poderoso da força. :-) Eu pretendo montar, com vários posts, algo que possa ser agrupado em um FAQ para ajudar essas pessoas a se converterem. Quero que esse movimento se transforme numa conversão em massa dos programadores para C++, mostrando a luz às pessoas que estão limitadas dentro de uma vida onde não se pode gerenciar sua própria memória. E assim, mudar meu país para melhor! (Se você costuma ler o que eu escrevo já sabe que não pode me levar muito a sério. Mas, como diz o Alfred, o mais fácil é fazer como a Globo: explique tudo detalhadamente e não deixe nada nas entrelinhas, alguém pode não entender. Então, lá vai: Isso foi uma brincadeira.) Quero me converter para o lado poderoso da força, mas essa história de C e C++ me confunde. O que é o que? A linguagem C foi criada no início dos anos 70 para ser usada na programação do UNIX. Cansados de fazer tudo em Assembly, os programadores resolveram criar uma linguagem que fosse estruturada e que permitisse programação low-level ao mesmo tempo. Assim nasceu a linguagem C.
/* Isso está em C */ #include <stdio.h> int main() { int a = 15; int b = 20; char buffer[128]; /* uma string é um array zero */ strcpy(buffer, "A variável [a] é "); if(a > b) strcat(buffer, "maior"); else strcat(buffer, "igual ou menor "); strcat(buffer, " que a variável [b] \r\n"); printf(buffer); return 0; }

(ou vetor) de bytes terminado por ASCII

O C++ é uma evolução da linguagem C, e foi criada por Bjarne Stroustrup. Nessa evolução foi adicionado à linguagem C o conceito de orientação à objetos, que virou moda naquela época (começo dos anos 80) e é muito usado hoje em dia. Além disso, o próprio C++ foi evoluindo no decorrer da década de 80 e 90, com a adição de recursos como templates e a STL (que veremos depois). O C++ tem tudo que a linguagem C tem (99,8% de compatibilidade) e mais toda a evolução. Todo compilador C++ que eu conheço compila código C sem problemas.
// // Isso está em C++ // #include <iostream>

Afinal. // string é um objeto buffer = "A variável [a] é ". já que ele é também um código C++ válido. com suporte à programação orientada a objetos. etc). os profissionais de C++ são mais valorizados. if(a > b) buffer += "maior". Por serem mais simples. tirando muitos recursos que. else buffer += "igual ou menor ". leia o The C++ Programming Languagedo Stroustrup. switch. templates. Não se esqueça que praticamente todos os softwares comerciais que existem são feitos em C ou C++ (Windows. como gerenciamento automático de memória. Foi feita uma simplificação e um nivelamento por baixo (ok. As estruturas básicas de controle (if. } O exemplo feito em C. Oracle. não e não.NET e todas as VMs Java.using namespace std. Se algum dia você precisar fazer algo em C. Como as pessoas estão indo para as linguagens mais fáceis. Photoshop. quando se precisa de algo 10 vezes mais rápido. qualquer material pode te ajudar. o próprio .. Office. Mesmo assim. buffer += " que a variável [b] \r\n". etc. Depois que você já estiver com alguma prática em C++.. Todo mundo diz que C++ é muito complicado. bibliotecas. controlam regras de negócios e fazem entradas de dados. sem passar pelo C.NET e Java. int b = 20. int main() { int a = 15. CorelDRAW. Esqueça o que os outros dizem e estude aquilo que você tem vontade. Eu já ouvi falar que o Java e o C# são versões melhoradas do C++. é só estudar as limitações do C em relação ao C++. Eu recomendo que você aprenda C++ direto. Preciso aprender C antes de aprender C++? Não. independência relativa de arquitetura e mais facilidade para leitura dos metadados (enumerar as . Se você é iniciante. while. Isso é verdade? Você é um homem ou um rato? C++ requer mais estudo por ser uma linguagem completa e poderosa. apesar de poderosos. será que vale a pena estudar C++? Vale. string buffer. que é o guia definitivo sobre o assunto. é compilado sem problemas por qualquer compilador C++.. return 0. mas não é nada que um ser humano normal não consiga aprender. A moda agora é . O Java e o C# são baseadas na linguagem C++. causavam confusão ou dificuldade. As duas runtimes (JVM e . Linux. SQL Server.. Isso é verdade? Se você acha que uma versão mais limitada de alguma coisa é uma melhoria. etc. alguém precisa fazer. etc. cout << buffer. o que muda é que a linguagem C não suporta todos os recursos do C++. Você pode me recomendar algum livro para aprender C++? O único livro para iniciantes que eu conheço e achei bom é o Beginning Visual C++ Programming. Tem gente que acha que usar o Microsoft Word é complicado. como os que manipulam bancos de dados. e que eu recomendo até para os programdores C++ experientes. essas duas linguagens são indicadas para aplicativos tecnicamente mais simples.NET) têm algumas vantagens sobre o C++. pelo meio) para atender às necessidades mais comuns. desde um livro de C até um tutorial de Internet.) são as mesmas. já que hoje em dia o C++ é mais usado. Visual Studio. Eu prentendo recomendar mais livros a medida que o FAQ for avançando. em C++ você pode usar as bibliotecas do C sem problemas.

você chama uma função de 8 parâmetros mais só passa 2. essa complicação tem motivo: como a Win32 API é o acesso mais baixo nível que se pode ter ao sistema (considerando user-mode). não é possível fazer overload das funções com versões mais simples para os usos mais simples. por exemplo). existem alguns que você é obrigado a preencher. NULL.h> void main() { STARTUPINFO si. Além dos parâmetros que você passa como NULL. serem mais lentas (isso pode melhorar com o tempo) e terem limitações técnicas que as impedem de desenvolver certos tipos de software (como device drivers). Além disso. sizeof(p)). Mas têm a desvantagem de consumirem bem mais memória. mas que devem ser cobertas pela API.) // ZeroMemory(&si. vou falar hoje sobre Win32. Programação Win32 em C/C++ Continuando o meu projeto de projeto de FAQ C++. // // Abrindo o Bloco de Notas // if( !CreateProcess( NULL. &si. Esse é um erro comum de iniciantes (eu apanhei muito. e o LPPROCESS_INFORMATION lpProcessInformation. Vou exemplificar isso usando a famosa função CreateProcess como exemplo. isso é verdade? Isso tem lá seu fundo de verdade. mas em 99% dos casos você só usa o LPTSTR lpCommandLine. // linha de comando para o executável NULL. . muitas vezes. Ouvi falar que Win32 é complicado. si. Por isso. Esse membro deve ser preenchido com o sizeof() // da estrutura ANTES de chamar a função. ZeroMemory(&p.NET Framework e em bibliotecas C++. // Sem módulo "C:WINDOWS \\notepad. NULL. alguns assuntos são extremamente complicados.classes de um DLL. NULL. PROCESS_INFORMATION p. sizeof(si)). Se você não fizer isso a função // retornará um erro. // // dica: muitas estruturas no Windows têm uma variável membro chamada // cb ou cbSize. ela deve possibilitar que você a use para fazer tudo que é possível no Windows.cb = sizeof(si).h> #include <stdio. O que é Win32 e para que serve? Já expliquei isso em outro post. Esses outros 6 parâmetros são usados em situações não muito comuns. como é feito muitas vezes nas classes do . como essa API é C (e não C++). // Ponteiro para STARTUPINFO &p ) // Ponteiro para PROCESS_INFORMATION ) { printf( "Erro em CreateProcess: 0x%X". FALSE. como o LPSTARTUPINFO lpStartupInfo. De qualquer forma..exe". os mais usuais nem tanto. // O processo criado não herdará os handles 0. Veja um exemplo adaptado da MSDN: #include <windows. GetLastError() ).. Essa função pede 10 parâmetros.

Isso já é suficiente para você ser um programador Win32. Ele é hardcore do meio pra frente (eu não tive paciência para ler a parte de toolbar). bibliotecas que encapsulam a Win32 API para facilitar o seu uso (o . 100 linhas para fazer uma janelinha branca e feia? Existe algo mais fácil? Existe. outro clássico. que geralmente é a complexibilidade. Pronto. e é essencial para que você entenda como a GDI do Windows funciona.NET foi lançado em 2001 e a maioria dos aplicativos comerciais ainda são feitos em C e C++. Existem outras bibliotecas. não é. CloseHandle(p. Não se esqueça que o . A API Win32 é exportada como funções C. se você não tiver paciência leia até o capítulo 11 (página 566). // CloseHandle(p.. A GDI é complexa pelo mesmo motivo que eu já expliquei. Explique para os seus amigos que TODOS os aplicativos para Windows hoje são feitos em Win32. A biblioteca provida pelo Microsoft Visual C++ é a MFC (Microsoft Foundation Classes). Hoje em dia. } O que eu preciso saber antes de estudar Win32? Você precisa ter prática em programação C/C++. Ele já está na quinta edição. já que ela é o Windows.NET sobre a GDI). como eu já disse. mas é usada a partir do C++ sem problemas. Para resolver isso. Além disso. vale muito mais a pena comprar um livro e ler do que ficar procurando na Internet.NET.NET Framework é uma delas). ela é muito flexível e é um dos motivos do sucesso do Windows. É verdade? . Você anda convivendo demais com Piranhas. entendendo como funciona o Win32 e a GDI MFC não será um problema. como a VCL/CLX do Delphi e do C++ Builder e o WTL da Microsoft (que é a que eu mais gosto). O livro do Petzold cobre extensivamente a GDI (gráficos). Leia algo sobre MFC depois de ler o Petzold.hThread)..NET do que de Win32. por diversas empresas.. No Windows Longhorn (previsto para 2006/2007) ALGUMAS NOVAS APIs serão disponibilidas como classes . e. Nossa. a IDE do Visual C++ possui diversos wizards que geram classes e código e facilitam muito a programação. que encapsula uma boa parte da Win32 API em objetos C++.return.. Só 3 livros :-) Meus amigos dizem que a API Win32 está ultrapassada e não vale a pena estudar isso. Quais livros de Win32 você recomenda? Primeiramente: eu indico que você leia os livros que vou indicar :-) Eu acho muito mais difícil estudar Win32 com tutoriais e lendo a MSDN. Não acho que exista muito matérial para iniciantes na Internet. Poder e flexibilidade sempre têm um custo. considerado a Bíblia definitiva sobre o assunto. Isso já será suficiente para entender como as coisas funcionam no Windows. mas isso deve levar no mínimo uns 5 anos. usando a API Win32 (que por enquanto é a API do Windows) Meus amigos disseram que existe mais material de estudos e livros falando de . e será muito útil MESMO QUE VOCÊ USE Window s Forms (afinal. O Windows vai ficar cada vez mais . O primeiro livro que você deve ler é o Programming Windows do Charles Petzold. Pode ser qualquer livro.NET. WinForms nada mais é do que uma camada . É verdade? Não. Usar dialogs (forms) em MFC é quase tão fácil quanto VB6.NET. Win32 é complicado mesmo. E o resto? Depois de ler o Petzold e algo sobre MFC. quase ninguém mais usa API diretamente ("à la Petzold" como é conhecido). precisamos fechá -los.hProcess). foram criadas. } // // O CreateProcess preencheu as estruturas e colocou handles nelas // como não vamos usar os handles. leia o Advanced Windows do Jeffrey Richter.

NET virar a plataforma oficial do Windows. etc. Esse conjunto de classes acabou se transformando no que conhecemos como WTL. Além disso . A API Win32 existe desde de 1993. O fator multiplataforma do . tem seus problemas como qualquer API/Framework/Arquitetura. Como eu já disse. o kernel (C). Compilando seu executável em Release.NET. pela Adobe (Photoshop).NET é tão ruim assim. hoje tudo é C++ e Win32 e vai levar anos (talvez mais de uma década) para que o . garantindo que a filosofia ATL/WTL não suma a medida que milhares de classes sejam adicionadas à biblioteca. KDE. Há algum tempo atrás o projeto WTL foi colocado no SourceForge para que a comunidade C++/Win32 pudesse ajudar o Nenad nas correções e sugestões. com destaque para as classes para Wizards. Se o . Adobe/Macromedia e outros vão refazer todos os aplicativos em C#? Além disso. controles Win32 (botões. Só não fique sentado esperando o .NET é ruim. um programador da Microsoft chamado Nenad Stefanovic criou diversas outras classes para encapsular o restante da GDI. a WTL não causa nenhum overhead em relação a programas feito em Win32 puro. Thunderbird.também pelo fato de usar templates . em Linux quase tudo é C e C++.NET ainda é incerto.NET.NET pelo Win32. seu executável fica completamente independente. Mesmo assim. Eu já escrevi um artigo sobre perspectivas para o NET a quase 1 ano atrás. então eu devo abandoná-lo e fazer tudo em C++? Primeiro: Eu nunca disse que o . Por ser uma extensão da ATL. etc).NET resolve todos os problemas. As duas arquiteturas são importantes. a maioria das funcões acabam "sumindo" durante a compilação. Nada resolve todos os problemas. não é necessário usar uma LIB ou DLL.o tamanho do executável fica muito pequeno. você vai perder vários anos de mercado e da sua vida. Essas classes da ATL foram criadas inicialmente para ajudar na confecção de controles ActiveX e seus Property Pages. não troque o . . A WTL é uma extensão da ATL. Além disso. (C++). etc). e acho que ela continua a mesma. sem classes. Na realidade poucas classes foram adicionadas à WTL depois disso. C++ ainda é a coisa mais portável que existe (em termos de código fonte). no Code Project tem muito mais coisa útil em MFC do que em . e esse é o motivo dele ter sido usado pela Mozilla Foundation (Firefox. barras de progresso. dialogs. Você acha mesmo que a Microsoft. etc. Explicando a sopa de letrinhas da programação C/C++ para Windows: WTL Outros posts dessa mesma série: ATL COM MFC Win32 WTL (Windows Template Library) é uma biblioteca de templates C++ que encapsula a parte da Win32 API que lida com interface gráfica (GDI).Não é verdade que existem mais livros sobre . Na verdade eu acho ele muito bom para resolver os problemas que ele se propõe. Você me deixou em dúvida. a WTL segue a mesma filosofia: classes template enxutas (inspiradas pela STL).NET seja realmente a plataforma de programação do Windows. Procure "MFC" na Amazon. pois são colocadas inline. sendo possível criar executáveis de 70 kb ou menos sem dependência de DLLs ou runtimes. wizards. etc. e uma procura por livros na Amazon retornará vários livros. Como o código da WTL é muito enxuto. liberdade de uso das classes fora de um framework (ao contrário da MFC) e código simples e rápido. o Nenad ainda é o coordenador e responsável pelo projeto. que já contém algumas classes básicas para manipulação de janelas. O grande problema é que no Brasil as pessoas acreditam no pessoal de marketing da Microsoft sem pensar se isso resolve o problema. aprenda os dois e use o que for melhor para cada caso. E se isso conta. Sobre esse suporte básico da ATL. e depende de implementações de terceiros (como o Mono). Mas. depois procure "Windows Forms" e veja a diferença. Ela contém classes para criar janelas. e acham que . Gnome (C). Por ser todo baseado em templates.

Mesmo assim. NULL. BN_CLICKED. mas a biblioteca oficial da Microsoft para C++ ainda é a MFC. Apesar dessa biblioteca ter nascido dentro da Microsoft. WPARAM.h> <atlapp. OnButtonClick) CHAIN_MSG_MAP(CFrameWindowImpl<CMainFrame>) END_MSG_MAP() LRESULT OnCreate(UINT.h> <atldlgs.h> <atlctrls.h> extern CAppModule _Module. Apesar de todas as vantagens que eu citei. vamos a um programa simples feito em WTL: #define #define #define #define #define #include #include #include #include WINVER 0x0400 _WIN32_WINNT 0x0400 _WIN32_IE 0x0400 UNICODE _UNICODE <atlbase. existem algumas desvantagens.h> <atlstr. suporte que nunca foi dado à WTL. LPARAM.h> <atlctrlw.h> CAppModule _Module. Como um trecho de código vale mais do que 20 palavras.pelo próprio fato de ser uma biblioteca simples e enxuta. // // faz a janela ficar com o fundo cinza de dialog // (ao invés de branco padrão) // DECLARE_FRAME_WND_CLASS_EX(NULL. Outro problema da WTL sempre foi a falta de suporte da IDE para ela. CString (que a partir do Visual C++ 7.Muitas classes da WTL reproduzem funcionalidades disponíveis na MFC. #include #include #include #include #include <atlwin. usando mapas de mensagens.h> <atlframe. Mesmo assim existe um comunidade grande voltada para a WTL. como as classes CRect. não deixa de ser um produto não-oficial e que passa longe do controle de qualidade da Microsoft. A MFC provê diversos wizard e funcionalidades na IDE para assinatura de eventos e criação de classes. COLOR_BTNFACE) BEGIN_MSG_MAP(CMainFrame) MESSAGE_HANDLER(WM_CREATE.h> <atlmisc. 0. ela nunca ofereceu suporte para a WTL. BOOL& ) { SetWindowText(L "WTL Rules!" ). . WTL::CEdit m_edtTest.0 faz parte da ATL e não da MFC) e muitas outras. class CMainFrame : public CFrameWindowImpl<CMainFrame> { public: WTL::CButton m_btnTest. Ela chegou a ser disponibilizada junto com o Platform SDK e o download ainda pode ser feito diretamente nos servidores da Microsoft. Não é difícil para um programador MFC usar WTL. Esse problema foi resolvido por uma santa alma que disponibilizou no CodeProject o WTLHelper. a adaptação é fácil. e sempre que eu tive problemas uma pergunta ou uma busca na lista de discussão foi suficiente . O suporte a janelas também é bem parecido com a MFC. OnCreate) COMMAND_HANDLER(1. que chega a ser melhor do que o suporte do Visual Studio para a MFC (ClassWizard ou suporte do Visual Studio 7+).

200. 1). return 0. WS_CAPTION | WS_SYSMENU | WS_THICKFRAME). HINSTANCE.SetFocus(). NULL. MessageBox(str).RemoveMessageLoop(). return nRet. } int WINAPI WinMain(HINSTANCE hInstance . m_edtTest. HWND. m_btnTest. existe um objeto s eparado que controla o message loop // vamos adicioná -lo ao _Module. ATL e Common Controls // ::CoInitialize(NULL).GetWindowText(str)..Run().10. m_edtTest. 2).UpdateWindow().80).32). WS_EX_CLIENTEDGE .GetWindowTextLength()). wndMain.ShowWindow(SW_SHOW). CRect(100.Creat eEx(NULL. wndMain.220).45. BOOL&) { ATL::CString str. } }.SetSel(0. // // no WTL. WORD.200.// // cria um botão e um edit // m_edtTest. LPSTR. . } LRESULT OnButtonClick(WORD. // // agora é só criar a janela e rodar o message loop // wndMain.SetFont((HFONT)GetStockObject(DEFAULT_GUI_FONT)).SetFont((HFONT)GetStockObject(DEFAULT_GUI_FONT)).SetWindowText(L "digite algo aqu i").Create(m_hWnd.320. BS_PUSHBUTTON | WS_VISIBLE | WS_CHILDWINDOW. m_edtTest. CRect(120. m_btnTest. // // usa o fonte padrão de dialog // (tem que fazer isso porque criamos um janela. CRect(10. não um dialog) // m_edtTest. return 0. int Run() { CMessageLoop theLoop. NULL. int nRet = theLoop.100. que é o objeto global do ATL que // controla toda a aplicação // _Module. int) { // // primeiro inicializamos o COM. CMainFrame wndMain.Create(m_hWnd. m_edtTest. m_edtTest.AddMessageLoop(&theLoop). NULL. _Module.SetWindowText(L "Botão"). m_btnTest. ES_LEFT | WS_VISIBLE | WS_CHILDWINDOW.

comunicação HTTP e SMTP.794 palavras. _Module. MMC e vários outros (ao contrário da MFC. Windows Movie Maker. } rodar Para compilar esse trecho de código é só instalar e configurar a WTL. É usada pela Microsoft internamente em seus produtos. Como um trecho de código vale muito mais do que 186. criptografia. como o Windows Explorer. acesso à arquivos. hInstance). o que torna o trabalho chato e repetitivo. public: CTest() { m_ref = 0. implementada em camadas e que tem um overhead muito pequeno. Além disso. Além de suportar a implementação de objetos COM. é sempre a mesma: controle de referência e solicitação das interfaces suportadas. // // Objeto que implementa a class ITest // class CTest : public ITest { DWORD m_ref. Muitas interfaces que precisam ser implementadas contém muitas funções cujo código de implementação é o mesmo para todos os componentes. veja como é implementado um objeto COM e seu Class Factory em C++ puro: // // interface do nosso objeto COM // __interface __declspec (uuid("977BF132-B6B6-4d70-88BD-C427A2724B48" )) ITest : IUnknown { HRESULT WINAPI Method1(BSTR str. A implementação da interface IUnknown. como classes para acesso ao registro. ULONG ul). ACLs. O desenvolvimento COM em C++. é trabalhoso. }.Term().Active Template Library . quando você instala o WTL você terá um novo Wizard no Visual Studio para criar um "ATL/WTL Application".112. já que o VB até a versão 6 é todo baseado em COM.é uma biblioteca de templates C++ criada pela Microsoft para simplificar a programação de objetos COM/OLE/ActiveX em C++. BASE64. . // // e agora colocamos o programa para // int nRet = Run(). apesar de não ser muito complicado. por ser baseada em templates. listas e hashmaps. por exemplo. etc. a ATL é uma biblioteca com diversas classes e templates que facilitam muito a programação Windows. return nRet. ::CoUninitialize(). criar um programa "Win32 Application" e substituir o código gerado pelo Wizard por esse. Hoje em dia ela é distribuída junto com todas as versões do Visual C++. que é pouco usada dentro da Microsoft). Ela foi criada inicialmente pela equipe do Visual Basic para simplificar o desenvolvimento interno.Init(NULL. AtlInitCommonControls(ICC_COOL_CLASSES | ICC_BAR_CLASSES). É uma biblioteca pouco intrusiva._Module. Explicando a sopa de letrinhas da programação C/C++ para Windows: ATL Outros posts dessa mesma série: Win32 COM MFC ATL .

__uuidof(ITest))) { AddRef(). return S_OK. ULONG ul) { MessageBoxW(NULL. return S_OK. public: CTestClassFactory() { m_ref = 0. a runtime do Microsoft COM // chama a função GetClassObject exportada pela DLL do objeto.} // // implementação de IUnknown // STDMETHOD(QueryInterface)(REFIID riid. } else if(InlineIsEqualGUID(riid. *ppvObject = static_cast <ITest*>(this). . return S_OK. } return E_NOINTERFACE. L "". str. } STDMETHOD_(ULONG. MB_ICONEXCLAMATION). vamos criar esse helper // static HRESULT CreateClassFactory(REFIID riid.AddRef)() { return ++m_ref. } STDMETHOD_(ULONG. *ppvObject = static_cast <IUnknown*>( this). void **ppvObject) { if(InlineIsEqualUnknown(riid)) { AddRef().Release)() { DWORD ref = --m_ref. // como vamos fazer tudo na mão agora. // // Class Factory para o nosso obejto // class CTestClassFactory : public IClassFactory { DWORD m_ref. return ref. if(ref == 0) delete this. } // // implementação de ITest // STDMETHOD(Method1)(BSTR str. } }. void **ppv) { HRESULT hr. } // // quando o objeto é registrado.

} p->AddRef(). hr = pUnk ->QueryInterface(riid... ppvObject). return hr. return S_OK. try { // // pelo padrão C++. try { p = new CTestClassFactory(). pUnk->Release(). ppv). } // // implementação do IClassFactory // STDMETHOD(CreateInstance)(IUnknown *pUnkOuter.) { return E_OUTOFMEMORY.. } catch(. void **ppvObject) . se o new falha uma exceção é disparada // pUnk = new CTest(). } pUnk->AddRef(). p->Release( ).IUnknown* p. hr = p->QueryInterface(riid.. return hr.) { return E_OUTOFMEMORY. *ppvObject = this. if(pUnkOuter) return CLASS_E_NOAGGREGATION. void **ppvObject) { if(InlineIsEqualUnknown(riid)) { AddRef(). IUnknown* pUnk. } // // implementação de IUnknown // STDMETHOD(QueryInterface )(REFIID riid. } STDMETHOD(LockServer)(BOOL fLock) { return S_OK. } catch(. REFIID riid. { HRESULT hr.

if(ref == 0) delete this. } return E_NOINTERFACE. // // solicitando gentilmente para que ele crie um objeto daquele tipo // hr = pClassFactory ->CreateInstance(NULL. hr = pTest ->Method1(bstr. SysFreeString(bstr). // // E no sétimo dia Deus disse: "int main" // int main() { HRESULT hr. if(FAILED(hr)) { pClassFactory ->Release(). 20). if(FAILED(hr)) { pClassFactory ->Release(). return S_OK. // // criando o class factory // hr = CTestClassFact ory::CreateClassFactory(IID_IClassFactory. } STDMETHOD_(ULONG. (void**)&pClassFactory).AddRef)() { return ++m_ref. __uuidof(ITest).Release)() { DWORD ref = --m_ref. *ppvObject = static_cast <IClassFactory*>( this). if(FAILED(hr)) return hr. } }. } STDMETHOD_(ULONG. BSTR bstr. IID_IClassFactory)) { AddRef(). .} else if(InlineIsEqualGUID(riid. ITest* pTest. IClassFactory* pClassFactory. ( void**)&pTest). } // // usando o objeto // bstr = SysAllocString(L "Uma string bem legal" ). return hr. return ref.

hr = CTest1::CreateInstance(NULL. o mesmo das APIs do Windows. str. // // "olhe mamãe. CComPtr<ITest1> pTest. &CLSID_Test1>. O resto é tudo suporte ao contador de referências que todo objeto COM deve ter. &pTest). if(FAILED(hr)) return hr. L "". public ITest1 { public: DECLARE_REGISTRY_RESOURCEID(IDR_TEST1) BEGIN_COM_MAP(CTest1) COM_INTERFACE_ENTRY(ITest1) END_COM_MAP() public: STDMETHOD(Method1)(BSTR p1. return S_OK. MB_ICONEXCLAMATION).pTest->Release(). int main() { HRESULT hr. return S_OK. return hr. public CComCoClass<CTest1. 150). Com ATL. } // // liberar as interfaces // pClassFactory ->Release(). if(FAILED(hr)) return hr. eu sei coletar meu próprio lixo" // return S_OK. } }. } Lembre-se. . hr = pTest ->Method1(CComBSTR(L "Uma string muuuuito mais legal" ). DWORD p2) { MessageBoxW(NULL. a única coisa realmente útil para nós nesse código é a implementação de ITest::Method1. pTest->Release(). nossa implementação seria assim: class ATL_NO_VTABLE CTest1 : public CComObjectRootEx<CComSingleThreadModel>. } Explicação: STDMETHOD nada mais é do que uma macro que coloca o retorno da função com HRESULT (padrão de retorno de erros COM) e coloca o calling convention como __stdcall.

que veremos mais a frente. JScript. O COM serve de base para diversas outras tecnologias criadas pela Microsoft. E com a elegância e leveza que só o ATL tem :-) Explicando a sopa de letrinhas da programação C/C++ para Windows: COM Outros posts dessa mesma série: Win32 ATL MFC COM . . }. além das premissas que eu já enumerei. toda a comunicação entre eles para que isso seja possível é feita usado OLE.dll). etc. VBScript.NET (C#. Para ser um COM. ela é usada em praticamente todas as partes do Windows e em quase todos os produtos da Microsoft. Os pilares básicos desse tecnologia são o acesso aos objetos a partir de interfaces. As tecnologias baseadas em COM são geralmente nada mais são do que uma lista de interfaces COM que determinam a comunicação entre os diversos componentes (de um modo geral. Visual Basic 4/5/6. ocorre o inverso. VB.Salvamos algumas dezenas de linhas de código usando ATL. C++. quando o usuário salva um documento Microsoft Word que contém um gráfico do CorelDRAW!. um objeto precisa implementar IUnknown e mais as interfaces específicas da tecnologia ActiveX. Nesse exemplo específico. é necessário registrar o objeto e o objeto que sabe criá-lo (objeto que implementa a interface IClassFactory). ULONG AddRef().sigla para Component Object Model . Veja algumas tecnologias que usam COM como base: y y y ActiveX: Usada para criar controles (ActiveX control) que tem interação com o usuário. um objeto só precisa implementar a interface IUnknown. a quantidade de código boilerplate que deixaríamos de escrever seria da ordem de centenas de linhas. Voltando ao nosso exemplo anterior. Quando o documento é carregado. Perl e outras. Se estivessemos fazendo um servidor OLE. além de toda a implementação para que o nosso objeto seja registrado e usado por qualquer cliente COM. todas as linguagens . o Microsoft Word chama um objeto COM/OLE do CorelDRAW! solicitando que ele desenhe o objeto para que o Word possa exibí-lo. que salva o seu desenho dentro do arquivo DOC do Word. permite que um arquivo possa guardar informações de vários programas. Python. Delphi. Seu uso é muito comum no Visual Basic 6 e anteriores. uma interface padrão (IUnknown) para controle de referência e acesso às outras interfaces (da qual todas as interfaces criadas devem herdar). ULONG Release(). Entre as linguagem compatíveis com COM estão: C. Structured Storage: Parte do OLE. Para um objeto ser chamado de objeto COM. Sendo uma das tecnologias mais importantes desenvolvidas pela Microsoft.O próprio Internet Explorer nada mais é do que um programa que hospeda o controle ActiveX de renderização de HTML da Microsoft (mshtml. e o padrão binário da vtable (tabela com os ponteiros para as funções da interface) para que os objetos feitos em diversas linguagens possam se comunicar entre si. isso que dizer que o objeto deve herdar de IUnknown e implementar seu três métodos: interface IUnknown { HRESULT QueryInterface(REFIID riid.[ out]void **ppvObject). Para ser um controle ActiveX (ActiveX é uma das tecnologias baseadas em COM). etc). a nossa é só single) e um Class Factory. o Word faz uma chamada para um objeto COM/OLE do CorelDRAW!. OLE: Object Linking and Embedding é a tecnologia de troca de dados entre aplicativos que sucedeu o DDE. já que ele tem uma implementação para IUnknown (single threaded e multi threaded. Quando você copia um desenho no CorelDRAW! e cola no Microsoft Word. ele só precisa seguir essas premissas.NET. Delphi. No seu uso mais comum. seja VB6. Quando a implementação é em C++. não necessariamente componentes COM).é um padrão binário de componentes que foi criado para facilitar o uso de objetos entre as diversas linguagens de programação. PHP. .

Já mostrei antes um exemplo de como mudar a imagem de fundo do desktop usando o objeto COM do ActiveDesktop. vamos à ele: #include <afxwin. Windows Shell: A API para usar os recursos do Windows Shell (basicamente Windows Explorer) é exportada como objetos COM. Scripting. existem várias outras. Internet Explorer: Todas as barras de ferramentas personalizadas do Internet Explorer (como as feitas pelo Yahoo! e Google) são objetos COM. Excel. use o CTRL+H para descobrir o que é um Pane). Tudo que você vê aí é implementado em COM. Hoje em dia é possível fazer em . As extensões para aplicativos feitas em VBA nada mais são do que programas VB(A) que usam esses objetos Automation para controlá-los. etc. digite "compmgmt. DirectX: O DirectX é 100% implementado como objetos COM. seguindo certos requisitos.NET o que se fazia com o VBA. Office. SQL Server. Ela não foi feita para ser incluída em um projeto só para usar algumas classes. Visual Studio. ASP. mas os objetos . vá em "Start Menu" >> "Run" ("Menu Iniciar" >> "Executar" para alguns). etc.NET nada mais fazem do que repassar as chamadas para os objetos COM. Quem controla isso são objetos COM chamados pelo Explorer e registrados pelos respectivos aplicativos. Alguém conhece mais algum que não use nada de COM? Explicando a sopa de letrinhas da programação C/C++ para Windows: MFC Outros posts dessa mesma série: Win32 COM ATL MFC: A Microsoft Foundation Classes é um framework e uma biblioteca de classes C++ que encapsula grande parte da API Win32. Eu tinha preparado uma lista de programas Microsoft ou módulos do Windows que usam COM (Windows Explorer. Windows Media Player e outros. Ela foi criada pela Microsoft para facilitar a programação em Win32 usando C++. um Pane (se você usa IE. Ela é um framework no sentido de que todos os aplicativos MFC devem "se encaixar" nesse framework de alguma forma. Além dessas tecnologias que eu detalhei. todas as extensões feitas ao Internet Explorer são objetos COM.NET. não em C++). Microsoft Office Addins. Entre os aplicativos que suportam automation estão todos do pacote Office (Word. Para entender melhor. como é o caso do WTL (eu falarei de WTL em outro post). no final das contas. Extensions: Todos os Addins e extensões para o Office são feitos em COM. O Snapins do MMC nada mais são do que objetos COM que implementam as interfaces específicas para se comunicar com o MMC. eles adicionam ao menu de contexto do Windows Explorer opções para manipulação de arquivos ZIP ou RAR e para compactar arquivos comuns. como WMI.msc". Internet Explorer. Hoje é possível fazê-los em . ISA. Automation: É a possibilidade de controlar um aplicativo usando objetos COM exportados por ele. o Bloco de Notas e a Calculadora. já que a API Win32 é exportada como funções C. Na realidade.NET que encapsulam os objetos COM do Office (ou seja. Exchange. seja um Browser Helper Objects. já que a Microsoft provê objetos . Depois cheguei a conclusão que é mais fácil listar os módulos que não usam COM: o kernel do Windows (que é feito em C. seja barra de ferramentas. é tudo COM). inclusive exemplos conhecidos como a intergração do Google Desktop Search e do MSN Desktop Search com o Outlook.h> // // Minha janela principal // class CMyWindow : public CFrameWnd { private: . etc).y y y y y y y MMC: O Microsoft Management Console é uma iniciativa da Microsoft de padronização da aparência e funcionamento das ferramentas de gerenciamento do Windows. Como um trecho de código vale mais do que 2 + 2 palavras. etc). Shell Extensions: Quando você instala o WinZip ou WinRAR.

return TRUE. SetWindowText(str). CPoint) { AfxMessageBox( "dbl click!" ).CButton m_btnTest. eu a criei para inicializar meus // controles daqui // BOOL InitializeControls() { m_btnTest. return 0. this. m_btnTest. 1). } // // evento de resize // LRESULT OnSize(UINT nType. cy). } // // função que trata o evento de clique do botão // LRESULT OnButtonTestClick() { AfxMessageBox( "button click!" ). return 0. altura:%d" .10. CFrameWnd) ON_BN_CLICKED(1.60).Create( "blah". OnButtonTestClick) ON_WM_LBUTTONDBLCLK() ON_WM_SIZE() END_MESSAGE_MAP( ) // // classe que representa a aplicação em si. . } // // evento de duplo click // LRESULT OnLButtonDblClk(UINT. CRect(10.ShowWindow(SW_SHOW). int cy) { CString str.Format( "largura: %d. } }.BS_PUSHBUTTON . int cx. public: // // essa função não é da MFC. cx.100. // // vamos colocar a nova altura e largura como título // da janela // str. return 0. DECLARE_MESSAGE_MAP(). // // mapa de mensagens da classe CMyWindow // aqui colocamos de modo declarativo qual eve nto será // tratado por qual função // BEGIN_MESSAGE_MAP(CMyWindow.

// herda de CWinApp // class CMyApp : public CWinApp { // // Função chamada pela MFC assim que o aplicativo é // inicializado. facilitando a nossa vida com wizards e "clique com o botão direito e.o que em muitas situações é desprezível. A literatura é vasta e existem diversos sites com seções especializadas em MFC (como o Code Project e o Code Guru). A MFC também tem suporte à bancos de dados ODBC ou OLEDB. A MFC é a principal biblioteca de classes para C++ da Microsoft. CorelDRAW!. Muitas empresas (inclusive brasileiras) desenvolvem aplicativos em MFC. // // vamos criar nossa janela e mostrá -la // pMyWindow ->Create(NULL. Além disso. Usando a MFC você tem a opção de fazer um link estático com a MFC ou usar a MFC em uma DLL (de aproximadamente 1 MB). fica bem mais fácil fazer um aplicativo de edição de documentos com open/save.".. e é possível achar muita informação sobre ela na Internet. Como no VB. m_pMainWnd = pMyWindow. você desenha um botão visualmente. Ela vem junto com o Visual C++. Junto com o suporte a serialização.. e a finada certificação "Developing Desktop Applications Using Microsoft Visual C++" era toda sobre MFC. Coloque aqui o que seria colocado // no WinMain // BOOL InitInstance() { CMyWindow* pMyWindow = new CMyWindow. Eu acho esse um dos recursos mais úteis da MFC. dá um duplo clique no botão criado e a MFC cria um handler para o evento de clique do botão. No exemplo de código acima. a MFC contém diversas macros e funções para associar variáveis com controles Win32. o link estático fez o executável ficar com 100kb a mais. que provê um framework para aplicativos que usam o conceito de documento (como o Word.1bit. etc). "www. pMyWindow ->InitializeControls(). área de transferência e várias views de um mesmo documento. um wizard cria classes com propriedades (variáveis membro) equivalentes aos campos do banco de dados. } }. A MFC é bastante criticada por não usar recursos modernos do C++ e não ser totalmente type-safe. a MFC ainda é muito usada. e é muito útil para formulários cheios de CheckBoxes e TextBoxes. pMyWindow ->UpdateWindow(). Apesar das melhorias no quesito type-safe a partir da MFC 7. return TRUE. Mas o grande destaque da MFC é "Document/View Model".br" ). Esse recurso é chamado de DDX. as críticas ainda persistem. e a IDE tem total suporte para ela. e reduz bastante o tempo de desenvolvimento de programas com essas características. pMyWindow ->ShowWindow(SW_SHOW). Explicando a sopa de letrinhas da programação C/C++ para Windows: Win32 Outros posts dessa mesma série: ATL COM MFC .com. mas eu já vi casos onde o executável fica 300kb maior . No caso de OLEDB. CMyApp theApp. Apesar de tudo isso. Fazer um "Dialog Application" usando MFC e o Visual C++ é quase tão fácil quanto fazer um programa em VB (meus alunos de C++ disseram isso).

exe user32.8447 Copyright (C) Microsoft Corp 1992 -1998. 256). 98. o malloc da linguagem C acaba chamando HeapAlloc ou VirtualAlloc da API. veja a documentação na MSDN. NULL. você pode fazer download do Microsoft Visual C++ Toolkit Compiler e do Microsoft Platform SDK. 98SE. L"Mensagem". // HeapFree(hHeap. A compilação em linha de comando fica assim: C:Temp>cl win. HANDLE hHeap.00. 2000. // // se eu usasse ATL eu não precisava fazer isso. Código fonte sempre vale mais do que h palavras: #define #define #define #define #define UNICODE _UNICODE WIN32 _WINDOWS WIN32_LEAN_AND_MEAN #include <windows. hHeap = GetProcessHeap (). L"TickCount: %d". NT.. WTL e MFC. MessageBox (NULL. All rights reserved. /out:win. Longhorn. veja o meu post "FAQ: Programação Win32 em C/C++" Se você não tiver o Visual C++.Win32 API: API (Application Programming Interface) das versões do Windows que são 32 bits (95. MB_OK). LPSTR lpCmdLine.cpp Microsoft (R) Incremental Linker Version 6. Cada sistema operacional tem a sua API.. Alguém tem mais alguma sugestão? . GetTickCount ()). HINSTANCE hPrevInstance.00. } Para mais informações sobre Win32. Para mais detalhes. wzBuffer). 2003.lib Microsoft (R) 32 -bit C/C++ Optimizin g Compiler Version 12.lib win.obj Depois ainda teremos COM. // // usando a função HeapAlloc da API para alocar memória // wzBuffer = (WCHAR*) HeapAlloc (hHeap.cpp /link user32. return 0. XP. All rights reserved. win. Millenium.int nCmdShow) { WCHAR* wzBuffer. HEAP_ZERO_MEMORY. wzBuffer. etc). ATL. Nada mais é do que as funções que o sistema operacional exporta para serem usadas pelas aplicações. // // wsprintf também é da API // wsprintf(wzBuffer.h> // // programa Win32 tem como entry point (função inicial) a função WinMain // int WinMain(HINSTANCE hInstance. e a runtime do C e C++ é implementada em cada plataforma usando essa API. Por exemplo.8804 for 80x86 Copyright (C) Microsoft Corp 1984 -1998.

coloque \\SUA_MAQUINA\bin_debug\SEU_EXECUTAVEL. . Com essas configurações que eu passei. Pronto. Em Transport coloque TCP/IP.NET 2003\Common7\Packages\Debugger" que está na sua máquina. Em Remote Settings >> Connection escolha Remote via TCP/IP. F10) ele conecte na máquina remota e execute o programa lá. Uma das formas de se fazer debug é dar um attach em um processo que já está rodando. Nesse exemplo. Em Remote Settings >> Remote Command. O problema mais comum nesse tipo de configuração é relativo a permissões. rode o filemon NA MÁQUINA REMOTA e veja qual o motivo da falha. usando o psexec. mesmo sem ter acesso via Terminal Sevices .. Depois disso aperte F5 ou F10 e veja se o debug começa.. ACHO que para o Visual C++ 8 os passos são os mesmos.exe. e isso pode ser um problema. Nesse exemplo vou compartilhar como bin_debug.. Clique em OK. Essa é a forma mais simples.1 Primeiro é necessário habilitar o servidor de debug na máquina remota: y y y y y Reze um pouco.Como fazer debug remoto com o Visual C++ 7. veja os parâmetros do msvcmon (rode msvcmon /?) e configure a conexão via Named Pipes ao invés de TCP/IP. Esse aplicativo permite que você execute um programa em outra máquina pela rede. compartilhe a pasta onde fica o executável na sua máquina (pasta Debug geralmente). Execute o msvcmon. é claro. digite-a. e reze um pouco. Em Working Directory configure o diretório de trabalho da máquina remota. e funciona assim: y y y y y No Visual Studio. Em Remote Settings >> Remote Machine coloque o nome da máquina remota. A outra forma .exe -tcpip -anyuser -timeout -1 O psexec vai pedir sua senha de rede. Agora é só selecionar um e clicar em Attach.contanto que você tenha permissões na máquina remota. Baixe o PsExec do site do SysInternals. Faça assim: y y y y y y y y Antes de começar configurar o Visual Studio.é configurar o Visual Studio para que toda vez que você fizer o debug normal (F5.exe na máquina remota. vou chamar a pasta compartilhada de vc7debug. e em Name coloque o nome da máquina remota. Clique em Refresh e a lista de processos da máquina remota deve aparecer.a mais complicada . Rode a seguinte linha de comando NA SUA MÁQUINA: psexec \\MAQUINA_REMOTA -u DOMINIO\SEU_USUARIO \\SUA_MAQUINA\vc7debug\msvcmon. Se o Visual Studio reclamar que não consegue abrir o executável. Compartilhe a pasta "C:\Program Files\Microsoft Visual Studio . Abra as propriedades do projeto No TreeView da esquerda escolha Debugging. menu Tools >> Debug Processes... Se precisar de mais segurança.. o msvcmon (servidor de debug) aceitará conexão de qualquer usuário.