ActiveDelphi - Índice do Fórum ActiveDelphi
.: O site do programador Delphi! :.
 
 FAQFAQ   PesquisarPesquisar   MembrosMembros   GruposGrupos   RegistrarRegistrar 
 PerfilPerfil   Entrar e ver Mensagens ParticularesEntrar e ver Mensagens Particulares   EntrarEntrar 

[Resolvido] Mensagens Windows Entre Aplicações Delphi 6 e XE

 
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Delphi
Exibir mensagem anterior :: Exibir próxima mensagem  
Autor Mensagem
tiago.prs
Aprendiz
Aprendiz


Registrado: Sábado, 9 de Mai de 2009
Mensagens: 193

MensagemEnviada: Qui Set 27, 2012 10:18 am    Assunto: [Resolvido] Mensagens Windows Entre Aplicações Delphi 6 e XE Responder com Citação

Saudações pessoal,

Venho novamente a vocês pedir uma ajudinha.
Tenho que fazer duas aplicações comunicarem entre si, sendo uma feita em Delphi 6 e outra em Delphi XE.
Para essa comunicação estou utilizando o envio de mensagens do windows.

No Delphi XE, dentro da unit Messages já possuo a função SendGetStructMessage (Sim, estou utilizando o envio de Record´s). No Delphi 6 eu não possuo esse método, mas é só realizar a escrita do mesmo da seguinte forma (pelo menos está quase lá):
Código:

SendMessageW(WinHandle,WM_MENSAGEM,0,Windows.LPARAM(@RMensagem));

Isso é para enviar a mensagem pela aplicação em Delphi 6.

Onde:
- WinHandle é o Handle da janela da aplicação em Delphi XE, obtida pelo FindWindow();
- WM_MENSAGEM é a constante da minha mensagem;
- Windows.LPARAM(@RMensagem) é a forma como está escrita dentro da função SendGetStructMessage da unit Messages no Delphi XE.
- RMensagem é o meu record.

Essa função SendGetStructMessage do Delphi XE está assim:
Código:

function SendGetStructMessage(Handle: HWND; Msg: UINT; WParam: WPARAM;
  var LParam; Unused: Boolean = False): LRESULT;
begin
  Result := SendMessage(Handle, Msg, WParam, Windows.LPARAM(@LParam));
end;

Exemplos sobre em: http://docwiki.embarcadero.com/CodeExamples/en/Messages_(Delphi)

Bom, não estou conseguindo ler o membro String do meu Record na aplicação feita em Delphi XE. Acredito que seja devido a alteração no modo de trabalho com as Strings (nas novas versões do Delphi) que agora é Unicode (antes era no padrão ANSI).

Ao acessar o membro do Record na aplicação em Delphi XE dá erro de acesso à memória.

Segue o trecho dos códigos.

Delphi 6 (procedure de envio da mensagem).
Código:

Function TFrmMenuApp6.EnviarMensagem(): TRMensagem;
var
  WinHandle: THandle;
Begin
  RMensagem.Campo1 := StrToIntDef(Valor1,0);
  RMensagem.Campo2 := IntToStr(Valor2);

  WinHandle := FindWindow('TFrmMenuAppXE','Sistema Recebedor da Mensagem - AppXE');
  If WinHandle = 0 Then
     Begin
        WinExec('AppXE.exe',0);
        WinHandle := FindWindow('TFrmMenuAppXE','Sistema Recebedor da Mensagem - AppXE');       
     End;

  SendMessageW(WinHandle,WM_MENSAGEM,0,Windows.LPARAM(@RMensagem));

  Result := RLicenca;
End;


Nas duas aplicações eu ligo uma Unit com os seguintes valores definidos
Código:

Unit Mensagem

Interface

Uses
  Messages, Windows;

Const
  WM_MENSAGEM = WM_USER + 101;

Type
  TRMensagem = Packet Record
    Campo1: Integer;
    Campo2: String;
  End;

  TStructMessage = Packed Record
    Msg: Cardinal;
    WParam: Integer;
    LParam: ^TRMensagem;
    Result: LResult;
  End;

Implementation

End.


Na aplicação em DelphiXE, o recebimento da Mensagem Está:
Código:

Procedure TFrmMenuAppXE.GetMsg(var Msg: TStructMessage);
Begin
   ShowMessage(Msg.LParam^.Valor2);
End;


Visualizando o conteúdo de Msg.LParam eu encontro o membro 1 com o seu conteúdo, porém o membro 2 que é do tipo String está aparecendo como valor inacessível e consequentemente gera erro de violação de acesso ao tentar gerar o ShowMessage.

Bom, desculpem o testamento. Só quis ser bem detalhista.

Então é isso pessoal, alguém poderia me ajudar?
Acredito que o problema esteja no padrão diferente entre as duas aplicações (uma em UNICODE e outra em ANSI).

Desde já, muito grato pela atenção de vocês!
Att.
Tiago


Editado pela última vez por tiago.prs em Sex Set 28, 2012 9:16 am, num total de 1 vez
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
GustavoToyota
Profissional
Profissional


Registrado: Domingo, 9 de Outubro de 2011
Mensagens: 605
Localização: Sorocaba - SP

MensagemEnviada: Qui Set 27, 2012 12:07 pm    Assunto: Responder com Citação

Acredito que dessa forma não é possível entre duas aplicações. Vai vai ter que usar WM_COPYDATA.
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail MSN Messenger
tiago.prs
Aprendiz
Aprendiz


Registrado: Sábado, 9 de Mai de 2009
Mensagens: 193

MensagemEnviada: Qui Set 27, 2012 12:23 pm    Assunto: Responder com Citação

GustavoToyota escreveu:

Acredito que dessa forma não é possível entre duas aplicações. Vai vai ter que usar WM_COPYDATA.

Vou dar uma pesquisada sobre e conseguindo resolver eu posto a solução.

Grato!
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
tiago.prs
Aprendiz
Aprendiz


Registrado: Sábado, 9 de Mai de 2009
Mensagens: 193

MensagemEnviada: Sex Set 28, 2012 9:15 am    Assunto: Responder com Citação

Só para concluir o tópico, seguindo a dica dada pelo amigo Gustavo.
Usando esse link (http://delphi.about.com/od/windowsshellapi/a/wm_copydata.htm) como fonte eu consegui fazer as duas aplicações se comunicarem.

Não fui ver o que estava fazendo de errado. Achei a solução e logo implementei.
Para quem quer saber mais, aconselho baixar o exemplo dado no endereço acima. Ele usa duas aplicações e faz transferência de String, Record e Imagem (Lembrando que se trata de mensagem windows, então é somente local).

Meu pequeno exemplo:

Delphi 6
Código:

Type
  TRecordType = Packed Record
    Campo1: String[50];
    Campo2: String[50];
  End;

......

Procedure TFrmSender.BtnSendRecordClick(Sender: TObject);
var
  WinH: THandle;
  Result: Integer;
  MyRecord: TRecordType;
  copyDataStruct: TCopyDataStruct;
Begin
  MyRecord.Campo1 := 'Teste de Mensagem 1';
  MyRecord.Campo2 := 'Teste de Mensagem2' +#13+
                                  'Outra linha no Teste de Mensagem 2';

  //É usado como identificador, para quando for fazer transferência de mais de um tipo ou para objetivos diferentes
  copyDataStruct.dwData := 2;
  copyDataStruct.cbData := SizeOf(MyRecord);
  copyDataStruct.lpData := @MyRecord;

  WinH := FindWindow(PChar('TFrmMenuValidacao'),PChar('Validação'));
  If WinH = 0 Then
     Begin
       ShowMessage('Receiver NOT found!!');
       Exit;
     End;

  Result := SendMessage(WinH,WM_COPYDATA, Integer(Handle), Integer(@copyDataStruct));

  If Result = 999 Then
     ShowMessage('Mensagem recebida e processada com sucesso!');
End;


Exemplo no Delphi XE
Código:

Type
  TRecordType = Packed Record
    Campo1: String[50];
    Campo2: String[50];
  End;

......

Procedure TFrmMenuValidacao.Validar(var Msg: TWMCopyData);
var
  MyRecord: TRecordType;
Begin
  MyRecord := TRecordType(Msg.CopyDataStruct.lpData^);

  If (MyRecord.Campo1 <> '') And (MyRecord.Campo2 <> '') Then
    Begin
      ShowMessage(MyRecord.Campo1 +#13+#13+ MyRecord.Campo2);
      Msg.Result := 999;
    End;
End;


Abraços!
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
Mostrar os tópicos anteriores:   
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Delphi Todos os horários são GMT - 3 Horas
Página 1 de 1

 
Ir para:  
Enviar Mensagens Novas: Proibido.
Responder Tópicos Proibido
Editar Mensagens: Proibido.
Excluir Mensagens: Proibido.
Votar em Enquetes: Proibido.


Powered by phpBB © 2001, 2005 phpBB Group
Traduzido por: Suporte phpBB