Club Builder - Foros de discusión Club Builder
Foro de C++Builder en español
 
 FAQFAQ   BuscarBuscar   MiembrosMiembros   Grupos de UsuariosGrupos de Usuarios   RegistrarseRegistrarse 
 PerfilPerfil   Entra para ver tus mensajes privadosEntra para ver tus mensajes privados   EntrarEntrar 

Comunicación entre Aplicaciones
Ir a página 1, 2  Siguiente
 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Consultas
Ver tema anterior :: Ver tema siguiente  
Autor Mensaje
Mensaje    Asunto: Comunicación entre Aplicaciones Responder citando

Hola
Haber si sabe alguien cual es la mejor
forma de comunicar dos aplicaciones (.exes )

He estado mirando algo de SendMessage, pero
no se como debe recibir el mensaje la
aplicación receptora del mensaje

Haber si alguien me puede indicar como
se maneja esto

De antemano, Gracias
Viky

Volver arriba
Mensaje    Asunto: Comunicación entre Aplicaciones Responder citando

Tienes varias maneras de comunicar las aplicaciones: MailSlots, Sockets, Pipes, File Mapping, Portapapeles, DDE, OLE, WM_COPYDATA etc... Tienes más información y ejemplos sobre esto en la referencia del API.

Como has nombrado SendMessage vamos a ver una de ellas, es el mensaje WM_C OPYDATA que sirve precisamente para enviar datos entre aplicaciones.

Y como explicándolo probablemente lo voy a liar mas de lo que es en realidad, mejor te pego aquí un poco de código comentado como ejemplo:

- Creamos un proyecto nuevo y añadimos lo siguiente al Form:

2 TEdit (Edit1, Edit2)
2 TButton (Button1, Button2)
1 TMemo (Memo1)

### Cabecera - Unit1.h

code:
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TEdit *Edit1;
TEdit *Edit2;
TMemo *Memo1;
TLabel *Label1;
TLabel *Label2;
TLabel *Label3;
TPanel *Panel1;
TBevel *Bevel1;
TBevel *Bevel2;
TButton *Button1;
TButton *Button2;
void __fastcall Button2Click(TObject *Sender);
void __fastcall Button1Click(TObject *Sender);
private: // User declarations
///////////////////////////////////////////////////////////////////
// Añadimos lo siguiente en el receptor
// es el evento que se disparara al recibir datos
void __fastcall OnDatosRecibidos(TWMCopyData& msg);
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_COPYDATA, TWMCopyData, OnDatosRecibidos);
END_MESSAGE_MAP(TForm)
///////////////////////////////////////////////////////////////////
// Nuestra estructura para enviar y recibir los datos
// esto tiene que ser identico en el transmisor y en el receptor
struct TNuestrosDatos
{
char szNombre[80];
char szTelefono[40];
} nuestrosDatos;
///////////////////////////////////////////////////////////////////
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

### Implementación - Unit1.cpp

code:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
/// Esta funcion junto con lo que hemos declarado en la cabecera
// es el evento que se disparara cuando se reciban datos
void __fastcall TForm1::OnDatosRecibidos(TWMCopyData& msg)
{
// Comprueba si el mensaje viene con el
// identificador numerico que ha usado el transmisor
if ( msg.CopyDataStruct->dwData == 130 )
{
// Obtenemos el puntero que apunta a nuestros datos
TNuestrosDatos *nuestrosDatos =
reinterpret_cast<TNuestrosDatos*>( msg.CopyDataStruct->lpData );

// Añadimos al memo los datos recibidos
Memo1->Lines->Add( nuestrosDatos->szNombre );
Memo1->Lines->Add( nuestrosDatos->szTelefono );
Memo1->Lines->Add( "-----" );

// Aqui tenemos el handle desde donde se envio el mensaje
// podemos usarlo por ejemplo para enviar una respuesta
// HWND hWnd = msg.From;

msg.Result = true; // Devolvemos true para indicar
// que hemos procesado el mensaje
}
}
//---------------------------------------------------------------------------
/// Boton enviar (Button1)
void __fastcall TForm1::Button1Click(TObject *Sender)
{
// Copiamos los datos de los edits a nuestra estructura
lstrcpyn( nuestrosDatos.szNombre, Edit1->Text.c_str(), 80 );
lstrcpyn( nuestrosDatos.szTelefono, Edit2->Text.c_str(), 40 );

COPYDATASTRUCT copydata;
copydata.dwData = 130; // Esto lo podemos usar como un identificador, para
// que el receptor compruebe que es solo para el
copydata.cbData = sizeof( nuestrosDatos ); // Tamaño de nuestra estructura
copydata.lpData = &nuestrosDatos; // Puntero a nuestra estructura

// Si no sabemos el handle de la ventana con la que queremos comunicarnos
// podemos usar HWND_BROADCAST para que el mensaje se envie a todas
// las ventanas, aunque normalmente solo lo procesara la que coincida
// con el identificador que le hemos dato.
// (podemos usar FindWindow para buscar el handle de la ventana a la que
// queremos enviarle los datos)
SendMessage( HWND_BROADCAST, WM_COPYDATA,
reinterpret_cast<LPARAM>(Handle), // Handle del remitente
reinterpret_cast<WPARAM>(©data) );
}
//---------------------------------------------------------------------------
/// Boton salir (Button2)
void __fastcall TForm1::Button2Click(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------


Si te resulta mas comodo te puedes bajar el mismo ejemplo compilado con el código fuente incluido, tanto para BCB1 como para BCB6

Espero que te sea útil.

Volver arriba
Mensaje    Asunto: Comunicación entre Aplicaciones Responder citando

Se me olvidaba comentar que para probarlo debes abrir varias instancias del ejecutable de ejemplo, ya que en el mismo esta el código del transmisor como del receptor.
Volver arriba
Mensaje    Asunto: Comunicación entre Aplicaciones Responder citando

_Leo
He estado realizando una serie de pruebas, con el codigo que enviaste:

- He abierto 3 instancias ( estoy usando WinXP )

Pues resulta que cuando se envian mensajes de forma continua
y rapida desde la misma o cambiando de instancia, la aplicación
se queda como bloqueada (ventana en blanco ) bajando el rendimiento de
todas las demás ventanas de windows, inclusive en otra de las pruebas tuve que
reiniciar el equipo.

Imagino que es porque el mensaje se envia a todas las ventanas de Windows,
no pudiendo controlar si el identificador afecta a alguna otra ventana
del propio Windows.

Lo lógico sería enviarla al Handle de la Aplicación que quieres comunicar.

Cual seria la mejor forma de indicar a la instancia emisora del handle de
la ventana receptora, por ejem. "usar algun fichero por el medio para indicar este handle " o existe algo mejor atraves de
algun otro mensaje ??

De todas formas, te doy las gracias de antemano

Saludos
Viky

Volver arriba
Mensaje    Asunto: Comunicación entre Aplicaciones Responder citando

Viky,

Para buscar el handle del programa receptor,
en lugar de usar ficheros temporales que
guarden el handle de la instancia receptora
es mejor, que busques el nombre de la
instancia receptora ( nombre del proyecto
que recibe el mensaje )

Si sabes el nombre de esa instancia puedes
hacerlo tal que:

HWND hwnd;
AnsiString Programa = "Receptor"; // Nombre del Proyecto Receptor del Mensaje

hwnd = FindWindow(NULL, Programa.c_str());

if (hwnd) {
// Instancia Encontrada
..
..
..
SendMessage( hwnd, WM_COPYDATA,
reinterpret_cast<LPARAM>(Handle),
reinterpret_cast<WPARAM>(©data) );
}
else
MessageDlg("No se Encontro la Ventana.",mtInformation,TMsgDlgButtons() << mbOK,NULL);

Espero haberte aclarado algo más este tema

~-~~-~~-~~-~
Saludos
_Willa
~-~~-~~-~~-~

Volver arriba
Mensaje    Asunto: Comunicación entre Aplicaciones Responder citando

La solución que te da _Willa para encontrar al receptor normalmente es más que suficiente. Solo añadir que si no te interesa por lo que sea buscar la ventana del receptor por su titulo (Caption) también podrías buscarla por su nombre de clase.

Para ello en el receptor solo tendrías que añadir el siguiente código en la parte privada por ejemplo:

...
private:
    void __fastcall CreateParams(TCreateParams &Params)
    {
        inherited::CreateParams(Params);
        // cambiamos el nombre de clase de
        //   la ventana que mas tarde buscaremos con
        //   ...FindWindow("miReceptor", NULL)...
        lstrcpyn(Params.WinClassName, "miReceptor", 64);
    }
...

y en el transmisor usarías el primer argumento del FindWindow en vez del segundo para encontrar al emisor del siguiente modo:

...
  HWND hWnd = FindWindow("miReceptor", NULL);
  if ( IsWindow(hWnd) )
  {
      SendMessage( hWnd, // Handle del receptor
          WM_COPYDATA,
          reinterpret_cast<LPARAM>( Handle ), // Handle del remitente
          reinterpret_cast<WPARAM>( ©data) );
  }
  // else ShowMessage( "No se encontro..." );
...

Espero que se entienda y no liarlo mas Wink

Saludos:
_Leo

Volver arriba
Mensaje    Asunto: Comunicación entre Aplicaciones Responder citando

NOTA: Ese signo de copyright ( © ) que sale en realidad es:

    & c o p y d a t a

(va todo sin espacios, pero lo pongo con espacios porque al ponerlo normal se convierte en el foro automáticamente por ese signo)

Volver arriba
Mensaje    Asunto: Responder citando

Hola Leo, por algún motivo, la aplicación receptora, solo captura los mensjes cuando van dirigidos al Broadcast.

He probado con Findwindow, buscar y mandar al handle correcto y nada. Para asegurarme le he enviado un WM_CLOSE a la aplicación y en ese caso funcionó perfecto.
_________________
Adrián

http://adrian.org.ar
Volver arriba
Ver perfil de usuario Enviar mensaje privado Visitar sitio web del autor
Mensaje    Asunto: Responder citando

Me funciona tanto con Broadcast como con FindWindow, no se donde puede estar tu problema. Si quieres mandame un proyecto de ejemplo donde se reproduzca el problema.

leosoftware ARROBA gmail PUNTO com
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

ya encontré el problema, Leo, era una tontería.

gracias!!
Volver arriba
Ver perfil de usuario Enviar mensaje privado Visitar sitio web del autor
Mensaje    Asunto: Responder citando

Hola a todos!

Si, ya se, ya se que este hilo es un tanto viejito pero me ha servido mucho la explicacion y el codigo que aqui se encuentra. jejeje.

En el codigo que pone _Leo dice:

Cita:
// Aqui tenemos el handle desde donde se envio el mensaje
// podemos usarlo por ejemplo para enviar una respuesta
// HWND hWnd = msg.From;
msg.Result = true;
// Devolvemos true para indicar
// que hemos procesado el mensaje


Por lo que entiendo, entonces el Receptor envia al Transmisor una confirmacion del mensaje recibido. Verdad? Entonces mi pregunta es, en el Transmisor dónde se recibe esa confirmacion?

Gracias por su ayuda!
_________________
Dios es real... a menos que se declare entero!
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

en el OnDatosRecibidos
Volver arriba
Ver perfil de usuario Enviar mensaje privado Visitar sitio web del autor
Mensaje    Asunto: Responder citando

Hola Ikis.

Gracias por tu respuesta.

Te cuento como lo hice. Tengo un programa que es solo Transmisor y otro que es solo Receptor.

Entonces por lo que entiendo, debo poner en mi Transmisor tambien la funcion OnDatosRecibidos y para recibir el msg.Result = true, hago algo asi?

Código:
void OnDatosRecibidos() //Perdonen la simplicidad del codigo
{
  if(msg.Result == True)
  {
  ......
  }
  else if(msg.Result == False)
  {
  ......
  }
}


De todas formas voy a probarlo a ver si funciona la confirmacion. Cualquier idea es bienvenida.

Gracias por su ayuda!
_________________
Dios es real... a menos que se declare entero!
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

claro, eso es porque tienes comunicación en ambos sentidos.
Volver arriba
Ver perfil de usuario Enviar mensaje privado Visitar sitio web del autor
Mensaje    Asunto: Responder citando

Hola Ikis

Nada.

El transmisor no recibe la confirmacion msg.Result = True en el OnDatosRecibidos.

Sera que no lo esta recibiendo o que no lo estoy enviando?

Tienes alguna idea?

Gracias!
_________________
Dios es real... a menos que se declare entero!
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mostrar mensajes de anteriores:   
Cambiar a:  
No puedes publicar temas nuevos en este foro
No puedes responder a temas en este foro
No puedes editar tus mensajes en este foro
No puedes borrar tus mensajes en este foro
No puedes votar en las encuestas de este foro


Hosting WordPress Indedmedia desde 3,99 €
© 2002–2026 Club Builder · Funciona con phpBB.