A Aldeia Numaboa ancestral ainda está disponível para visitação. É a versão mais antiga da Aldeia que eu não quis simplesmente descartar depois de mais de 10 milhões de pageviews. Como diz a Sirley, nossa cozinheira e filósofa de plantão: "Misericórdia, ai que dó!"

Se você tiver curiosidade, o endereço é numaboa.net.br.

Leia mais...

Informática Numaboa - Tutoriais e Programação

Message Box (masm)

Sab

16

Dez

2006


11:41

(11 votos, média 4.55 de 5) 


Avançado Se a sua plataforma é Windows, então você quer ver pelo menos uma janela. Neste tutorial vamos usar novamente a API do Windows para fazer a maior parte do trabalho. Como o SO é baseado em janelas, existem algumas delas prontinhas para serem usadas. A escolhida é a Caixa de Mensagem (Message Box), com a qual vamos colocar um recado na tela.

Projeto

  1. O sistema operacional é o Windows de 32 bits.
  2. Não precisamos mais do que o conjunto de instruções do processador 386.
  3. O MASM vai fazer o trabalho pesado.
  4. O objetivo do programa é mostrar uma janela do tipo Message Box com um texto.

Botando a mão na massa

Abra o QEditor do MASM32 e digite o esqueleto de um programa que possa ser finalizado (Exit Process). É idêntico ao programa do tutorial "O Folgado":

.386
.MODEL FLAT,STDCALL
includelib \masm32\lib\kernel32.lib
include \masm32\include\kernel32.inc

.CODE
inicio:
invoke ExitProcess,0
end inicio

Vamos novamente usar uma função da API do Windows mas, antes de analisá-la, é bom saber alguma coisa a mais sobre as funções. Existem dois tipos de funções na API: do tipo ANSI e do tipo Unicode. Os nomes das funções da API para ANSI possuem um sufixo "A", por exemplo, MessageBoxA. As para Unicode têm o sufixo "W" (acho que é para Wide Char). O Windows 9x/Me suporta ANSI e o Windows NT, o Unicode.

As strings ANSI são as mais conhecidas. Elas são arrays de caracteres terminados em NULL. Um caractere ANSI tem o tamanho de 1 byte. Se o padrão ANSI é para 1 byte, isto significa que podem existir 256 caracteres diferentes (1 byte = 8 bits = 2ˆ8 = 256). Para as línguas européias o código ANSI é suficiente, pois não existem mais do que 256 caracteres diferentes. Este padrão, no entanto, não é adequado para muitas das línguas orientais, que possuem alguns milhares de caracteres únicos. Este é o motivo da existência do UNICODE. Um caractere UNICODE tem o tamanho de 2 bytes, tornando possível a existência de 65.536 caracteres únicos nas strings.

A função MessageBox

Na maioria das vezes usaremos um arquivo include que pode determinar e selecionar as funções da API apropriadas para a plataforma. Use apenas o nomes das funções API sem o sufixo que o MASM se encarrega do resto smile

A função da API do Windows que "fabrica" uma janela do tipo Message Box é a MessageBox e faz parte da biblioteca user32.dll. Dando uma olhada na referência da API do Windows, encontramos o seguinte:

int MessageBox(
HWND hWnd, // manipulador da janela proprietária
LPCTSTR lpText, // endereço do texto da message box
LPCTSTR lpCaption, // endereço do título da message box
UINT uType // estilo da message box
);

O valor de retorno da função é um inteiro e os parâmetros exigidos são:

  • hWnd: é o manipulador (handle) da janela-mãe. Você pode considerar o manipulador como um número que representa a janela. O valor deste número não é importante, apenas lembre-se de que representa uma janela. Quando você quiser fazer alguma coisa com a janela, refira-se a ela através do seu manipulador.
  • lpText: é um ponteiro para o texto que se quer mostrar na área cliente da janela. Um ponteiro, na realidade, é o endereço de alguma coisa. Um ponteiro para uma string de texto é igual ao endereço de memória onde está esta a string.
  • lpCaption: é um ponteiro para o título da janela.
  • uType: especifica o ícone e o número e tipo de botões na janela message box.

Se conhecemos o nome da função e a biblioteca à qual ela pertence, além de informar o assembler/linker que esta função deve ser vinculada ao programa, podemos adicionar sem susto as linhas seguintes:

.386
.MODEL FLAT,STDCALL
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc

.CODE
inicio:
invoke ExitProcess,0
end inicio

Os parâmetros exigidos pela função MessageBox são:

  • hWnd é o manipulador da janela-mãe. Como não existe uma janela-mãe, porque nossa janela é a única, então este parâmetro pode ser NULL.
  • lpText é o texto da janela - uma string ANSI terminada em zero. Lembre-se de que no Windows toda string ANSI precisa ser terminada em NULL (0 hexadecimal). Quem determina o texto que deve ser apresentado somos nós, portanto, vamos ter que inicializar esta string.
  • lpCaption é o título da janela - mais uma string terminada em zero que precisa ser inicializada.
  • uType determina o tipo da Message Box. Existem várias flags, agrupadas pelo tipo de aplicação, que determinam o conteúdo e o comportamento da MessageBox. Estas flags possuem nomes para facilitar o trabalho dos programadores. Assim, o grupo que determina os botões, possui flags como MB_OK (0 hexa), MB_YESNO (4 hexa), etc. O grupo do ícone possui MB_ICONWARNING (30 hexa), MB_ICONSTOP (10 hexa) e outros. Podemos fazer uma composição de flags para associar vários comportamentos e características fazendo um OR lógico com as flags desejadas. Por exemplo, para obter uma Message Box com botões Yes e No e com um ponto de interrogação como ícone, indica-se MB_YESNO (4 hexa) OR MB_ICONQUESTION (20 hexa).

Os parâmetros que precisam ser inicializados são o lpText e o lpCaption. A seção .DATA é onde estes dados podem ser inicializados. Os outros podem ser passados diretamente como valores ou como constantes predefinidas. Se quisermos utilizar as constantes predefinidas, é preciso incluir um arquivo include que contenha as definições. É onde entra o excelente arquivo windows.inc do Iczelion & Hutch (está no pacote do MASM32 versões 8 e 9).

O assembler faz distinção entre letras maiúsculas e minúsculas. Assim, nomejanela é diferente de NomeJanela. A sintaxe do MASM aceita uma diretiva que determina seu comportamento com letras maiúsculas e minúsculas: é a option casemap. Option casemap pode ser ALL, NONE e NOTPUBLIC (a última é o default). Usando option casemap:none logo abaixo da diretiva .MODEL, o MASM preserva a caixa dos identificadores. Usando option casemap:all, o MASM passa todos os identificadores para maiúsculo (por exemplo, tanto nomejanela quanto NomeJanela são transformados em NOMEJANELA). Queremos a caixa dos nossos identificadores preservada, então, para ir preparando o terreno, inclua o seguinte no script do seu programa:

.386
.MODEL FLAT,STDCALL
option casemap:none
include \masm32\include\windows.inc

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc

.DATA
TituloJanela db "Tutorial NumaBoa 3",0
TextoJanela db "Message Box NumaBoa",0


.CODE
inicio:
invoke ExitProcess,0
end inicio

Informações adicionais