Curso completo de DirectX 9 com C\C++
Gameprog - Escola de programação de jogos digitais
Contato: gameprog.br@gmail.com
Fase 01-5

index << >>


01.5 Linhas

1.1 Visão geral
O directx apresenta a interface ID3DXLine que simplifica o trabalho de desenhar linhas dando ainda a opção de controlar a espessura da linha e de aplicar facilmente o filtro antialias para suavizar o serrilhado desagradável que pode surgir nas linhas diagonais. A aplicação desse tópico vai desenhar retângulos utilizando essa interface e vai mostrar como tratar o evento de mouse WM_MOUSEMOVE que ocorre quando o ponteiro do mouse é movimentado sobre a tela. 1.2 Estrutura principal da aplicação
Arquivo: entrada.cpp
WinMain() criação da classe da janela registro da classe da janela criação da janela de acordo com a classe definida chama initGfx() para inicializar o motor gráfico mostra a janela estabelecimento do laço de mensagens finaliza a aplicação
Arquivo: motor.cpp
initGfx() Inicializa objeto Direct3d Inicializa dispositivo renderizador Inicializa objeto para mostrar texto quadrado() Cria o objeto para desenhar linhas Define os pontos das linhas Calcula os pontos do quadrado Configura como as linhas serão desenhadas Desenha as linhas Libera o objeto de desenhar linhas Renderizar() Limpa a tela Desenha a cena mostra texto Desenha retângulos com quadrado() Apresenta a cena processaJanela() tratamento das mensagens Verifica teclado - finaliza aplicação na tecla Escape Verifica mouse - mostra coordenada do mouse no evento WM_MOUSEMOVE chama Limpar() na finalização da aplicação chama Renderizar() para desenhar os gráficos Limpar() Libera objeto de mostrar texto Libera dispositivo renderizador Libera objeto Direct3d
2.1 Aspectos globais - Arquivo: motor.h
// Projeto: prj_Linhas - Arquivo: motor.h #ifndef motor_h #define motor_h // Esta função inicializa o Direct3D HRESULT initGfx (HWND hJanela); // Essa função libera os objetos utilizados void Limpar(); // Essa função desenha a cena void Renderizar(); // Esta função inicializa o objeto para mostrar texto void inicializarTexto(); // Esta função mostra um texto na coordenada (x, y) da janela void mostrarTexto( int x, int y, char* texto); // Desenha um quadrado na posição (x, y) com as dimensões // especificadas (largura, altura) void quadrado( float x, float y, float largura, float altura); // Declaração da função que atende as mensagens da janela LRESULT CALLBACK processaJanela (HWND hJanela, UINT mensagem, WPARAM wParam, LPARAM lParam); #endif
// Desenha um quadrado na posição (x, y) com as dimensões // especificadas (largura, altura) void quadrado( float x, float y, float largura, float altura); Essa função mostra como inicializar e utilizar o objeto da interface ID3DXLine para desenhar linhas. // Declaração da função que atende as mensagens da janela LRESULT CALLBACK processaJanela (HWND hJanela, UINT mensagem, WPARAM wParam, LPARAM lParam); Como anunciado antes, essa função dinâmica veio fazer parte do arquivo motor.cpp merecidamente. 2.2 Desenhando linhas
void quadrado( float x, float y, float largura, float altura) { // Criação do objeto linha ID3DXLine* linhas = NULL; D3DXCreateLine(g_device, &linhas); // Quantidade de pontos const int nQtd = 5; // Array de coordenadas dos pontos D3DXVECTOR2 pontos[nQtd]; // Preenchimento dos pontos do quadrado // (esquerda, cima) pontos[0] = D3DXVECTOR2(x, y ); // (direita, cima) pontos[1] = D3DXVECTOR2(x + largura, y ); // (direita, baixo) pontos[2] = D3DXVECTOR2(x + largura, y + altura ); // (esquerda, baixo) pontos[3] = D3DXVECTOR2(x, y + altura); // (esquerda, cima) pontos[4] = D3DXVECTOR2(x, y); // Cor da linha const DWORD vermelho = 0xFFFF0000; // Configura espessura da linha e antiAlias linhas->SetWidth (3.0f); linhas->SetAntialias(true); // Prepara o ambiente linhas->Begin(); // Desenha a linha linhas->Draw(pontos, nQtd, vermelho ); // Finaliza restaurando estados internos linhas->End(); // Libera o objeto linhas linhas->Release(); } // quadrado().fim
// Criação do objeto linha ID3DXLine* linhas = NULL; D3DXCreateLine(g_device, &linhas); Novamente aqui se repete o padrão de criação de objetos do directx; primeiro ocorre a declaração do ponteiro e na sequência temos uma função Create...() criando alguma coisa. Utilizamos ID3DXLine* para declarar o ponteiro e depois utilizamos D3DXCreateLine para criar o objeto que desenha linhas com o ponteiro declarado previamente como referência ( &linhas ) na função de criação. Esse padrão se repete ao longo do curso com outros objetos diferentes do directx. // Quantidade de pontos const int nQtd = 5; Vamos utilizar cinco pontos que esse objeto fará a conexão para gerar as linhas e montar o quadrado. // Array de coordenadas dos pontos D3DXVECTOR2 pontos[nQtd]; Os pontos são criados utilizando a estrutura D3DXVECTOR2 que traz como membros os elementos x e y do tipo float.
// Preenchimento dos pontos do quadrado // (esquerda, cima) pontos[0] = D3DXVECTOR2(x, y ); // (direita, cima) pontos[1] = D3DXVECTOR2(x + largura, y ); // (direita, baixo) pontos[2] = D3DXVECTOR2(x + largura, y + altura ); // (esquerda, baixo) pontos[3] = D3DXVECTOR2(x, y + altura); // (esquerda, cima) pontos[4] = D3DXVECTOR2(x, y);
Destacamos o simples algoritmo que gera o retângulo a partir de uma posição (x, y) e dimensões (largura, altura). Destacamos visualmente a formação desta forma geométrica porque o retângulo desempenha um papel fundamental dentro de programação de jogos e da própria programação Windows. A tela, o backbuffer, imagens e textura são todas superfícies retangulares. As técnicas de colisões mais simples são desenvolvidas usando o retângulo como referência. Então é importante pegar intimidade com o retângulo. // Cor da linha const DWORD vermelho = 0xFFFF0000; A linha aceita configuração de cor. // Configura espessura da linha e antiAlias linhas->SetWidth (3.0f); Esta é a forma de configurar a espessura da linha. linhas->SetAntialias(true); Esta configuração ativa a correção do serrilhado que ocorre em linhas diagonais. Para uma retângulo essa configuração não tem sentido mas para linhas diagonais é importante ativar essa correção. // Prepara o ambiente linhas->Begin(); O processo de desenhar as linhas é cercado por Begin() e End() desse objeto que faz o trabalho de preservar e restaurar estados internos do motor gráfico do directx. Aliás, esse é um outro padrão do directx que ocorre com outros objetos que realizam processos particulares de renderização. Na programação Windows, há as funções BeginPaint() e EndPaint() que cercam processos de desenho na janela. // Desenha a linha linhas->Draw(pontos, nQtd, vermelho ); A função Draw desse objeto pega uma array de pontos, uma indicação de quantidade de pontos nessa array e a cor para fazer seu trabalho de desenhar linhas conectando esse pontos pré-definidos. // Finaliza restaurando estados internos linhas->End(); O processo de desenhar linhas é encerrado. // Libera o objeto linhas linhas->Release(); Por fim, o objeto linhas é devidamente liberado. 2.3 Renderizando a cena
// ----------------------------------------------------------------------------- // Renderizar() - Desenha a cena // ----------------------------------------------------------------------------- VOID Renderizar() { // Retorne se o dispositivo estiver nulo if( g_device == NULL) return; // Cor de fundo da janela const D3DCOLOR branco = D3DCOLOR_XRGB( 255, 255, 255 ); const D3DCOLOR cor_fundo = branco; // Superfícies que serão limpas DWORD superficies = D3DCLEAR_TARGET; // Configuração padrão do buffer de profundidade float zBuffer = 1.0f; // Configuração padrão do stencil DWORD sBuffer = 0; // Quantidade de retângulos a serem limpos DWORD nPartes = 0; // Array de retângulos que serão limpos const D3DRECT* pPartes = NULL; // Limpa o backbuffer com uma cor branca g_device->Clear( nPartes, pPartes, superficies, cor_fundo, zBuffer, sBuffer); // Começa a cena if( SUCCEEDED( g_device->BeginScene() ) ) { // Todo código de desenhar ocorre aqui dentro mostrarTexto (120, 160, "Produzido na escola Gameprog"); mostrarTexto (200, 200, "Programar é legal!"); // Desenha dois quadrados quadrado (90.0f, 130.0f, 420.0f, 120.0f); quadrado (100.0f, 140.0f, 400.0f, 100.0f); // Finalizando a cena g_device->EndScene(); } // endif // Apresenta o conteúdo do backbuffer na tela // Retangulo fonte e destino const RECT* rFonte = NULL; const RECT* rDestino = NULL; // Janela alternativa para apresentar os dados visuais HWND hOutraJanela = NULL; g_device->Present( rFonte, rDestino, hOutraJanela, NULL); } // Renderizar().fim
// Começa a cena if( SUCCEEDED( g_device->BeginScene() ) ) { // Todo código de desenhar ocorre aqui dentro mostrarTexto (120, 160, "Produzido na escola Gameprog"); mostrarTexto (200, 200, "Programar é legal!"); // Desenha dois quadrados quadrado (90.0f, 130.0f, 420.0f, 120.0f); quadrado (100.0f, 140.0f, 400.0f, 100.0f); // Finalizando a cena g_device->EndScene(); } // endif
Aqui sem novidade: primeiro desenhamos o texto e depois desenhamos os quadrados. Mas é importante destacar que o que é desenhando por último é o que prevalesce visualmente. Se ocorrer do quadrado estiver na posição do texto, o texto é coberto pelo quadrado que foi desenhado por último. 2.4 Tratando o mouse
// Esta função é chamada por DispatchMessage() LRESULT CALLBACK processaJanela (HWND hJanela, UINT mensagem, WPARAM wParam, LPARAM lParam) { // Variáveis para coletar informação do mouse int xmouse = 0; int ymouse = 0; char info[25]; switch (mensagem) { case WM_DESTROY: // Coloca uma mensagem WM_QUIT na fila de mensagem Limpar(); PostQuitMessage (0); break; case WM_KEYDOWN: if (wParam == VK_ESCAPE) { Limpar(); PostQuitMessage( 0); } // endif break; case WM_MOUSEMOVE: xmouse = LOWORD (lParam); ymouse = HIWORD (lParam); sprintf (info, "prj_Linhas (%i, %i)", xmouse, ymouse); SetWindowText (hJanela, info); break; // Essa mensagem vai ocorrer a todo momento case WM_PAINT: // Renderiza a cena Renderizar(); // Invalida a tela para chamar WM_PAINT novamente InvalidateRect( hJanela, NULL, false); break; // Processamento default de mensagens não tratada pela aplicação default: return DefWindowProc (hJanela, mensagem, wParam, lParam); } // endswitch return 0; } // processaJanela().fim
Mostramos com os blocos de código a seguir como tratar o evento de mouse notificado pela mensagem WM_MOUSEMOVE que ocorre quando o mouse é movimentado pela tela. Primeiro criamos algumas variáveis para para guardar as informações coletadas: // Variáveis para coletar informação do mouse int xmouse = 0; int ymouse = 0; char info[25]; (xmouse, ymouse) coletam a informação da coordenada (x,y) do mouse, e usamos a função sprintf() para formatar estas informações dentro da string info criada. switch (mensagem) { case WM_MOUSEMOVE: xmouse = LOWORD (lParam); ymouse = HIWORD (lParam); sprintf (info, "prj_Linhas (%i, %i)", xmouse, ymouse); SetWindowText (hJanela, info); break; } // endswitch No caso particular da mensagem WM_MOUSEMOVE, lParam recebe as coordenadas do mouse codificadas dessa maneira: YYYY XXXX. A legenda XXXX é a palavra baixa extraída pela macro LOWORD() e YYYY é a palavra alta extraída pela macro HIWORD(). Uma palavra é um valor de 16 bits ou dois bytes. sprintf() imprime informações numa string e SetWindowText() configura o texto da barra de títulos da janela. Esse código parece não fazer nada prático e útil na aplicação como um todo, mas usamos este artifício para definir o posicionamento dos dois quadrados na tela. 3. Código fonte do projeto de exemplo: prj_Linhas
// Projeto: prj_Linhas - Arquivo: motor.h #ifndef motor_h #define motor_h // Esta função inicializa o Direct3D HRESULT initGfx (HWND hJanela); // Essa função libera os objetos utilizados void Limpar(); // Essa função desenha a cena void Renderizar(); // Esta função inicializa o objeto para mostrar texto void inicializarTexto(); // Esta função mostra um texto na coordenada (x, y) da janela void mostrarTexto( int x, int y, char* texto); // Desenha um quadrado na posição (x, y) com as dimensões // especificadas (largura, altura) void quadrado( float x, float y, float largura, float altura); // Declaração da função que atende as mensagens da janela LRESULT CALLBACK processaJanela (HWND hJanela, UINT mensagem, WPARAM wParam, LPARAM lParam); #endif
// ----------------------------------------------------------------------------- // Projeto: prj_Linhas - arquivo: motor.cpp // Esta aplicação ilustra como desenhar linhas // Produzido por www.gameprog.com.br // ----------------------------------------------------------------------------- #include <windows.h> #include <d3d9.h> #include <d3dx9.h> #include <stdio.h> #include "motor.h" // Inclui as bibliotecas do Direct3D #pragma comment(lib, "d3d9.lib") #pragma comment(lib, "d3dx9.lib") // Variáveis globais // Representa o dispositivo D3D LPDIRECT3D9 g_Direct3d = NULL; // Representa o dispositivo Renderizador IDirect3DDevice9* g_device = NULL; // Ponteiro para uma fonte do directx ID3DXFont* gdxFonte = NULL; // Essa variável recebe informação de erro do Directx HRESULT g_hr = 0; extern int g_xtela; extern int g_ytela; // initGfx() - Inicializa o Direct3D HRESULT initGfx( HWND hJanela ) { // Cria o objeto D3D que é necessário para criar o dispositivo gráfico g_Direct3d = Direct3DCreate9( D3D_SDK_VERSION); // Verifica se objeto Direct3D foi criado if(g_Direct3d == NULL) { MessageBox (NULL, "Falha na inialização do Direct3D", "InitGfx()", MB_OK); return E_FAIL; } // endif // Declara a variável para os parâmetros de apresentação D3DPRESENT_PARAMETERS pps; // Limpa a estrutura ZeroMemory( &pps, sizeof(pps) ); // Configura os parâmetros de apresentação // A aplicação vai ter janela pps.Windowed = TRUE; // Esse método vira rapidamente o backbuffer para a tela imediata pps.SwapEffect = D3DSWAPEFFECT_DISCARD; // Esse formato vai procurar se encaixar no modo de video corrente pps.BackBufferFormat = D3DFMT_UNKNOWN; // Configuração do renderizador a ser criado // Adaptador default (0) int nAdaptador = D3DADAPTER_DEFAULT; // Tipo de dispositivo Hardware ou emulador de referência (software) D3DDEVTYPE dispositivo_tipo = D3DDEVTYPE_HAL; // Flags de configuração do dispositivo DWORD create_flags = D3DCREATE_SOFTWARE_VERTEXPROCESSING; // Criamos aqui o dispositivo renderizador g_hr = g_Direct3d->CreateDevice( nAdaptador, dispositivo_tipo, hJanela, create_flags, &pps, &g_device ); // Verifica se houve falha no processo if( FAILED( g_hr ) ) { MessageBox (NULL, "Falha na criação: g_device", "initGfx()", MB_OK); return E_FAIL; } // endif inicializarTexto(); return S_OK; } // initGfx().fim void quadrado( float x, float y, float largura, float altura) { // Criação do objeto linha ID3DXLine* linhas = NULL; D3DXCreateLine(g_device, &linhas); // Quantidade de pontos const int nQtd = 5; // Array de coordenadas dos pontos D3DXVECTOR2 pontos[nQtd]; // Preenchimento dos pontos do quadrado // (esquerda, cima) pontos[0] = D3DXVECTOR2(x, y ); // (direita, cima) pontos[1] = D3DXVECTOR2(x + largura, y ); // (direita, baixo) pontos[2] = D3DXVECTOR2(x + largura, y + altura ); // (esquerda, baixo) pontos[3] = D3DXVECTOR2(x, y + altura); // (esquerda, cima) pontos[4] = D3DXVECTOR2(x, y); // Cor da linha const DWORD vermelho = 0xFFFF0000; // Configura espessura da linha e antiAlias linhas->SetWidth (3.0f); linhas->SetAntialias(true); // Prepara o ambiente linhas->Begin(); // Desenha a linha linhas->Draw(pontos, nQtd, vermelho ); // Finaliza restaurando estados internos linhas->End(); // Libera o objeto linhas linhas->Release(); } // quadrado().fim // Esta função é chamada por DispatchMessage() LRESULT CALLBACK processaJanela (HWND hJanela, UINT mensagem, WPARAM wParam, LPARAM lParam) { // Variáveis para coletar informação do mouse int xmouse = 0; int ymouse = 0; char info[25]; switch (mensagem) { case WM_DESTROY: // Coloca uma mensagem WM_QUIT na fila de mensagem Limpar(); PostQuitMessage (0); break; case WM_KEYDOWN: if (wParam == VK_ESCAPE) { Limpar(); PostQuitMessage( 0); } // endif break; case WM_MOUSEMOVE: xmouse = LOWORD (lParam); ymouse = HIWORD (lParam); sprintf (info, "prj_Linhas (%i, %i)", xmouse, ymouse); SetWindowText (hJanela, info); break; // Essa mensagem vai ocorrer a todo momento case WM_PAINT: // Renderiza a cena Renderizar(); // Invalida a tela para chamar WM_PAINT novamente InvalidateRect( hJanela, NULL, false); break; // Processamento default de mensagens não tratada pela aplicação default: return DefWindowProc (hJanela, mensagem, wParam, lParam); } // endswitch return 0; } // processaJanela().fim void inicializarTexto() { // Altura int nAltura = 24; // Largura UINT nLargura = 0; // Peso ( weight ) UINT nPeso = FW_BOLD; // Nível de mipmap - 0: mipmap automático UINT nMipmap = 0; // Efeito itálico bool bItalico = false; // Conjunto de caracteres (charset) DWORD nCharset = DEFAULT_CHARSET; // Precisão (OutputPrecision) DWORD nPrecisao = OUT_DEFAULT_PRECIS; // Qualidade DWORD nQualidade = DEFAULT_QUALITY; // Pitch e família DWORD nFamilia = DEFAULT_PITCH | FF_DONTCARE; // Nome da fonte char* sFonte = "Arial"; g_hr = D3DXCreateFont( g_device, nAltura, nLargura, nPeso, nMipmap, bItalico, nCharset, nPrecisao, nQualidade, nFamilia, sFonte, &gdxFonte ); if(FAILED (g_hr) ) MessageBox(NULL, "Texto: falha na inicialização", "inicializarTexto()", MB_OK); } // inicializarTexto() void mostrarTexto(int x, int y, char* texto) { // Retorne se não houver fonte inicializada if(gdxFonte == NULL) return; // Cor de fundo da janela D3DCOLOR azul = D3DCOLOR_XRGB(0, 0, 255); RECT area_limite; SetRect( &area_limite, x, y, g_xtela, g_ytela ); gdxFonte->DrawText( NULL, texto, -1, &area_limite, 0, azul ); } // mostrarTexto(); // Limpar() - Libera todos os objetos previamente inicializados // ----------------------------------------------------------------------------- VOID Limpar() { // Libera objeto de mostrar texto if( gdxFonte != NULL) gdxFonte->Release(); // Libera o dispositivo gráfico if( g_device != NULL) g_device->Release(); // Libera o motor do Direct3D if( g_Direct3d != NULL) g_Direct3d->Release(); } // Limpar().fim // ----------------------------------------------------------------------------- // Renderizar() - Desenha a cena // ----------------------------------------------------------------------------- VOID Renderizar() { // Retorne se o dispositivo estiver nulo if( g_device == NULL) return; // Cor de fundo da janela const D3DCOLOR branco = D3DCOLOR_XRGB( 255, 255, 255 ); const D3DCOLOR cor_fundo = branco; // Superfícies que serão limpas DWORD superficies = D3DCLEAR_TARGET; // Configuração padrão do buffer de profundidade float zBuffer = 1.0f; // Configuração padrão do stencil DWORD sBuffer = 0; // Quantidade de retângulos a serem limpos DWORD nPartes = 0; // Array de retângulos que serão limpos const D3DRECT* pPartes = NULL; // Limpa o backbuffer com uma cor branca g_device->Clear( nPartes, pPartes, superficies, cor_fundo, zBuffer, sBuffer); // Começa a cena if( SUCCEEDED( g_device->BeginScene() ) ) { // Todo código de desenhar ocorre aqui dentro mostrarTexto (120, 160, "Produzido na escola Gameprog"); mostrarTexto (200, 200, "Programar é legal!"); // Desenha dois quadrados quadrado (90.0f, 130.0f, 420.0f, 120.0f); quadrado (100.0f, 140.0f, 400.0f, 100.0f); // Finalizando a cena g_device->EndScene(); } // endif // Apresenta o conteúdo do backbuffer na tela // Retangulo fonte e destino const RECT* rFonte = NULL; const RECT* rDestino = NULL; // Janela alternativa para apresentar os dados visuais HWND hOutraJanela = NULL; g_device->Present( rFonte, rDestino, hOutraJanela, NULL); } // Renderizar().fim
//----------------------------------------------------------------------------- // Projeto: prj_Linhas - arquivo: entrada.cpp // Esta aplicação ilustra como desenhar linhas // Produzido por www.gameprog.com.br //----------------------------------------------------------------------------- #include <windows.h> #include <d3d9.h> #include <d3dx9.h> #include "motor.h" // Variável global da classe da janela char sclasseJanela[ ] = "cls_directx"; // Dimensões da janela int g_xtela = 640; int g_ytela = 480; int WINAPI WinMain (HINSTANCE app_instancia, HINSTANCE app_anterior, LPSTR sComando,int nExibir) { // alça da janela HWND hJanela; // Estrutura de recepção das mensagens MSG mensagem; // Estrutura de descrição da janela WNDCLASSEX wcls; // Estrutura que descreve a janela wcls.hInstance = app_instancia; wcls.lpszClassName = sclasseJanela; wcls.lpfnWndProc = processaJanela; wcls.style = CS_HREDRAW | CS_VREDRAW; wcls.cbSize = sizeof (WNDCLASSEX); // O cursor e os ícones da aplicação são default wcls.hIcon = LoadIcon (NULL, IDI_APPLICATION); wcls.hIconSm = LoadIcon (NULL, IDI_APPLICATION); wcls.hCursor = LoadCursor (NULL, IDC_ARROW); // Aplicação sem menu wcls.lpszMenuName = NULL; // Nada de espaço extra atrelado a classe da janela (wcls) wcls.cbClsExtra = 0; // Nada de espaço extra atrelado a janela wcls.cbWndExtra = 0; // Cor default da janela wcls.hbrBackground = ( HBRUSH) COLOR_BACKGROUND; // Registra a janela e retorna se esta operação falhar int status = RegisterClassEx (&wcls); if(status == 0) { MessageBox(NULL, "Registro falhou!", "WinMain()", MB_OK); return 0; } // endif // Com a classe criada pode-se criar a janela DWORD estiloExtra = 0; const char janelaTitulo[] = "prj_Linhas"; DWORD controleEstilo = WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX; int xpos = 160; int ypos = 120; HWND hjanelaPai = HWND_DESKTOP; HMENU sem_menu = NULL; LPVOID dadoExtra = NULL; // Cria a janela hJanela = CreateWindowEx(estiloExtra, sclasseJanela, janelaTitulo, controleEstilo, xpos, xpos, g_xtela, g_ytela, hjanelaPai, sem_menu, app_instancia, dadoExtra ); // Verifica se janela foi criada if(hJanela == NULL) { MessageBox(NULL, "Falha na criação da janela!", "WinMain()", MB_OK); return 0; } // endif // Essa variável recebe informação de erro do Directx HRESULT hr; // Inicia o Direct3D hr = initGfx ( hJanela ); // Encerre a aplicação se houve falha if(FAILED (hr) ) { MessageBox (hJanela, "Direct3D: falha na inicialização", "WinMain()", MB_OK); UnregisterClass( sclasseJanela, wcls.hInstance); return E_FAIL; } // endif // Mostra a janela ShowWindow(hJanela, nExibir); UpdateWindow(hJanela ); // Rode a bombeamento de mensagens até GetMessage() retornar 0 while (GetMessage(&mensagem, NULL, 0, 0)) { // Traduz mensagem de tecla virtual em mensagem de caracteres TranslateMessage( &mensagem ); // Despacha a mensagem para a função processaJanela */ DispatchMessage( &mensagem ); } // endwhile // O valor de retorno é zero(0) passado por PostQuitMessage() UnregisterClass( sclasseJanela, wcls.hInstance); return mensagem.wParam; } // WinMain().fim

index << >>

Produzido por Gameprog: Jair Pereira - Agosto/2014 © gameprog.br@gmail.com http://www.gameprog.com.br