Escolar Documentos
Profissional Documentos
Cultura Documentos
Andr Kishimoto
Programao Windows:
C e Win32 API com
nfase em Multimdia
So Paulo, 2006
1a edio
Todos os direitos reservados e protegidos por lei. Nenhuma parte deste livro
pode ser utilizada ou reproduzida sob qualquer forma ou por qualquer meio,
nem armazenada em base de dados ou sistema de recuperao sem permisso
prvia e por escrito do autor, com exceo de citaes breves em artigos
crticos e anlises. Fazer cpias de qualquer parte deste livro constitui violao
das leis internacionais de direitos autorais.
ISBN 85-906129-1-0
Andr Kishimoto
kishimoto@tupinihon.com
http://www.tupinihon.com
Captulo 1 Iniciando 5
Win32 API, Platform SDK, MFC??? 5
Notao hngara e nomenclatura de variveis 6
Seu primeiro programa 8
A #include <windows.h> 9
Entendendo o programa 10
A caixa de mensagem 12
Bibliografia 209
Introduo
A idia de escrever um livro sobre programao Windows teve incio
em 2002, durante uma aula de Estrutura de Dados na faculdade. Nessa aula,
todos os alunos tinham que entregar um trabalho sobre implementao de
filas, e o projeto consistia em implementar uma simulao de fbrica: quando o
usurio quisesse, o programa deveria criar diferentes tipos de matria-prima,
que seriam processados por uma suposta mquina, na qual, dependendo da
matria-prima que fosse processada, um produto diferente seria criado.
- O Autor
Estilos de escrita:
void main(void)
{
printf(Texto exemplo\n);
}
Avisos:
Recursos necessrios
Para criar os programas-exemplo desse livro ser necessrio ter um
compilador C/C++ 32-bit que crie arquivos executveis para Windows
instalado no computador. Existem diversos compiladores no mercado, tais
como Dev-C++, lcc-Win32, Inprise/Borland C++ Builder e Microsoft Visual
C++. Escolha um que voc se adapte melhor.
Captulo 1 Iniciando
A criao de programas para Windows um pouco diferente da
programao de aplicativos console para MS-DOS, sendo primeira vista algo
mais complexo, pois o prprio Windows em si um sistema mais complexo e
avanado que o MS-DOS.
//--------------------------------------------------------------------------
// Bibliotecas
//--------------------------------------------------------------------------
#include <windows.h>
//--------------------------------------------------------------------------
// WinMain() -> Funo principal
//--------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MessageBox(NULL, "Esse o Primeiro Programa-Exemplo!", "Prog 01", MB_OK);
return(0);
}
Listagem 1.1: Um programa mnimo em Windows.
A #include <windows.h>
Para que voc possa comear a criar um programa para Windows, o
primeiro passo a ser feito incluir o arquivo de cabealho windows.h no seu
programa. Esse arquivo de cabealho contm definies, macros e estruturas
para escrever cdigos portveis entre as verses do Microsoft Windows.
Nota: na Win32 API, foram criados novos tipos de variveis, como LONG,
LPSTR e HANDLE. Todos esses tipos so modificaes dos tipos padres da
linguagem C (LONG, por exemplo, um inteiro de 32 bits), e devem ser
utilizados para compatibilidade, pois no futuro um LONG poder ser de 64
bits, suportando os novos processadores e sistemas operacionais. Assim,
facilitar a portabilidade de um sistema para outro.
Entendendo o programa
Como voc pode notar, no existe mais uma funo main() no cdigo
do programa, sendo essa substitudo pela funo WinMain(). A funo WinMain()
a funo principal de qualquer programa Windows e deve ser inclusa
obrigatoriamente, pois chamado pelo sistema como ponto inicial do
programa. Diferente da funo main(int argv, char *argc[]), ela recebe quatro
parmetros e possui o seguinte prottipo:
Nota: enquanto a funo main(int argv, char *argc[]) pode ser declarada
apenas como main() sem parmetros, a funo WinMain(HINSTANCE
hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) deve
sempre ser declarada com todos seus quatro parmetros, mesmo que esses
no sejam utilizados.
Valor Descrio
SW_HIDE Esconde a janela e ativa outra janela.
SW_MINIMIZE Minimiza a janela especificada e ativa a janela
de nvel mais alto na listagem do sistema.
A caixa de mensagem
Vamos passar agora para o cdigo dentro da funo WinMain(). A
funo MessageBox() uma funo da Win32 API que mostra uma caixa de
mensagem para o usurio com alguns botes e cones pr-definidos.
int MessageBox(
HWND hWnd, // identificador da janela-pai
LPCTSTR lpText, // ponteiro para texto da caixa de mensagem
LPCTSTR lpCaption, // ponteiro para ttulo da caixa de mensagem
UINT uType // estilo da caixa de mensagem
);
Valor Descrio
MB_ABORTRETRYIGNORE A caixa de mensagem contm trs botes:
Anular, Repetir e Ignorar.
MB_OK A caixa de mensagem contm um boto OK
(esse o padro)
MB_OKCANCEL A caixa de mensagem contm os botes OK e
Cancelar.
MB_RETRYCANCEL A caixa de mensagem contm os botes
Repetir e Cancelar.
MB_YESNO A caixa de mensagem contm os botes Sim e
No.
MB_YESNOCANCEL A caixa de mensagem contm os botes Sim,
No e Cancelar.
MB_ICONEXCLAMATION Um cone de ponto de exclamao aparecer
na caixa de mensagem.
MB_ICONINFORMATION Um cone com a letra i aparecer na caixa
de mensagem.
MB_ICONQUESTION Um cone de ponto de interrogao aparecer
na caixa de mensagem.
MB_ICONSTOP Um cone de sinal de parada aparecer na
caixa de mensagem.
MB_DEFBUTTON1 O primeiro boto da caixa de mensagem o
boto padro (default), a menos que
MF_DEFBUTTON2, MF_DEFBUTTON3 ou MF_DEFBUTTON4
seja especificado.
MB_DEFBUTTON2 O segundo boto da caixa de mensagem o
boto padro.
MB_DEFBUTTON3 O terceiro boto da caixa de mensagem o
boto padro.
MB_DEFBUTTON4 O quarto boto da caixa de mensagem o
boto padro.
Tabela 1.3: Os flags que podem ser utilizados no MessageBox().
Valor Descrio
IDABORT Boto Anular foi pressionado.
IDCANCEL Boto Cancelar foi pressionado.
IDIGNORE Boto Ignorar foi pressionado.
IDNO Boto No foi pressionado.
IDOK Boto OK foi pressionado.
IDRETRY Boto Repetir foi pressionado.
IDYES Boto Sim foi pressionado.
Tabela 1.4: Valores retornado pela funo MessageBox().
Definindo a classe
A primeira etapa para a criao da janela do seu programa declarar
uma classe da janela. Apesar de ser chamada de classe, esse novo tipo de
dado uma struct que armazena as informaes sobre a janela do programa.
Sua estrutura definida como:
typedef struct _WNDCLASSEX {
UINT cbSize; // tamanho da estrutura, em bytes
UINT style;
style; // estilo da classe
WNDPROC lpfnWndProc; // ponteiro para a funo que processa mensagens
int cbClsExtra; // bytes extras a serem alocados depois da estrutura da
janela
int cbWndExtra; // bytes extras a serem alocados depois da instncia da
janela
HANDLE hInstance; // identificador da instncia da janela
HICON hIcon; // identificador do cone
Valor Descrio
CS_DBLCLKS Envia mensagens de duplo-clique do mouse
para o programa.
CS_HREDRAW Redesenha toda a janela se um ajuste de
movimento ou tamanho foi feito na horizontal
da janela.
CS_NOCLOSE Desabilita o menu Fechar ALT+F4 do menu
da janela.
CS_OWNDC Aloca um contexto de dispositivo para cada
janela da classe.
CS_VREDRAW Redesenha toda a janela se um ajuste de
movimento ou tamanho foi feito na vertical da
janela.
Tabela 2.1: Alguns estilos de janela.
Valor Descrio
IDI_APPLICATION cone padro (parecido com um cone de
programas MS-DOS).
IDI_ASTERISK Idem a IDI_INFORMATION.
IDI_ERROR cone crculo vermelho com um X.
IDI_EXCLAMATION Idem a IDI_WARNING.
IDI_HAND Idem a IDI_ERROR.
IDI_INFORMATION cone com ponto de exclamao num balo
branco.
IDI_QUESTION cone com ponto de interrogao num balo
branco.
IDI_WARNING cone com ponto de exclamao numa placa
amarela.
IDI_WINLOGO cone com o logotipo do Windows.
Tabela 2.2: cones pr-definidos pelo sistema.
Valor Descrio
IDC_APPSTARTING Cursor padro com pequena ampulheta.
IDC_ARROW Cursor padro.
IDC_CROSS Cursor em forma de cruz.
IDC_HELP Cursor seta e ponto de interrogao.
IDC_IBEAM Cursor de texto (I-beam).
IDC_NO Cursor com smbolo de proibido.
IDC_SIZEALL Cursor com setas na vertical e horizontal.
IDC_SIZENESW Cursor com setas na diagonal para direita.
IDC_SIZENS Cursor com setas na vertical.
IDC_SIZENWSE Cursor com setas na diagonal para esquerda.
IDC_SIZEWE Cursor com setas na horizontal.
IDC_UPARROW Cursor com seta para cima.
IDC_WAIT Cursor de ampulheta.
Tabela 2.3: Cursores pr-definidos pelo sistema.
HGBIOBJ GetStockObject(
int fnObject // tipo de objeto pr-definido
};
Valor Descrio
BLACK_BRUSH Pincel preto.
DKGRAY_BRUSH Pincel cinza escuro.
GRAY_BRUSH Pincel cinza.
HOLLOW_BRUSH Pincel transparente (idem a NULL_BRUSH).
LTGRAY_BRUSH Pincel cinza claro.
NULL_BRUSH Pincel transparente (idem a HOLLOW_BRUSH).
WHITE_BRUSH Pincel branco.
Tabela 2.4: Pincis pr-definidos do Windows.
Registrando a classe
Com a classe da janela j inicializada, a prxima etapa registr-la para
que o Windows permita que voc crie janelas a partir das informaes
fornecidas dentro da classe. preciso registrar a classe antes de tentar criar
qualquer janela! Para isso, utilizamos a funo RegisterClassEx(), que tem o seguinte
prottipo:
ATOM RegisterClassEx(
CONST WNDCLASSEX *lpwcx // endereo da estrutura com os dados da classe
);
Criando a janela
Depois de definir a classe da janela e registr-la, podemos ento criar a
janela principal do programa. Para isso, utilizamos a seguinte funo:
HWND CreateWindowEx(
DWORD dwExStyle, // estilos extras da janela
LPCTSTR lpClassName, // ponteiro string para o nome da classe registrada
LPCTSTR lpWindowName, // ponteiro string para o ttulo da janela
DWORD dwStyle, // estilo da janela
int x, // posio horizontal da janela
int y, // posio vertical da janela
int nWidth, // largura da janela
int nHeight,
nHeight, // altura da janela
HWND hWndParent, // identificador da janela-pai
HMENU hMenu, // identificador do menu
HINSTANCE hInstance, // identificador da instncia do programa
LPVOID lpParam // ponteiro para dados de criao da janela
);
Estilo Descrio
WS_BORDER Cria uma janela com borda fina.
WS_CAPTION Cria uma janela com barra de ttulo (inclui o
estilo WS_BORDER).
WS_CHILD Cria uma janela-filho. Esse estilo no pode ser
utilizado junto com o estilo WS_POPUP.
WS_CLIPCHILDREN Exclui a rea ocupada pelas janelas-filho
quando necessrio fazer atualizao da
janela-pai. Esse estilo usado quando se cria
uma janela-pai.
WS_DISABLED Cria uma janela inicialmente desabilitada.
Uma janela desse estilo no pode receber
entradas do usurio.
WS_DLGFRAME Cria uma janela com borda tpica de caixas de
dilogo. No possui barra de ttulo.
WS_HSCROLL Cria uma janela com barra de rolagem
horizontal.
WS_MAXIMIZE Cria uma janela inicialmente maximizada.
WS_MAXIMIZEBOX Cria uma janela que contm o boto de
Maximizar. No pode ser combinado com o
estilo WS_EX_CONTEXTHELP e o estilo WS_SYSMENU
deve ser especificado.
WS_MINIMIZE Cria uma janela inicialmente minimizada.
WS_MINIMIZEBOX Cria uma janela que contm o boto de
Minimizar. No pode ser combinado com o
estilo WS_EX_CONTEXTHELP e o estilo WS_SYSMENU
deve ser especificado.
WS_OVERLAPPED Cria uma janela com borda e barra de ttulo.
WS_OVERLAPPEDWINDOW Cria uma janela com os estilos WS_OVERLAPPED,
WS_CAPTION, WS_SYSMENU, WS_THICKFRAME,
WS_MINIMIZEBOX e WS_MAXIMIZEBOX.
WS_POPUP Cria uma janela pop-up. No pode ser utilizado
com o estilo WS_CHILD.
WS_POPUPWINDOW Cria uma janela pop-up com os estilos
WS_BORDER, WS_POPUP e WS_SYSMENU. Os estilos
WS_POPUPWINDOW e WS_CAPTION devem ser
combinados para deixar a janela visvel.
WS_SIZEBOX Cria uma janela que contm uma borda de
ajuste de tamanho.
WS_SYSMENU Cria uma janela que tem o menu de sistema
na barra de ttulo. O estilo WS_CAPTION tambm
deve ser especificado.
WS_TABSTOP Especifica um controle que pode receber o
cursor do teclado quando o usurio pressiona
a tecla TAB. Ao pressionar a tecla TAB, o
cursor do teclado muda para o prximo
controle com o estilo WS_TABSTOP.
WS_VISIBLE Cria uma janela inicialmente visvel.
WS_VSCROLL Cria uma janela com barra de rolagem
vertical.
Tabela 2.5: Principais estilos da janela.
Estilo Descrio
WS_EX_ACCEPTFILES A janela com esse estilo aceita arquivos
arrastados para ela.
WS_EX_CLIENTEDGE Cria uma borda afundada na janela.
WS_EX_CONTROLPARENT Permite o usurio navegar entre as janelas-
filho usando a tecla TAB.
WS_EX_MDICHILD Cria uma janela-filho MDI.
WS_EX_TOOLWINDOW Cria uma janela de ferramentas flutuante;
contm uma barra de ttulo menor que a
normal e utiliza uma fonte menor para o
ttulo. Esse estilo de janela no aparece na
barra de tarefas ou quando o usurio aperta
as teclas ALT+TAB.
WS_EX_TOPMOST Especifica que a janela criada deve
permanecer acima de todas as outras janelas
do sistema, mesmo que essa seja desativada.
Tabela 2.6: Principais estilos extras da janela.
hWnd = CreateWindowEx(parmetros);
BOOL ShowWindow(
HWND hWnd, // identificador da janela
int nCmdShow // estado da janela
);
O loop de mensagens
A prxima etapa criar um loop onde sero verificadas todas as
mensagens que o Windows enviar para a fila de mensagens do programa. Essa
etapa consiste em trs passos: em primeiro lugar, o programa deve receber a
mensagem que est na fila; em seguida, traduz cdigos de teclas virtuais ou
aceleradoras (de atalho) em mensagens de caracteres/teclado, para finalmente
despachar as mensagens para a funo que processam elas. Porm, antes do
loop, declaramos uma varivel do tipo MSG que armazenar a mensagem atual,
com as seguintes informaes:
typedef struct tagMSG {
HWND hWnd; // identificador da janela que recebe as mensagens
Processando mensagens
Para o funcionamento do nosso programa, preciso que as mensagens
enviadas pelo Windows sejam processadas, e isso feito atravs da funo
WindowProc(), que uma funo j definida para todos os programas (essa a
tal funo especial que foi mencionada no segundo pargrafo do captulo 1).
Seu prottipo tem o seguinte aspecto:
LRESULT CALLBACK WindowProc(
HWND hWnd, // identificador da janela
UINT uMsg, // identificador da mensagem
WPARAM wParam, // primeiro parmetro da mensagem
LPARAM lParam // segundo parmetro da mensagem
);
motivo, a funo tem o retorno do tipo LRESULT CALLBACK, significando que ela
chamada pelo sistema e retorna ao Windows. O valor de retorno o
resultado do processamento da mensagem, o qual depende da mensagem
enviada.
Quanto aos seus parmetros, a funo WindowProc() recebe um
identificador da janela principal (HWND hWnd), a mensagem a ser processada, UINT
uMsg (note que essa mensagem no a mesma do loop de mensagens a do
loop uma varivel do tipo MSG), e dois parmetros (WPARAM wParam e LPARAM
lParam) que podem conter informaes adicionais sobre a mensagem por
exemplo, na mensagem de movimento de mouse (WM_MOUSEMOVE), wParam indica
se algum boto do mouse est pressionado e lParam armazena a posio (x, y)
do cursor do mouse.
Mensagem Descrio
WM_ACTIVATE Enviada quando a janela ativada.
WM_CHAR Enviada quando uma mensagem WM_KEYDOWN
traduzida pela funo TranslateMessage().
WM_CLOSE Enviada quando a janela fechada.
WM_COMMAND Enviada quando o usurio seleciona um item
de um menu, quando um controle (boto,
scrollbar, etc) envia uma mensagem para a
janela-pai ou quando uma tecla de atalho
ativada.
WM_CREATE Enviada quando a janela criada pela funo
CreateWindowEx(). Essa mensagem enviada
funo de processamento de mensagens aps a
janela ser criada, mas antes dela se tornar
visvel.
WM_DESTROY Enviada quando a janela destruda. Essa
mensagem enviada funo de
programa expira.
Tabela 2.7: Principais mensagens enviadas ao programa.
return(0);
} break;
return(0);
} break;
return(0);
} break;
}
}
Listagem 2.2: Exemplo da funo WindowsProc().
Essa funo indica ao sistema que uma foi feito um pedido para que o
programa termine. O parmetro int nExitCode especifica o cdigo de sada do
programa e utilizado como o parmetro wParam da mensagem WM_QUIT
(lembre-se que aps o loop de mensagens receber WM_QUIT, o programa
finalizado com a WinMain() retornando o valor de msg.wParam).
//--------------------------------------------------------------------------
// Bibliotecas
//--------------------------------------------------------------------------
#include <windows.h>
//--------------------------------------------------------------------------
// Definies
//--------------------------------------------------------------------------
// Nome da classe da janela
#define WINDOW_CLASS "prog02"
// Ttulo da janela
#define WINDOW_TITLE "Prog 02"
// Largura da janela
#define WINDOW_WIDTH 320
// Altura da janela
#define WINDOW_HEIGHT 240
//--------------------------------------------------------------------------
// Prottipo das funes
//--------------------------------------------------------------------------
LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM);
//--------------------------------------------------------------------------
// WinMain() -> Funo principal
//--------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// Cria a classe da janela e especifica seus atributos
WNDCLASSEX wcl;
wcl.cbSize = sizeof(WNDCLASSEX);
wcl.style = CS_HREDRAW | CS_VREDRAW;
wcl.lpfnWndProc = (WNDPROC)WindowProc;
wcl.cbClsExtra = 0;
wcl.cbWndExtra = 0;
wcl.hInstance = hInstance;
wcl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcl.hCursor = LoadCursor(NULL, IDC_ARROW);
wcl.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wcl.lpszMenuName = NULL;
wcl.lpszClassName = WINDOW_CLASS;
wcl.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
NULL,
WINDOW_CLASS,
WINDOW_TITLE,
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
(GetSystemMetrics(SM_CXSCREEN) - WINDOW_WIDTH) / 2,
(GetSystemMetrics(SM_CYSCREEN) - WINDOW_HEIGHT) / 2,
WINDOW_WIDTH,
WINDOW_HEIGHT,
HWND_DESKTOP,
NULL,
hInstance,
NULL);
return(0);
}
}
// Se a classe da janela no foi registrada
else
{
// Exibe mensagem de erro e sai do programa
MessageBox(NULL, "No foi possvel registrar a classe da janela.",
"Erro!", MB_OK | MB_ICONERROR);
return(0);
}
//--------------------------------------------------------------------------
// WindowProc() -> Processa as mensagens enviadas para o programa
//--------------------------------------------------------------------------
LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
// Variveis para manipulao da parte grfica do programa
HDC hDC = NULL;
PAINTSTRUCT psPaint;
return(0);
} break;
return(0);
} break;
return(0);
} break;
}
}
Listagem 2.3: O programa completo para criar a janela.
HWnd = CreateWindowEx(
...
(GetSystemMetrics(SM_CXSCREEN) - WINDOW_WIDTH) / 2,
(GetSystemMetrics(SM_CYSCREEN) - WINDOW_HEIGHT) / 2,
...);
Valor Descrio
SM_CLEANBOOT Valor que especifica como o sistema foi
iniciado:
0 Boot normal
1 Boot em modo de segurana
2 Boot em modo de segurana com rede
SM_CMONITORS Nmero de monitores no desktop (apenas
para Windows NT 5.0 ou superior e Windows
98 ou superior).
SM_CMOUSEBUTTONS Nmero de botes do mouse, ou zero se no
h mouse instalado.
SM_CXBORDER, Largura e altura da borda da janela.
SM_CYBORDER
Equivalente ao valor de SM_CXEDGE e SM_CYEDGE
para janelas com visual 3D.
SM_CXCURSOR, Largura e altura do cursor.
SM_CYCURSOR
Enviando mensagens
Quando os usurios utilizam nossos programas, eles esto
indiretamente gerando mensagens a serem processadas (cliques de mouse, uso
do teclado, mudana de posio ou tamanho da janela, etc). Ns, como
programadores, podemos enviar mensagens explicitamente para serem
processadas pela WindowProc().
return(0);
} break;
// mensagens...
}
}
Listagem 2.4: Enviando mensagens.
IDs
Os recursos so reconhecidos pelo programa atravs de nmeros
inteiros e positivos, definidos num arquivo de cabealho .h. Esses nmeros so
conhecidos como sendo os IDs dos recursos. A Win32 API possui algumas
funes que no aceitam variveis-identificadores (handles) como parmetro, e
sim IDs de controles (botes, caixas de texto, etc) e recursos (cones, menus,
etc), como a funo LoadIcon().
cones personalizados
O primeiro recurso que aprenderemos a incluir no programa o cone.
Com o editor de textos ASCII aberto, digitamos a seguinte linha no arquivo .rc:
IDI_MEUICONE ICON meuicone.ico"
//--------------------------------------------------------------------------
// prog03-1-res.rc - Arquivo de recursos
//--------------------------------------------------------------------------
#include "prog03-1-res.h"
//--------------------------------------------------------------------------
// Bibliotecas
//--------------------------------------------------------------------------
#include <windows.h>
Novos cursores
O prximo recurso que veremos o cursor. Sua definio no arquivo
de recursos muito semelhante ao cone:
IDC_MEUCURSOR CURSOR meucursor.cur
Bitmaps e sons
Figura 3.4: Informaes utilizadas pelo Windows Explorer (no Windows XP).
Valor Descrio
VS_FF_DEBUG Arquivo tem informaes de depurao ou foi
compilado no modo debug.
VS_FF_PATCHED Arquivo foi modificado e no igual ao
original de mesmo nmero de verso.
Valor Descrio
VOS_UNKNOWN Sistema operacional para o qual o arquivo foi
desenvolvido desconhecido.
VOS_DOS Arquivo foi desenvolvido para MS-DOS.
VOS_NT Arquivo foi desenvolvido para Windows
NT/2000/XP.
VOS__WINDOWS16 Arquivo foi desenvolvido para Windows
plataforma 16-bit.
VOS__WINDOWS32 Arquivo foi desenvolvido para Windows
plataforma 32-bit.
VOS_DOS_WINDOWS16 Arquivo foi desenvolvido para Windows
plataforma 16-bit rodando MS-DOS.
VOS_DOS_WINDOWS32 Arquivo foi desenvolvido para Windows
plataforma 32-bit rodando MS-DOS.
VOS_NT_WNDOWS32 Arquivo foi desenvolvido para Windows
NT/2000/XP.
Tabela 3.2: Valores para fileos.
Valor Descrio
VFT_UNKNOWN Arquivo desconhecido.
VFT_APP Arquivo um aplicatico.
VFT_DLL Arquivo uma biblioteca DLL.
VFT_DRV Arquivo um driver de dispositivo. No caso,
subtype especifica mais detalhes do driver.
VFT_FONT Arquivo uma fonte. No caso, subtype
especifica mais detalhes da fonte.
VFT_VXD Arquivo um dispositivo virtual.
VFT_STATIC_LIB Arquivo uma biblioteca esttica.
Tabela 3.3: Valores para filetype.
Valor Descrio
VFT2_UNKNOWN Tipo do driver desconhecido.
VFT2_DRV_COMM Driver de comunicao.
VFT2_DRV_PRINTER Driver de impressora.
VFT2_DRV_KEYBOARD Driver de teclado.
VFT2_DRV_LANGUAGE Driver de lngua.
VFT2_DRV_DISPLAY Driver de vdeo.
VFT2_DRV_MOUSE Driver de mouse.
VFT2_DRV_NETWORK Driver de rede.
VFT2_DRV_SYSTEM Driver de sistema.
VFT2_DRV_INSTALLABLE Driver de instalao.
VFT2_DRV_SOUND Driver de som.
VFT2_DRV_VERSIONED_PRINTER Driver de impressora (com verso).
Tabela 3.4: Valores de drivers para subtype.
Valor Descrio
VFT2_UNKNOWN Tipo de fonte desconhecida.
VFT2_FONT_RASTER Fonte do tipo bitmap.
VFT2_FONT_VECTOR Fonte do tipo vetorial.
VFT2_FONT_TRUETYPE Fonte do tipo True Type.
Tabela 3.5: Valores de fontes para subtype.
Valor Lngua
0407 Alemo
0408 Grego
0409 Ingls americano
0909 Ingls britnico
040A Espanhol
040B Finlands
040C Francs
0410 Italiano
0411 Japons
0416 Portugus (Brasil)
0816 Portugus (Portugal)
Tabela 3.6: Alguns valores para lang-charset.
Valor Descrio
CompanyName Nome da empresa que produziu o arquivo.
FileDescription Descrio do arquivo.
FileVersion Verso do arquivo.
InternalName Nome interno do arquivo. Geralmente o
nome original do arquivo sem extenso.
LegalCopyright Informaes de direitos autorais que se
aplicam ao arquivo. Essa informao
opcional.
LegalTrademarks Informaes de marcas registradas que se
aplicam ao arquivo. Essa informao
opcional.
OriginalFilename Nome original do arquivo, sem o caminho.
Essa informao til para o programa
determinar se o arquivo foi renomeado pelo
usurio.
PrivateBuild Informaes sobre uma verso particular do
arquivo. Essa informao s deve ser inclusa
se VS_FF_PRIVATEBUILD for especificado na linha
FILEFLAGS fileflags.
ProductName Nome do produto o qual o arquivo est sendo
distribudo junto.
ProductVersion Verso do produto o qual o arquivo est
sendo distribudo junto.
SpecialBuild Especifica a diferena entre a verso desse
arquivo com sua verso padro. Essa
informao s deve ser inclusa se
VS_FF_SPECIALBUILD for especificado na linha
FILEFLAGS fileflags.
Comentrios / Informao adicional.
Qualquer outro texto
Tabela 3.8: Informaes do bloco lang-charset.
#include <windows.h>
#include "prog03-4-res.h"
1 VERSIONINFO
FILEVERSION 1,0,0,0
PRODUCTVERSION 1,0,0,0
FILEFLAGSMASK 0x17L
FILEFLAGS 0x0L
FILEOS VOS__WINDOWS32
FILETYPE VFT_APP
FILESUBTYPE VFT2_UNKNOWN
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "041604e4"
BEGIN
VALUE "CompanyName", "Andr Kishimoto"
VALUE "FileDescription", "Uso de recursos - VERSIONINFO"
VALUE "FileVersion", "1.0"
VALUE "InternalName", "prog03-4"
VALUE "LegalCopyright", "Copyright 2004, Andr Kishimoto"
VALUE "OriginalFilename", "prog03-4.exe"
IDM_MEUMENU MENU
{
POPUP "menu1"
" ", tipos (opcional)
{
MENUITEM "item1",
" ", ID_DO_MENU1_ITEM1,
ID_DO_MENU1_ITEM1 tipos (opcional)
MENUITEM "item2",
" ", ID_DO_MENU1_ITEM2,
ID_DO_MENU1_ITEM2 tipos (opcional)
MENUITEM "itemX",
" ", ID_DO_MENU1_ITEMX,
ID_DO_MENU1_ITEMX tipos (opcional)
}
POPUP "menu2"
" ", tipos (opcional)
{
MENUITEM "item1",
" ", ID_DO_MENU2_ITEM1,
ID_DO_MENU2_ITEM1 tipos (opcional)
MENUITEM "item2",
" ", ID_DO_MENU2_ITEM2,
ID_DO_MENU2_ITEM2 tipos (opcional)
MENUITEM "itemX",
" ", ID_DO_MENU2_ITEMX
ID_DO_MENU2_ITEMX,
MENU2_ITEMX tipos (opcional)
}
}
Listagem 3.4: Esqueleto de um menu.
Valor Descrio
CHECKED Menu marcado/selecionado.
GRAYED Menu no pode ser clicado (desabilitado). No
pode ser usado junto com INACTIVE.
HELP Identifica um item de ajuda
INACTIVE Menu inativo (no faz nada, mas pode ser
clicado). No pode ser usado junto com
GRAYED.
MENUBARBREAK Idem a MENUBREAK, exceto que adiciona uma
linha separando as colunas (para itens do
menu-pai).
MENUBREAK Posiciona o menu-pai numa nova linha. Para
itens do menu-pai, posiciona-os numa nova
coluna, sem linhas separatrias.
Tabela 3.9: Aparncia do item do menu.
Nos textos dos menus, so muito utilizadas as teclas hot keys, que so
teclas de atalhos combinadas com o uso do ALT. Para definir uma letra do
texto como hot key, usamos o smbolo & antes da letra. Por exemplo, ao definir
MENUITEM Sai&r, ID_MENU_SAIR, estamos informando que a hot key do item do
menu Sair a combinao ALT+R.
IDA_MEUATALHO ACCELERATORS
{
"1", ID_DO_MENU1_ITEM1, ALT ; ALT+1
VK_F2, ID_DO_MENU1_ITEM2, VIRTKEY ; F2
"^X", ID_DO_MENU1_ITEMX ; CONTROL+X
VK_ESCAPE, IDA_ATALHO_ESC, VIRTKEY ; ESC
}
Listagem 3.6: Criando teclas de atalho.
hWnd = CreateWindowEx(..., ..., ..., ..., ..., ..., ..., ..., ...,
hMenu, ..., ...);
if(hWnd)
{
// Cria identificador do menu do recurso
HMENU hMenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDM_MEUMENU));
// etc
}
Listagem 3.7: Definindo o menu com SetMenu().
BOOL EnableMenuItem(
HMENU hMenu, // identificador do menu
UINT uIDEnableItem // item de menu a ser modificado
UINT uEnable // opes
);
Essa funo faz com que um item do menu fique marcado ou no. Os
parmetros recebem os mesmos valores da funo EnableMenuItem(), com uma
nica diferena no ltimo: ao invs de receber MF_ENABLED, MF_DISABLED ou
MF_GRAYED, a funo deve receber MF_CHECKED (item ser marcado) ou
MF_UNCHECKED (item ser desmarcado). A funo retorna o estado anterior do
item (MF_CHECKED ou MF_UNCHECKED) ou 1 se o item do menu no existir.
BOOL
BOOL CheckMenuRadioItem(
HMENU hmenu, // identificador do menu
UINT idFirst, // ID ou posio do primeiro item do menu
UINT idLast, // ID ou posio do ltimo item do menu
UINT idCheck, // ID ou posio do item do menu a ser modificado
UINT uFlags // opes
);
Caixas de dilogo
O ltimo recurso que veremos a caixa de dilogo janela muito
parecida com as dos programas que estivemos criando at agora, mas que
definida no arquivo de recursos atravs de palavras-chave, facilitando a criao
e layout da mesma.
Na prxima linha, FONT define qual fonte ser utilizado pelos controles
(textos estticos, botes, listas, etc) da caixa de dilogo. O parmetro tamanho
recebe o tamanho da fonte; fonte recebe uma string contendo o nome da fonte
(por exemplo, MS Sans Serif); espessura pode receber um dos valores da
Tabela 4.5 (captulo 4, onde aprenderemos a utilizar fontes no programa); o
parmetro itlico recebe 1 (fonte itlica) ou 0 (fonte no-itlica) e charset
recebe um dos valores da Tabela 4.6.
Valor Descrio
DS_ABSALIGN Indica que a coordenada da caixa de dilogo
est em coordenadas da tela. Se no utilizado,
Nota: o uso do estilo WS_GROUP indica que o controle com esse estilo o
primeiro de um grupo de controles, onde o usurio pode movimentar o
cursor do teclado entre eles atravs das setas direcionais. O prximo
controle com esse estilo comea um outro grupo, finalizando o grupo
anterior.
Valor Descrio
ES_AUTOHSCROLL Rolagem automtica do texto na horizontal.
ES_AUTOVSCROLL Rolagem automtica do texto na vertical.
ES_CENTER Texto centralizado.
ES_LEFT Texto alinhado esquerda.
ES_LOWERCASE Converte todos os caracteres para minsculo.
ES_MULTILINE A caixa possui mltiplas linhas, no apenas
uma (que o padro). Note que para a tecla
ENTER ser utilizada para pular de linha, o
estilo ES_WANTRETURN deve ser especificado.
ES_NUMBER A caixa aceita apenas nmeros.
ES_PASSWORD Mostra um asterisco para cada caractere
inserido na caixa.
ES_READONLY Impede que o usurio possa editar o contedo
da caixa.
ES_RIGHT Texto alinhado direita.
ES_UPPERCASE Converte todos os caracteres para maisculo.
ES_WANTRETURN Indica que uma nova linha ser inserida
quando o usurio apertar a tecla ENTER
numa caixa de mltiplas linhas.
Tabela 3.11: Alguns valores de estilo de caixas de edio.
Valor Descrio
AUTO3STATE Cria um checkbox automtico de trs estados
(marcado, desmarcado ou indeterminado). O
parmetro estilos pode receber BS_AUTO3STATE
(padro), WS_TABSTOP (padro), WS_DISABLED e
WS_GROUP.
AUTOCHECKBOX Cria um checkbox automtico de dois estados
(marcado ou desmarcado). O parmetro
estilos pode receber BS_AUTOCHECKBOX (padro),
WS_TABSTOP (padro) e WS_GROUP.
AUTORADIOBUTTON Cria um boto de rdio automtico. O
parmetro estilos pode receber
BS_AUTORADIOBUTTON (padro), WS_TABSTOP
(padro), WS_DISABLED e WS_GROUP.
CHECKBOX Cria um checkbox de dois estados (marcado ou
desmarcado). O parmetro estilos pode
receber BS_CHECKBOX (padro), WS_TABSTOP
(padro) e WS_GROUP.
PUSHBOX Cria um boto contendo apenas o texto, sem
sua janela em volta. O parmetro estilos pode
receber BS_PUSHBOX (padro), WS_TABSTOP
(padro), WS_DISABLED e WS_GROUP.
PUSHBUTTON Cria um boto comum, com o texto
centralizado. O parmetro estilos pode
receber BS_PUSHBUTTON (padro), WS_TABSTOP
Valor Descrio
BS_3STATE Cria um checkbox de trs estados.
BS_AUTO3STATE Cria um checkbox automtico de trs estados.
BS_AUTOCHECKBOX Cria um checkbox automtico de dois estados.
BS_AUTORADIOBUTTON Cria um boto de rdio automtico.
BS_CHECKBOX Cria um checkbox de dois estados.
BS_DEFPUSHBUTTON Cria um boto comum com uma borda preta
em volta, indicando que ele o padro;
quando o usurio pressiona ENTER numa
caixa de dilogo, mesmo que o cursor do
teclado no esteja nele, o boto executado.
Valor Descrio
CBS_AUTOHSCROLL Faz a rolagem de texto automtica quando o
usurio digita um caracter no fim da linha. Se
esse estilo no for definido, apenas textos que
se encaixam dentro da caixa de seleo so
permitidos.
Valor Descrio
LBS_DISABLENOSCROLL Mostra uma barra de rolagem vertical
desativada quando a lista no contm itens
suficientes para fazer a rolagem. Sem esse
estilo, a barra de rolagem fica escondida
Valor Descrio
SBS_BOTTOMALIGN Alinha a parte inferior da barra de rolagem
com a parte inferior do retngulo definido
pelos parmetros x, y, largura e altura. Use
esse estilo com SBS_HORZ.
SBS_HORZ Cria uma barra de rolagem horizontal.
SBS_LEFTALIGN Alinha o lado esquerdo da barra de rolagem
com o lado esquerdo do retngulo definido
pelos parmetros x, y, largura e altura. Use
esse estilo com SBS_VERT.
SBS_RIGHTALIGN Alinha o lado direito da barra de rolagem com
o lado direito do retngulo definido pelos
parmetros x, y, largura e altura. Use esse
estilo com SBS_VERT.
SBS_TOPALIGN Alinha a parte superior da barra de rolagem
Valor Descrio
SS_BITMAP Indica que um bitmap ser mostrado no
controle esttico. O texto que o controle
recebe o ID do bitmap, definido no arquivo
de recursos. A largura e altura especificadas
so ignoradas, pois o controle se ajusta ao
tamanho do bitmap.
SS_BLACKFRAME Indica que o controle ser um retngulo com
borda preta (sem preenchimento).
SS_BLACKRECT Indica que o controle ser um retngulo preto
(com preenchimento).
SS_CENTER Indica que o controle exibir um texto
centralizado.
SS_CENTERIMAGE Indica que o bitmap ser centralizado no
controle.
SS_GRAYFRAME Indica que o controle ser um retngulo com
borda cinza (sem preenchimento).
SS_GRAYRECT Indica que o controle ser um retngulo cinza
(com preenchimento).
SS_ICON Indica que um cone ser mostrado no
controle esttico. O texto que o controle
recebe o ID do cone, definido no arquivo
de recursos. A largura e altura especificadas
so ignoradas, pois o controle se ajusta ao
tamanho do cone.
SS_LEFT Indica que o controle exibir um texto
alinhado esquerda.
SS_RIGHT Indica que o controle exibir um texto
alinhado direita.
SS_SUNKEN Indica que o controle ter uma borda em
baixo relevo.
SS_WHITEFRAME Indica que o controle ser um retngulo com
borda branca (sem preenchimento).
SS_WHITERECT Indica que o controle ser um retngulo
branco (com preenchimento).
Tabela 3.18: Alguns estilos de controle esttico.
INT_PTR DialogBox(
HINSTANCE hInstance, // identificador do mdulo
LPCTSTR lpTemplate, // recurso da caixa de dilogo
HWND hWndParent, // identificador da janela-pai
DLGPROC lpDialogFunc // funo que processa mensagens da caixa de dilogo
);
BOOL EndDialog(
HWND hDlg, // identificador da caixa de dilogo
INT_PTR nResult // valor de retorno
);
//--------------------------------------------------------------------------
// WindowProc() -> Processa as mensagens enviadas para o programa
//--------------------------------------------------------------------------
LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
// Processando alguma mensagem da WindowProc()
...
...
// continuao da WindowProc()
}
//--------------------------------------------------------------------------
// DlgProcExemp() -> Processa as mensagens enviadas para a caixa de dilogo
//--------------------------------------------------------------------------
INT_PTR CALLBACK DlgProcExemp(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM
lParam)
{
// Verifica qual foi a mensagem enviada
switch(uMsg)
{
return(TRUE);
} break;
}
} break;
}
}
Listagem 3.11: Criao e processamento de mensagens de uma caixa de dilogo modal.
//--------------------------------------------------------------------------
// WinMain() -> Funo principal
//--------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
...
...
}
//--------------------------------------------------------------------------
// WindowProc() -> Processa as mensagens enviadas para o programa
//--------------------------------------------------------------------------
LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
// Processando alguma mensagem da WindowProc()
...
{
// Se no foi, cria e salva identificador em g_hDlg
g_hDlg = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_MEUDIALOGO2), hWnd,
(DLGPROC)DlgProcModeless);
...
// continuao da WindowProc()
}
//--------------------------------------------------------------------------
// DlgProcModeless() -> Processa as mensagens enviadas para a caixa de
// dilogo
//--------------------------------------------------------------------------
INT_PTR CALLBACK DlgProcModeless(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM
lParam)
{
// Verifica qual foi a mensagem enviada
switch(uMsg)
{
return(TRUE);
} break;
}
} break;
}
}
Listagem 3.13: Criao e processamento de mensagens de uma caixa de dilogo modeless.
Dica: assim como um pintor utiliza uma tela para fazer seus desenhos,
podemos dizer que o contexto de dispositivo de vdeo a nossa tela. Em
ambientes de programao como o C++ Builder, o termo canvas (tela)
utilizado em referncia rea onde iremos desenhar.
Figura 4.2: Parte da rea cliente invalidada quando outra janela sobreposta.
HDC BeginPaint(
HWND hWnd, // identificador da janela
LPPAINTSTRUCT lpPaint // ponteiro para estrutura que contm informaes de
desenho
);
//
// Cdigo para desenhar grficos
//
return(0);
} break;
Listagem 4.1: mensagem WM_PAINT.
Nota: assim como ocorre com BeginPaint() e EndPaint(), para cada GetDC()
chamado, deve existir um ReleaseDC() correspondente.
// Obtm identificador do DC
hDC = GetDC(hWnd);
// Desenha crculo
Ellipse(hDC, x - 10, y - 10, x + 10, y + 10);
// Libera DC
ReleaseDC(hWnd, hDC);
return(0);
} break;
Listagem 4.2: Uso das funes GetDC() e ReleaseDC().
//
// Cdigo para desenhar grficos
//
return(0);
} break;
Listagem 4.3: Invalidando a rea cliente.
return(0);
} break;
return(0);
} break;
Listagem 4.4: Enviando mensagem WM_PAINT.
Validando reas
Assim como podemos invalidar partes da rea cliente, tambm
podemos valid-las, atravs da funo ValidateRect(), que valida a parte da rea
cliente especificada num retngulo (passada como parmetro para a funo).
BOOL ValidateRect(
HWND hWnd, // identificador da janela
CONST RECT *lpRect // ponteiro para coordenadas do retngulo
);
No faz muito sentido validarmos parte ou toda a rea cliente, pois isso
feito ao processarmos a mensagem WM_PAINT com as funes BeginPaint() e
EndPaint(). Ento, quando podemos validar manualmente a rea cliente?
Objetos GDI
Alm do DC, precisamos trabalhar com objetos GDI. Os objetos GDI
so tipos de variveis definidas pela Win32 API os quais devem ser criados e
selecionados no DC antes de desenharmos grficos na rea cliente.
isso evita problemas inesperados que possam ocorrer. Veja o trecho de cdigo
a seguir (Listagem 4.5), que seleciona uma caneta no DC e depois restaura a
caneta antiga (no se preocupe em entender como criar uma caneta, mas sim
como funciona a funo SelectObject()):
HPEN hPen; // Nova caneta;
HPEN hPenOld; // Caneta antiga
//
// Cdigo para desenhar grficos
//
Voc deve ter percebido que a ltima linha desse cdigo contm uma
funo que ainda no foi discutida aqui: DeleteObject() exclui um objeto e
libera a memria associada ao mesmo. Uma vez excludo, o identificador do
objeto no mais vlido.
BOOL DeleteObject(
HGDIOBJ hObject // identificador do objeto grfico
);
char texto[255];
char nome[] = Adauto;
int idade = 20;
Usar uma varivel do tipo char[] (ou LPSTR) tambm facilita quando
precisamos passar o ltimo parmetro da funo, pois podemos usar lstrlen()
para indicarmos a quantidade de caracteres da string automaticamente.
Valor Descrio
DT_BOTTOM Alinha o texto para a parte inferior do
retngulo. Esse valor deve ser combinado com
DT_SINGLELINE.
DT_CENTER Centraliza o texto horizontalmente no
retngulo.
DT_EXPANDTABS Aumenta os caracteres de tabulao. O valor
padro de caracteres por tabulao oito.
DT_LEFT Alinha o texto esquerda.
DT_RIGHT Alinha o texto direita.
DT_SINGLELINE Mostra o texto em uma nica linha. Quebra de
linhas (\n) no tm efeito nesse caso.
DT_TOP Alinha o texto na parte superior do retngulo.
Esse valor deve ser combinado com
DT_SINGLELINE.
DT_VCENTER Centraliza o texto verticalmente. Esse valor
deve ser combinado com DT_SINGLELINE.
DT_WORDBREAK Quebra de linhas so automaticamente
inseridas caso uma palavra ultrapasse a rea do
retngulo especificado no parmetro lpRect.
Tabela 4.3: Alguns valores de formatao de texto para DrawText().
O mais comum e prtico utilizar a macro RGB() para definir uma cor.
A definio da macro RGB a seguinte:
#define RGB(r, g, b) ((DWORD) (((BYTE)(r) | ((WORD)(g) << 8)) | (((DWORD)
(BYTE)(b)) << 16)))
COLORREF RGB(
BYTE bRed, // cor vermelha
BYTE bGreen, // cor verde
BYTE bBlue // cor azul
);
COLORREF SetBkColor(
HDC hdc, // identificador do DC
COLORREF crColor // cor do fundo
);
int SetBkMode(
HDC hdc, // identificador da janela
int iBkMode // modo de fundo
);
valores da Tabela 4.5 podem ser enviados a esse parmetro. O valor zero faz
com que uma espessura padro da fonte seja utilizada.
Valor Espessura
FW_DONTCARE 0
FW_THIN 100
FW_EXTRALIGHT 200
FW_ULTRALIGHT 200
FW_LIGHT 300
FW_NORMAL 400 (normal)
FW_REGULAR 400
FW_MEDIUM 500
FW_SEMIBOLD 600
FW_DEMIBOLD 600
FW_BOLD 700 (negrito)
FW_EXTRABOLD 800
FW_ULTRABOLD 800
FW_HEAVY 900
FW_BLACK 900
Tabela 4.5: Espessuras da fonte.
Valor
ANSI_CHARSET
BALTIC_CHARSET
CHINESEBIG5_CHARSET
DEFAULT_CHARSET
EASTEUROPE_CHARSET
GB2312_CHARSET
GREEK_CHARSET
HANGUL_CHARSET
MAC_CHARSET
OEM_CHARSET
RUSSIAN_CHARSET
SHIFTJIS_CHARSET
SYMBOL_CHARSET
TURKISH_CHARSET
VIETNAMESE_CHARSET
JOHAB_CHARSET (verso Windows na linguagem coreana)
ARABIC_CHARSET (verso Windows na linguagem do Oriente
Mdio)
HEBREW_CHARSET (verso Windows na linguagem do Oriente
Mdio)
THAI_CHARSET (verso Windows na linguagem tailandesa)
Tabela 4.6: Valores para fdwCharSet.
Valor Descrio
OUT_CHARACTER_PRECIS No utilizado.
OUT_DEFAULT_PRECIS Especifica o comportamento padro do
mapeador de fontes.
OUT_DEVICE_PRECIS Instrui o mapeador de fontes a escolher uma
fonte de dispositivo quando o sistema possui
contm diversas fontes com o mesmo nome
(por exemplo, uma fonte fornecida pelo
fabricante de impressora).
OUT_OUTLINE_PRECIS Instrui o mapeador de fontes a escolher
fontes True Type ou variaes de fontes outline
quando existe mais de uma fonte com o
mesmo nome.
OUT_PS_ONLY_PRECIS Instrui o mapeador de fontes a escolher
apenas fontes PostScript. Caso no exista
nenhuma fonte PostScript instalada no sistema,
Valor Descrio
CLIP_DEFAULT_PRECIS Preciso de corte padro.
CLIP_EMBEDDED Este valor deve ser especificado quando
utilizamos uma fonte embedded read-only.
CLIP_LH_ANGLES Quando utilizado, a rotao das fontes
Valor Descrio
ANTIALIASED_QUALITY A impresso da fonte feita suavemente.
DEFAULT_QUALITY Qualidade padro da fonte.
DRAFT_QUALITY A aparncia da fonte no importante.
NONANTIALIASED_QUALITY A impresso da fonte no feita suavemente.
PROOF_QUALITY A qualidade da fonte alta e no ocorrem
distores na aparncia.
Tabela 4.9: Valores para fdwQuality.
Valor Descrio
FF_DECORATIVE Fontes diferentes, como Old English.
FF_DONTCARE Usar a fonte padro.
FF_MODERN Fontes com traado constante, como Courier
New.
FF_ROMAN Fontes com traado varivel e com serif, como
MS Serif.
FF_SCRIPT Fontes com estilo de escrita mo, como
Script.
FF_SWISS Fontes com traado varivel e sem serif, como
MS Sans Serif.
Tabela 4.10: Famlias das fontes.
HFONT CreateFontIndirect(
CONST LOGFONT* lplf // caractersticas da fonte
);
Para exemplificar (Listagem 4.12), vamos criar uma fonte Times New
Roman com tamanho padro (12), itlica e com ngulo de 45 graus, utilizando
ambas funes:
// Cria fonte utilizando funo CreateFont()
HFONT hFonte1 = NULL;
HFonte = CreateFont(0, 0, 450, 450, FW_NORMAL, TRUE, FALSE, FALSE,
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH, Times New Roman);
// Modifica ngulo para 0, negrita fonte, retira itlico e muda para Arial
lf.lfEscapement = 0;
lf.lfOrientation = 0;
lf.lfWeight = FW_BOLD;
lf.lfItalic = FALSE;
lstrcpy(lf.lfFaceName, Arial);
Verificando o teclado
Na programao Windows, verificamos o estado do teclado de duas
maneiras: atravs do cdigo de tecla virtual ou atravs do caractere referente
tecla pressionada. Para isso, podemos processar trs mensagens do teclado:
WM_KEYDOWN, WM_KEYUP e WM_CHAR. As duas primeiras esto relacionadas ao cdigo
de tecla virtual, sendo que WM_KEYDOWN enviada ao programa quando o usurio
pressiona alguma tecla e WM_KEYUP enviada quando o usurio solta a tecla.
WM_CHAR enviada quando uma mensagem WM_KEYDOWN traduzida pela funo
TranslateMessage().
Bits Descrio
0-15 Contagem de repetio da tecla.
16-23 Scan code.
24 Indica se a tecla pressionada de extenso,
como a tecla ALT+CTRL (ALT direito) em
teclados de 101 ou 102 teclas. O valor 1 se a
tecla de extenso ou 0 caso contrrio.
25-28 Reservado.
29 Indica cdigo de contexto. O valor sempre
zero na mensagem WM_KEYDOWN.
30 Indica o estado anterior da tecla. O valor 1 se
a tecla estava pressionada antes da mensagem
ser enviada ou 0 se tecla no estava pressionada.
31 Indica o estado de transio. O valor sempre
zero na mensagem WM_KEYDOWN.
Tabela 4.11: lParam das mensagens de teclado.
A Tabela 4.12 lista alguns valores das teclas virtuais, que so verificadas
durante o processo da mensagem WM_KEYDOWN e WM_KEYUP. Note que todos os
cdigos das teclas virtuais comeam com VK_*.
VK_DELETE Delete
VK_UP Seta acima
VK_DOWN Seta abaixo
VK_LEFT Seta esquerda
VK_RIGHT Seta direita
VK_SNAPSHOT Print Screen
VK_CAPITAL Caps Lock
VK_SCROLL Scroll Lock
VK_NUMLOCK Num Lock
VK_LWIN Windows da esquerda
VK_RWIN Windows da direita
VK_APPS Tecla de Menu Pop-up
VK_NUMPAD0 ... VK_NUMPAD9 Teclado numrico 0 ... 9
VK_ADD Sinal +
VK_SUBTRACT Sinal -
VK_MULTIPLY Sinal *
VK_DIVIDE Sinal /
VK_F1 ... VK_F12 Teclas F1 F12
Tabela 4.12: Alguns valores das teclas virtuais.
// Obtm identificador do DC
hDC = GetDC(hWnd);
// Incrementa posio x
itx += 16;
// Libera DC
ReleaseDC(hWnd, hDC);
return(0);
} break;
//--------------------------------------------------------------------------
// Bibliotecas
//--------------------------------------------------------------------------
#include <windows.h>
#include <stdio.h>
//--------------------------------------------------------------------------
// Definies
//--------------------------------------------------------------------------
// Nome da classe da janela
#define WINDOW_CLASS "prog04-1"
// Ttulo da janela
#define WINDOW_TITLE "Prog 04-1"
// Largura da janela
#define WINDOW_WIDTH 320
// Altura da janela
#define WINDOW_HEIGHT 240
//--------------------------------------------------------------------------
// Prottipo das funes
//--------------------------------------------------------------------------
LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM);
//--------------------------------------------------------------------------
// WinMain() -> Idntica ao cdigo do prog02.cpp
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// WindowProc() -> Processa as mensagens enviadas para o programa
//--------------------------------------------------------------------------
LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
// Variveis para manipulao da parte grfica do programa
HDC hDC = NULL;
PAINTSTRUCT psPaint;
return(0);
} break;
{
// Destri a janela
DestroyWindow(hWnd);
return(0);
} break;
return(0);
} break;
// Libera DC
ReleaseDC(hWnd, hDC);
return(0);
} break;
return(0);
} break;
}
}
Listagem 4.15: Cdigo-fonte do programa-exemplo prog04-1.cpp.
Verificando o mouse
Alm do teclado, outro dispositivo de entrada/controle o mouse. O
funcionamento de um mouse mais simples que o de um teclado, pois h
apenas a movimentao do mesmo e o uso de dois ou trs botes, em geral. A
Win32 API possui mensagens para processamento de movimentao do
mouse e clique dos botes, conforme a Tabela 4.14:
Mensagem Descrio
WM_MOUSEMOVE Enviada quando o mouse sofre movimentao.
WM_LBUTTONDBLCLK Enviada quando o usurio d um duplo-clique
no boto esquerdo do mouse. necessrio
definir o membro WNDCLASSEX.style com o flag
CS_DBLCLKS.
WM_LBUTTONDOWN Enviada quando o usurio clica no boto
esquerdo do mouse.
WM_LBUTTONUP Enviada quando o usurio solta o boto
esquerdo do mouse.
WM_MBUTTONDBLCLK Enviada quando o usurio d um duplo-clique
no boto do meio do mouse. necessrio
definir o membro WNDCLASSEX.style com o flag
CS_DBLCLKS.
WM_MBUTTONDOWN Enviada quando o usurio clica no boto do
meio do mouse.
WM_MBUTTONUP Enviada quando o usurio solta o boto do
meio do mouse.
WM_RBUTTONDBLCLK Enviada quando o usurio d um duplo-clique
no boto direito do mouse. necessrio
definir o membro WNDCLASSEX.style com o flag
CS_DBLCLKS.
WM_RBUTTONDOWN Enviada quando o usurio clica no boto
direito do mouse.
WM_RBUTTONUP Enviada quando o usurio solta o boto direito
do mouse.
Tabela 4.14: Mensagens do mouse.
return(0);
} break;
// Traa reta
LineTo(hDC, x, y);
// Libera DC
ReleaseDC(hWnd, hDC);
}
return(0);
} break;
Listagem 4.17: Processando a mensagem WM_MOUSEMOVE.
Valor Descrio
MK_LBUTTON Boto esquerdo do mouse est pressionado.
MK_MBUTTON Boto do meio do mouse est pressionado.
MK_RBUTTON Boto direito do mouse est pressionado.
Tabela 4.15: Estado dos botes do mouse.
Verificando o mouse, II
Tambm podemos utilizar a funo GetAsyncKeyState() para obtermos
o estado dos botes do mouse quando no estamos processando suas
mensagens (veja valores dos botes do mouse na Tabela 4.12).
Um simples ponto
Em computao grfica, o pixel (ponto) a base da criao de todos os
grficos e o menor grfico que voc pode manipular. Retas e curvas so
formadas por diversos pixels, assim como uma foto no computador
composta por milhares de pixels, cada um com uma certa tonalidade de cor.
BOOL SetPixelV(
HDC hdc, // identificador do DC
int X, // coordenada x do pixel
int Y, // coordenada y do pixel
COLORREF crColor // cor do pixel
);
Canetas e pincis
Alguns termos utilizados na programao grfica do Windows podem
ser facilmente relacionados com a vida real. Assim, veremos como funciona o
uso de canetas e pincis GDI com exemplos do dia-a-dia.
Numa pintura leo, depois que o pintor faz o esboo (traado) da sua
obra na tela, ele comea a trabalhar com pincis e tintas (e outras ferramentas
que no vem ao caso) para preencher os espaos vazios entre os traados. No
caso da GDI, os pincis tambm so utilizados para preenchimento (podemos
pensar nos pincis como a ferramenta balde de tinta encontrada em softwares
de edio grfica), podendo ter cores slidas, preenchimento de linhas ou de
texturas.
Criando canetas
Para criarmos uma caneta, usamos a funo CreatePen(), definindo suas
propriedades.
HPEN CreatePen(
int fnPenStyle,
fnPenStyle, // estilo da caneta
int nWidth, // espessura da caneta
COLORREF crColor // cor da caneta
);
Valor Descrio
PS_SOLID Caneta slida.
//
// Cdigo para desenhar grficos
//
return(0);
} break;
Listagem 5.1: Criando e utilizando uma caneta.
Criando pincis
Podemos criar e utilizar quatro tipos de pincis: preenchimento com
cores slidas, com linhas, com texturas e pincis definidos pelo sistema. Para
cada tipo, existem funes especficas para criar pincis, respectivamente:
CreateSolidBrush(), CreateHatchBrush(), CreatePatternBrush() e
GetStockObject().
HBRUSH CreateSolidBrush(
COLORREF crColor // cor do pincel
);
Valor Descrio
HS_BDIAGONAL Linhas diagonais (da esquerda para direita e
para cima).
HS_CROSS Linhas horizontais e verticais.
HS_DIAGCROSS Linhas diagonais cruzadas.
HS_FDIAGONAL Linhas diagonais (da esquerda para direita e
para baixo).
HS_HORIZONTAL Linhas horizontais.
HS_VERTICAL Linhas verticais.
Tabela 5.2: Estilos de preenchimento de linhas.
HBRUSH CreatePatternBrush(
HBITMAP hbmp // identificador do bitmap
);
//
// Cdigo para desenhar grficos
//
return(0);
} break;
Listagem 5.2: Criando e utilizando um pincel.
Valor Descrio
R2_BLACK Cor sempre preta.
aquele efeito de negativo da imagem. Com o mix mode definido como R2_NOT,
uma linha ser desenhada com a cor inversa da rea cliente. Caso a mesma
linha seja desenhada novamente, a mesma ser apagada, pois a cor da rea
cliente voltar ao seu original.
return(0);
} break;
Listagem 5.3: Uso de MoveToEx() e LineTo().
BOOL PolylineTo(
HDC hdc, // identificador do DC
CONST POINT *lppt, // vetor de pontos
DWORD cCount // nmero de pontos no vetor
);
return(0);
} break;
Listagem 5.4: Uso de PolylineTo().
Dica: caso as coordenadas do ponto inicial e final sejam iguais, uma elipse
completa ser desenhada.
Nota: h tambm a funo ArcTo() para desenhar arcos, porm, ela utiliza
e atualiza o cursor invisvel. Uma linha traada da posio atual do
cursor invisvel at a coordenada do ponto inicial do arco quando
utilizamos ArcTo().
Dica: esse tipo de curva foi criado por um engenheiro francs, Pierre Bzier,
que as utilizou para criar o design de um carro da Renault nos anos 70.
BOOL PolyBezier(
HDC hdc, // identificador do DC
CONST POINT* lppt, // pontos das extremidades e de controle
DWORD cPoints // quantidade de pontos
);
// Desenha a curva
PolyBezier(hDC, ptUmaCurva, 4);
// Desenha as 3 curvas
PolyBezier(hDC, ptTresCurvas, 10);
return(0);
} break;
Listagem 5.5: Criando curvas de Bzier com PolyBezier().
Dica: para que duas curvas de Bzier consecutivas sejam interligadas sem
uma mudana brusca de angulao, certifique-se que o segundo ponto de
controle da curva anterior, sua extremidade final e o primeiro ponto de
controle da curva atual estejam em uma mesma linha (como entre a
primeira e a segunda curva da Figura 4.4).
Desenhando retngulos
O primeiro tipo de figura fechada que veremos o retngulo, que
criado utilizando a funo Rectangle().
BOOL Rectangle(
HDC hdc, // identificador do DC
int nLeftRect, // coordenada x do canto superior esquerdo
int nTopRect, // coordenada y do canto superior esquerdo
int nRightRect, // coordenada x do canto inferior direito
int nBottomRect // coordenada y do canto inferior direito
);
// Cria retngulo
RECT rcRect = { WINDOW_WIDTH / 2 - 50 , WINDOW_HEIGHT / 2 - 50,
WINDOW_WIDTH / 2 + 50, WINDOW_HEIGHT / 2 + 50 };
// Desenha retngulo
Rectangle(hDC, 20, 20, 120, 100);
return(0);
} break;
Listagem 5.6: Desenhando retngulos.
Desenhando elipses
Outro tipo de figura fechada que a GDI pode desenhar so as elipses,
atravs do uso da funo Ellipse(). Quando aprendemos a desenhar arcos,
vimos que para desenh-los era necessrio especificar um retngulo invisvel,
formado pelas extremidades da elipse (Figura 5.3). Essa regra continua valendo
para desenhar elipses, sendo que o centro da elipse o centro do retngulo
especificado na funo.
BOOL Ellipse(
HDC hdc, // identificador do DC
int nLeftRect, // coordenada x do canto superior esquerdo do retngulo
int nTopRect, // coordenada y do canto superior esquerdo do retngulo
int nRightRect, // coordenada x do canto inferior direito do retngulo
int nBottomRect // coordenada y do canto inferior direito do retngulo
);
BOOL Chord(
HDC hdc, // identificador do DC
int nLeftRect, // coordenada x do canto superior esquerdo do retngulo
int nTopRect, // coordenada y do canto superior esquerdo do retngulo
int nRightRect, // coordenada x do canto inferior direito do retngulo
int nBottomRect, // coordenada y do canto inferior direito do retngulo
int nXRadial1, // coordenada x do ponto inicial do arco
int nYRadial1, // coordenada y do ponto inicial do arco
int nXRadial2, // coordenada x do ponto final do arco
int nYRadial2 // coordenada y do ponto final do arco
);
Desenhando polgonos
Para concluir a seo de figuras fechadas, vamos aprender como
desenhar polgonos com o uso da funo Polygon(). Polgonos so figuras
formadas por um conjunto de pontos interligados com retas consecutivas
(vrtices).
BOOL Polygon(
HDC hdc, // identificador do DC
CONST POINT *lpPoints, // vrtices do poligono
int nCount // quantidade de vrtices do polgono
);
int SetPolyFillMode(
HDC hdc, // identificador do DC
int iPolyFillMode // modo de preenchimento
);
Captulo 6 Bitmaps
Entre os objetos GDI citados no captulo 4, um deles foi HBITMAP, que
um objeto do tipo bitmap. Nesse captulo, estaremos estudando como utilizar
esse objeto, carregando e mostrando imagens armazenadas em arquivos *.bmp
nos nossos programas.
O que so bitmaps?
Podemos definir bitmaps como um vetor de (largura * altura) bits,
onde uma certa quantidade de bits representa um ponto/cor que compe a
figura. Atualmente, existem dezenas de mtodos para armazenar uma figura no
computador, resultando em diferentes tipos de arquivos, como, por exemplo,
imagens do tipo JPEG ou GIF, famosos pela utilizao em pginas HTML.
char cPaletaDeCores[256];
for(int i = 0; i < 256; i++)
cPaletaDeCores[i] = i;
Carregando bitmaps
Em nossos programas, possvel utilizar imagens armazenadas em
disco (arquivos *.bmp) ou imagens de recursos (conforme visto no captulo 3),
armazenadas no final do arquivo executvel. Carregamos bitmaps atravs da
funo LoadImage().
HANDLE LoadImage(
HINSTANCE hinst, // identificador da instncia
LPCTSTR lpszName, // imagem a ser carregada
UINT uType, // tipo de imagem
int cxDesired, // largura desejada
int cyDesired, // altura desejada
UINT fuLoad // opes de carregamento
);
Dica: essa funo tambm pode ser utilizada para carregar cones e
cursores, pois ela tem o retorno do tipo HANDLE genrico (sendo necessrio
fazer type-casting para o tipo de imagem que estamos carregando).
// ...
DC de memria
Antes de aprendermos como mostrar um bitmap na rea cliente de um
programa, devemos saber como criar um DC de memria, que auxilia essa
operao.
HBITMAP CreateCompatibleBitmap(
HDC hdc, // identificador do DC
int nWidth, // largura do bitmap, em pixels
int nHeight // altura do bitmap, em pixels
);
BOOL DeleteDC(
HDC hdc // identificador do DC
);
// ...
// Cria DC de memria
hMemDC = CreateCompatibleDC(hDC);
//
// Chama funes para desenhar no DC de memria
//
// Deleta DC de memria
DeleteDC(hMemDC);
// Libera DC de vdeo
ReleaseDC(hDC);
// ...
Listagem 6.5: Criando um DC de memria.
DC particular de um programa
At agora, estvamos trabalhando com um DC de vdeo que tinha sua
memria compartilhada com o sistema e os programas em execuo. Para
programas que usam operaes de desenho intensivamente (como programas
grficos e jogos), o compartilhamento da memria do DC de vdeo no
vivel, sendo recomendado o uso de um DC com sua memria restrita
unicamente para o programa.
Mostrando bitmaps
Agora que j aprendemos que para mostrar um bitmap na tela
necessrio o uso de um DC de memria, vamos ver como podemos visualizar
um bitmap.
BOOL BitBlt(
HDC hdcDest, // identificador do DC de destino
int nXDest, // x do canto superior esquerdo do retngulo de destino
int nYDest, // y do canto superior esquerdo do retngulo de destino
int nWidth, // largura do retngulo de destino (canto inferior direito)
int nHeight, // altura do retngulo de destino (canto inferior direito)
HDC hdcSrc, // identificador do DC de origem
int nXSrc, // x do canto superior esquerdo do retngulo de origem
int nYSrc, // y do canto superior esquerdo do retngulo de origem
DWORD dwRop // modo de transferncia
);
Valor Descrio
BLACKNESS Preenche o retngulo de destino com a cor
preta.
MERGECOPY Combina as cores do retngulo de origem
com o pincl selecionado no DC de destino
usando a operao AND.
MERGEPAINT Combina as cores inversas do retngulo de
origem com as cores do retngulo de destino
usando a operao OR.
NOTSRCCOPY Copia as cores inversas do retngulo de
origem para o destino.
NOTSRCERASE Combina as cores dos retngulos de origem e
destino usando a operao OR e inverte a
cor resultante.
PATCOPY Copia o pincel selecionado no DC de destino
no bitmap de destino.
PATINVERT Combina as cores do pincel selecionado no
DC de destino com as cores do retngulo de
destino usando a operao XOR.
PATPAINT Combina as cores do pincel selecionado no
DC de destino com as cores inversas do
retngulo de origem usando a operao OR.
O resultado dessa operao combinada
com as cores do retngulo de destino usando
a operao OR.
SRCAND Combina as cores dos retngulos de origem e
destino usando a operao AND.
SRCCOPY Copia o retngulo de origem diretamente no
retngulo de destino.
SRCERASE Combina as cores inversas do retngulo de
destino com as cores do retngulo de origem
usando a operao AND.
SRCINVERT Combina as cores dos retngulos de origem e
destino usando a operao XOR.
SRCPAINT Combina as cores dos retngulos de origem e
destino usando a operao OR.
WHITENESS Preenche o retngulo de destino com a cor
branca.
Tabela 6.2: Modos de transferncia (combinao de cores entre os DCs).
BOOL StretchBlt(
HDC hdcDest, // identificador do DC de destino
int nXOriginDest, // x do canto superior esquerdo do retngulo de destino
int nYOriginDest, // y do canto superior esquerdo do retngulo de destino
int nWidthDest, // largura do retngulo de destino (canto inferior
direito)
int nHeightDest, // altura do retngulo de destino (canto inferior
direito)
HDC hdcSrc, // identificador do DC de origem
int nXOriginSrc,
nXOriginSrc, // x do canto superior esquerdo do retngulo de origem
int nYOriginSrc, // y do canto superior esquerdo do retngulo de origem
int nWidthSrc, // largura do retngulo de origem (canto inferior direito)
int nHeightSrc, // altura do retngulo de origem (canto inferior direito)
DWORD dwRop // modo de transferncia
);
// Libera DC de vdeo
EndPaint(hWnd, &psPaint);
return(0);
} break;
// Deleta DC de memria
DeleteDC(hMemDC);
// Destri a janela
DestroyWindow(hWnd);
return(0);
} break;
// ...
}
Listagem 6.6: Usando BitBlt() e StretchBlt().
Figura 6.2: Direo que StretchBlt() mostra bitmaps: (a) normais e (b) invertidos.
DIB Section
Os bitmaps do tipo DDB possuem a desvantagem de no podermos
acessar e manipular diretamente os seus bits, como j dito anteriormente. Por
exemplo, no podemos carregar uma imagem colorida e mostr-la em tons de
cinza, pois para isso devemos manipular os bits da imagem.
Nota: caso biHeight seja positivo, isso significa que a origem do bitmap o
canto inferior-esquerdo. Caso seja negativo, o bitmap tem sua origem no
canto superior-esquerdo.
Captulo 7 Regies
H alguns anos, os programas para Windows eram montomos;
todos eles tinham o mesmo visual-padro retangular que j estamos
acostumados a trabalhar. Com o lanamento e o grande uso do tocador de
msicas digitais Winamp, essa padronizao de programas com janelas
retangulares perdeu um pouco seu territrio, pois o Winamp deu ao usurio a
possibilidade de modificar totalmente o visual do programa, atravs de imagens
conhecidas por skins. Seguindo o conceito de utilizao de skins, diversos
programas foram surgindo, onde acabaram acrescentando algo mais: a
personalizao no somente do visual, como tambm do formato da janela do
programa.
O que so regies?
Regies so objetos GDI (HRGN) que armazenam retngulos, polgonos,
elipses ou combinaes desses trs tipos de geometria, sendo possvel
preencher, executar testes da posio de cursor e modificar o formato da janela
(rea cliente) de um programa.
Dica: uma regio pode ser classificada de acordo com sua complexidade,
ou seja, de que forma ela formada. Uma regio do tipo SIMPLEREGION
quando composta por um nico retngulo e do tipo COMPLEXREGION
quando composta por mais de um retngulo. NULLREGION significa que uma
regio vazia.
Criando regies
Podemos criar quatro tipos de regies: no formato de uma elipse
(funo CreateEllipticRgn()), retangulares (funo CreateRectRgn()),
retangulares com cantos arredondados (funo CreateRoundRectRgn()) e
poligonais (funo CreatePolygonRgn()). Cada um desses formatos possuem
suas prprias funes para criao de regies, conforme mencionados entre
HRGN CreateRectRgn(
CreateRectRgn(
int nLeftRect, // coordenada x do canto superior esquerdo
int nTopRect, // coordenada y do canto superior esquerdo
int nRightRect, // coordenada x do canto inferior direito
int nBottomRect // coordenada y do canto inferior direito
);
HRGN
HRGN CreateRoundRectRgn(
int nLeftRect, // coordenada x do canto superior esquerdo
int nTopRect, // coordenada y do canto superior esquerdo
int nRightRect, // coordenada x do canto inferior direito
int nBottomRect, // coordenada y do canto inferior direito
int nWidthEllipse, // largura da elipse
int nHeightEllipse // altura da elipse
);
HRGN CreatePolygonRgn(
CONST POINT *lppt, // vrtices do poligono
int cPoints, // quantidade de vrtices do polgono
int fnPolyFillMode // modo de preenchimento
);
Desenhando regies
Uma regio fica invisvel at que o programa seja instrudo para
preencher seu interior por determinado pincel, inverter as cores do seu interior
ou traar uma borda em volta da regio.
BOOL FrameRgn(
HDC hdc,
hdc, // identificador do DC
HRGN hrgn,
hrgn, // identificador da regio onde ser traada a borda
HBRUSH hbr,
hbr, // identificador do pincel para traar a borda
int nWidth,
nWidth, // largura da borda
int nHeight // altura da borda
);
int CombineRgn(
HRGN hrgnDest, // identificador da regio de destino
HRGN hrgnSrc1, // identificador da regio de origem 1
HRGN hrgnSrc2, // identificador da regio de origem 2
int fnCombineMode // modo de combinao das regies
);
Regies de corte
As regies tambm atuam como regies de corte (clipping region),
especificando um espao onde qualquer operao grfica fora desse limite no
ser afetada. Isso pode ser til quando precisamos modificar apenas um
determinado pedao da rea cliente ou quando queremos que todas as
operaes sejam feitas em apenas uma regio da rea cliente, no limitando-se
regies retangulares.
Para determinar uma regio de corte, basta que criemos uma regio (e,
se necessrio, realizar operaes com regies, conforme mencionado nesse
captulo) e em seguida selecionarmos a regio no DC atual. Por exemplo,
podemos criar uma regio de corte circular em um programa que mostre um
bitmap (retangular), conforme a Listagem 7.1. Como definimos uma regio de
corte, toda a rea ocupada pela imagem que no esteja dentro da regio
delimitada no ser mostrada na tela (Figura 7.1).
//--------------------------------------------------------------------------
// WindowProc() -> Processa as mensagens enviadas para o programa
//--------------------------------------------------------------------------
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
lParam)
{
// ...
hMemDC = CreateCompatibleDC(hDC);
// Libera DC de vdeo
ReleaseDC(hWnd, hDC);
// Libera DC de vdeo
EndPaint(hWnd, &psPaint);
return(0);
} break;
// ...
}
Listagem 7.1: Definindo uma regio de corte.
return(0);
} break;
Listagem 7.2: Simulando clique na barra de ttulo.
// Cor transparente
// Depois que varreu todo o bitmap, verificando seu formato (de acordo com
// as partes transparentes e no-transparentes da imagem), define o
// formato da janela conforme a regio atual (hRgn).
SetWindowRgn(hWnd, hRgn, TRUE);
}
Listagem 7.3: Criao de skin para uma janela.
Reproduzindo sons
A maneira mais rpida e simples de reproduzir um som wave
utilizando a funo PlaySound(). Essa funo pode reproduzir arquivos wave
do disco ou um som wave que est em um arquivo de recursos (que
geralmente anexado ao programa executvel em tempo de compilao),
porm, no suporta a reproduo de mltiplos sons ao mesmo tempo.
BOOL PlaySound(
LPCSTR pszSound, // arquivo ou recurso wave
HMODULE hmod, // instncia do executvel que contm o recurso (som)
DWORD fdwSound // flags
);
Valor Descrio
SND_ASYNC A funo retorna o controle para o programa
imediatamente aps o som comear a ser
reproduzido.
SND_FILENAME O parmetro pszSound recebe o nome de um
arquivo.
SND_LOOP A funo reproduz o som repetidamente, at
que a funo seja chamada novamente com o
valor NULL no parmetro pszSound. O valor
SND_ASYNC tambm deve ser informado nesse
caso.
SND_NOWAIT Se o driver de som estiver ocupado, retorna
imediatamente sem reproduzir o som.
SND_RESOURCE O parmetro pszSound recebe um
identificador de recurso e o parmetro hmod
indica a instncia que contm o recurso.
SND_SYNC O controle para o programa retornado
somente aps o som ter sido reproduzido
por completo.
Tabela 8.1: Como PlaySound() deve reproduzir um som.
MCI
Para trabalharmos com multimdia atravs da Win32 API, podemos
utilizar a Interface de Controle de Mdia (Media Control Interface, ou
simplesmente MCI). Essa interface nos fornece comandos padres para o
acesso e uso de diversos dispositivos multimdia, tais como som, msica e
vdeo.
MCIERROR mciSendCommand(
MCIDEVICEID IDDevice,
IDDevice, // identificador do dispositivo
UINT uMsg,
uMsg, // mensagem de comando
DWORD fdwCommand,
fdwCommand, // flags da mensagem
DWORD_PTR dwParam // estrutura que contm parmetros da mensagem
);
Valor Descrio
MCI_CLOSE Libera acesso ao dispositivo ou arquivo.
MCI_OPEN Inicia um dispositivo ou abre um arquivo.
MCI_PAUSE Pausa o dispositivo.
MCI_PLAY Comea reproduo dos dados do
dispositivo.
MCI_RESUME Despausa o dispositivo.
MCI_SEEK Muda a posio atual dos dados do
dispositivo.
MCI_STOP Pra a reproduo dos dados do dispositivo.
Tabela 8.2: Principais mensagens de comando.
// ...
// Abre o dispositivo
mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_ELEMENT,
(DWORD)&mciOpenParms);
// ...
Listagem 8.3: Configurando MCI_OPEN_PARMS e inicializando um dispositivo.
mciDeviceID = NULL;
Listagem 8.5: Fechando um dispositivo MCI.
// ...
// Reproduz o dispositivo
mciSendCommand(mciDeviceIDmidi, MCI_PLAY, NULL, NULL);
Listagem 8.6: Configurando e reproduzindo dispositivo MIDI.
Timers
H momentos em que precisamos utilizar timers (temporizadores) em
nossos programas recursos que enviam mensagens WM_TIMER em um
determinado intervalo de tempo para serem processadas pela funo
WindowProc() (ou uma funo callback especfica para timers TimerProc(),
como veremos mais a frente). Um exemplo do uso de timers quando
queremos mostrar a hora atual no programa, sendo atualizada a cada segundo.
Seguiremos com esse exemplo para o estudo de timers.
return(0);
} break;
// ...
}
// ...
}
//--------------------------------------------------------------------------
// TimerProc() -> Processa os eventos de timer
//--------------------------------------------------------------------------
VOID CALLBACK TimerProc(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD
dwTime)
{
// Armazena hora atual
char cHora[9] = { 0 };
BOOL KillTimer(
HWND hWnd,
hWnd, // identificador da janela
UINT_PTR uIDEvent // identificador do timer
);
// Destri a janela
DestroyWindow(hWnd);
return(0);
} break;
// ...
}
// ...
}
Listagem 8.9: Destruindo timers.
Nesse captulo, vimos como trabalhar com sons wave e msicas MIDI.
Vimos tambm como utilizar timers, atravs da criao de um programa
(arquivo prog08-2.cpp no CD-ROM) que mostra a hora atual na tela, atualizando
a informao a cada segundo. No captulo a seguir, estudaremos a manipulao
de arquivos atravs da Win32 API e como trabalhar com o registro do
Windows.
Figura 9.1: Boto criado na rea cliente aps arquivo ser aberto/criado.
Fechando arquivos
Para fechar um arquivo, liberando a memria do seu identificador (e o
acesso ao arquivo para outros programas, dependendo do modo de
compartilhamento em que o mesmo foi aberto), chamamos a funo
CloseHandle(), que recebe o identificador do arquivo como parmetro.
BOOL CloseHandle(
HANDLE hObject // identificador do arquivo
);
Escrita em arquivos
Para escrever alguma informao no arquivo aberto, utilizamos a
funo WriteFile().
BOOL WriteFile(
HANDLE hFile,
hFile, // identificador do arquivo
LPCVOID lpBuffer,
lpBuffer, // buffer de dados
DWORD nNumberOfBytesToWrite,
nNumberOfBytesToWrite, // nmero de bytes a serem escritos
LPDWORD lpNumberOfBytesWritten,
lpNumberOfBytesWritten, // nmero de bytes escritos
LPOVERLAPPED lpOverlapped // buffer de sobreescrita
);
Leitura em arquivos
Depois de aberto o arquivo, podemos acessar seu contedo atravs da
funo ReadFile().
BOOL ReadFile(
HANDLE hFile,
hFile, // identificador do arquivo
LPVOID lpBuffer,
lpBuffer, // buffer de dados
DWORD nNumberOfBytesToRead,
nNumberOfBytesToRead, // nmero de bytes a serem lidos
LPDWORD lpNumberOfBytesRead,
lpNumberOfBytesRead, // nmero de bytes lidos
LPOVERLAPPED lpOverlapped // buffer de sobreescrita
);
// L contedo do arquivo
ReadFile(hFile, lpstrBuffer, tam, &dwBytesEscritos, NULL);
// ...
return(0);
} break;
// ...
Listagem 9.4: Leitura em arquivos, processamento de boto e criao de caixa de texto.
Excluindo arquivos
Para apagar um arquivo em disco, usamos a funo DeleteFile(). Essa
funo recebe o nome do arquivo que ser excludo, retornando um valor
diferente de zero caso o arquivo seja apagado ou zero caso contrrio.
BOOL DeleteFile(
LPCTSTR lpFileName // nome do arquivo a ser excludo
);
Registro do Windows
O registro do Windows um banco de dados onde so armazenadas
informaes de configurao sobre o ambiente do sistema, dispensando o uso
de arquivos de inicializao (.ini) que eram comuns em sistemas Windows 16-
bit (at a verso 3.11). No registro, por exemplo, possvel armazenar as
preferncias de diferentes usurios, fazendo com que cada usurio trabalhe em
um ambiente personalizado (escolha de temas, configurao de teclado, entre
outros). Ainda, podemos associar determinado tipo de arquivo a ser aberto
com um determinado programa, como tambm podemos incluir um programa
para ser executado assim que o Windows inicializado (ou seja, assim que um
usurio faa login no sistema).
Chave Descrio
HKEY_CLASSES_ROOT Parte da chave HKEY_LOCAL_MACHINE, contm
definies de tipos de documentos,
associao de arquivos e interface de
comando (shell).
HKEY_CURRENT_USER Ligao com HKEY_USERS, corresponde s
configuraes do usurio atual. Usurios
padres que no possuem configuraes
especficas utilizam as informaes de
.DEFAULT (da chave HKEY_USERS)
HKEY_LOCAL_MACHINE Armazena configuraes de hardware,
protocolos de rede e classes de software.
HKEY_USERS Utilizado para armazenar as preferncias de
cada usurio.
HKEY_CURRENT_CONFIG Configurao selecionada na subchave de
configurao de HKEY_LOCAL_MACHINE.
Tabela 9.1: Descrio das 5 principais chaves-razes.
LONG RegOpenKeyEx(
HKEY hKey,
hKey, // chave-raz ou identificador da chave de registro
LPCTSTR lpSubKey,
lpSubKey, // subchave
DWORD ulOptions,
ulOptions, // reservado (deve receber zero)
REGSAM samDesired,
samDesired, // modo de acesso
PHKEY phkResult // ponteiro para identificador da chave de registro
);
if(lResultado == ERROR_SUCCESS)
MessageBox(...); // excluda
else
MessageBox(...); // erro
Ou visite o site:
http://www.tupinihon.com
- Andr Kishimoto
Bibliografia
CALVERT, Charles. Teach Yourself Windows Programming in 21 Days.
Indianopolis: Sams. 1993.
ndice Remissivo
reas Classes 6
De corte 86 Clipping region
Validando 91 (ver rea de corte)
Arquivos Comentrios 8
.INI 193 Controles
Abrindo 193 Barra de rolagem 72
Criando 193 Botes 66
Escrita em 195 Caixas de edio 66
Excluindo 198 Genricos 69
Fechando 195 Labels
Leitura em 197 (ver Textos estticos)
Atoms 208 Lista de seleo 71
Textbox
Bitmaps (ver Caixas de edio)
Carregando 151 Textos estticos 65, 73
Classificao 148 Cores
Compatvel 155 Combinao 128
DDB 150 Inverso de 143
De recursos 152 Paleta de 149
Definio 148 Preenchimento 144
Device-dependent bitmap RGB 99
(ver DDB) Cursores
Device-independent bitmap Carregar 18
(ver DIB) De Recursos 45
DIB 150 Curvas de Bzier 133
DIB Section 164
Invertidos 161 Delphi 6
Luminance 168 Device context
Manipulando bits 166 De memria 154
Mostrando 157 De vdeo 85
Obtendo informaes de 153 Obter identificador 85, 87
Off-screen
C++ 7 (ver DC de memria)
Caixas de dilogo Particular 157
Comuns 208 Pblico 83
Criar 63, 74
Destruindo 74 Fontes 103
Estilos 64 Form 24
Mensagens 75
Canvas 83 GDI 82
Charles Simonyi 6 Graphics Device Interface
Classe (ver GDI)
Da Janela 15
Registrando 20
Handle MS-DOS 5
(ver Identificador) MSDN 13
Hello World 8
Nomenclatura 6
Identificador 10 Notao hngara 6
cones
Carregar 17 Objetos GDI
De Recursos 42 Bitmaps 148
Canetas 125
Janelas Elipses 140
Criando 21 Excluindo 93
Destruir 32 Linhas curvas 133
Estilos de 24 Obtendo informaes de 94
Janela-pai 74 Pincis Padres 19
Mostrar 24 Pincis 127
No-retangulares 177 Polgonos 142
Java 7 Ponto 123
Retngulos 137
Macros 9 Retas 130
Main() 9 Selecionando 91
MCI Textos 95
(ver Sons)
Mensagens Platform SDK 5
Caixa de 12 Portabilidade 9
Caixas de dilogo 75
Enviando 38 Recursos
Envio de 5, 27 Arquivos de 41
Gerando WM_PAINT 89 Bitmaps 46
Loop de 25 Caixas de dilogo 63
Processamento de 5 Cursores 45
Processando 28 IDs 42
Traduzir 27 cones 42
WM_PAINT 85 Menus 54
Menus Sons 46
Definindo 54 Teclas de atalho 54
Destruindo 58 Verso do programa 46
Hot keys 56 Regies
Menu-pai 55 Criando 170
Modificando itens do 62 De corte 175
Teclas de atalho 54 Definio 170
Usando 57 Desenhando 171
MFC 5 Operaes com 173
Microsoft Foundation Class Registro
(ver MFC) Abrindo chaves do 201
MIDI Criando chaves do 203
(ver Sons) Excluindo chaves do 204
Mouse 118, 121 Excluindo valores do 206
Sons
MCI 183
Msicas MIDI 188
Reproduo de mltiplos 185
Reproduzindo 181
Windows Multimedia 182
Visual Basic 6
Wave
(ver Sons)
Win32 API 5
Windows 5
Windows.h 9
WinMain() 9