Delphi - Como enviar dados para outro executável utilizando SendMessage?


Supondo que precisamos fazer duas aplicações se conversarem, passando informações que podem variar de acordo com uma ação do usuário.
O problema é que um endereço de memória só faz sentido no processo em questão, o que não é o caso, uma vez que vamos ter dois processos apartados.
Uma saída seria usar banco de dados, outra seria utilizar mapeamento de arquivo em memória.
Ambas funcionam mas são complicadas, afinal queremos apenas passar uma informação para outro executável.
Para nossa solução, vamos utilizar o WM_COPYDATA para mandar a mensagem com o SendMessage e para mandar a estrutura vamos utilizar o CopyDataStruct.

Vamos criar uma estrutura packed record que servirá para colocarmos tudo que precisamos para transferir as informações:

TMinhaEstrutura = packed record
  Opcao: Integer; //aqui pode-se usar várias variáveis para passar mais de uma informação de uma única vez
end;

Agora vamos fazer o envio da mensagem com a estrutura carregada:

var
  xHandle: HWND;  
  xCMD: TMinhaEstrutura ;
  xSendCMD: TCopyDataStruct;
begin
  xHandleMonitor := FindWindowExtd('Titulo da sua janela');   

  xCMD.Opcao := 1; //carregamos o xCMD com todas as informações que precisamos 
                   //(neste exemplo só passei uma variável mas poderia ser várias).

  //Aqui vamos utilizar o TCopyDataStruct para copiar a estrutura do record e enviá-la para o outro processo
  xSendCMD.cbData := SizeOf(xCMD);
  xSendCMD.lpData := @xCMD;

  //Aqui enviamos de fato a mensagem (O SendMessage manda a mensagem de forma síncrona, já o PostMessage manda de forma assíncrona) 
  SendMessage(xHandleMonitor, WM_COPYDATA, 0, Integer(@xSendCMD));
end;

A função FindWindowExtd foi feita com base em outra dica que você pode conferir clicando aqui


Agora vamos ver como receber essa informação no outro processo (.exe).
Aqui vamos fazer uso da mesma estrutura TMinhaEstrutra para receber os dados.
Para tal, vamos declarar a procedure na seção "private" do formulário:

procedure WMCopyData(var Msg: TWMCopyData); message WM_COPYDATA;

Não esqueça de declarar o uses "Messages" casa ainda não o tenha declarado.

Pressione ctrl + shift + c  para que o delphi crie o método.
Em seguida vamos implementá-lo da seguinte forma:

procedure TfrmPrincipal.WMCopyData(var Msg: TWMCopyData);
var
  xCMD: TMinhaEstrutura;
begin
  xCMD := TMinhaEstrutura(Msg.CopyDataStruct.lpData^);

  if xCMD.Opcao > 0 then begin

    Showmessage(IntToStr(xCMD.Opcao));
  end;
end;

E pronto, agora você pode mandar mensagens com dados para qualquer executável aberto.

Neste exemplo foi utilizado o Dephi 7 para enviar a mensagem e o Delphi Tokyo para receber.

delphi · ‎message · ‎sendmessage · ‎postmessage · ‎copydatastruct · ‎handle · ‎packedrecord · ‎record · ‎findwindow

Última atualização: 31/01/2018 às 15:06


  • Buscar