Página 1 de 2

Ajuda com comunicação entre aplicações

Enviado: 22 Fev 2011 11:36
por binho_fasa
Amigos,

Devido a uma necessidade específica de um cliente, preciso fazer com que uma aplicação Delphi "converse" com um programa XHarbour usando Mensagens do Windows. O que acontece é que a aplicação Delphi enviará uma mensagem e meu programa Xharbour deverá ficar "rodando" em background aguardando a mensagem e dependendo da mesma acionar a rotina A, B, C, etc. Alguém tem alguma idéia de como realizar isso usando Mensagens do Windows?

Obrigado,

Fabio Souza

Ajuda com comunicação entre aplicações

Enviado: 22 Fev 2011 12:15
por Pablo César
Não tem como o programa Delphi criar arquivo intermediário ?

Re: Ajuda com comunicação entre aplicações

Enviado: 22 Fev 2011 15:07
por rochinha
Amiguinho,

Neste tópico aqui foi abordado algo semelhante e várias dicas foram expostas.

Re: Ajuda com comunicação entre aplicações

Enviado: 22 Fev 2011 16:42
por Maligno
Todo programa Windows GUI possui uma função para processamento de mensagens. É regra. Ela é chamada WndProc, que no Delphi precisa ser sobreposta para processar as mensagens e, ao final, executar a antiga função WndProc.

As mensagens do Windows são apenas números fixos. Há uma faixa de números reservada para uso da aplicação, que é conhecida pela constante WM_USER (de 0x400 a 0x7FFF). O que você deve fazer é criar suas mensagens e fazer um broadcasting pelo SO, utilizando funções da API como SendMessage() (só retorna após o processamento da mensagem) ou PostMessage() (retorno imediato). Pesquise no MSDN pois essa matéria é extensa e há outras funções pertinentes ao assunto.

Particularmente eu utilizo bastante, mas por enquanto apenas para comunicação dentro da mesma aplicação, para abstração de tarefas, mas o seu caso não é muito diferente disso. O processo é o mesmo. Pode parecer meio difícil, mas depois você vai ver que é bem simples.

Re: Ajuda com comunicação entre aplicações

Enviado: 22 Fev 2011 17:50
por alxsts
Olá!

Apreciaria muito se o Maligno postasse um exemplo prático e didático dessa comunicação, mesmo que entre a mesma apicação. Gostaria de entender como funciona e para que serve.

Perdoem a ignorância mas, poderia falar um pouco sobre "abstração de tarefas"?

(seria interessante abrir outro tópico)

Grato

Re: Ajuda com comunicação entre aplicações

Enviado: 23 Fev 2011 08:43
por binho_fasa
Amigos, obrigado pelas respostas. Existem várias formas de fazer isso. Estou vendo com o programador Delphi como resolver.
Se o Maligno conseguir postar algum exemplo usando SendMessage, PostMessage, etc, será bastante valioso já que não existem muito exemplos a respeito.

Obrigado,

Fabio Souza

Re: Ajuda com comunicação entre aplicações

Enviado: 28 Fev 2011 17:23
por Maligno
Me desculpem. Andei meio ocupado por esses dias. Não estava sobrando muito tempo para responder. Mas, resumidamente,...

Abstração é um importante conceito de programação que ajuda a diminuir consideravelmente as chances de ocorrência de problemas. Abstrair significa tornar algo completamente alheio ao que ocorre à sua volta. Por exemplo: uma função de validação que apenas faz isso, não se importando com o que ocorre fora dela. É um isolamento saudável, que desonera o código e o torna muito modular, já que não possui ou quase não possui dependências externas. Isso vale também para o uso de símbolos que um sistema normalmente tem aos montes.

Um exemplo prático. No meu cadastro de cliente tenho o campo de CEP. Como tenho a base dos correios completa, basta o usuário pressionar uma tecla para abrir a consulta de CEPs. Selecionado o endereço, essa consulta é fechada e o foco retorna ao cadastro já no campo do número do imóvel. Para o usuário fica bem confortável.

Mas por baixo do capô tem um motor que torna isso possível. Ao selecionar o endereço, memória é alocada no heap global da aplicação. Nela são inseridas todas as informações dos campos, mas sem qualquer menção à símbolos fixos das tabelas de dados. É tudo padronizado como texto, no formato "NAME=VALUE", como nos arquivos INI. O ponteiro dessa memória é passado em broadcasting pelo sistema de mensagens do Windows com um handle previamente informado pelo objeto chamador (o cadastro de cliente). Todas as janelas irão recusar esses dados, já que o handle não lhes pertence. Menos uma janela, claro. Ela perceberá sua resposta já pronta, processará os dados apontados na memória e destruirá o ponteiro. Ao final, preencherá os campos conforme sua necessidade e mudará o foco para o campo do número do imóvel, já que possivelmente será o único dado restante.

Em suma: o objeto requisitante não conhece absolutamente nada nem do objeto requisitado, nem dos dados que ele manipula. Conhece apenas os apelidos desses dados, e não importa a ordem em que aparecem. Aliás, o objeto requisitante não conhece nem mesmo o nome do objeto requisitado. Não há uma chamada direta. O pedido de consulta à tabela de CEPs segue para o formulário principal da aplicação com o handle do requisitante. O formulário principal é o único objeto que conhece todos os demais objetos. Ele é quem invocará o objeto de consulta de CEPs. Ou seja, não importa quem faz; desde que faça. Não importa quem pediu; está pronto e é só pegar. Isolamento total.

Esse isolamento de funções torna tudo muito mais fácil e, consequentemente, altamente modular. E pode ser utilizado para tudo: cadastros, configurações, consultas, etc. Sem falar nas funções de níveis mais baixos, que é um conceito mais natural para nós. Já disse isso várias vezes: se a função faz validação de CPF, por exemplo, não é ela quem deve disparar um sinal de erro se o resultado for falso. Ela deve apenas cumprir seu papel, retornando um valor lógico que representa o resultado da validação. Se misturarmos tudo, qualquer trabalho de manutenção ficará sensivelmente maior e mais caro. Sem falar no comprometimento da modularidade.

Não sei se vão querer realmente um exemplo de código, já que trabalho apenas com C/C++. Se quiserem ver assim mesmo, posso postar algo resumido.

Re: Ajuda com comunicação entre aplicações

Enviado: 03 Mar 2011 23:56
por alxsts
Olá!

Muito obrigado!

É uma explicação resumida, como você mesmo escreveu, mas que abre um vasto leque para pesquisa.

Re: Ajuda com comunicação entre aplicações

Enviado: 04 Mar 2011 08:53
por vailton
O Fábio conseguiu resolver o problema?

Re: Ajuda com comunicação entre aplicações

Enviado: 04 Mar 2011 10:39
por MARCELOG
Olá combatente,
as aplicações Windows trabalham enviando e recebendo/tratando mensagens recebidas do sistema operacional (S.O. = SO).
Toda vez, por exemplo, que ocorre um evento nas janelas do windows, uma mensagem é enviada e processada.
Da mesma forma que tem a função API sendmessage (envia mensagem) e postmessage (posta a mensagem), também existe a getmessage (pega mensagem).
Então vamos raciocinar...
Se o programa Delphi criar um arquivo, beleza, é só ir na pasta onde o arquivo deve ser criado, verificar sua existência, fazer sua leitura e, com base no resultado, tomar as providências.
A comunicação sem dor de cabeça alguma foi realizada.
Todavia, se usar as mensagens enviadas ao SO, aí complica um pouco.
Primeiro, deve se saber a mensagem que deve ser interceptada. Ex:presionamento da tecla ENTER no programa Delphi.
Aí sim, criamos o programa harbour/ xharbou com a função C, que chama a função API getmessage que verifica se a mensagem "tecla ENTER pressionada" foi enviada/recebida na janela do programa Delphi.
Isso mesmo, você vai ter que monitorar a janela do programa Delphi e interceptar/ processar todas as mensagens.
Logo, embora possível, não acho viável o procedimento.

Para superior consideração.

MarceloG

Re: Ajuda com comunicação entre aplicações

Enviado: 05 Mar 2011 03:57
por Stanis Luksys
Opa,

Poderia fazer uma conexão via socket, fazendo o servidor no harbour para escutar em uma porta específica. É bem simples fazer, naquele guia CHM do xharbour tem um exemplo pronto que funciona perfeitamente, não deve ter nem 30 linhas. Procure pelas funções "inet..".

Aí no Delphi teria que fazer o cliente, mas não me pergunte como.

Assim é interessante porque o servidor pode interpretar as mensagens vindas de qualquer lugar.

Abraços.

Re: Ajuda com comunicação entre aplicações

Enviado: 07 Mar 2011 08:21
por binho_fasa
Stanis,

Foi o que fiz. Consegui realizar todo o processo usando comunicação via Sockets. Ficou muito bom, rápido e consigo enviar e receber respostas da aplicação Delphi com isso. Estou usando os componentes LNET que são OpenSource e servem tanto para Delphi como para o Lazarus/FPC.

Obrigado,

Fabio Souza

Re: Ajuda com comunicação entre aplicações

Enviado: 10 Mar 2011 08:55
por Maligno
Sockets é também uma boa alternativa de comunicação. Porém, ainda aconselho aprender a usar as mensagens do Windows. A meu ver é o melhor meio de comunicação entre os formulários da aplicação. Se, por exemplo, uma aplicação MDI tiver 10 formulários abertos, onde uma delas é um cadastro semi-pronto, for encerrada, é preciso "perguntar" aos formulários se o encerramento é possível. Se houver alguma pendência, a aplicação não pode ser encerrada. Com mensagens esse questionamento pode ser feito facilmente. Isso é apenas um exemplo. Há várias utilidades.

Re: Ajuda com comunicação entre aplicações

Enviado: 10 Mar 2011 13:46
por vailton
Eu apostaria em FileMap... mas é complexo e nunca mesclei com xBase, mas pode ser feito com C/C++.

Re: Ajuda com comunicação entre aplicações

Enviado: 10 Mar 2011 14:32
por Maligno
Muito mais complexo. Só a necessidade de manter um sincronismo já desamina. Você pode fazer algo mais fácil e prático com mensagens. Basta que cada formulário tenha uma ID e a mensagem pode ser precisamente direcionada. Aliás, com mensagens pode-se até simular a mesma complexidade (e flexibilidade) de "File Mapping", compartilhando uma porção do heap com vários formulários e/ou aplicações distintas. Mas para comunicação dentro da mesma aplicação, a meu ver, usar mensagens é o melhor caminho.