Buscar

Fazendo dois aplicativos se comunicarem - parte 2

nome

Diego De Queiroz Macedo

Colunista ainda sem descrição. Caro colunista, por favor envie-nos sua descrição.

Agora que já possuímos algum conteúdo teórico, partiremos para um pequeno exemplo prático:
Vamos simular uma comunicação bem simples entre um aplicativo denominado A e um outro aplicativo denominado B:

  • Nosso script:
         - O programa A envia a mensagem WM_USER para o aplicativo B;

  •      - O aplicativo B recebe esta mensagem e exibe uma mensagem na tela "Mensagem recebida!".

 

Codificação:

Form principal do aplicativo A

Componentes utilizados: Um Botão comum (Button1)

  
unit UnitTransmissor;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;

const
  MOSTRA_MENSAGEM = WM_USER;

type
  TTransmissorMainForm0001 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  TransmissorMainForm0001: TTransmissorMainForm0001;

implementation

{$R *.dfm}

procedure TTransmissorMainForm0001.Button1Click(Sender: TObject);
var
  ProgReceptor: THandle;
begin
  ProgReceptor:=FindWindow('TReceptMainForm0001',nil);
  SendMessage(ProgReceptor,MOSTRA_MENSAGEM,0,0);
end;

end.

  

 

Form principal do aplicativo B

Componentes utilizados: Nenhum

  
unit UnitReceptor;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs;

const
  MOSTRA_MENSAGEM = WM_USER;

type
  TReceptMainForm0001 = class(TForm)
  Private
    { Private declarations }
    procedure MostraMensagem(var Message: TMessage); message MOSTRA_MENSAGEM;
  public
    { Public declarations }
  end;

var

  ReceptMainForm0001: TReceptMainForm0001;

implementation

{$R *.dfm}

{ TReceptMainForm0001 }

procedure TReceptMainForm0001.MostraMensagem(var Message: TMessage);
begin
  ShowMessage('Mensagem recebida!');
end;

end.


  

 

Para um melhor entendimento, vamos analisar alguns trechos do código:

procedure TTransmissorMainForm0001.Button1Click(Sender: TObject);

Esta função possui é responsável pelo envio da mensagem. Ela está associada ao evento OnClick do botão do nosso Form transmissor.


var ProgReceptor: THandle;

Declaramos uma variável do tipo THandle. O tipo THandle é o tipo básico para armazenamento de Handles que nada mais são que os identificadores de objeto do Windows®. Os Handles são valores numéricos e podem ser substituídos pela variável integer comum.


ProgReceptor:=FindWindow('TReceptMainForm0001',nil);

Atribuímos um valor à variável ProgReceptor, este valor será o resultado da função FindWindow e é neste local onde mora um cuidado muito especial: O nosso aplicativo A tem de alguma forma encontrar o aplicativo B, para isso temos que encontrar o "endereço" dele. Dentro do Windows® este endereço é o Handle.
Mas para que isso seja sempre possível o aplicativo A tem de saber o nome do aplicativo B. O nome da classe do aplicativo B geralmente é o nome do Form precedido pela letra "T" (não é uma regra), mas o método mais fácil é verificar o nome que está após a palavra Type na Unit do Form que se deseja encontrar o Handle:


type TReceptMainForm0001 = class(TForm)

Logo o nome da classe da nossa janela é "TReceptMainForm0001". É EXTREMAMENTE recomendado que você sempre dê um nome ao seu Form, pois imagine bem: você cria um aplicativo cujo nome do Form principal é Form1, logo a classe provavelmente será TForm1, depois cria outro aplicativo totalmente diferente com o mesmo nome, logo possuirá o mesmo nome de classe. A partir deste momento você passa a ter uma instabilidade, pois o resultado da função será sempre o primeiro aplicativo da fila, ou seja, entre duas janelas com o mesmo nome de classe, a função FindWindow sempre retornará o Handle da janela que foi iniciada primeiro.


SendMessage(ProgReceptor,MOSTRA_MENSAGEM,0,0);

Declaração de SendMessage (este código não deve ser escrito! Ele já existe na UNIT Windows que acompanha o Delphi):

Function SendMessage(
     hWnd: HWND;      // handle da janela de destino
     Msg: Cardinal;   // mensagem a ser enviada
     wParam: integer; // primeiro parâmetro da mensagem
     lParam: integer  // segundo parâmetro da mensagem
): integer;

A função SendMessage envia uma mensagem para a janela especificada e espera que ela termine o processamento da mesma. Ela pode processar um resultado também (veremos mais detalhes sobre este resultado mais a frente). Como você também deve ter notado na declaração, ela também implementa a possibilidade de enviar dois parâmetros do tipo inteiro para o programa destino.


procedure MostraMensagem(var Message: TMessage); message MOSTRA_MENSAGEM;

Neste ponto você deve ter notado algo extremamente incomum, como a palavra reservada "message". Este tipo de implementação faz com que a função declarada seja executada sempre que a classe receber a mensagem especificada (MOSTRA_MENSAGEM no nosso caso).

 

Agora vamos ver o resultado deste exemplo:

  • Execute os dois programas e clique no botão do aplicativo A.


  • Quando o botão é clicado a mensagem é enviada, ao receber esta mensagem o programa receptor executa a função associada, exibindo a mensagem. Note que o aplicativo Transmissor fica desabilitado até que o aplicativo Receptor termine de processar a mensagem, ou seja, até que você pressione o botão OK.
    Uma maneira de evitar isso é substituir a função SendMessage pela função PostMessage cuja declaração é exibida a seguir (este código também não deve ser escrito! Ele já está escrito na UNIT Windows que acompanha o Delphi):

    Declaração de PostMessage (este código não deve ser escrito! Ele já existe na UNIT Windows que acompanha o Delphi):

    Function PostMessage(
         hWnd: HWND;
         Msg: Cardinal;
         wParam: integer;
         lParam: integer
    ): LongBool;

    A função PostMessage tem a mesma utilidade da função SendMessage (note que são os mesmos parâmetros), tendo como único diferencial a questão de não esperar que o programa destino processe a mensagem, de tal modo, ela também não permite que seja processado um resultado. O valor que ela retorna é um valor boleano (True ou False) que representa se a chamada à função foi bem sucedida.

    Para as próximas partes pretendo me aprofundar no assunto, trazendo exemplos mais complexos e trabalhados.
    Espero pelos seus comentários!

    Publicidade

    Vote no artigo




    Quantidade de votos: 0 votos
    Aceitação: 0%


    Detalhes do artigo

    Categoria: Windows
    Adicionado dia: 16/01/06
    Por: Diego De Queiroz Macedo
    Visualizado: 45395 vezes

    Planeta Delphi - Tudo sobre programação Delphi Planeta Delphi - www.planetadelphi.com.br - Todos os direitos reservados | Copyright 2001-2009