Delphi: обмен данными между приложениями

КОМПЬЮТЕРНЫЕ КУРСЫ "ПОИСК"

[Главная страница] [Delphi] [Контакты]

Копирование структуры и изображения при помощи WM_COPYDATA


Форма для отправки данных.

Листинг 1. Отправка данных (структуры и изображения)


unit SenderMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type

  TCopyDataType = (cdtImage = 1, cdtRecord = 2);

  TSampleRecord = packed record
    s : string[50];
    i : integer;
    d : TDateTime;
  end;


  TSenderMainForm = class(TForm)
    SendDataButton: TButton;
    rgCopyOptions: TRadioGroup;
    procedure SendDataButtonClick(Sender: TObject);
  private
    procedure SendData(copyDataStruct : TCopyDataStruct);
    procedure SendImage();
    procedure SendRecord();
  public
    { Public declarations }
  end;

var
  SenderMainForm: TSenderMainForm;

implementation

{$R *.dfm}

procedure TSenderMainForm.SendData(copyDataStruct: TCopyDataStruct);
var
  receiverHandle  : THandle;
  res : integer;
begin
  receiverHandle := FindWindow(PChar('TReceiverMainForm'),PChar('ReceiverMainForm'));
  if receiverHandle = 0 then
  begin
    ShowMessage('CopyData Receiver NOT found!');
    Exit;
  end;

  res := SendMessage(receiverHandle, WM_COPYDATA, Integer(Handle), Integer(@copyDataStruct));

  if res > 0 then ShowMessage(Format('Receiver has %d lines in Memo!',[res]));
end;

procedure TSenderMainForm.SendDataButtonClick(Sender: TObject);
begin
  if rgCopyOptions.ItemIndex = -1 then
  begin
    ShowMessage('Nothing selected!');
    Exit;
  end;

  case rgCopyOptions.ItemIndex of
    0 : SendImage;
    1 : SendRecord;
  end;
end;

procedure TSenderMainForm.SendImage();
var
  ms : TMemoryStream;
  bmp : TBitmap;
  copyDataStruct : TCopyDataStruct;
begin
  ms := TMemoryStream.Create;
  try
    bmp := self.GetFormImage;
    try
      bmp.SaveToStream(ms);
    finally
      bmp.FreeImage;
    end;
    copyDataStruct.dwData := Integer(cdtImage); //use it to identify the message contents
    copyDataStruct.cbData := ms.Size;
    copyDataStruct.lpData := ms.Memory;

    SendData(copyDataStruct);
  finally
    ms.Free;
  end;
end;

procedure TSenderMainForm.SendRecord();
var
  sampleRecord : TSampleRecord;
  copyDataStruct : TCopyDataStruct;
begin
  sampleRecord.s := 'Hello Receiver';
  sampleRecord.i := 1973;
  sampleRecord.d := Now;

  copyDataStruct.dwData := Integer(cdtRecord); //use it to identify the message contents
  copyDataStruct.cbData := SizeOf(sampleRecord);
  copyDataStruct.lpData := @sampleRecord;

  SendData(copyDataStruct);

end;

end.

Форма для приема данных

Листинг 2. Прием данных (структуры и изображения)


unit ReceiverMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TCopyDataType = (cdtImage = 1, cdtRecord = 2);

  TSampleRecord = packed record
    s : string[50];
    i : integer;
    d : TDateTime;
  end;

  TReceiverMainForm = class(TForm)
    cdMemo: TMemo;
    receivedImage: TImage;
    procedure FormCreate(Sender: TObject);
  private
    procedure WMCopyData(var Msg : TWMCopyData); message WM_COPYDATA;

    procedure HandleCopyDataImage(copyDataStruct : PCopyDataStruct);
    procedure HandleCopyDataRecord(copyDataStruct : PCopyDataStruct);
  public
    { Public declarations }
  end;

var
  ReceiverMainForm: TReceiverMainForm;

implementation

{$R *.dfm}

{ TReceiverMainForm }

procedure TReceiverMainForm.FormCreate(Sender: TObject);
begin
  cdMemo.Clear;
end;

procedure TReceiverMainForm.HandleCopyDataImage(
  copyDataStruct: PCopyDataStruct);
var
  ms: TMemoryStream;
begin
  ms := TMemoryStream.Create;
  try
    ms.Write(copyDataStruct.lpData^, copyDataStruct.cbData);
    ms.Position := 0;
    receivedImage.Picture.Bitmap.LoadFromStream(ms);
  finally
    ms.Free;
  end;

  cdMemo.Lines.Add(Format('Received image at %s',[DateToStr(Now)]));
end;

procedure TReceiverMainForm.HandleCopyDataRecord(
  copyDataStruct: PCopyDataStruct);
var
  sampleRecord : TSampleRecord;
begin
  sampleRecord.s := TSampleRecord(copyDataStruct.lpData^).s;
  sampleRecord.i := TSampleRecord(copyDataStruct.lpData^).i;
  sampleRecord.d := TSampleRecord(copyDataStruct.lpData^).d;

  cdMemo.Lines.Add(Format('Received record at %s',[DateToStr(Now)]));
  cdMemo.Lines.Add(Format('sampleRecord.s = %s',[sampleRecord.s]));
  cdMemo.Lines.Add(Format('sampleRecord.i = %d',[sampleRecord.i]));
  cdMemo.Lines.Add(Format('sampleRecord.d = %s',[DateToStr(sampleRecord.d)]));
end;

procedure TReceiverMainForm.WMCopyData(var Msg: TWMCopyData);
var
  copyDataType : TCopyDataType;
begin
  copyDataType := TCopyDataType(Msg.CopyDataStruct.dwData);

  //Handle of the Sender
  cdMemo.Lines.Add(Format('WM_CopyData from: %d',[msg.From]));

  case copyDataType of
    cdtImage: HandleCopyDataImage(Msg.CopyDataStruct);
    cdtRecord: HandleCopyDataRecord(Msg.CopyDataStruct);
  end;

  //Send something back
  msg.Result := cdMemo.Lines.Count;
end;

end.

Загрузить исходный код проекта. Выполнен на Delphi XE.