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...

Oficina

Bloco de Notas com linhas numeradas

Seg

28

Mai

2007


20:28

(22 votos, média 4.05 de 5) 


Criando o código adicional

Vimos que, para cada mensagem WM_SIZE, a janela-filha "edit" é atualizada através de uma chamada a MoveWindow de acordo com o novo tamanho da janela principal. Porém, queremos evitar que a janela-filha "edit" ocupe a área total da janela mãe, ou seja, teremos que criar uma rotina que gerencie a altura das janelas com valores diferentes. Lembrando do trecho de código onde estes parâmetros são utilizados:

... .text:00401224 push eax ; hWnd <--- Handle da janela edit .text:00401225 call ds:InvalidateRect .text:0040122B push 1 ; bRepaint .text:0040122D push [esp+0C] ; nHeight <--- Altura da janela .text:00401231 push [esp+0C] ; nWidth <--- Largura da janela .text:00401235 push 0 ; Y .text:00401237 push 0 ; X .text:00401239 push hWnd ; hWnd .text:0040123F call ds:MoveWindow ; Atualização do tamanho da janela "edit" .text:00401245 retn 8

Colocando um salto (jump) na linha 40122D, podemos fazer com que o programa faça um "desvio" para o nosso código, o qual irá alterar nHeight de acordo com nossas instruções antes de alcançar a chamada que atualiza o tamanho da janela-filha "edit". Para gerenciar o tamanho da janela-filha "edit", nosso novo código altera o valor original da altura para repassá-lo à função MoveWindow:

Código para alterar a altura da janela-filha "edit"

Codigo_Altura: MOV EAX,[ESP+C] ; Obtém o valor da altura (nHeight) SUB EAX,14 ; Subtrai 14 hexa = 20 dec da altura (3) MOV novaAltura,EAX ; Guarda valor calculado em 40DB70 (1) PUSH EAX ; Põe valor da altura no topo da pilha (2) PUSH [ESP+C] ; Põe valor da largura no topo da pilha (nWidth) JMP 00401235 ; Retorna ao local da chamada

Observação: o desvio para nosso bloco de código vai ser obtido a partir de uma instrução jump que ocupará 5 bytes. Com isto, existem duas linhas do código original que serão "comidas" pelo jump e que precisam ser substituídas em algum ponto do nosso novo código. As duas linhas estão em 40122D e 401231. A primeira coloca no topo da pilha a altura (nHeight) da janela-filha com push [esp+C] e a segunda coloca no topo da pilha a largura (nWidth) da mesma janela-filha, também com um push [esp+C]. Como utilizamos o registrador EAX para calcular o novo valor da altura da janela-filha "edit", substituímos a linha 40122D push [esp+C] pela linha indicada em (1), colocando diretamente o valor de EAX no topo da pilha. A linha 401231 é substituída pela linha indicada em (2), mantendo a instrução push [esp+C].

Além disso, na linha indicada em (3), o valor calculado da nova altura é salvo no endereço 40DB70 porque vai ser necessário no módulo de código referente à impressão, citado logo adiante. A escolha do endereço das variáveis encontra-se logo abaixo na tabela de variáveis.

Após ter projetado o código para gerenciar o tamanho da janela-filha "edit", precisamos imprimir algum texto na janela principal (os números das linhas). Toda vez que uma janela precisa ser "repintada" (por exemplo, quando esteve encoberta por outra janela ou quando o usuário alterar seu tamanho), o Windows chama o procedimento WndProc com WM_PAINT. Isto significa que teremos que "caçar" a mensagem WM_PAINT e, novamente, forçar um salto para a nossa rotina que, desta vez, será um módulo que imprima texto.

Também precisamos imprimir texto toda vez que o cursor muda a sua posição vertical. A melhor maneira para conseguir isto é ignorar todas as mensagens possíveis que informem qualquer mudança na posição do cursor e passar a comparar a nova posição do cursor com a antiga.

Examinando o início do código do WndProc, nota-se que nada é feito com a mensagem WM_PAINT. Desta forma, no início do procedimento WndProc podemos inserir um salto (jump) para nosso módulo de código:

... .text:00401C8C push ebp .text:00401C8D mov ebp, esp <--- Local indicado para o salto .text:00401C8F push esi .text:00401C90 mov esi, [ebp+0C] .text:00401C93 cmp esi, 5 <--- Retornando para este endereço

Novamente precisaremos de 5 bytes para forçar o salto. Temos espaço suficiente entre os endereços 401C8C e 401C90. O endereço para o retorno no nosso módulo de código será 401C93.

Informações adicionais