Informática Numaboa - Tutoriais e Programação
Usando recursos (masm)
Qua 14 Jan 2009 17:12 |
- Detalhes
- Categoria: Assembly Numaboa (antigo oiciliS)
- Atualização: Domingo, 21 Junho 2009 18:44
- Autor: vovó Vicki
- Acessos: 13184
Depois do tutorial Janelas somos felizes possuidores de uma classe que nos permite criar janelas com a nossa grife. A janela que produzimos no tutorial anterior estava peladinha da silva, onde muitos recursos que costumam acompanhar janelas estão faltando. Este tutorial tem justamente este propósito: discutir os RECURSOS. Como exemplo, vamos colocar um bitmap numa janela.
O que são recursos
Recursos são dados binários que um compilador de recursos ou o programador adicionam ao arquivo executável de um aplicativo. Recursos podem ser do tipo padrão ou do tipo definido. Os dados de um recurso padrão descrevem ícones, cursores, menus, caixas de diálogo, gráficos do tipo .bmp e .emf, fontes, tabelas de teclas de atalho, tabela de mensagens, tabela de strings ou versão. Um recurso definido pelo aplicativo, também chamado de recurso personalizado (custom resource), pode conter quaisquer dados requeridos por um aplicativo específico.
Os recursos são descritos em arquivos texto próprios, chamados arquivos de recurso, geralmente com a extensão .rc. Estes arquivos precisam ser compilados (no menu do MASM [Project / Compile Resource File]) e, depois de compilados, podem ser combinados com o arquivo de código fonte durante o estágio de link. O produto final é um arquivo executável que contém instruções e recursos.
Podemos usar qualquer editor de texto para escrever arquivos de recursos. O texto é composto por frases que descrevem a aparência e os atributos dos recursos desejados para um determinado programa. Os recursos possuem uma linguagem própria, a Resource Script Language. Conhecendo um mínimo desta linguagem é o suficiente para podermos trabalhar (o help do Resource Workshop da Borland é uma referência muito boa).
Existem editores de recursos que facilitam muito o trabalho por oferecerem uma plataforma de trabalho visual. Editores de recursos geralmente estão incluídos nos pacotes de compiladores como Visual C++, Borland C++, etc.
Você pode usar o excelente XN Resource Editor, o ResourceStudio da Symantec ou o Resource Compiler. Estes você encontra na seção de Downloads/Informática/Compiladores.
Criando um arquivo de recursos
Use o programa gráfico da sua preferência para criar um gráfico ou escolha um da sua preferência. Salve-o ou transfira-o para o diretório de trabalho deste tutorial. O arquivo de recursos deve ficar no mesmo diretório do arquivo com o código fonte. O gráfico que preparei para este tutorial recebeu o nome de "bits.bmp" e é o que se vê abaixo:
A diretiva para indicar um recurso bitmap é a seguinte:
IDentificador BITMAP [tipo de carregamento] [opção de memória] NomeDoArquivo
- Identificador é o ID do recurso, que é um número. O ID será usado quando quisermos usar este recurso no programa (Obrigatório).
- BITMAP é uma palavra chave para indicar o tipo de recurso (Obrigatório).
- Tipo de carregamento é opcional. Indica se queremos que o bitmap seja previamente carregado (PRELOAD) ou apenas seja carregado quando solicitado (LOADONCALL). O default é LOADONCALL.
- Opção de memória indica como o recurso deve ser carregado na memória. Pode ser descartável para livrar espaço de memória (DISCARDABLE), ficar fixo num endereço de memória (FIXED), ser modificado após o carregamento (IMPURE), pode ser deslocado na memória (MOVEABLE), precisa permanecer na memória (NONDISCARDABLE), não é modificado após o carregamento (PURE). O default é MOVEABLE e DISCARDABLE.
- NomeDoArquivo é o nome do bitmap.
Podemos resumir nosso arquivo RSRC.RC numa linha que contenha apenas o ID, a palavra chave BITMAP e o nome do arquivo. O restante deixamos como default. Abra um editor de texto (pode ser o GUN do MASM que você encontra em [Tools / TheGUN Text Editor]) e digite a linha abaixo:
760 BITMAP "bits.bmp"
Você pode usar qualquer número para o ID, contanto que não seja o mesmo usado por outro recurso. Salve o arquivo com o nome de "RSRC.RC" no mesmo diretório onde estará o código fonte do nosso programa teste. Por enquanto é só.
O programa teste
Vamos criar uma janela que conterá o bitmap do recurso, portanto podemos partir do modelo "Janelas" que criamos no tutorial anterior.
Vamos mudar o título da janela para "NumaBoa com Recursos" só para identificá-la melhor:
Como queremos que o gráfico seja mostrado assim que a janela aparecer na tela, precisamos gerenciar a mensagem WM_CREATE que é enviada ao gerenteMensagem assim que a janela é criada. Primeiramente vamos criar uma área dentro da janela principal onde o bitmap deve ser mostrado. Essa área especial nada mais é que um controle, ou seja, uma janela especial. Já sabemos que, para criar uma janela/controle, precisamos de uma classe registrada que servirá como modelo. No Windows existem classes predefinidas para controles: BUTTON, COMBOBOX, EDIT, LISTBOX, SCROLLBAR e STATIC. Usaremos a STATIC, por que não esperamos adicionar nenhuma funcionalidade ao nosso bitmap. A primeira provicência, então, é inicializar uma variável com o nome da classe na seção .DATA:
Criando a janela
Como vamos precisar da função CreateWindowEx, não custa dar uma recapitulada:
HWND CreateWindowEx( DWORD dwExStyle, // estilo especial de janela LPCTSTR lpClassName, // ponteiro para a classe registrada LPCTSTR lpWindowName, // pointeiro para o nome da janela: NULL DWORD dwStyle, // estilo da janela int x, // posição horizontal da janela int y, // posição vertical da janela int nWidth, // largura da janela int nHeight, // altura da janela HWND hWndParent, // manipulador da janela-mãe ou proprietário da janela HMENU hMenu, // manipulador do menu ou identificador da janela-filha HINSTANCE hInstance, // manipulador da instância do aplicativo LPVOID lpParam // ponteiro para dados de criação da janela );
- dwExStyle: não usaremos um estilo especial - NULL.
- lpClassName: o nome da classe está na variável ClasseAreaBMP - seu endereço será ADDR ClasseAreaBMP.
- lpWindowName: a janela não precisa de título - usaremos NULL.
- dwStyle: a composição do estilo será "Estilo Janela (WS) Filha" + "Estilo Janela (WS) Visível" + "Controle Estático (SS) com Bitmap" que é indicado com WS_CHILD or WS_VISIBLE or SS_BITMAP.
- x e y: a posição horizontal e vertical do canto superior esquerdo da janela do controle dentro da janela-mãe - indicamos ambos como 20 pixels.
- nWidth e nHeight: a largura e a altura da janela em pixels - indicamos temporariamente como 10. O porque do temporário será explicado logo adiante (4.4. Preparando a pintura).
- hWndParent: o manipulador da janela-mãe - no nosso exemplo é o parâmetro hWnd do procedimento gerenteMensagem.
- hMenu: não existe menu no controle, portanto NULL.
- hInstance: o manipulador do módulo, mInstancia.
- lpParam: não há dados na criação da janela - NULL.
Tudo em riba para podermos incluir a chamada à função que criará o controle com a área que deve conter o bitmap:
A função CreateWindowEx retorna o valor do manipulador da janela em EAX. Precisaremos deste valor logo adiante, portanto, criaremos uma variável local e a inicializamos com o valor de retorno:
Nosso bitmap está nos recursos e tem o identificador 760. Agora precisamos obter um manipulador para o bitmap para que possamos acessá-lo. Usamos a função LoadBitmap:
HBITMAP LoadBitmap( HINSTANCE hInstance, // manipulador da instância do aplicativo LPCTSTR lpBitmapName // endereço do nome do recurso bitmap );
Da mesma forma que acima, precisamos de uma variável local que receba o manipulador:
O sistema possui um "pintor" de plantão que pode ser acionado sempre que necessário. Basta enviar uma mensagem com os dados necessários para que ele possa trabalhar. A função SendMessage envia a mensagem especificada para uma ou mais janelas. Esta função chama o gerente de mensagens do(s) destinatário(s) e não retorna enquanto o pedido não for integralmente realizado.
LRESULT SendMessage( HWND hWnd, // manipulador da janela destino UINT Msg, // mensagem a ser enviada WPARAM wParam, // primeiro parâmetro da mensagem LPARAM lParam // segundo parâmetro da mensagem );
- hWnd: nossa janela destino é a janela do controle com a área que foi preparada para receber o bitmap - mAreaBMP.
- Msg: a mensagem é dirigida a um controle estático (STatic control Message), ou seja, do tipo STM_ alguma coisa. As mensagens que existem são STM_GETICON, STM_SETICON, STM_GETIMAGE e STM_SETIMAGE. Obviamente é da STM_SETIMAGE que estamos precisando.
- wParam: o primeiro parâmetro de uma mensagem do tipo STM_SETIMAGE refere-se ao tipo de imagem e pode ser IMAGE_BITMAP, IMAGE_CURSOR, IMAGE_ENHMETAFILE e IMAGE_ICON. O tipo da nossa imagem é IMAGE_BITMAP.
- lParam: o segundo parâmetro da mensagem STM_SETIMAGE refere-se ao manipulador da imagem. No nosso caso, mBMP.
Vamos enviar nossa mensagem com:
Você ainda se lembra de que dimensionamos nosso controle para ter 10 x 10 pixels? Nosso gráfico tem 255 x 185 pixels. Vai faltar pixel para abrigar o gráfico inteiro - problema do "pintor" de plantão. Como enviamos as coordenadas da posição do controle estático, o "pintor" vai transferindo a sequência de pixels que ele encontrar nos recursos e "estica" o controle para fazer espaço para o gráfico. Tão simples assim... mas precisamos saber disso para que o gráfico não avance sobre outros controles desformatando nosso layout.
Finalmentes
Neste exemplo, o resultado final será este:
Se você quiser fazer o download do texto, do código fonte e do executável deste tutorial, procure em Downloads / Tutoriais / Assembly Numaboa clicando no menu à direita.
Espero que tenham gostado e, como sempre
Grande abraço da vó Vicki