Esse artigo faz parte da revista Clube Delphi Edição 85. Clique aqui para ler todos os artigos desta edição

-SIZE: 10pt; FONT-FAMILY: Verdana">Revista ClubeDelphi, publiquei uma coluna chamada “Oráculo da ClubeDelphi”. A idéia seria apresentar situações reais que são enfrentadas no dia a dia de um desenvolvedor Delphi ou que não fossem tão triviais, não aquelas que você encontra em uma simples busca no Google ou nos demos do Delphi, mas problemas mais “bruxos”.

O que apresento aqui, em mais uma versão da coluna, são quatro dúvidas para alguns problemas relacionados ao desenvolvimento com o Delphi. Antes de iniciar, lembrem-se que jamais se pergunta para um desenvolvedor Delphi se “dá para fazer determinada coisa”, mas “para quando ele pode fazer”, porque não há limites  para quem tem um Delphi aberto na sua frente.

 

Missão Impossível?

            Em certa ocasião, trabalhei para o CPD de uma universidade em Santa Maria no RS. Desenvolvíamos alguns sistemas internos, como o controle financeiro e vestibular. Porém, o sistema de biblioteca era terceirizado. Os alunos tinham um cartão pessoal (e intransferível) que utilizavam para retirar livros na biblioteca, através de uma leitura do cartão por código de barras.

         Alguns alunos mais “espertinhos”, e sem cadastro na instituição, utilizavam o cartão de outras pessoas para retirarem livros. A solução foi fazer toda a universidade tirar foto para ser examinada no momento da retirada do livro, já que o cartão não possuía foto.

         Aí começaram os problemas. Foi requisitado ao CPD que construísse um sistema que exibisse a foto do usuário no terminal de empréstimo justamente no momento em que o cartão de código de barras fosse passado no sistema. A matrícula aparecia em um TextBox / Edit do sistema externo e precisaríamos interceptar essa matrícula, localizar a foto, e exibir no canto da tela. Porém, tínhamos algumas pedras no caminho. Como iríamos fazer o sistema exibir a foto, se:

  1. Não tinhamos os fontes do sistema de biblioteca;
  2. Ele não foi feito em Delphi;
  3. Não tínhamos como modificá-lo.

A API do Windows é repleta de surpresas. Apesar de usar tipos exotéricos e não ser OO, você pode fazer um sistema inteiro, totalmente funcional, só usando API. Para algumas situações, precisamos recorrer a esse artifício para solucionar problemas mais complexos ou não suportados diretamente pela VCL do Delphi.

         Bom, como não existem limites para um desenvolvedor Delphi, topamos o desafio, e achamos essa solução na API do Windows. Vou simular aqui uma solução bastante semelhante ao que fiz na época.

No exemplo deste artigo construí primeiramente um formulário chamado “Server”, com um “TextBox” para ser informado um texto (nesse caso um nome). Esse form representa o form de empréstimo onde o usuário fornecia a matrícula. Como precisava ser em outra linguagem, construí a aplicação em Windows Forms com C#. A Figura 1 apresenta o layout do form, que não tem código.

 

Figura 1. Formulário em C#

Em seguida, construí o formulário Delphi, que no caso representaria o form que exibiria a foto. O layout está na Figura 2. Um ClientDataSet está ligado ao arquivo biolife.xml dos demos do Delphi, pela propriedade FileName. Um DBText e um DBImage ligam, via DataSource, aos campos Common_Name e Graphic da tabela biolife. O Timer é explicado a seguir. O objetivo é: quando um nome ou iniciais forem digitados no TextBox na aplicação “Server”, vamos dar um locate no respectivo registro no form Delphi e exibir os dados (como se fosse a foto da biblioteca, o procedimento é o mesmo).

 

Figura 2. Formulário Delphi

 

A grande pergunta para achar a solução para o problema: “Como descobrir o que está digitado no TextBox?”. Vamos começar pelo código do Timer (Listagem 1).

 

Listagem 1. Código do evento OnTimer

implementation

var

  MainForm: TMainForm;

  Texto: string;

  PRect: TRect;

....

procedure TMainForm.tmrTimer(Sender: TObject);

var

  Programa: THandle;

begin

   Programa := FindWindow(nil,pchar('Server'));

   if programa <> 0 Then

   begin

      GetWindowRect(Programa,Prect);

      EnumChildWindows(Programa,@ListaFilhos,0);

      if Texto <> '' then

        ClientDataSet1.Locate('Common_Name',Texto,

                   [loCaseInsensitive,loPartialKey]);

   end;

end;

 

No Windows, toda janela tem uma Handle, que na verdade é um número. Exato, tipos no Windows são números! O primeiro passo foi localizar a janela Server pelo seu nome, usando a API FindWindow. O Handle da janela é armazenado na variável Programa. Pronto, já temos acesso à janela servidora. A seguir, chamamos GetWindowRect para obter as dimensões do form Server.

EnumChildWindows é uma função interessante. Ela funciona assim, passamos para ela a Handle do form desejado e um ponteiro para uma função de ...

Quer ler esse conteúdo completo? Tenha acesso completo