(Tutorial) WinAPI Introdução(pt1)
3 participantes
Página 1 de 1
(Tutorial) WinAPI Introdução(pt1)
Estou dando inicio a uma sequência de mini-tutoriais divididos por partes para o desenvolvimento básico em C++
usando a estrutura do WinAPI, nos permitindo criar janelas e handles de uma forma nem tão
simples, mas bem completa por assim dizer.
(Recomendado para pessoas que já tenham uma noção básica de desenvolvimento)
usando a estrutura do WinAPI, nos permitindo criar janelas e handles de uma forma nem tão
simples, mas bem completa por assim dizer.
(Recomendado para pessoas que já tenham uma noção básica de desenvolvimento)
Índice:
- Primeira visão
- métodos de produção
- definição & estruturação: WinMain
- outros tipos de handles(filhos)
--------------------------------------------------------------------------------------------------------------
Primeira visão/Métodos de produção:
Well, vamos dar inicio lembrando de relance conceitos que aprendemos desde o Pawn até
o próprio C/C++/C#/Java dente outras linguagens quando desenvolvimento em modo CONSOLE.
Talvez alguns não percebam isso, mas quando estamos desenvolvendo em console,
sempre provemos da ajuda de uma função chamada MAIN.
Pois como já diz o próprio nome: Main = Principal, é a função que dá entrada
no nosso projeto, pois sem ela oque escrevemos em outros métodos auxiliares, criados pelo
desenvolvedor, não executariam a sua devida função.
Bom, lembrando disso, podemos fazer uma breve comparação.
Assim como temos o Main que dá a entrada ao nosso console,
no WinAPI temos o nosso WinMain(Definição padrão), que é o que dá entrada em nosso desenvolvimento desktop,
janelas, handles, etc...
Definimos um WinMain para fazer toda a produção de um software visualmente dentre o Registro, até adicionar botões, textboxes, labels, e todas as parafernalhas que utilizamos em um software qualquer.
Definimos logo após um WinProcc para fazer toda a produção estrutural do software, que seria os eventos e as determinadas funções que cada hwnd que você adicionou no WinMain vai executar, botões, textboxes, labels, etc...
Essas dois métodos são os mais utilizados e definidos como padrão(muito usado) de desenvolvimento de WinAPI C++,
mas existem muitas outras maneiras de serem feitas, eu por exemplo utilizo métodos auxiliares, pra manter a organização e a 'estética' do meu código, haha.
Exemplo: eu costumo utilizar o WinMain apenas para tratar as formas de mensagem que o HANDLE principal recebe, como quando você clica com o mouse, como quando você aperta algum botão do teclado...
Eu costumo utilizar o WinProcc, por padrão, para receber as mensagens tratadas do WinMain e atribuir a elas um determinado "evento", função a executar...(tratamento)
o próprio C/C++/C#/Java dente outras linguagens quando desenvolvimento em modo CONSOLE.
Talvez alguns não percebam isso, mas quando estamos desenvolvendo em console,
sempre provemos da ajuda de uma função chamada MAIN.
Pois como já diz o próprio nome: Main = Principal, é a função que dá entrada
no nosso projeto, pois sem ela oque escrevemos em outros métodos auxiliares, criados pelo
desenvolvedor, não executariam a sua devida função.
Bom, lembrando disso, podemos fazer uma breve comparação.
Assim como temos o Main que dá a entrada ao nosso console,
no WinAPI temos o nosso WinMain(Definição padrão), que é o que dá entrada em nosso desenvolvimento desktop,
janelas, handles, etc...
Definimos um WinMain para fazer toda a produção de um software visualmente dentre o Registro, até adicionar botões, textboxes, labels, e todas as parafernalhas que utilizamos em um software qualquer.
Definimos logo após um WinProcc para fazer toda a produção estrutural do software, que seria os eventos e as determinadas funções que cada hwnd que você adicionou no WinMain vai executar, botões, textboxes, labels, etc...
Essas dois métodos são os mais utilizados e definidos como padrão(muito usado) de desenvolvimento de WinAPI C++,
mas existem muitas outras maneiras de serem feitas, eu por exemplo utilizo métodos auxiliares, pra manter a organização e a 'estética' do meu código, haha.
Exemplo: eu costumo utilizar o WinMain apenas para tratar as formas de mensagem que o HANDLE principal recebe, como quando você clica com o mouse, como quando você aperta algum botão do teclado...
Eu costumo utilizar o WinProcc, por padrão, para receber as mensagens tratadas do WinMain e atribuir a elas um determinado "evento", função a executar...(tratamento)
Definição da estrutura padrão do WinMain:
- Código:
//Definição:
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int);
//Pronto para uso:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
//hInstance, o handle da atual instância da aplicação.
//hPrevInstance, o handle da instância antiga da aplicação.
//lpCmdLine
//nCmdShow, controles de como a janela deve ser mostrada. Propriedades básicas abaixo:
/*
| - SW_HIDE (0): Esconde a janela atual e ativa outra.
| - SW_MAXIMIZE (3): Maximiza uma janela específica.
| - SW_MINIZE (6): Minimiza uma janela específica.
| - SW_RESTORE (9): Ativa e mostra a janela, caso esteja minimiza, caso esteja maximizada ele
| retorna a janela para o tamanho e para a posição padrão.
| - SW_SHOW (5): Ativa uma janela e a mostra em sua atual posição e tamanho.
*/
}
Definição da estrutura padrão do WinProcc:
- Código:
//Definição:
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//Pronto para uso:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
//hWnd, handle da janela que acionou o evento(botão, textboxes, labels, etc).
//message, id da mensagem recebida
//wParam, é uma forma de tratar eventos quando a requisição é por botões(F5, F6) etc..
//lParam, forma de tratar eventos quando a requisição vem do HWND.(Exemplo: clicar em um botão)
}
--------------------------------------------------------------------------------------------------------------
Definição & estruturação(WinMain):
Como já diz o nome do tutorial (Introdução), eu vou deixar para falar sobre a callback WndProcc no próximo tutorial, neste vou tratar especificamente da definição e utilização do WinMain.
Vamos lá, como já expliquei um pouco sobre a definição do winMain, vou mostrar um exemplo de uso
de acordo com um que fiz aqui para demonstrar nesse tutorial, nele estarei apenas criando
handles para o visual do hwnd principal, não estarei tratando sobre desgin propriamente dito,
pois eu não sou bom e nem tão criativo assim para mexer com cores, alinhamento, etc.
Vamos lá, como já expliquei um pouco sobre a definição do winMain, vou mostrar um exemplo de uso
de acordo com um que fiz aqui para demonstrar nesse tutorial, nele estarei apenas criando
handles para o visual do hwnd principal, não estarei tratando sobre desgin propriamente dito,
pois eu não sou bom e nem tão criativo assim para mexer com cores, alinhamento, etc.
Exemplo de uso:
- Código:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wcex; //Classe usada para fazer o cadastro de todos detalhes da nossa HANDLE principal.
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW; //Estilo da handle
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance; //Instância da handle atual do aplicativo.
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION)); //Icone que será utilizado(default neste caso)
wcex.hCursor = LoadCursor(NULL, IDC_ARROW); //Cursor que será utilizado(default neste caso)
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); //Cor de fundo da HANDLE principal
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"code.me"; //Nome da classe que iremos registrar, para poder adicionar outros hwnd como ferramentas
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION)); //Handle do Icone pequeno associado a classe.
//hWnd, será a HANDLE principal que estaremos criando.
HWND hWnd = CreateWindow(
L"code.me", // Nome da classe que definimos no nosso registro, para poder herdar as propriedades e os detalhes.
L"code.me tutorial: Criando seu primeiro aplicativo(WinAPI).", // titulo da janela
WS_OVERLAPPEDWINDOW, //estilo
CW_USEDEFAULT, CW_USEDEFAULT, //posição da janela (x, y)
500, 100, //tamanho da janela(width, height)
NULL, // utilizado para associar a uma HANDLE pai, no caso da hwnd principal não usaremos, ou seja(null, 0)
NULL, // utilizado para definir um nome 'abstrato' para podermos identificar quando fomos acionar um evento no winprocc
hInstance, // instância utilizada.
NULL
);
ShowWindow(hWnd, nCmdShow); //Utilizado para mostrar a HANDLE principal, sem isso a janela não aparece.
MSG msg; //instância de mensagens, utilizaremos para fazer o processo dos 'eventos'
while (GetMessage(&msg, NULL, 0, 0)) //Pegamos as mensagens enviadas pelo cliente, usuário
{
TranslateMessage(&msg); //Traduzimos as mensagens para podermos interpretar pelo WinProcc
DispatchMessage(&msg); //Enviamos as mensagens para o WinProcc
}
return (int) msg.wParam; // retorno = 0, valor do postQuitMessage
}
Agora citarei um exemplo que eu costumo utilizar, que é com callbacks auxiliares, para manter a organização do código.
Não estarei comentando este, pois ele tem a mesma função do antigo acima, apenas está dividido.
- Código:
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow )
{
UNREFERENCED_PARAMETER( hPrevInstance );
UNREFERENCED_PARAMETER( lpCmdLine );
if( FAILED( InitWindow( hInstance, nCmdShow ) ) )
return 0;
MSG msg = {0};
while( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
return ( int )msg.wParam;
}
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow )
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof( WNDCLASSEX );
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon( hInstance, ( LPCTSTR )IDI_TUTORIAL1 );
wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
wcex.hbrBackground = ( HBRUSH )GetStockObject(LTGRAY_BRUSH);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"code.me";
wcex.hIconSm = LoadIcon( wcex.hInstance, ( LPCTSTR )IDI_TUTORIAL1 );
if( !RegisterClassEx( &wcex ) )
return E_FAIL;
RECT rc = { 0, 0, 470, 240 };
AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );
HWND g_hWnd = CreateWindow( L"code.me", L"code.me tutorial: Criando seu primeiro aplicativo(WinAPI).", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance,
NULL );
if( !g_hWnd )
return E_FAIL;
ShowWindow( g_hWnd, nCmdShow );
return S_OK;
}
Teve algumas modificações deste exemplo para o primeiro, como o seguinte código:
- Código:
RECT rc = { 0, 0, 470, 240 };
--------------------------------------------------------------------------------------------------------------
Outros tipos de handles(filhos):
Bom, chegando ao fim, vamos agora falar um pouco sobre outros tipos de HWND(handles)
que podem ser criados com um estilo diferente do principal, que são os que são denominados de
handles filhos, que estabelecem um parêntesco com o handle principal(qual ?),
eles são impostos DENTRO do handle principal, exemplo: botões são um ótimo exemplo de hwnds filhos
que você associou a um pai(handle principal), atráves de uma pequena alteração no código
que vou lhes mostrar atráves de um exemplo reduzido, mas estarei explicando em comentários.
que podem ser criados com um estilo diferente do principal, que são os que são denominados de
handles filhos, que estabelecem um parêntesco com o handle principal(qual ?),
eles são impostos DENTRO do handle principal, exemplo: botões são um ótimo exemplo de hwnds filhos
que você associou a um pai(handle principal), atráves de uma pequena alteração no código
que vou lhes mostrar atráves de um exemplo reduzido, mas estarei explicando em comentários.
Vamos supor que já criamos toda a estruturação do WinMain, e lá onde inserimos a criação do hwnd principal:
- Código:
//hWnd, será a HANDLE principal que estaremos criando.
HWND hWnd = CreateWindow(
L"code.me", // Nome da classe que definimos no nosso registro, para poder herdar as propriedades e os detalhes.
L"code.me tutorial: Criando seu primeiro aplicativo(WinAPI).", // titulo da janela
WS_OVERLAPPEDWINDOW, //estilo
CW_USEDEFAULT, CW_USEDEFAULT, //posição da janela (x, y)
500, 100, //tamanho da janela(width, height)
NULL, // utilizado para associar a uma HANDLE pai, no caso da hwnd principal não usaremos, ou seja(null, 0)
NULL, // utilizado para definir um nome 'abstrato' para podermos identificar quando fomos acionar um evento no winprocc
hInstance, // instância utilizada.
NULL
);
Logo abaixo disto(por questões de organização de código), vamos meter os handles filhos que serão impostos ao handle principal, vejamos:
- Código:
CreateWindow(
L"BUTTON", //Aqui o nome da classe será diferente, pois não pretendemos herdar detalhes da
//classe que registramos, pretendemos herdas detalhes de um BOTÃO, por isso classe: "BUTTON"
L"Procurar", //Título do botão
WS_CHILD + WS_VISIBLE, //Estilo do botão.
/*
| - WS_CHILD, estamos indicando que ele será FILHO de um hwnd pai.
| - WS_VISIBLE, estamos indicando que ele estára visível.
*/
270, 50, 70, 25, //Posição dentro da janela(hwnd pai)(x,y), tamanho do hwnd filho(width, height)
hWnd, //Aqui está a diferença, estaremos indicando que ele será parente do handle principal(pertencerá)
NULL, //Aqui não estaremos atribuindo nada, pois ainda não aprendemos sobre WinProcc.
hInstance, //Instância do aplicativo.
NULL
);
Eu dei um exemplo sobre botões, mas podem ser herdadas outras classes também, deixarei uma lista de mais algumas abaixo:
- Código:
BUTTON - Botões, que podem ser checkbox, radio, comando, etc...
COMBOBOX - caixa de combinações.
EDIT - textbox, caixa de texo.
LISTBOX - Lista de opções.
STATIC - Cria um objeto stático, exemplo: Label, texts de título, etc...
SCROLLBAR - Barra de rolagem.
--------------------------------------------------------------------------------------------------------------
Conclusão:
No mais é isso, eu espero ter deixado algo importante para vocês,
caso tenham dúvidas ou dicas estarei esperando pelos comentários.
OBS: Só continuarei a parte 2, se tiver um bom aproveitamento deste tópico, então aguardo
comentário a respeito do mesmo,
abraços.
caso tenham dúvidas ou dicas estarei esperando pelos comentários.
OBS: Só continuarei a parte 2, se tiver um bom aproveitamento deste tópico, então aguardo
comentário a respeito do mesmo,
abraços.
--------------------------------------------------------------------------------------------------------------
Referências:
Créditos: Willian Luigi (© code.me - 2013.1)
Agradecimentos: Gustavo Araújo, pela ideia.
Re: (Tutorial) WinAPI Introdução(pt1)
Não consegui ler tudo pois está tarde aqui ,
mais estou pensando em me aprofundar mais em C++..
Oque acha ? vale a pena ? ..
Parabéns pelo tutorial...
mais estou pensando em me aprofundar mais em C++..
Oque acha ? vale a pena ? ..
Parabéns pelo tutorial...
BrunnoVinicius- Novato
- Mensagens : 27
Data de inscrição : 25/07/2013
Idade : 26
Re: (Tutorial) WinAPI Introdução(pt1)
BrunnoVinicius escreveu:Não consegui ler tudo pois está tarde aqui ,
mais estou pensando em me aprofundar mais em C++..
Oque acha ? vale a pena ? ..
Parabéns pelo tutorial...
Boa noite Brunno, eu só posso te dizer oque vale apena você aprender, quando eu souber oque você pretende seguir dentro do ramo.
Dá um like na nossa page no facebook, ai você vai ficar atualizado dos tutoriais novos que eu estou dando entrada.
Abraços.
Re: (Tutorial) WinAPI Introdução(pt1)
gostei do tópico, muito interessante.
Voltz- Novato
- Mensagens : 7
Data de inscrição : 14/08/2013
Idade : 30
Localização : Barueri
Tópicos semelhantes
» (Tutorial) Introdução a linguagem
» (Tutorial) WinAPI Eventos(pt2)
» (C++) Identificando processo
» (Tutorial) CallRemoteFuncion (dicas)
» [Tutorial]Dicas para mapear mtasa/samp
» (Tutorial) WinAPI Eventos(pt2)
» (C++) Identificando processo
» (Tutorial) CallRemoteFuncion (dicas)
» [Tutorial]Dicas para mapear mtasa/samp
Página 1 de 1
Permissões neste sub-fórum
Não podes responder a tópicos
|
|