 |
Club Builder Foro de C++Builder en español
|
| Ver tema anterior :: Ver tema siguiente |
| Autor |
Mensaje |
Viky Invitado
|
Publicado: Lun 01 Jul, 2002 1:43 pm Asunto: Comunicación entre Aplicaciones |
|
|
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 |
|
 |
_Leo Invitado
|
Publicado: Lun 01 Jul, 2002 7:01 pm Asunto: Comunicación entre Aplicaciones |
|
|
| 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 |
|
 |
_Leo Invitado
|
Publicado: Mar 02 Jul, 2002 11:04 am Asunto: Comunicación entre Aplicaciones |
|
|
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 |
|
 |
Viky Invitado
|
Publicado: Mar 02 Jul, 2002 12:03 pm Asunto: Comunicación entre Aplicaciones |
|
|
_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 |
|
 |
_Willa Invitado
|
Publicado: Mar 02 Jul, 2002 12:54 pm Asunto: Comunicación entre Aplicaciones |
|
|
| 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 |
|
 |
_Leo Invitado
|
Publicado: Mar 02 Jul, 2002 1:26 pm Asunto: Comunicación entre Aplicaciones |
|
|
| 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 Saludos: _Leo
|
|
| Volver arriba |
|
 |
_Leo Invitado
|
Publicado: Mar 02 Jul, 2002 1:36 pm Asunto: Comunicación entre Aplicaciones |
|
|
| 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 |
|
 |
ikis Master


Registrado: 28 Dic 2002Mensajes: 703Ubicación: Madrid, España
|
Publicado: Vie 19 Ago, 2005 4:46 am Asunto: |
|
|
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 |
|
 |
_Leo Site Admin

Registrado: 11 Ago 2002Mensajes: 1875Ubicación: Lanzarote - Islas Canarias (España)
|
Publicado: Sab 20 Ago, 2005 1:27 am Asunto: |
|
|
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 |
|
 |
ikis Master


Registrado: 28 Dic 2002Mensajes: 703Ubicación: Madrid, España
|
Publicado: Sab 20 Ago, 2005 4:00 am Asunto: |
|
|
ya encontré el problema, Leo, era una tontería.
gracias!! |
|
| Volver arriba |
|
 |
jacko Master


Registrado: 03 Sep 2005Mensajes: 287Ubicación: Colombia
|
Publicado: Lun 28 May, 2007 3:12 pm Asunto: |
|
|
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 |
|
 |
ikis Master


Registrado: 28 Dic 2002Mensajes: 703Ubicación: Madrid, España
|
Publicado: Lun 28 May, 2007 3:24 pm Asunto: |
|
|
| en el OnDatosRecibidos |
|
| Volver arriba |
|
 |
jacko Master


Registrado: 03 Sep 2005Mensajes: 287Ubicación: Colombia
|
Publicado: Lun 28 May, 2007 3:32 pm Asunto: |
|
|
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 |
|
 |
ikis Master


Registrado: 28 Dic 2002Mensajes: 703Ubicación: Madrid, España
|
Publicado: Lun 28 May, 2007 3:51 pm Asunto: |
|
|
| claro, eso es porque tienes comunicación en ambos sentidos. |
|
| Volver arriba |
|
 |
jacko Master


Registrado: 03 Sep 2005Mensajes: 287Ubicación: Colombia
|
Publicado: Mie 30 May, 2007 4:57 pm Asunto: |
|
|
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 |
|
 |
|
|
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
|
© 2002–2026 Club Builder · Funciona con phpBB.
|