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) 


Código para imprimir números de linhas

Código_Imprime: mov ebp, esp ; Substituindo a linha 401C8D push esi ; Substituindo a linha 401C8F mov esi, [ebp+0C] ; Substituindo a linha 401C90 (4) push 0 ; lParam push -1 ; wParam push C9 ; EM_LINEFROMCHAR push [405004] ; Handle da janela-filha "edit" call SendMessageA ; Após esta chamada, EAX contém a ; posição Y do cursor (5) cmp eax,linhaAtual ; Posição do cursor mudou ? jnz atualiza_nro_linha ; Sim, imprimir novo número de linha cmp esi,0Fh ; A mensagem atual é WM_PAINT ? jnz nao_atualiza ; Não, retorne para WndProc atualiza_nro_linha: mov linhaAtual,eax ; Salva a posição Y do cursor em 40DB78 (6) inc eax ; Ajusta o número da linha push eax ; Põe número ajustado no topo da pilha (7) lea eax,stringFormatação ; Obtém a string de formatação push eax ; Põe string de formatação no topo da pilha (8) lea eax,offsetNroAscii ; Obtém posição para guardar número push eax ; Põe posição no topo da pilha (9) call wsprintfA ; Transforma número em ASCII e transfere ; resultado para a posição offsetNroAscii push [405000] ; Handle da janela principal (10) call GetDC ; Obtém contexto do ambiente (11) mov hContexto,eax ; Salva Ambiente push 1 ; Coordenada X para expansão de Tabs push 0 ; Array de posições de Tabs push 0 ; Número de Tabs no array push F ; Número de caracteres da string (nCount) (12) lea eax,stringNroLinha ; Endereço da String push eax ; Põe string no topo da pilha push novaAltura ; Coordenada Y da posição inicial push 0 ; Coordenada X da posição inicial push [hContexto] ; Põe handle de contexto no topo da pilha (13) call TabbedTextOut ; Imprime o texto push [hContexto] ; Põe handle de contexto no topo da pilha push [405000] ; Põe handle da janela principal na pilha (14) call ReleaseDC ; Libera o Ambiente add esp,C ; Corrige o Ponteiro da Pilha nao_atualiza: jmp 00401C93 ; Volta para WndProc

Note que foram utilizadas algumas variáveis. Cada uma destas variáveis possui um endereço próprio. Alguns dos valores são alterados pelo próprio programa, outros precisam ser introduzidas através de um editor hexadecimal. Os endereços das variáveis foram escolhidos num bloco logo após o final do código:

Referência NomeEndereçoValor
(3)novaAltura 40DB70
(5)linhaAtual 40DB78
(7)stringFormatação 40DB80%#05d
(12)stringNroLinha 40DB90linha :
(8)offsetNroAscii 40DB9A
(11)hContexto 40DBA0

Foram usadas somente funções da API do Windows já importadas pelo notepad.exe (verifique a tabela de importações). O que fazer caso seja necessário lançar mão de funções da API que não constem da tabela de importações? No final do tutorial há uma explicação de como proceder nestes casos.

Algumas funções necessitam do handle da janela principal como parâmetro. Já foi descrito anteriormente como encontrar este valor.

  • (4) Nesta linha e nas três seguintes a chamada para a função SendMessageA é preparada. Esta função obtém o valor da coordenada Y do cursor e o retorna no registrador EAX.
  • (6) Se a posição do cursor for 0 (zero), estamos na linha 1. Se for 1, estamos na linha 2, etc. Portanto, precisamos ajustar o valor da coordenada Y do cursor somando 1.
  • (7) Preparamos os parâmetros da função wsprintfA.
  • (9) A função wsprintfA transforma o número enviado como parâmetro em caracteres ASCII de acordo com a string de formatação e coloca o resultado no endereço especificado. Por exemplo, transforma 1 em "00001".
  • (10) Para utilizar a função TabbedTextOut, precisamos primeiro obter o handle do contexto. Para isto chamamos a função GetDC com o parâmtero da janela principal (onde o texto deve ser impresso).
  • (11) A função GetDC devolve o handle do contexto no registrador EAX. Como precisaremos deste handle para liberar o contexto, armazenamos seu valor na variável hContexto.
  • (13) A função TabbedTextOut exige muitos parâmetros para imprimir a string enviada no local especificado. As 9 linhas anteriores à chamada preparam os parâmetros necessários.
  • (14) Finalmente, após a impressão da string na janela mãe, precisamos liberar o contexto que foi bloqueado pela função GetDC. Para isto utilizamos a função ReleaseDC.

Informações adicionais