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

Menu malandro (masm)

Qui

16

Abr

2009


20:57

(2 votos, média 5.00 de 5) 


Nível intermediário

Trabalhando com variáveis do sistema. Brinque com o usuário. Resolução de tela, coordenadas de janelas, data e hora do sistema são algumas das novidades usadas para criar uma janela que "foge" do cursor do mouse.

Neste tutorial vamos fazer uma brincadeira com o usuário. Aproveitando o código fonte do tutorial anterior, o Criando menus em Assembly, vamos obter algumas informações do contexto (as assim chamadas variáveis do sistema) e fazer com que a janela "fuja do cursor do mouse". Veremos como obter a resoluçãoo de tela, o tamanho de uma janela, hora e data do sistema e a posição de uma janela na tela. Veremos também como interagir com estes dados para obter os resultados desejados.

O tipo da janela

O código fonte base é o mesmo escrito para o tutorial "Criando menus em Assembly", assim como o arquivo de recursos. O arquivo de recursos não precisa ser alterado. Fazendo algumas pequenas modificações no código fonte, podemos fazer uma brincadeira com o usuário - escolhendo determinados itens do menu, a janela "foge". A primeira pequena modificação será feita na função CreateWindowEx: fixaremos o tamanho da janela em 300 x 200 pixels e tiraremos os elementos do canto superior direito da janela que permitem maximizar ou minimizar a janela.

... .DATA ... largJanela dd 300 altJanela dd 200 .CODE inicio: ... gerenteJanela proc mInst:HINSTANCE, mInstAnt:HINSTANCE, linhaCmd:LPSTR, Mostra:DWORD ... INVOKE CreateWindowEx, NULL, ADDR NomeClasse, ADDR TituloJanela,\ WS_POPUPWINDOW or WS_CAPTION, CW_USEDEFAULT,\ CW_USEDEFAULT, largJanela, altJanela, NULL, NULL,\ mInst, NULL ... end inicio

Trocando o texto

Primeiramente vamos trocar o texto que será mostrado ao usuário quando escolher algum item do menu. Use a imaginação e divirta-se. Minha sugestão não está "aquelas coisas", mas serve como exemplo:

... .DATA NomeClasse db "MenuPadrao",0 TituloJanela db "Menu Malandro",0 NomeMenu db "lanchonete",0 Texto_sopa db "SOPA de Letrinhas - Só para adultos",0 Texto_salada db "SALADA Brejeira - Temperada com besteira",0 Texto_peixe db "PEIXE Ecológico - Direto do brejão",0 Texto_frango db "FRANGO Sadio - Goleiro sarado",0 Texto_piranha db "Nananinanão... hehehe",0 Texto_sobremesa db "SOBREMESA Especial - Bala perdida",0 Texto_fim db "Até outra hora...",0

Trocando caixas de mensagens por texto na tela

Ao invés de utilizar a função MessageBox para criar caixas de mensagem para indicar o item de menu escolhido, vamos "pintar" o texto referente a cada item do menu na área cliente da janela. O procedimento já foi descrito em detalhes no tutorial Pintando Texto. A lógica é a seguinte:

  • Criamos uma variável global que recebe o endereço do texto referente ao item de menu selecionado. Este valor é obtido quando interceptamos a mensagem WM_COMMAND.
  • No final da rotina do WM_COMMAND chamamos a função InvalidateRect, a qual força uma repintura da área cliente da janela, ou seja, invalida a área e envia uma mensagem WM_PAINT.
  • Interceptamos a mensagem WM_PAINT e fazemos a pintura do texto indicado pelo endereço da variável global.

A coisa fica com esta cara:

... .DATA? mInstancia HINSTANCE ? endTexto WPARAM ? ... gerenteMensagem proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM LOCAL mCM:HDC LOCAL ps:PAINTSTRUCT LOCAL eRet: RECT ... .ELSEIF uMsg == WM_COMMAND mov eax, wParam .IF ax == mnID_fim invoke MessageBox, NULL, ADDR Texto_fim, OFFSET TituloJanela, MB_OK invoke DestroyWindow, hWnd .ELSEIF ax == mnID_sopa mov endTexto, OFFSET Texto_sopa .ELSEIF ax == mnID_salada mov endTexto, OFFSET Texto_salada .ELSEIF ax == mnID_peixe mov endTexto, OFFSET Texto_peixe .ELSEIF ax == mnID_frango mov endTexto, OFFSET Texto_frango .ELSEIF ax == mnID_sobremesa movendTexto, OFFSET Texto_sobremesa .ELSEIF ax == mnID_piranha mov endTexto, OFFSET Texto_piranha ... .ELSEIF ax == mnID_amendoim mov endTexto, OFFSET Texto_piranha ... .ENDIF invoke InvalidateRect, hWnd, NULL, TRUE .ELSEIF uMsg == WM_PAINT invoke BeginPaint, hWnd, ADDR ps mov mCM, eax invoke GetClientRect, hWnd, ADDR eRet invoke DrawText, mCM, endTexto, -1, ADDR eRet,\ DT_SINGLELINE or DT_CENTER or DT_VCENTER invoke EndPaint, hWnd, ADDR ps .ELSE ...

Se você quiser, neste ponto é possível compilar um executável e testá-lo. A janela ainda não "foge", porém as mensagens relativas aos itens de menu aparecem na área cliente da janela.

Informações adicionais