Compartir datos entre dos aplicaciones propias
Artículo por Club Developers · 31 diciembre 2005
3225 vistas
De lo que se trata es de dar una idea de cómo compartir información entre dos aplicaciones realizadas por nosotros.
Hay muchas maneras de hacerlo, pero vamos a ver cómo hacerlo usando un fichero de memoria para poder compartir una zona de memoria y poder asà enviar la información de una aplicación a otra.
El funcionamiento será el siguiente:
Aplicación que escribirá en la memoria
Ésta será la encargada de crear el fichero de memoria mediante la API CreateFileMapping, la cual se encarga de reservar el espacio de memoria necesario. Para ello, también se definirá una estructura de tamaño fijo (!!atención a la utilización de strings, éstos tienen que tener tamaño fijo!!)
Una vez creado el fichero, direccionamos un puntero a la zona de memoria a la que apunta el fichero, para poder escribir los datos en nuestra estructura mediante la API MapViewOfFile:
De esta manera, cualquier cosa que se escriba en la estructura se escribirá en la zona de memoria del fichero de memoria, y será accesible para otras aplicaciones que
mapeen el mismo fichero:
Además, se enviará un mensaje de Windows para advertir a la otra aplicación que se ha cambiado la información compartida.
Por otra parte, no podemos alvidarnos de cerrar tanto la vista del fichero de memoria como el propio fichero de memoria cuando ya no la necesitemos (por ejemplo en el OnDestroy) mediante la API UnmapViewOfFile y CloseHandle.
Asà quedarÃa el programa de escritura
Aplicación que leerá los datos
A diferencia de la aplicación "escritora", ésta no creará el fichero de memoria, sino que lo abrirá para lectura mediante la API OpenFileMapping controlando el hecho de no poder abrirlo debido a que la aplicación "escritora" no lo ha creado aun (o no ha sido capaz).
Tendremos que capturar el mensaje de Windows enviado por la aplicación "escritora" y leer la información enviada.
Como en la otra aplicación, no podemos alvidarnos de cerrar tanto la vista del fichero de memoria como el propio fichero de memoria cuando ya no la necesitemos (por ejemplo en el OnDestroy) mediante la API UnmapViewOfFile y CloseHandle.
Asà quedarÃa el programa de lectura
Hay muchas maneras de hacerlo, pero vamos a ver cómo hacerlo usando un fichero de memoria para poder compartir una zona de memoria y poder asà enviar la información de una aplicación a otra.
El funcionamiento será el siguiente:
Aplicación que escribirá en la memoria
Ésta será la encargada de crear el fichero de memoria mediante la API CreateFileMapping, la cual se encarga de reservar el espacio de memoria necesario. Para ello, también se definirá una estructura de tamaño fijo (!!atención a la utilización de strings, éstos tienen que tener tamaño fijo!!)
Una vez creado el fichero, direccionamos un puntero a la zona de memoria a la que apunta el fichero, para poder escribir los datos en nuestra estructura mediante la API MapViewOfFile:
De esta manera, cualquier cosa que se escriba en la estructura se escribirá en la zona de memoria del fichero de memoria, y será accesible para otras aplicaciones que
mapeen el mismo fichero:
Además, se enviará un mensaje de Windows para advertir a la otra aplicación que se ha cambiado la información compartida.
Por otra parte, no podemos alvidarnos de cerrar tanto la vista del fichero de memoria como el propio fichero de memoria cuando ya no la necesitemos (por ejemplo en el OnDestroy) mediante la API UnmapViewOfFile y CloseHandle.
Asà quedarÃa el programa de escritura
delphi
unit Trans; interface uses  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,  StdCtrls; const  WM_TRANSFER = WM_USER + 1; // Definimos un mensaje type PCompartido = ^TCompartido; TCompartido = record  Manejador1: Cardinal;  Manejador2: Cardinal;  Cadena: String[20]; end; type  TForm1 = class(TForm)   Edit1: TEdit;   procedure FormCreate(Sender: TObject);   procedure Edit1Change(Sender: TObject);   procedure FormDestroy(Sender: TObject);   procedure Edit1KeyDown(Sender: TObject; var Key: Word;    Shift: TShiftState);  private   Compartido: PCompartido;   FicheroM: THandle;  public  end; var  Form1: TForm1; implementation {$R *.DFM} procedure TForm1.FormCreate(Sender: TObject); begin  Edit1.MaxLength := 20;  { Creamos el fichero de memoria }  FicheroM := CreateFileMapping( $FFFFFFFF, nil, PAGE_READWRITE, 0,                SizeOf(TCompartido), 'MiFichero');  { Si no se creó el fichero, lanzamos excepción }  if FicheroM = 0 then   raise Exception.Create( 'Error al crear el fichero');  { Direccionamos nuestra estructura al fichero de memoria }  Compartido := MapViewOfFile(FicheroM,FILE_MAP_WRITE, 0, 0, 0);  { Inicializamos estructura }  Compartido^.Manejador1 := Handle; end; procedure TForm1.Edit1Change(Sender: TObject); begin  // cada vez que haya un cambio en el TEdit, escribimos en el fichero de memoria  Compartido^.Cadena := Edit1.Text; end; procedure TForm1.FormDestroy(Sender: TObject); begin  { Cierre de la vista del fichero }  UnmapViewOfFile(Compartido);  { Cierre del fichero }  CloseHandle(FicheroM); end; procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;  Shift: TShiftState); begin  // al pulsar ENTER, lanzamos mensaje de Windows si se ha especificado la  // aplicación de lectura (Manejador2 de la estructura)  if key = 13 then   if compartido^.Manejador2 <> 0 then    PostMessage(Compartido^.Manejador2, WM_TRANSFER,0, 0); end; end.
Aplicación que leerá los datos
A diferencia de la aplicación "escritora", ésta no creará el fichero de memoria, sino que lo abrirá para lectura mediante la API OpenFileMapping controlando el hecho de no poder abrirlo debido a que la aplicación "escritora" no lo ha creado aun (o no ha sido capaz).
Tendremos que capturar el mensaje de Windows enviado por la aplicación "escritora" y leer la información enviada.
Como en la otra aplicación, no podemos alvidarnos de cerrar tanto la vista del fichero de memoria como el propio fichero de memoria cuando ya no la necesitemos (por ejemplo en el OnDestroy) mediante la API UnmapViewOfFile y CloseHandle.
Asà quedarÃa el programa de lectura
delphi
unit Recep; interface uses  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,  StdCtrls; const  WM_TRANSFER = WM_USER + 1; type PCompartido = ^TCompartido; TCompartido = record  Manejador1: Cardinal;  Manejador2: Cardinal;  Cadena: String[20]; end; type  TForm1 = class(TForm)   Label1: TLabel;   procedure FormCreate(Sender: TObject);   procedure FormDestroy(Sender: TObject);  private   Compartido: PCompartido;   FicheroM: THandle;   procedure Reciviendo(var Msg: TMessage); message WM_TRANSFER;  public  end; var  Form1: TForm1; implementation {$R *.DFM} procedure Tform1.Reciviendo(var Msg: TMessage); begin  label1.Caption := compartido^.Cadena; end; procedure TForm1.FormCreate(Sender: TObject); begin  { Miramos si existe el fichero }  FicheroM := OpenFileMapping(FILE_MAP_READ, False, 'MiFichero');  { Si no existe, lanzamos error }  if FicheroM = 0 then   raise Exception.Create('Error');   // si existe direccionamos puntero y lo inicializamos  Compartido := MapViewOfFile(FicheroM, FILE_MAP_READ, 0, 0, 0);  compartido^.Manejador2 := Handle; end; procedure TForm1.FormDestroy(Sender: TObject); begin  { Cerramos la vista del fichero }  UnmapViewOfFile(Compartido);  { Cerramos el fichero }  CloseHandle(FicheroM); end; end.