Hay muchas situaciones en las que necesita permitir que dos aplicaciones se comuniquen. Si no desea meterse con TCP y la comunicación de sockets (porque ambas aplicaciones se ejecutan en la misma máquina), puede * simplemente * enviar (y recibir correctamente) un mensaje especial de Windows: WM_COPYDATA.
Dado que manejar mensajes de Windows en Delphi es simple, emitir una llamada a la API SendMessage junto con WM_CopyData con los datos a enviar es bastante sencillo.
El mensaje WM_COPYDATA le permite enviar datos de una aplicación a otra. La aplicación receptora recibe los datos en un registro TCopyDataStruct. TCopyDataStruct se define en la unidad Windows.pas y envuelve la estructura COPYDATASTRUCT que contiene los datos a pasar.
Aquí está la declaración y la descripción del registro TCopyDataStruct:
tipo TCopyDataStruct = registro lleno dwData: DWORD; // hasta 32 bits de datos para pasar a la aplicación receptora cbData: DWORD; // el tamaño, en bytes, de los datos señalados por el miembro lpData lpData: puntero; // Señala los datos que se pasarán a la aplicación receptora. Este miembro puede ser nulo. final;
Para que una aplicación "Remitente" envíe datos a "Receptor", CopyDataStruct debe completarse y pasarse utilizando la función SendMessage. Aquí se explica cómo enviar un valor de cadena sobre WM_CopyData:
procedimiento TSenderMainForm.SendString (); var stringToSend: cadena; copyDataStruct: TCopyDataStruct; empezar stringToSend: = 'Acerca de la programación de Delphi'; copyDataStruct.dwData: = 0; // utilízalo para identificar el contenido del mensaje copyDataStruct.cbData: = 1 + Longitud (stringToSend); copyDataStruct.lpData: = PChar (stringToSend); SendData (copyDataStruct); final;
La función personalizada SendData localiza el receptor utilizando la llamada a la API FindWindow:
procedimiento TSenderMainForm.SendData (const copyDataStruct: TCopyDataStruct); var receptorHandle: THandle; res: entero; empezar receptorHandle: = FindWindow (PChar ('TReceiverMainForm'), PChar ('ReceiverMainForm')); Si receptorHandle = 0 luego empezar ShowMessage ('¡No se encontró el receptor CopyData!'); Salida; final; res: = SendMessage (receptorHandle, WM_COPYDATA, Integer (Handle), Integer (@copyDataStruct)); final;
En el código anterior, la aplicación "Receiver" se encontró usando la llamada API FindWindow al pasar el nombre de clase del formulario principal ("TReceiverMainForm") y el título de la ventana ("ReceiverMainForm").
Nota: SendMessage devuelve un valor entero asignado por el código que manejó el mensaje WM_CopyData.
La aplicación "Receiver" maneja el mensaje WM_CopyData como en:
tipo TReceiverMainForm = clase (TForm) privado procedimiento WMCopyData (var Msg: TWMCopyData); mensaje WM_COPYDATA;… implementación... procedimiento TReceiverMainForm.WMCopyData (var Msg: TWMCopyData); var s: cadena; empezar s: = PChar (Msg.CopyDataStruct.lpData); // Enviar algo de vuelta Mensaje de resultado: = 2006; final;
El registro TWMCopyData se declara como:
TWMCopyData = registro empaquetado Msg: Cardinal; De: HWND;// Manija de la ventana que pasó los datos CopyDataStruct: PCopyDataStruct; // datos pasados Resultado: Longint;// Úselo para devolver un valor al "Remitente" final;