 |
ActiveDelphi .: O site do programador Delphi! :.
|
Exibir mensagem anterior :: Exibir próxima mensagem |
Autor |
Mensagem |
tiago.prs Aprendiz


Registrado: Sábado, 9 de Mai de 2009 Mensagens: 193
|
Enviada: Qui Set 27, 2012 10:18 am Assunto: [Resolvido] Mensagens Windows Entre Aplicações Delphi 6 e XE |
|
|
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 |
|
 |
GustavoToyota Profissional


Registrado: Domingo, 9 de Outubro de 2011 Mensagens: 605 Localização: Sorocaba - SP
|
Enviada: Qui Set 27, 2012 12:07 pm Assunto: |
|
|
Acredito que dessa forma não é possível entre duas aplicações. Vai vai ter que usar WM_COPYDATA. |
|
Voltar ao Topo |
|
 |
tiago.prs Aprendiz


Registrado: Sábado, 9 de Mai de 2009 Mensagens: 193
|
Enviada: Qui Set 27, 2012 12:23 pm Assunto: |
|
|
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 |
|
 |
tiago.prs Aprendiz


Registrado: Sábado, 9 de Mai de 2009 Mensagens: 193
|
Enviada: Sex Set 28, 2012 9:15 am Assunto: |
|
|
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 |
|
 |
|
|
Enviar Mensagens Novas: Proibido. Responder Tópicos Proibido Editar Mensagens: Proibido. Excluir Mensagens: Proibido. Votar em Enquetes: Proibido.
|
|