logo
Contato | Sobre...        
rebarba rebarba

Rodrigo Strauss :: Blog

follow us in feedly

FAQ: Programação Win32 em C/C++

Continuando o meu projeto de projeto de FAQ C++, vou falar hoje sobre Win32.

O que é Win32 e para que serve?
Já expliquei isso em outro post.

Ouvi falar que Win32 é complicado, isso é verdade?
Isso tem lá seu fundo de verdade, alguns assuntos são extremamente complicados, os mais usuais nem tanto. De qualquer forma, essa complicação tem motivo: como a Win32 API é o acesso mais baixo nível que se pode ter ao sistema (considerando user-mode), ela deve possibilitar que você a use para fazer tudo que é possível no Windows. Por isso, muitas vezes, você chama uma função de 8 parâmetros mais só passa 2. Esses outros 6 parâmetros são usados em situações não muito comuns, mas que devem ser cobertas pela API. Além disso, como essa API é C (e não C++), não é possível fazer overload das funções com versões mais simples para os usos mais simples, como é feito muitas vezes nas classes do .NET Framework e em bibliotecas C++.

Vou exemplificar isso usando a famosa função CreateProcess como exemplo. Essa função pede 10 parâmetros, mas em 99% dos casos você só usa o LPTSTR lpCommandLine. Além dos parâmetros que você passa como NULL, existem alguns que você é obrigado a preencher, como o LPSTARTUPINFO lpStartupInfo, e o LPPROCESS_INFORMATION lpProcessInformation. Veja um exemplo adaptado da MSDN:

#include <windows.h>
#include <stdio.h>

void main()
{
    STARTUPINFO si;
    PROCESS_INFORMATION p;

    //
    // dica: muitas estruturas no Windows têm uma variável membro chamada
    // cb ou cbSize. Esse membro deve ser preenchido com o sizeof()
    // da estrutura ANTES de chamar a função. Se você não fizer isso a função 
    // retornará um erro. Esse é um erro comum de iniciantes (eu apanhei muito...)
    //
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);

    ZeroMemory(&p, sizeof(p));

    //
    // Abrindo o Bloco de Notas
    //
    if( !CreateProcess( NULL,   // Sem módulo 
        "C:WINDOWS\\notepad.exe", // linha de comando para o executável 
        NULL,
        NULL,
        FALSE,            // O processo criado não herdará os handles
        0,
        NULL,
        NULL,
        &si,              // Ponteiro para STARTUPINFO
        &p )             // Ponteiro para PROCESS_INFORMATION 
    ) 
    {
        printf( "Erro em CreateProcess: 0x%X", GetLastError() );
        return;
    }

    //
    // O CreateProcess preencheu as estruturas e colocou handles nelas
    // como não vamos usar os handles, precisamos fechá-los...
    //
    CloseHandle(p.hProcess);
    CloseHandle(p.hThread);
}

O que eu preciso saber antes de estudar Win32?
Você precisa ter prática em programação C/C++. A API Win32 é exportada como funções C, mas é usada a partir do C++ sem problemas.

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, e, como eu já disse, vale muito mais a pena comprar um livro e ler do que ficar procurando na Internet.

O primeiro livro que você deve ler é o Programming Windows do Charles Petzold, considerado a Bíblia definitiva sobre o assunto. Ele já está na quinta edição, e é essencial para que você entenda como a GDI do Windows funciona. Ele é hardcore do meio pra frente (eu não tive paciência para ler a parte de toolbar), se você não tiver paciência leia até o capítulo 11 (página 566). Isso já será suficiente para entender como as coisas funcionam no Windows, e será muito útil MESMO QUE VOCÊ USE Windows Forms (afinal, WinForms nada mais é do que uma camada .NET sobre a GDI).

Nossa, Win32 é complicado mesmo... 100 linhas para fazer uma janelinha branca e feia? Existe algo mais fácil?
Existe. Hoje em dia, quase ninguém mais usa API diretamente ("à la Petzold" como é conhecido). A GDI é complexa pelo mesmo motivo que eu já expliquei, ela é muito flexível e é um dos motivos do sucesso do Windows. Poder e flexibilidade sempre têm um custo, que geralmente é a complexibilidade.

Para resolver isso, foram criadas, por diversas empresas, bibliotecas que encapsulam a Win32 API para facilitar o seu uso (o .NET Framework é uma delas). A biblioteca provida pelo Microsoft Visual C++ é a MFC (Microsoft Foundation Classes), que encapsula uma boa parte da Win32 API em objetos C++. Além disso, a IDE do Visual C++ possui diversos wizards que geram classes e código e facilitam muito a programação. Usar dialogs (forms) em MFC é quase tão fácil quanto VB6. Existem outras bibliotecas, como a VCL/CLX do Delphi e do C++ Builder e o WTL da Microsoft (que é a que eu mais gosto).

Leia algo sobre MFC depois de ler o Petzold. Pode ser qualquer livro, entendendo como funciona o Win32 e a GDI MFC não será um problema.

O livro do Petzold cobre extensivamente a GDI (gráficos). E o resto?
Depois de ler o Petzold e algo sobre MFC, leia o Advanced Windows do Jeffrey Richter, outro clássico. Pronto. Isso já é suficiente para você ser um programador Win32. Só 3 livros :-)

Meus amigos dizem que a API Win32 está ultrapassada e não vale a pena estudar isso. É verdade?
Não, não é. Você anda convivendo demais com Piranhas.NET. Explique para os seus amigos que TODOS os aplicativos para Windows hoje são feitos em Win32, já que ela é o Windows. No Windows Longhorn (previsto para 2006/2007) ALGUMAS NOVAS APIs serão disponibilidas como classes .NET. O Windows vai ficar cada vez mais .NET, mas isso deve levar no mínimo uns 5 anos. Não se esqueça que o .NET foi lançado em 2001 e a maioria dos aplicativos comerciais ainda são feitos em C e C++, usando a API Win32 (que por enquanto é a API do Windows)

Meus amigos disseram que existe mais material de estudos e livros falando de .NET do que de Win32. É verdade?
Não é verdade que existem mais livros sobre .NET. A API Win32 existe desde de 1993, e uma procura por livros na Amazon retornará vários livros. Procure "MFC" na Amazon, depois procure "Windows Forms" e veja a diferença. Além disso, no Code Project tem muito mais coisa útil em MFC do que em .NET.

Você me deixou em dúvida. Se o .NET é tão ruim assim, então eu devo abandoná-lo e fazer tudo em C++?
Primeiro: Eu nunca disse que o .NET é ruim. Na verdade eu acho ele muito bom para resolver os problemas que ele se propõe. Mas, tem seus problemas como qualquer API/Framework/Arquitetura. O grande problema é que no Brasil as pessoas acreditam no pessoal de marketing da Microsoft sem pensar se isso resolve o problema, e acham que .NET resolve todos os problemas. Nada resolve todos os problemas.

Como eu já disse, hoje tudo é C++ e Win32 e vai levar anos (talvez mais de uma década) para que o .NET seja realmente a plataforma de programação do Windows. Você acha mesmo que a Microsoft, Adobe/Macromedia e outros vão refazer todos os aplicativos em C#? Além disso, C++ ainda é a coisa mais portável que existe (em termos de código fonte), e esse é o motivo dele ter sido usado pela Mozilla Foundation (Firefox, Thunderbird, etc), pela Adobe (Photoshop), etc. E se isso conta, em Linux quase tudo é C e C++, o kernel (C), Gnome (C), KDE, (C++), etc. O fator multiplataforma do .NET ainda é incerto, e depende de implementações de terceiros (como o Mono).

Eu já escrevi um artigo sobre perspectivas para o NET a quase 1 ano atrás, e acho que ela continua a mesma. As duas arquiteturas são importantes, não troque o .NET pelo Win32, aprenda os dois e use o que for melhor para cada caso. Só não fique sentado esperando o .NET virar a plataforma oficial do Windows, você vai perder vários anos de mercado e da sua vida.


Em 11/07/2005 14:37, por Rodrigo Strauss


  
 
 
Comentários
Fabio Galuppo | em 14/07/2005 | #
Excelente artigo (assim como os outros) :)

Bom, para contribuir com a galera do C++ que está interessada em Win32 (ou vice versa) - "alguma coisa Win32 com cara/feeling de C++":

class Process
{
public:
struct CannotBeCreatedException
{
CannotBeCreatedException( const string& reason ) : reason(reason){}

string reason;
};

private:
struct ReasonFunctor
{
~ReasonFunctor(){ LocalFree( Buffer_ ); }

string operator()()
{
if ( FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
reinterpret_cast<char*>( &Buffer_ ),
0,
NULL )
)
{
return static_cast<char*>( Buffer_ );
}
else
{
return "Unknown";
}
}

private:
LPVOID Buffer_;
};

struct STARTUPINFO_ : public STARTUPINFO
{
STARTUPINFO_()
{
ZeroMemory(this, sizeof(STARTUPINFO_));
this->cb = sizeof(STARTUPINFO_);
}

LPSTARTUPINFO ptr()
{
return this;
}
};

struct PROCESS_INFORMATION_ : public PROCESS_INFORMATION
{
PROCESS_INFORMATION_()
{
ZeroMemory( this, sizeof(PROCESS_INFORMATION_) );
}

~PROCESS_INFORMATION_()
{
if( INVALID_HANDLE_VALUE != this->hProcess )
{
CloseHandle( this->hProcess );
if( INVALID_HANDLE_VALUE != this->hThread )
CloseHandle( this->hThread );
}
}

LPPROCESS_INFORMATION ptr()
{
return this;
}
};

public:
static void Start( const string& processName ) throw(...)
{
STARTUPINFO_ si;
PROCESS_INFORMATION_ p;

if( !CreateProcess( NULL,
const_cast<char*>( processName.c_str() ),
NULL,
NULL,
false,
0,
NULL,
NULL,
si.ptr(),
p.ptr() )
)
{
throw CannotBeCreatedException( ReasonFunctor()() );
}
}
};

para usar:

try
{
Process::Start( "C:\\Windows\\Notepad.exe" );
}
catch( Process::CannotBeCreatedException ex )
{
MessageBox( NULL, ex.reason.c_str(), "", 0 );
}

Falou ;)

Qual será o próximo tema? Definitivamente o melhor blog em português que temos no momento... ;)
Rodrigo Strauss | website | em 14/07/2005 | #
Isso soa bem mais C++ moderno :-)

O primórdio do projeto que acabou virando o .NET era transformar a API do Windows em objetos COM - que não usa tudo de C++ mais já é bem melhor do que [extern "C"].

Ainda estou em dúvida do próximo, mas acho que vou acabar escrevendo alguma coisa sobre COM. E o próximo da série de WinDbg já está no forno.
Evandro | e-mail | em 29/07/2005 | #
Gostaria de saber mais sobre as API´s do windows e com a programação em c... Valeu.
Rodrigo Strauss | website | em 29/07/2005 | #
A melhor forma de conhecer mais é ler os livros que eu indiquei no post
ramiro | em 13/02/2006 | #
Como e usado o win32 no delphi?
Rodrigo Strauss | website | em 13/02/2006 | #
Não a pessoa mais indicada para te responder isso, Delphi não é minha praia
FRANCISCO GOMES | em 29/08/2006 | #
Na realidade não é um comentário e sim uma dúvida. Gostaria muito que você me ajudasse :

Estou fazendo um programinha em delphi que lê a hora do relógio e quando esta for igual a uma determinada hora, um outro programa é carregado na tela. Até aí tudo bem. O problema é que este outro programa que é carregado não está sendo sobreposto a outras janelas que estão em uso (WORD ou EXCEL ou E-MAIL, etc).
Como eu faço para dar prioridade de abertura para o form que eu estou abrindo no delphi ???

Peço a sua ajuda.
OBRIGADO ...
Rodrigo Strauss | website | em 29/08/2006 | #
Não sou a pessoa mais indicada para te responder isso, Delphi não é minha praia...
Rimack Zelnick | website | e-mail | em 21/10/2006 | #
ola Rodrigo, meu nome é Rimack e eu sou iniciante em C/C++ eu estou querendo mais informacoes de como criar programas para win32 entao a pergunta é o seguinte: Que livro voce me indicaria para fazer aplicacoes em C/C++ ?

Obrigado
Rodrigo Strauss | website | em 22/10/2006 | #
Dê uma lida em http://www.1bit.com.br/content.1bit/weblog/faq_cpp_start
breno | em 02/11/2006 | #
Advanced Windows do richter foi lancado ha quase 10 anos.
e de acordo com o proprio titulo cobre a plataforma windows 95!

vc disse que é um bom material. confio, pois em todos os lugares que o procurei ele estava ao lado de cinco estrelas. mas agora bateu uma duvida: o que for aprendido nele pode ser ultilizado no windows xp? nao estaria ele meio desatualizado?
alguma outra indicacao?
Rodrigo Strauss | website | em 03/11/2006 | #
Ele cobre o Windows 95 e o Windows NT 3.51. 98% da API Win32 ainda é a mesma desde aquela época, ele não está desatualizado. Tanto que ainda não lançaram outro, provavelmente porque não há necessidade.
JULIO QUENI | em 09/11/2006 | #

Bom dia, boa tarde, boa noite conforme a disposiçao de tempo.
é com todo o gosto e prazer que li os seus comentarios.sou um sr da idade acima indicada e comecei a aprender progrmar pela primeira vez.mas nesta altura que escrevo ja vou no segundo mes de aprendizagem mas estou a deparar com muitas dificuldades tais como:

Primeiro pensava que motivo de nao assimilaçao era lingua e falta de computador,mas agora ja falo mais ou menos a lingua italiana e comprei um computador mas continuei com enormes dificuldades. confesso que o que nao me falta é a vontade de aprender.estou a trabalhar na linguagem C++, ja fiz o primeiro exame sem éxito.Epero e gostava que Sr.Paulo me ajude ultrapassar essa barreira, porque o que gostei de ser na vida é programador.por isso passo todo o tempo agarrado a programaçao, mas realmente me falta a base.Com esse seu comentàario devo mudar de mentalidade e deixar desculpas e trabalhar arduamente nem se for preciso passar noites a exercitar. por isso gostava de pedir Sr. ajuda no sentido de ser meu orientador pedagogico e de me facultar ou aconselhar os livros que achou essencial para essa fase.Parte de principio que nao sei nadinha e devo ter exame no mes de janeiro.neste momento falo de Array e Puntatori.
Gostava bastante de receber uma ajuda da sua parte. fiquei imocionado ao ler comentarios que mostram claramente o seu perfil. dedicado,humilde....
Peço desculpas de lhe tratar de Sr. porque a pessoa que nao gostam.mas espero que isso nao vai ser motivo de nao me responder.
Desejo-lhe sucessos na carreira e com muita sorte.
JULIO QUENI
Rodrigo Strauss | website | em 09/11/2006 | #
¿
Glauco | em 12/04/2007 | #
O livrinho difícil de comprar sem cartão de crédito internacional. Muito bom o artigo.
Romulo Ferrer | e-mail | em 25/05/2007 | #
Olá pessoal, sou iniciante na programação cpp para windows e gostei muito da materia e dos comentarios...A parti de agora serei um frequentador desse site, e o que eu puder ajudar e contribuir, farei! Após ler, as coisas ainda estão escuras, mas ja baixei o primeiro livro para estudar. Logo estarei aqui com mais duvidas...
um abraço a todos!!!
will ricco | em 02/10/2007 | #
legal
Márcio | website | e-mail | em 04/10/2007 | #
Usa a API FindWindow para pegar o manipulador da janela do Word depois usa SetForeground para colocar ela na frente.
Rodrigo Petarli Brandão | website | e-mail | em 04/10/2007 | #
Olá Rodrigo.

Faço faculdade de Ciência da Computação, e em uma das disciplinas (Sistemas Operacionais 1) fui solicitado pela professora para montar um programa que fizesse algumas tarefas que um shell faz (executar processos, listar arquivos,etc).
O primeiro lugar que consultei foi o site da microsoft MSDN, que tem bastante conteúdo até, mas nada muito explicado. Estou com uma dúvida sobre um tipo de struct chamado HANDLE (além de outros), que vejo que toda hora é usado como parâmetro para várias funções. Em qual arquivo .h posso ver estas estrutras? No windows.h não tem muita coisa. Você conhece algum site bom como referência?

PS: Estou "conseguindo" o livro do Petzold, mas estou procurando algo como uma lista de referência mesmo.

Obrigado pela atenção.

Rodrigo Petarli Brandão.
Rodrigo Strauss | website | em 05/10/2007 | #
Existem vários tutoriais de Win32. Veja http://www.google.com/search?q=win32%20tutorial
Edson | website | e-mail | em 05/06/2008 | #
Olá Rodrigo,
Tentei compilar o primeiro código utilizando o CreateProcess, no bcc55 da Borland, e GetLastError() retornou o erro 0x3.
Qual seria o problema?

Obrigado
Rodrigo Strauss | website | em 21/06/2008 | #
Edson, use o programa "Error Lookup" que vem junto com o Visual Studio para descobrir a descrição do código de erro. Ou coloque o sufixo ",hr" no watch (ex: "3,hr").

O erro 3 é caminho não encontrado. Veja se o executável existe e se você não esqueceu de colocar '\\' ao invés de '\'.
Will | em 08/07/2008 | #
Strauss,

Acho que vc se esqueceu de \\ após o C: na chamada do CreateProcess()

Onde se lê:
"C:WINDOWS\\notepad.exe", // linha de comando para o executável

Entendo que deveria estar:
"C:\\WINDOWS\\notepad.exe", // linha de comando para o executável

Tenho lido muito seu blog e vc está de parabéns! Muito conteúdo ÚTIL. Coisa rara de se achar na internet hj em dia :-)

[ ]'z

WB::
Pompeo | website | e-mail | em 02/03/2010 | #
Olá Rodrigo,
Estou iniciando em DEV C++ e estou precisando de manuais ou apostilas que detalhem os comandos para construir um programa para administração remota, tipo pcanywhere, teamviewer, showmypc, etc
Obrigado.

Pompeo
Wagner | em 02/09/2010 | #
Olá Rodrigo,
Pode me indicar algum livro sobre WIN32 em português?

Grato.
Rodrigo Strauss | website | em 03/09/2010 | #
Procure alguma tradução do livro do Charles Petzold.
Reginaldo | em 05/09/2010 | #
Rodrigo,
E agora, 5 anos depois, com Windows 7 a todo vapor, o que você me diz de .NET? Ainda vale a pena aprender Win API?
Essa API mudou alguma coisa com o Windows 7?

Parabéns pelo blog.
Rodrigo Strauss | website | em 08/09/2010 | #
.NET melhorou e evoluiu em termos de facilidades, Win32 ganhou mais recursos.

Ainda vale estudar Win32 API, mas C# fica cada vez melhor. Eu não usaria Win32 puro para fazer um aplicação hoje em dia, só se fosse muito especializado.
Michel | em 29/10/2010 | #
Rodrigo,

Sou um afortunado.
Achei os livros de Petzold e Richter nos sebos (hehehehe!!!)
E já mergulhei em Win32. Valeu mesmo pelas dicas, ambos os livros são de "outro mundo".

Por outro lado, tb programo em C# e estou maravilhado com a plataforma WCF para aplicações Client/Server, de modo que eu pretendo fazer as minhas aplicações clientes em Win32 se comunicarem com meu Server WCF usando a Interop COM/.NET.

Será que funciona bem essa Interoperação entre as plataformas?

P.S. Parabéns pelo blog!!

[]'s
Michel
Rodrigo Strauss | website | e-mail | em 29/10/2010 | #
Você pode usar C# para o WPF e integrr tudo via C++/CLI.
Fábio | em 10/06/2011 | #
Será que pra quem estuda Windows API e descobriu todas as velharias clássicas como Inside Windows NT, Advanced Windows, Inside Windows 2000 e muito mais... sem esquecer da última edição do Windows Internals :) achará um lugar no mercado no futuro? Agora com essa mania WinMin e completa faxina na Windows parece que estudar como o sistema funciona torna o futuro incerto para alguém como eu que quer não só entender e programar em C/C++ como trabalhar com isso...
Rodrigo Strauss | website | em 13/06/2011 | #
Eu não chamaria de velharias, já que praticamente todos os software que são parte do Windows e grande parte dos softwares comerciais são construídos sobre essa plataforma. .NET apesar de ser uma boa plataforma, é mais uma camada de abstração sobre o Windows, coisa que nem todos podem pagar o preço para ter.

Pelo que entendi, MinWin além de ser o Windows Executive completo (para mais detalhes veja o Windows Internals), não será vendido como um produto separado. Todos os livros que você citou se aplicam diretamente às APIs que continuam sendo expostas nessa teórica "versão".

Sim, vale a pena trabalhar com isso. Trabalho com isso até hoje e tenho visto bastante procura por profissionais com essas qualificações.
Fabio Galuppo | website | em 13/06/2011 | #
Complementando.

Para fazer "system programming" no Windows é necessário conhecer bem a Windows API e seus subsistemas. Para usar DirectX é bom conhecer o lado "consumer" do COM, e a estrutura de Message Pump. Mesmo no mundo da CLR (.NET), isto tem valor, pois quando você investigar um "system call" provavelmente encontrará um p/invoke para uma API (por exemplo: a classe File chama a Win32Native.CreateFile).

É extremanente válido tais conhecimentos!

Quanto ao MinWin, o Windows vem desde o Vista sofrendo Refactoring. Este artigo é muito interessante, e pode dar mais explicações: http://blogs.mcafee.com/mcafee-labs/windows-7-kernel-api-ref...
Fábio | em 13/06/2011 | #
Obrigado pelos esclarecimentos Rodrigo e Fábio :-)

Fábio | em 13/07/2011 | #
E será que mesmo alguém sem formação superior hoje em dia consegue emprego para programar baixo nível nessa área?
Rodrigo Strauss | website | e-mail | em 13/07/2011 | #
Sim. Se você souber o que está fazendo.
William | e-mail | em 09/11/2011 | #
É verdade que não há material muito bom na internet para iniciantes. Então tem alguma dica de livro que eu (como iniciante em C/C++) poderia comprar para aprender conceitos básicos???
Rodrigo Strauss | website | e-mail | em 16/11/2011 | #
William, é o livro do Petzold mesmo.
ninguém | em 04/02/2012 | #
não tenho nada a dizer, obrigado por perguntar.
Juliano Bueno | em 21/05/2012 | #
Eu acho interessante esses artigos que não se perdem com o tempo...

Muito bom seu post, isto pq, estamos em 2012 e ele ainda é muito atual! Sua idéias são muito sensatas e inteligentes...

Parabéns Rodrigo, seu trabalho é sensacional, tenho buscado acompanhar mais de perto nos últimos dias lendo seu material on-line!
Adriano | website | e-mail | em 12/06/2015 | #
Poxa artigo bacana! Parabéns!
Algo a dizer?
Nome:


Site:


E-mail:


Escreva o número vinte e seis:


 Não mostre meu e-mail no site, não serve pra nada mesmo...

Comentário





Os comentários devem ser sobre assuntos relativos ao post, eu provavelmente apagarei comentários totalmente offtopic. Se quiser me enviar uma mensagem, use o formulário de contato. E não esqueça: isso é um site pessoal e eu me reservo o direito de apagar qualquer comentário ofensivo ou inapropriado.
rebarba rebarba
  ::::