Tutorial API C++ (Outro =p)

Started by _Dr4k0_, 29 de June , 2006, 05:14:06 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

_Dr4k0_

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-=[ 06 ]=-=[ Programando API em C++ para Windows, por Vo5 ]=-=-=-=-=-=-=-=-=-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=


C++ API

Não vou dar noções básicas sobre C/C++.

A interface  API (Application  Program Interface)  corresponde a  um conjunto de
system  calls oferecidas  por um  determinado sistema  operacional. Neste  caso,
Windows.  A biblioteca  API de  Windows é  extensa, contendo  as mais  variadas
funções.  Não  pretendo  citar  todas,  mas  sim  as  que  eu  considerar   mais
importantes, mesmo assim,  pretendo fazer um  trabalho extenso. Para  não tornar
essa  matéria  um  tanto  monótona,  vou  restringi-la  à  explicação  à   nível
superficial. Não  entrarei em  detalhes como  estrutura das  funções, pois  isso
somente consumirá mais e mais bytes.

Um dos maiores  atrativos do Windows  é seu sistema  de janelas, que  permite ao
usuário  navegar  entre  elas  e  coloca-las  à  disposição  mais   conveniente.
Programadores de VB sabem  o quanto é fácil  criar uma janela, mas  em C++, isso
pode se tornar um processo que requer alguns procedimentos iniciais.

Primeiramente vamos analisar a estrutura mais básica de um programa Win32 em C++:


#include

int _stdcall WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR nCmdLine, int nCmdShow)
{
return 0;
}


Para manter compatibilidade, a função é declarada como _stdcall, porém em alguns
compiladores pode estar definida como WINAPI ou outras macros. A função  WinMain
tem como  objetivo definir  o inicio  do programa.  É relativamente semelhante à
função main, só que  é executada em contexto  Win32 hehe. Os parâmetros  são bem
simples:

Antes, o int de retorno: Da mesma  maneira que a função main(), quando a  função
WinMain() retornar um valor, esta finalizará o programa.

HINSTANCE: a HINSTANCE representa um valor de 32 bit´s que identifica um  objeto
no  sistema. O  sistema operacional  passa este  valor para  o aplicativo  para
identificar o aplicativo enquanto ele está  sendo executado e o libera quando  o
aplicativo é finalizado.

A primeira HINSTANCE (hInstance) refere-se ao valor de identificação passado  ao
aplicativo. A segunda (hPrevInstance) refere-se  á um valor curioso, é  nela que
vc recebe  o valor  da HINSTANCE  de outra  instância de  seu aplicativo,  dessa
maneira você pode monitorar se seu  aplicativo está sendo executado mais de  uma
vez e bloquear as  instanciações de seu programa,  caso o programa esteja  sendo
executado primariamente, esse valor passa a ser NULL.

LPSTR é  uma implementação  de char*.  nCmdLine corresponde  á linha  de comando
passada ao seu aplicativo,  ou, aos parâmetros á  ele passados. Como um  simples
exemplo  posso citar  o Internet  Explorer. A  linha de  comando á  ele passada
corresponde à página que será exibida.

nCmdShow corresponde  a um  valor identificando  o estado  inicial da  janela, é
recomendável que esse valor seja passado como 2º parâmetro de ShowWindow().

Aí está o ponto de entrada para qualquer programa Win32. Como esse tutorial  tem
como foco a criação de um programa Win32, iremos direto ao ponto: Como criar uma
simples janela?

A API do  Windows fornece uma  estrutura que descreve  os comportamentos padrões
para qualquer janela. Um tópico importante, é que num ambiente de programação em
C++ todas as classes e estruturas  são consideradas como objetos. Essa visão  se
traduz no Windows quando falamos sobre janelas e controles.

Tanto uma janela quanto  um controle são objetos  primários na construção de  um
aplicativo Win32, e, pela analise do Windows, são iguais.

Uma janela  corresponde à  uma área  (geralmente retangular)  num espaço virtual
conhecido como desktop, não seria correto  afirmar que um controle não passa  de
uma janela dentro de um espaço conhecido como outra janela qualquer?

É assim que você deve interpretar  janelas e controles, não como estruturas  que
diferem entre si, mas estruturas semelhantes entre si.

A  API  do Windows  fornece  uma estrutura  básica  para qualquer  janela,  que,
geralmente  em  controles já  é  predefinida. Essa  estrutura  é conhecida  como
WNDCLASS.

Como  essa  estrutura é  pertencente  à API  do  Win95, ficou  atrasada  para as
evoluções do software,  assim sendo, foi  criada uma estrutura  equivalente, que
possui mais opções, a WNDCLASSEX.

Ao longo do tutorial, você verá muitas funções e estruturas que foram  recriadas
com o sufixo  EX, porém todas  as funções e  estruturas mais antigas  prevalecem
ainda  hoje.  Por  razões  de  compatibilidade  vou  citar  mais  as  funções EX
(EXtended) do que as mais antigas.


A estrutura WNDCLASSEX possui os seguintes membros:

cbClsExtra – Corresponde à um  valor  em bytes que devem ser alocados  depois da
WNDCLASSEX na memória, o Windows inicializa este valor como zero.

cbSize – Um unsigned int que corresponde ao tamanho da estrutura, geralmente  um
sizeof(WNDCLASSEX) é suficiente ;]

cbWndExtra – Um valor que corresponde ao número de bytes que devem ser  alocados
após a instância da janela, o  Windows inicializa esse valor como zero,  porém é
recomendável que este valor seja  alterado para DLGWINDOWEXTRA caso você  deseje
utilizar caixas de diálogos criadas com WNDCLASSEX.

hbrBackground – Um HBRUSH que corresponde ao fundo inicial da janela, geralmente
esse  valor  é  igualado  à  um  dos  valores  predefinidos  do  sistema,   como
WINDOW_COLOR.

hCursor –  Corresponde à  um HCURSOR  que representa  o cursor  que será exibido
dentro da janela.

hIcon – Corresponde ao Ícone grande  a ser exibido representando a janela,  como
no menu de alt+tab.

hIconSm –  Corresponde ao  ícone pequeno  a ser  exibido na  barra de  título da
janela.

hInstance – Corresponde  à instância que  identifica um objeto  no sistema, esse
valor é passado ao  programa para que ele  não possa acessar objetos  externos à
seu processo indevidamente.  Deve-se atribuir à  esse valor a  hInstance que foi
passada à função WinMain.

lpfnWndProc  – Corresponde  à uma  função que  recebe as  mensagens enviadas  à
janela, em termos  de leigo, corresponde  à função responsável  por gerenciar os
eventos que ocorrem dentro da janela.

lpszClassName – Corresponde à uma string que identifica a classe.

lpszMenuName – Corresponde à uma string que aponta para o nome de menu associado
à esta janela. Este tipo de menu é criado no arquivo de resources do aplicativo.
Caso o valor seja identificado como  um inteiro no arquivo de resource,  deve-se
utilizar a macro MAKEINTRESOURCE.

style – Corresponde à um comportamento padrão da janela.


Qualquer  um  destes membros  pode  ser validado  como  NULL, porém  alguns  são
essenciais  na  construção   de  uma  janela.   Agora  vamos  analisar   algumas
peculiaridades de alguns deles.

A WNDCLASS não apresenta os seguintes valores: cbSize e hIconSm.

hbrBackground
Esta propriedade refere-se à  um HBRUSH que identifica  o tipo de fundo  que uma
janela receberá. É recomendável que se utilize somente cores. Há valores padrões
do sistema que podem ser utilizados:


COLOR_ACTIVEBORDER
COLOR_ACTIVECAPTION
COLOR_APPWORKSPACE
COLOR_BACKGROUND
COLOR_BTNFACE
COLOR_BTNSHADOW
COLOR_BTNTEXT
COLOR_CAPTIONTEXT
COLOR_GRAYTEXT
COLOR_HIGHLIGHT
COLOR_HIGHLIGHTTEXT
COLOR_INACTIVEBORDER
COLOR_INACTIVECAPTION
COLOR_MENU
COLOR_MENUTEXT
COLOR_SCROLLBAR
COLOR_WINDOW
COLOR_WINDOWFRAME
COLOR_WINDOWTEXT


hCursor
Assim como hIcon e hIconSm, este  valor pode ser criado no arquivo  de resource,
porém há tipos predefinidos de cursors que podem ser carregados utilizando-se  a
função LoadCursor, passando o primeiro  valor (hInstance) como NULL e  o segundo
como o valor a ser utilizado:


IDC_APPSTARTING
IDC_ARROW
IDC_CROSS
IDC_IBEAM
IDC_ICON
IDC_NO
IDC_SIZE
IDC_SIZEALL
IDC_SIZENESW
IDC_SIZENS
IDC_SIZENWSE
IDC_SIZEWE
IDC_UPARROW
IDC_WAIT


hIcon e hIconSm
Podem  ser  carregados valores  do  sistema utilizando-se  a  função LoadCursor,
passando o primeiro valor como NULL e o segundo como o valor a ser utilizado:

IDI_APPLICATION
IDI_ASTERISK
IDI_EXCLAMATION
IDI_HAND
IDI_QUESTION
IDI_WINLOGO


lpfnWndProc
O Window Procedure é uma função responsável por gerenciar as mensagens recebidas
em uma janela. A sintaxe do Window Procedure é:

LRESULT CALLBACK WinProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);

O valor de retorno corresponde a um long.

HWND é um unsigned  int que corresponde ao  valor do window handle,  ou seja, um
valor utilizado para a manipulação da janela.

Msg  corresponde ao  valor numérico  da mensagem  recebida pela  janela, wParam
corresponde à um DWORD com valores passados à Msg, o mesmo vale para lParam.


style

Define estilos padrões que alteram a performance da janela:


CS_BYTEALIGNCLIENT e CS_BYTEALIGNWINDOW
Alinham a janela em um determinado contexto na posição horizontal para  melhorar
a performance em operações gráficas. Estes estilos afetam a posição horizontal e
largura da janela. Não é muito utilizado

CS_CLASSDC
Aloca um DC para ser utilizado por todas as janelas da classe. É utilizado  para
diminuir  o tempo  de espera  em operações  gráficas. Este  estilo permite  que
somente uma janela manipule operações gráficas por vez

CS_DBLCLKS
Permite que a janela receba mensagens sobre cliques duplos (DblClick)

CS_GLOBALCLASS
Permite que uma janela seja criada  sem a necessidade que a hInstance  da classe
seja a mesma da janela. É utilizada em controles que são inicializados em DLLs

CS_HREDRAW e CS_VREDRAW
Redesenha  toda  a   janela  caso  esta   seja  modificada  horizontalmente   ou
verticalmente respectivamente. Tanto vale para movimentações como para reajustes
de tamanho

CS_NOCLOSE
Desabilita todas as opções naturais para se fechar uma janela

CS_OWNDC
Aloca um DC único para cada janela da classe

CS_PARENTDC
Permite que  janelas Child  possam realizar  operações gráficas  em suas janelas
pai. Essa opção aumenta a performance  de operações gráficas, já que uma  janela
dessa classe recebe um cachê de memória maior para alocar seu DC

CS_SAVEBITS
Caso uma janela seja parcialmente obscurecida por outra janela, essa opção salva
a  parte  obscurecida como  um  bitmap na  memória  para aumentar  a  rapidez no
processo de redesenhar a  janela, porém um certo  tempo é perdido para  alocar o
bitmap. Essa opção não é recomendada



DC´s serão explicados mais tarde.

Operações  gráficas referem-se  ao ato  de desenhar  uma janela  ou controle  ou
outras funções GDI.

Um simples exemplo da construção de uma WNDCLASSEX:

WNDCLASSEX wnd;
wnd.cbClsExtra  = 0;
wnd.cbSize = sizeof(WNDCLASSEX);
wnd.cbWndExtra = 0;
wnd.hbrBackground = (HBRUSH)(COLOR_WINDOW);
wnd.hCursor = LoadCursor(NULL,IDC_ARROW);
wnd.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wnd.hIconSm = LoadIcon(NULL,IDI_APPLICATION);
wnd.hInstance = hInstance;
wnd.lpfnWndProc = (WNDPROC) WProc;
wnd.lpszClassName = "MainWnd";
wnd.lpszMenuName = NULL;
wnd.style = CS_OWNDC;


Programadores mais "avançados" podem estudar a sintaxe da WNDCLASSEX e  montá-la
em somente uma linha de código ;]
Bom,  após a  criação da  WNDCLASSEX, deve-se  registrá-la para  que possa  ser
utilizada pelos threads do  processo em execução. Isso  se faz com o  auxílio da
função RegisterClassEx.

RegisterClassEx(&wnd);

O único parâmetro é  o endereço da WNDCLASSEX  a ser registrada. Logicamente  há
seu equivalente para a WNDCLASS:

RegisterClass(&WNDCLASS);

Estas funções  retornam um  valor (ATOM)  que identifica  unicamente a classe no
sistema. Caso haja erro, o valor de retorno é 0.

Bom, e agora? Agora vamos a parte principal, a tão esperada função que realmente
cria a janela, a CreateWindow(Ex).

A CreateWindowEX() possui  12 parâmetros, enquanto  que a CreateWindow()  possui
11,  sendo  assim elas  só  diferem no  parâmetro  dwExStyle, que,  logicamente,
pertence à CreateWindowEx e não à CreateWindow.

Vamos dar uma olhada nos seus parâmetros:

dwExStyle – Esse  valor é uma  DWORD (int de  32 bit´s para  os mais leigos) que
relata à função  alguns comportamentos extendidos  referentes à janela.  Veremos
seus possíveis valores mais à frente.

lpClassName – Esse valor refere-se ao nome da WNDCLASS registrada, ou seja  deve
ser o mesmo que lpszClassName da classe registrada.

lpWindowName – Um valor que na  maioria das vezes serve como string  primária da
janela.

dwtyle – Comportamentos padrões das janelas.

x e y – int´s que definem as posições horizontal e vertical (respectivamente) da
janela (Left e Top).

nWidth  e  nHeight  –  int´s  que  definem  a  largura  e  a  altura  da  janela
(respectivamente) (Width e Height).

hWndParent – Corresponde  à um HWND  (calma aí) que  identifica a janela  pai da
janela a ser criada. É recomendável  que este valor não seja NULL,  assim sendo,
para  janelas comuns,  deve-se utilizar  a função  GetDesktopWindow(void); como
parâmetro para este valor.

hMenu – Identifica um Menu criado em API pertencente à esta janela.

HInstance – Use sua imaginação ;]

lpParam – Há muito esse parâmetro deixou de ser utilizado. Seu valor consiste em
uma estrutura que contêm  todos os valores acima  citados e estes da  função são
substituídos pelos desta estrutura. Perda de memória, não? ;/

O valor de retorno corresponde à um  HWND. O HWND, ou Window Handle, é  um valor
de 32 bit´s  que identifica uma  janela para que  esta possa ser  manipulada por
diversas funções. Caso a  função falhe, o retorno  é NULL. Em API,  toda função,
quando retorna um erro,  pode ter esse valor  de erro re-adquirido com  a função
GetLastError(void), que retorna uma DWORD (int) com o valor de retorno da função
que retornou o erro.


Os possíveis valores para dwExStyle são:

WS_EX_ACCEPTFILES
Esta janela aceita arquivos arrastados até ela

WS_EX_CLIENTEDGE
Cria uma borda interna à área interna da janela

WS_EX_CONTEXTHELP
Inclui o botão de interrogação na barra de título da janela

WS_EX_CONTROLPARENT
Permite  que  seja  possível  navegar  entre  as  janelas  child  desta   janela
utilizando-se a tecla TAB

WS_EX_DLGMODALFRAME
Cria bordas em janelas com o valor WS_POPUP em dwStyle

WS_EX_LEFT e WS_EX_RIGHT
Cria uma janela que possui propriedades de texto alinhado à esquerda (padrão) ou
à direita, respectivamente

WS_EX_LEFTSCROLLBAR e WS_EX_RIGHTSCROLLBAR
Se  a barra  de rolagem  estiver visível  na janela,  essas opções  definem seu
alinhamento, à esquerda ou à direita (padrão) respectivamente

WS_EX_LTRREADING e  WS_EX_RTLREADING
O texto  da janela  é apresentado  da ordem  especificada, esquerda-para-direita
(padrão) ou direita-para-esquerda.  O segundo valor  só funciona em  línguas que
possuem suporte para este tipo de escrita, como o Hebraico

WS_EX_MDICHILD
Cria uma janela child

WS_EX_NOPARENTNOTIFY
Especifica  que uma  janela child  não irá  notificar sua  janela-pai sobre  sua
criação ou destruição

WS_EX_OVERLAPPEDWINDOW
Combina WS_EX_CLIENTEDGE e WS_EX_WINDOWEDGE

WS_EX_PALETTEWINDOW
Combina WS_EX_WINDOWEDGE, WS_EX_TOOLWINDOW e WS_EX_TOPMOST

WS_EX_STATICEDGE
Cria  uma  janela  com  uma borda  (interna)  em  sua  área externa,  geralmente
utilizados em controles estáticos

WS_EX_TOOLWINDOW
Cria uma janela geralmente utilizada como janela de ferramentas, com uma borda e
fonte de título menores que o original. Esse tipo de janela não aparece na barra
de tarefas ou no menu de ALT+TAB

WS_EX_TOPMOST
Especifica que a  janela deve sempre  sobrepor as janelas  que não possuem  este
valor

WS_EX_TRANSPARENT
Cria uma janela 100%  transparente (não translúcida ;|).  Este tipo de janela  é
comumente utilizado em operações de realinhamento de janela. Este tipo de janela
não é, geralmente, utilizado por aplicativos

WS_EX_WINDOWEDGE
Cria uma janela com uma borda (externa) em sua área externa


Para  x,y, nWidth  e nHeight,  o sistema  provê valores  padrões que  podem ser
utilizados igualando estes valores à CW_USEDEFAULT.

Os possíveis valores de dwStyle:


WS_BORDER
Cria uma janela com uma borda fina

WS_CAPTION
Cria uma janela com uma barra de título e WS_BORDER

WS_CHILD e WS_CHILDWINDOW
Cria uma janela child. Este valor não pode ser mesclado com WS_POPUP


WS_CLIPCHILDREN
Exclui a área ocupada pelas janelas child quando uma janela receber uma mensagem
WM_PAINT (operação gráfica). Esse valor deve ser utilizado em janelas pai

WS_CLIPSIBLINGS
Esse valor evita alguns problemas gráficos com janelas child. Você mesmo  poderá
fazer um  teste utilizandp  2 janelas  child, uma  com este  valor e  outra sem,
coloque uma sobre a outra e mude-as de tamanho e posição ;]

WS_DISABLED
Cria uma janela desabilitada. Esse tipo de janela não recebe entrada do usuário

WS_DLGFRAME
Cria uma borda que é comumente utilizada em caixas de diálogo

WS_GROUP
Especifica o primeiro controle em um grupo de controles

WS_HSCROLL e WS_VSCROLL
Cria  uma  janela que  possui  uma barra  de  rolagem horizontal  e/ou  vertical
(respectivamente)

WS_ICONIC e WS_MINIMIZE
Cria uma janela que está inicialmente minimizada

WS_MAXIMIZE
Cria uma janela que está inicialmente maximizada

WS_MAXIMIZEBOX e WS_MINIMIZEBOX
Cria uma janela que possui um botão de maximizar e/ou minimizar (respectivamente)

WS_OVERLAPPED e WS_TILED
Cria uma janela que possui uma borda e uma barra de titulo

WS_OVERLAPPEDWINDOW e WS_TILEDWINDOW
Cria  uma  janela num  estilo  mais comum  mesclando  WS_OVERLAPPED, WS_CAPTION,
WS_SYSMENU, WS_THICKFRAME, WS_MINIMIZEBOX e WS_MAXIMIZEBOX

WS_POPUP
Cria uma janela popup, sem bordas ou barra de titulo

WS_POPUPWINDOW
Mescla WS_BORDER, WS_POPUP e WS_SYSMENU

WS_SIZEBOX e WS_THICKFRAME
Cria uma janela que possui uma barra de reajuste de tamanho

WS_SYSMENU
Cria uma janela com um menu de janela comum. O valor WS_CAPTION é recomendado

WS_TABSTOP
Especifica um  controle que  pode receber  o foco  quando o  usuário pressiona a
tecla TAB

WS_VISIBLE
Cria uma janela que esta inicialmente visível

Exemplo =D:


HWND MainWnd = CreateWindowEx(WS_EX_WINDOWEDGE,"MainWnd","Janela de exemplo",
WS_OVERLAPPEDWINDOW,120,150, CW_USEDEFAULT,450,GetDesktopWindow(),NULL,hInstance,NULL);


Uma simples verificação:

If(!MainWnd){PostQuitMessage(0);}


A função PostQuitMessage(int) finaliza o programa terminando o seu Message  Loop
que será visto adiante.
Após  a  criação da  janela,  se esta  não  houver sido  criada  com WS_SHOW,  é
necessário mostrá-la. Para isso utiliza-se ShowWindow(HWND, int).

Exemplo:


ShowWindow(MainWnd,SW_SHOWNORMAL);

Os valores do 2º parâmetro são:

SW_HIDE - Esconde a janela e passa o foco para a próxima janela
SW_MAXIMIZE - Maximiza a janela e recebe o foco
SW_MINIMIZE – Minimiza a janela e recebe o foco
SW_RESTORE - Restaura a janela a seu status padrão e recebe o foco
SW_SHOW – Mostra a janela e recebe o foco
SW_SHOWMAXIMIZED, SW_SHOWMINIMIZED –  Mostra a janela  e a maximiza  ou minimiza
(respectivamente)
SW_SHOWMINNOACTIVE – Minimiza a janela e não recebe foco
SW_SHOWNA – Mostra a janela em seu estado atual, não recebe o foco
SW_SHOWNOACTIVE – Mostra a janela em sua posição e tamanho recentes, não  recebe
o foco
SW_SHOWNORMAL – Mostra a janela, faz o mesmo que SW_RESTORE e recebe o foco
nCmdShow – Isso  mesmo, este é  o valor passado  ao aplicativo por  WinMain, que
pode ser utilizado como valor padrão para o inicio das janelas do aplicativo.


O valor de retorno é um bool. Caso a janela estivesse anteriormente escondida, o
valor de retorno é false (0), caso contrário é true (1).

É  comum  utilizar  também UpdateWindow(HWND);  para  redesenhar  a janela  após
mostra-la:

UpdateWindow(MainWnd);

Caso a função falhe, o valor de retorno (bool) é false.


A partir daqui, caso você deseje que função subseqüentes sejam realizadas,  pode
incluí-las no código.
Após tudo isso você pensa que acabamos com a WinMain???
Lembra-se que quando a  função retorna um valor  ou chega ao seu  fim o programa
termina? Então, como os programas Win32 rodam por tempo indefinido?
Simples, com a utilização de um pequeno artifício chamado Message Loop.
O Message Loop, como seu nome sugere, consiste em um loop no qual uma mensagem é
analisada e enviada à janela. O loop consiste em 3 funções simples:


GetMessage(&MSG,HWND,unsigned int, unsigned int);
TranslateMessage(&MSG);
DispatchMessage(&MSG)

O MSG corresponde à um valor que identifica uma mensagem de sistema.

Sintáxe comum de um message loop:

MSG msg;

while ( GetMessage(&msg,NULL,0,0) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

Um sistema de mensagens é um  artifício do sistema operacional para coordenar  a
comunicação entre processos e não será abordado aqui.

A descrição do loop é simples:

while ( GetMessage(&msg,NULL,0,0) )

Esse linha simplesmente cria um loop no qual a função GetMessage pega a primeira
mensagem  na fila  de mensagens  do thread  atual. O  fato de  que as  mensagens
correspondem ao  thread atual  e não  à uma  janela especifica  provêm de  que o
segundo parâmetro é neutro, e assim deve permanecer, pois, caso uma janela  seja
descrita, com o fechamento de tal  janela o aplicativo todo seria finalizado  de
maneira indesejável.

O valor de retorno (bool), é true em casos normais, é false quando é  processada
uma mensagem WM_QUIT (Assim como a enviada por PostQuitMessage()) e –1 quando  a
função falha.

Caso você feche a janela descrita em  HWND, a função retornaria –1 para o  while
gerando, assim, um erro fatal ao aplicativo. Por estas razões, no message  loop,
HWND deve sempre ser NULL.

O 3º  parâmetro indica  a primeira  mensagem na  fila e  o 2º,  a última.  Estes
valores devem ser 0 para que as mensagens sejam processadas assim que chegarem à
fila.

TranslateMessage(&msg);

Essa função traduz mensagens que apresentam códigos virtuais para código  ASCII.
Tais mensagens são geralmente enviadas somente pelo teclado.


DispatchMessage(&msg);

Essa  função envia  a mensagem  para a  WindowProc responsável  pela janela  que
recebeu a mensagem.

Após o message loop, pode-se incluir normalmente o return ;]

return 0;

Aí  está  uma simples  WinMain.  Agora, vamos  à  WindowProc, que  analisará  as
mensagens enviadas para a janela. Como  já vimos, a sintaxe do Window  Procedure
é:

LRESULT CALLBACK WinProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);

E o valor de retorno corresponde a um long.


O primeiro  parâmetro da  função corresponde  ao HWND  da janela responsável por
receber a mensagem. O segundo, à mensagem em si, o terceiro e o quarto à  demais
parâmetros da mensagem.
O  método  mais  comum de  se  trabalhar  com o  WinProc  é  dando um  switch  e
verificando as mensagens enviadas:


LRESULT CALLBACK WinProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{

switch(msg) {
case WM_DESTROY:{
PostQuitMessage(1);
}

case WM_CREATE:{
FazAlgumaCoisa();
}
}

return DefWindowProc(hWnd,msg,wParam,lParam);
}

As mensagens  aí enviadas  correspondem, respectivamente,  à quando  a janela  é
finalizada e criada.

DefWindowProc corresponde  à uma  função que  recepta as  mensagens que  não são
processadas pela WinProc.  Os parâmetros são  os mesmos da  WinProc. Essa função
garante que todas as mensagens sejam receptadas de maneira correta.

return 0; geralmente funciona também ;]

As mensagens mais comuns são citadas a seguir com seus respectivos eventos:


WM_ACTIVATE
OnActivate, OnGetFocus, OnEnter

WM_ACTIVATEAPP, WM_KILLFOCUS
OnLostFocus, OnExit, OnDeactivate

WM_CLOSE
OnClose

WM_COPY
OnCopy

WM_CREATE
OnCreate, OnLoad

WM_CUT
OnCut

WM_DESTROY
OnDestroy

WM_ENABLE
OnEnable

WM_HELP
OnHelp

WM_KEYDOWN
OnKeyDown

WM_KEYUP
OnKeyUp

WM_KILLFOCUS
OnLostFocus, OnExit, OnDeactivate

WM_LBUTTONDNLCLK
OnDblClick (Botão esquerdo)

WM_LBUTTONDOWN
OnMouseDown (Botão esquerdo)

WM_LBUTTONUP
OnMouseUp (Botão esquerdo)

WM_MBUTTONDBLCLK
OnDblClick (Botão do meio)

WM_MBUTTONDOWN
OnMouseDown (Botão do meio)

WM_MBUTTONUP
OnMouseUp (Botão do meio)

WM_MOUSEMOVE
OnMouseMove

WM_MOUSEWHEEL
OnMouseWheel

WM_MOVE
OnMoved

WM_MOVING
OnMove

WM_PAINT
OnPaint, OnRepaint

WM_PASTE
OnPaste

WM_QUIT
OnTerminate

WM_RBUTTONDNLCLK
OnDblClick (Botão direito)

WM_RBUTTONDOWN
OnMouseDown (Botão direito)

WM_RBUTTONUP
OnMouseUp (Botão direito)

WM_SETFOCUS
OnActivate, OnGetFocus, OnEnter

WM_SIZE
OnResized

WM_SIZING
OnResizing, OnResize

WM_TIMER
OnTimer

WM_UNDO
OnUndo


A partir daí  você já está  apto a monitorar  suas próprias mensagens,  mas, por
enquanto, vamos montar um simples programa que não faça nada menos do que aquilo
que aprendemos até agora, exceto o uso da função API SetWindowText(HWND,char  *)
que modifica a string da barra de título da janela (Caption):



/*Programa simples de exemplo*/


#include
#pragma hdrstop      //diretiva de pré-processador

LRESULT CALLBACK WinProc(HWND,UINT,WPARAM,LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR nCmdLine,
 int nCmdShow)

{
MSG msg;
WNDCLASSEX wnd;
wnd.cbClsExtra = 0;
wnd.cbSize = sizeof(WNDCLASSEX);
wnd.cbWndExtra = 0;
wnd.hbrBackground = (HBRUSH) COLOR_WINDOW;
wnd.hCursor = LoadCursor(NULL,IDC_ARROW);
wnd.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wnd.hIconSm = LoadIcon(NULL,IDI_APPLICATION);
wnd.hInstance = hInstance;
wnd.lpfnWndProc = (WNDPROC) WinProc;
wnd.lpszClassName = "Janela";
wnd.lpszMenuName = NULL;
wnd.style = NULL;


if(!RegisterClassEx(&wnd)){PostQuitMessage(0);}

HWND handle = CreateWindowEx(NULL,"Janela","Janela de Exemplo",
WS_OVERLAPPEDWINDOW,150,150,300,300,GetDesktopWindow(),NULL,hInstance,NULL);


if(!handle){PostQuitMessage(0);}

ShowWindow(handle,nCmdShow);
UpdateWindow(handle);
while(GetMessage(&msg,NULL,0,0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return 0;

}

LRESULT CALLBACK WinProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{


switch(Msg){
case WM_RBUTTONDOWN:
SetWindowText(hWnd,"Clique direito");
break;

case WM_LBUTTONDOWN:
SetWindowText(hWnd,"Clique esquerdo");
break;

case WM_MBUTTONDOWN:
SetWindowText(hWnd,"Clique com botão do meio");
break;

case WM_MOVE:
SetWindowText(hWnd,"Janela movida");
break;

case WM_SIZE:
SetWindowText(hWnd,"Tamanho modificado");
break;

case WM_KEYDOWN:
SetWindowText(hWnd,"Tecla pressionada");
break;

case WM_DESTROY:
PostQuitMessage(0);
}

return DefWindowProc(hWnd,Msg,wParam,lParam);

}


/*Fim do programa!

Este programa foi compilado em  Visual Studio 6.0. A macro  WIN_32_LEAN_AND_MEAN
foi utilizada,  embora não  tenha sido  citada aqui.  O programa  compilado está
disponível aqui e possui 152 KB.*/

Bom, agora  você já  sabe criar  uma janela  simples e  manipular as  principais
mensagens que podem  vir a ocorrer.  No próximo capítulo  entraremos em detalhes
nos  controles  simples  de  Windows,  e  ainda  veremos  alguns  parâmetros das
mensagens mais comuns e aprenderemos alguns truquezinhos ;]]



Xor´s para todos ;]
100% Livre!!!Livre para escolher o que há de melhor no Windows e Linux. Livre de preconceito direto ou inverso!
Adote essa filosofia e tenha mais chance de sucesso profissional.

Anonymous


_Dr4k0_

Defcon:

não na motdguide dps eu posto o link aqui
100% Livre!!!Livre para escolher o que há de melhor no Windows e Linux. Livre de preconceito direto ou inverso!
Adote essa filosofia e tenha mais chance de sucesso profissional.