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

Janelas (masm)

Dom

7

Jan

2007


10:34

(12 votos, média 4.83 de 5) 


Pilotando a janela

Planta da casa elaborada, planta registrada, casa construída... é hora de inaugurá-la.

Vamos mostrar nossa janela no desktop com a função ShowWindow

BOOL ShowWindow(
HWND hWnd, // manipulador da janela
int nCmdShow // modo de apresentação
);

adicionando-a ao nosso código:

gerenteJanela proc mInst:DWORD, mInstAnt:DWORD, linhaCmd:DWORD, Mostra:DWORD
LOCAL ej:WNDCLASSEX
LOCAL mJanela:HWND
...

invoke RegisterClassEx, ADDR ej
invoke CreateWindowEx, NULL, ADDR NomeClasse, ADDR TituloJanela,
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, mInst, NULL
mov mJanela,eax
invoke ShowWindow, mJanela, SW_SHOWNORMAL
gerenteJanela endp

Atualizando a janela

Pode-se chamar UpdateWindow para refazer a pintura da área cliente da nossa janela. Esta função é útil quando se quer atualizar o conteúdo da área cliente. Esta chamada pode ser omitida, sem problemas... mas sempre é bom garantir. E, já que estamos garantindo algumas coisas, também vamos providenciar o retorno da função gerenteJanela para a área do procedimento chamador. O mnemônico ret garante esta volta.

gerenteJanela proc mInst:DWORD, mInstAnt:DWORD, linhaCmd:DWORD, Mostra:DWORD
LOCAL ej:WNDCLASSEX
LOCAL mJanela:HWND
...

invoke RegisterClassEx, ADDR ej
invoke CreateWindowEx, NULL, ADDR NomeClasse, ADDR TituloJanela,
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, mInst, NULL
mov mJanela,eax
invoke ShowWindow, mJanela, SW_SHOWNORMAL
invoke UpdateWindow, mJanela
ret

gerenteJanela endp

Estrutura das mensagens

Se interrompermos nosso código neste ponto, teremos uma surpresa: executando o programa, nossa linda janelinha é mostrada no desktop uma fração de segundo e desaparece. Faça o teste: Clique no item de menu do QEditor [Project / Assemble & Link] para criar o executável e depois em [Project / Run Program].

O que falta é um trechinho de código cuja função é a de manter a janela no desktop e, o que é mais importante, fazer com que ela saiba o que acontece com ela.

Imagine o seguinte: quem controla todos os eventos que ocorrem com esta janela é o Windows. Aliás, o Windows tem uma espécie de central que controla todos os eventos referentes a todas as janelas. É como se fosse uma agência de correio onde cada instância de janela possui sua caixa postal. Quando o gerente da janela solicita sua correspondência, a agência lhe envia um malote com a mensagem recebida - uma atrás da outra e sempre a primeira da fila - inclusive com o número da mensagem e a hora! O gerente da janela confere o recebimento e envia a mensagem para o gerente de mensagens. O gerente de mensagens da janela pode responder a mensagem a seu modo (ao nosso modo wink) ou pode devolvê-la para o remetente (o Windows) e deixar que ele processe a mensagem de acordo com as regras do sistema (procedimento padrão). Observação: no sistema Windows, o gerente de mensagens é conhecido como window procedure.

Ainda bem que a "agência de correio" cuida da correspondência da nossa janela. Só precisamos contratar os gerentes e fornecer o malote. O malote traz diversas informações que podem ser agrupadas, portanto o ideal é usar uma estrutura. A estrutura utilizada como "malote" é a MSG:

typedef struct tagMSG { // msg
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
} MSG;

Os membros que constituem a estrutura MSG são:

  • hwnd: Identifica a janela cujo procedimento de janela (nosso gerenteMensagem) recebe a mensagem.
  • message: Especifica o número da mensagem.
  • wParam: Informação adicional sobre a mensagem. O sentido exato depende do valor do membro mensagem.
  • lParam: Informação adicional sobre a mensagem. O sentido exato depende do valor do membro mensagem.
  • time: A hora que a mensagem foi enviada.
  • pt: A posição do cursor, em coordenadas de janela, quando a mensagem foi enviada.

Pois bem, então vamos criar o "malote" da nossa janela:

gerenteJanela proc mInst:DWORD, mInstAnt:DWORD, linhaCmd:DWORD, Mostra:DWORD
LOCAL ej:WNDCLASSEX
LOCAL mJanela:HWND
LOCAL malote:MSG
...

invoke RegisterClassEx, ADDR ej
invoke CreateWindowEx, NULL, ADDR NomeClasse, ADDR TituloJanela,
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, mInst, NULL
mov mJanela,eax
invoke ShowWindow, mJanela, SW_SHOWNORMAL
invoke UpdateWindow, mJanela
ret
gerenteJanela endp

Informações adicionais