segunda-feira, 12 de julho de 2010

Capturar janelas, classes e textos com o lazarus

No meu artigo sobre a api do windows eu já mencionei sobre a importância de um programinha que identifique as janelas, handles e clases do windows.

Muitos programas nos "baixaki" da vida fazem isso, e alguns debuggers e cheaters para games também. Mas a maior utilidade que vejo para um programinha assim é poder identificar nomes de classes e handles de janelas não feitas por você, para interagir com sua aplicação.

Seja para colocar uma janela externa como child da sua, seja para capturar o conteudo de um textbox em outra janela, esse tipo de aplicação pode ser útil.

Eu usei muito para descobrir quais eram as classes por trás de alguns editores de propriedade e / ou editores de componentes não documentados do Delphi 7 para fazer meus próprios.

Hoje vamos fazer uma aplicaçãozinha dessas em lazarus.

Primeiro de tudo baixe a última versão do lazarus no site oficial.

Depois de instalado, a instalação é bem simples, inicie um novo projeto e crie uma janela como a da figura 1.

figura 1: uma janela fina, com um botão que não faz nada, só de teste, um label, e um timer

Colocamos nessa janela apenas um botão, um label, chamado lblHandle e um timer. O timer conterá toda a lógica do programa.

O botão servirá apenas como um teste dentro da propria janela, mas o objetivo do programa é que funcione para qualquer janela feita com a api do windows.

Janelas feitas com outras api's gráficas, como gtk, não funcionarão.

O objetivo do programa é mostrar o handle, o nome de classe e o texto de qualquer janela ou controle "windowed" de qualquer programa pelo qual estivermos passando a seta do mouse em um dado momento.

figura 2: o programa em funcionamento mostra o handle do visor da calculadora do windows

Para isso digite o código da listagem abaixo no evento onTimer do timer.


procedure TForm1.Timer1Timer(Sender: TObject);
var
   //criamos dois pchars, um para o nome da classe (c) e outro para o texto da janelas (t)
   t,c: pchar;
   //para obter um handle (na verdade um handle é um inteiro de 4 bytes sem sinal)
   h: Thandle;
   //usaremos um ponteiro para a estrutura POINT para obter a posição da seta do mouse
   p: PPOINT;
begin

     try
        try

           //vamos alocar memoria para o nosso PPoint com new, visto que é uma estrutura simples
           new(p);
           //para c e t usaremos getmem porque trata-se de vetores/strings. Limitaremos a 255 caracteres neste exemplo.
           GetMem(t, 255);
           GetMem(c, 255);

           //preenchemos todo o conteudo da memória alocada com #0 para que strings menores que 255 caracteres possam terminar com um #0 no seu final sem concatenar com lixo randomico de memória
           FillChar(c^, 255, #0);
           FillChar(t^, 255, #0);

           //obtemos a posição do cursor
           GetCursorPos(p);

           //obtemos o handle nesse ponto
           h := WindowFromPoint(p^);

           //obtemos o texto dessa janela (handle)
           GetWindowText(h, t, 255);

           //e o nome da classe (no caso de programas feitos em Delphi, há a vantagem de o nome da classe na api ser igual ao nome da classe na sua unit.pas)
           GetClassName(h, c, 255);

           //mostramos as informações no handle
           lbHandle.Caption := 'Handle: ' + IntToStr(h) + ' - Texto: ' + string(t) + ' - Classe: ' + string(c);

        except

        end;
     finally

            //desalocamos a memória
            dispose(p);
            Freemem(t);
            Freemem(c);

     end;

end;    
  

Veja que é importante desalocar a memória dentro de um bloco finally para garantir que não ocorram leaks (vazamentos de memória).

Você pode baxar os fontes aqui.

Espero que seja útil para vocês quanto foi para mim.

Amanhã teremos mais dicas do Lazarus.

Have Fun ;)

Nenhum comentário:

Postar um comentário

Postagens populares

Marcadores

delphi (60) C# (31) poo (21) Lazarus (19) Site aos Pedaços (15) sql (13) Reflexões (10) .Net (9) Humor (9) javascript (9) ASp.Net (8) api (8) Básico (6) Programação (6) ms sql server (5) Web (4) banco de dados (4) HTML (3) PHP (3) Python (3) design patterns (3) jQuery (3) livros (3) metaprogramação (3) Ajax (2) Debug (2) Dicas Básicas Windows (2) Pascal (2) games (2) linguagem (2) música (2) singleton (2) tecnologia (2) Anime (1) Api do Windows (1) Assembly (1) Eventos (1) Experts (1) GNU (1) Inglês (1) JSON (1) SO (1) datas (1) developers (1) dicas (1) easter egg (1) firebird (1) interfaces (1) introspecção (1) memo (1) oracle (1) reflexão (1)