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

Criando uma mini-calculadora em Assembly para Win32

Qua

14

Jan

2009


20:06

(11 votos, média 4.45 de 5) 


Agora que já temos o nosso procedimento de criar a janela feito iremos para onde trataremos as mensagens, onde saberemos qual foi a mensagem recebida e o que será feito. É lá onde o negócio legal vai começar!

Continuando com o código:

GerenteMensagem proc hWnd: DWORD, uMsg: UINT, wParam: WPARAM, lParam: LPARAM

Primeiro verificamos se a mensagem que foi recebida é WM_DESTROY. Se for, feche o programa, caso contrário prossiga com as nossas instruções.

.If uMsg == WM_DESTROY Invoke PostQuitMessage, NULL

Bem, aí sabemos que o programa recebeu a mensagem para ser fechado e depois disto nada mais pode ser feito.

Agora chegou a hora em que temos que criar o Edit Principal da Calculadora, onde ficarão os números, e depois os botões. Para criá-los, verificamos se a mensagem é igual a WM_CREATE; se for, podemos criar os edits e os botões.

.ELSEIF uMsg == WM_CREATE

Bem, pessoal, como meu irmão sempre me disse, tudo no Windows é uma janela. Pode não ser tudo, mas pelo menos quase tudo é: botões, edits, ListBox, etc, são todos janelas, porém são diferentes da nossa janela "mãe". São janelas filhas e, se são filhas, com certeza precisam de uma janela mãe. Então, já que agora sabemos que são janelas filhas e você já tem a mãe delas, então é só chamar a API CreateWindowEx pra criar novas janelas. Mas como sabemos, uma janela precisa basicamente de uma classe, de um título e de um Handle. Então sabemos agora que precisamos criar variáveis novas para o nosso programa. Para criar o Edit, não precisamos necessariamente de um título - então crie somente o nome da classe do Edit e uma variável não inicializada para ficar com o Handle do Edit.

Voltando ao início do código você teria:

.DATA Titulo_Janela db "Calculadora em ASM", 0 Classe_Janela db "Form1",0 Edit_Classe db "Edit", 0 .DATA ? Handle_Janela DWORD ? LinhaComando DWORD ? EditHandle DWORD ?

Pronto. Agora podemos criar nosso novo Edit! É só chamar a API CreateWindowEx smile

Invoke CreateWindowEx, NULL, ADDR Edit_Classe, NULL, WS_CHILD or WS_VISIBLE or WS_BORDER or ES_LEFT or ES_AUTOHSCROLL, 8, 8, 193, 21, hWnd, NULL, Handle_Janela, NULL Mov EditHandle, eax .ELSE Invoke DefWindowProc, hWnd, uMsg, wParam, lParam ret .ENDIF GerenteMensagem endp End Inicio

A partir de agora temos o nosso edit criado. Se você quiser executá-lo neste ponto, se o seu código estiver correto você já terá um edit na tela.

Criando os botões

Agora iremos aprender ou, se já sabemos, iremos criar os botões na nossa tela. Os botões irão de 0 até 9 e ainda teremos os botões de Soma, Subtração, Multiplicação e Divisão. Um ainda não implementado por mim, mas que pode ser implementado por vocês, é o da vírgula ou ponto como queira. Teremos ainda o CE, e por fim o Botão C.

Se já sabemos quais botões temos que criar, então vamos criar a classe de todos os botões. Voltando novamente ao início:

.DATA ... ; Logo após as variáveis que você já criou, crie uma agora que conterá a classe do botão Botao_Classe db "Button", 0 ; Classe criada, mas nós queremos mostrar o titulo do botão nele para sabermos quem é o ; Botão 1, o 2 , 3 e etc... sendo assim, temos que criar o titulo desse botão. Botao1_Titulo db "1",0 .DATA? ... ; Logo após todas as variáveis que você já criou dentro dessa seção, você terá que criar outra. ; Sabemos que um botão é uma janela, então significa que ele terá que ter seu próprio Handle. ; Então temos que criar um novo Handle para o botão que vai ter o número 1. Botao1_Handle DWORD ?

Agora podemos tranquilamente criar o nosso primeiro botão, que será o botão que conterá o número 1. Teremos que ir agora pra o procedimento GerenteMensagem e, logo abaixo de onde criamos o nosso edit, vamos criar o resto dos botões.

Invoke CreateWindowEx, NULL, ADDR Edit_Classe, NULL, WS_CHILD or WS_VISIBLE or WS_BORDER or ES_LEFT or ES_AUTOHSCROLL, 8, 8, 193, 21, hWnd, NULL, Handle_Janela, NULL Mov EditHandle, eax

Logo após essa parte do código chamaremos novamente a função CreateWindowEx para criar o primeiro botão, mas, antes disso, um problema que talvez seja achado por muitos "difícil" de resolver é onde ficará a posição dos botões na tela definida através de valores. Com o tempo, porém, se você pegar o jeito, isso deixa de ser um "problema" e sem contar que você pode usar suas técnicas smile Mas não se preocupe, no tutorial os botões já virão todos com suas posições definidas na tela, e lembrando que você pode alterar a posição deles na hora que quiser. Então vem o código do botão.

Invoke CreateWindowEx, NULL, ADDR Botao_Classe, ADDR Botao1_Titulo, WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON, 8, 32, 33, 25, hWnd, NULL, Handle_Janela, NULL Mov Botao1_Handle, eax

Se você adicionar o código e executar o programa, terá um botão na tela. Criar os outros botões não é diferente. Você só tem que se lembrar de criar uma nova variável em .DATA com o título do botão e uma nova em .DATA? que salvará o Handle do novo botão. Podemos fazer aquele velho CTRL + C e CTRL + V, sem esquecer de alterar algumas coisas.

OBS: A variável Botão_Classe pode ser usada para criar o resto de todos os outros botões. Então ela não muda, por que todos pertencem à mesma classe - a classe não precisa ser recriada. Ah, se você quiser pegar mais familiaridade com a API CreateWindowEx, então crie todos os botões digitando os códigos, sem copiar e colar.

Segue abaixo o código para criar o resto dos botões com as devidas posições. Primeiro adicionar os títulos de todos os botões e os Handles para os mesmos na seção .DATA e .DATA?

.DATA ... Botao2_Titulo db "2", 0 Botao3_Titulo db "3", 0 Botao4_Titulo db "4", 0 Botao5_Titulo db "5", 0 Botao6_Titulo db "6", 0 Botao7_Titulo db "7", 0 Botao8_Titulo db "8", 0 Botao9_Titulo db "9", 0 Botao0_Titulo db "0", 0 BotaoVirgulaTitulo db ",", 0 BotaoIgualTitulo db "=", 0 BotaoMaisTitulo db "+", 0 BotaoMenosTitulo db "-", 0 BotaoMultiplicarTitulo db "*", 0 BotaoDividirTitulo db "/", 0 BotaoCETitulo db "CE", 0 BotaoCTitulo db "C", 0 .DATA? ... Botao2Handle DWORD ? Botao3Handle DWORD ? Botao4Handle DWORD ? Botao5Handle DWORD ? Botao6Handle DWORD ? Botao7Handle DWORD ? Botao8Handle DWORD ? Botao9Handle DWORD ? Botao0Handle DWORD ? BotaoVirgulaHandle DWORD ? BotaoMaisHandle DWORD ? BotaoMenosHandle DWORD ? BotaoMultiplicarHandle DWORD ? BotaoDividirHandle DWORD ? BotaoIgualHandle DWORD ? BotaoCEHandle DWORD ? BotaoCHandle DWORD ?

Logo após o código do botão 1 você pode implementar o código de acordo com meu...

invoke CreateWindowEx, NULL, ADDR Botao_Classe, ADDR Botao2_Titulo, WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON, 48, 32, 33, 25, hWnd, NULL, Handle_Janela, NULL mov Botao2Handle, eax invoke CreateWindowEx, NULL, ADDR Botao_Classe, ADDR Botao3_Titulo, WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON, 88, 32, 33, 25, hWnd, NULL, Handle_Janela, NULL mov Botao3Handle, eax invoke CreateWindowEx, NULL, ADDR Botao_Classe, ADDR Botao4_Titulo, WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON, 8, 64, 33, 25, hWnd, NULL, Handle_Janela, NULL mov Botao4Handle, eax invoke CreateWindowEx, NULL, ADDR Botao_Classe, ADDR Botao5_Titulo, WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON, 48, 64, 33, 25, hWnd, NULL, Handle_Janela, NULL mov Botao5Handle, eax invoke CreateWindowEx, NULL, ADDR Botao_Classe, ADDR Botao6_Titulo, WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON, 88, 64, 33, 25, hWnd, NULL, Handle_Janela, NULL mov Botao6Handle, eax invoke CreateWindowEx, NULL, ADDR Botao_Classe, ADDR Botao7_Titulo, WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON, 8, 96, 33, 25, hWnd, NULL, Handle_Janela, NULL mov Botao7Handle, eax invoke CreateWindowEx, NULL, ADDR Botao_Classe, ADDR Botao8_Titulo, WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON, 48, 96, 33, 25, hWnd, NULL, Handle_Janela, NULL mov Botao8Handle, eax invoke CreateWindowEx, NULL, ADDR Botao_Classe, ADDR Botao9_Titulo, WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON, 88, 96, 33, 25, hWnd, NULL, Handle_Janela, NULL mov Botao9Handle, eax invoke CreateWindowEx, NULL, ADDR Botao_Classe, ADDR Botao0_Titulo, WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON, 8, 128, 33, 25, hWnd, NULL, Handle_Janela, NULL mov Botao0Handle, eax invoke CreateWindowEx, NULL, ADDR Botao_Classe, ADDR Botao0_Titulo, WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON, 8, 128, 33, 25, hWnd, NULL, Handle_Janela, NULL mov Botao0Handle, eax invoke CreateWindowEx, NULL, ADDR Botao_Classe, ADDR BotaoVirgulaTitulo, WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON, 48, 128, 33, 25, hWnd, NULL, Handle_Janela, NULL mov BotaoVirgulaHandle, eax invoke CreateWindowEx, NULL, ADDR Botao_Classe, ADDR BotaoIgualTitulo, WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON, 88, 128, 33, 25, hWnd, NULL, Handle_Janela, NULL mov BotaoIgualHandle, eax invoke CreateWindowEx, NULL, ADDR Botao_Classe, ADDR BotaoMaisTitulo, WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON, 128, 32, 33, 25, hWnd, NULL, Handle_Janela, NULL mov BotaoMaisHandle, eax invoke CreateWindowEx, NULL, ADDR Botao_Classe, ADDR BotaoMenosTitulo, WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON, 128, 64, 33, 25, hWnd, NULL, Handle_Janela, NULL mov BotaoMenosHandle, eax invoke CreateWindowEx, NULL, ADDR Botao_Classe, ADDR BotaoMultiplicarTitulo, WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON, 128, 96, 33, 25, hWnd, NULL, Handle_Janela, NULL mov BotaoMultiplicarHandle, eax invoke CreateWindowEx, NULL, ADDR Botao_Classe, ADDR BotaoDividirTitulo, WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON, 128, 128, 33, 25, hWnd, NULL, Handle_Janela, NULL mov BotaoDividirHandle, eax invoke CreateWindowEx, NULL, ADDR Botao_Classe, ADDR BotaoCETitulo, WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON, 168, 32, 33, 25, hWnd, NULL, Handle_Janela, NULL mov BotaoCEHandle, eax invoke CreateWindowEx, NULL, ADDR Botao_Classe, ADDR BotaoCTitulo, WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON, 168, 64, 33, 25, hWnd, NULL, Handle_Janela, NULL mov BotaoCHandle, eax

Pronto. Com todas essas adições nós temos o design final da nossa mini_calc.

Informações adicionais