Informática Numaboa - Tutoriais e Programação
Criando uma mini-calculadora em Assembly para Win32
- Detalhes
-
Categoria: Assembly Numaboa (antigo oiciliS)
-
Atualização: Quinta, 15 Janeiro 2009 17:45
-
Autor: Felipe Costa
-
Acessos: 21433
Pagina 2 de 4
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
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 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.