...Texte, Bilder (Streams) zwischen Prozessen austauschen?

Autor: Thomas Stutz

Kategorie: System

{
  The WM_COPYDATA messages makes it possible to transfer information
  between processes. It does this by passing the data through the kernel.
  Space is allocated in the receiving process to hold the information that is copied,
  by the kernel, from the source process to the target process.
  The sender passes a pointer to a COPYDATASTRUCT, which is defined as a structure
  of the following:
}

{
  Mit der Windows-Nachricht WM_COPYDATA ist es unter 32 Bit-Windows möglich,
  Daten verschiedenster Natur zwischen unterschiedlichen Prozessen auszutauschen.
  Eine Windows-interne Funktionalität ermöglicht bei Verwendung von WM_COPYDATA die Nutzung
  eines gemeinsamen Speicherbereichs über eine Datenstruktur COPYDATASTRUCT,
  die wie folgt aussieht:
}

type
  
TCopyDataStruct = packed record
    
dwData: DWORD; // anwendungsspezifischer Wert
    
cbData: DWORD; // Byte-Länge der zu übertragenden Daten
    
lpData: Pointer; // Adresse der Daten
  
end;

{
  Dabei geschieht der Datenaustausch auf folgende Weise
  (Zitat aus J. Richter, "Windows Programmierung für Experten",
   Microsoft Press 1997, S. 524):

  "Beim Senden einer Meldung des Typs WM_COPYDATA reserviert die Funktion SendMessage
  einen Speicherbereich der angegebenen Größe (cbData Bytes) und kopiert die Daten
  vom Adreßraum ihres Prozesses in eben diesen Speicherbereich. Danach sendet SendMessage
  die Meldung an das ausgewählte Fenster. Wenn schließlich die empfangende Fensterprozedur
  mit der Bearbeitung der Meldung beginnt, verweist der Parameter lParam auf eine
  COPYDATASTRUCT-Struktur im Adreßraum des empfangenden Prozesses.
  Die lpData-Komponente der Struktur verweist auf den gemeinsamen
  Speicherbereich, dessen Adresse jedoch an den Adreßraum des
  empfangenden Prozesses angepaßt worden ist.
}


}

{ Sender Application }
{ Sender Applikation }

unit SenderApp;

interface

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

type
  
TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Button2: TButton;
    Image1: TImage;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    procedure 
SendCopyData(hTargetWnd: HWND; ACopyDataStruct:TCopyDataStruct);
  public
  end
;

var
  
Form1: TForm1;

implementation

{$R *.DFM}

// Sender: Send data
// Sender: Daten schicken
procedure TForm1.SendCopyData(hTargetWnd: HWND; ACopyDataStruct:TCopyDataStruct);
begin
  if 
hTargetWnd <> 0 then
    
SendMessage(hTargetWnd, WM_COPYDATA, Longint(Handle), Longint(@ACopyDataStruct))
  else
    
ShowMessage('No Recipient found!');
end;

// Send Text from Edit1 to other app
// Text von Edit1 an andere Anwendung schicken
procedure TForm1.Button1Click(Sender: TObject);
var
  
MyCopyDataStruct: TCopyDataStruct;
  hTargetWnd: HWND;
begin
  
// Set up a COPYDATASTRUCT structure for use with WM_COPYDATA
  // TCopyDataStruct mit den Sende-Daten Infos ausfüllen
  
with MyCopyDataStruct do
  begin
    
dwData := 0; // may use a value do identify content of message
    
cbData := StrLen(PChar(Edit1.Text)) + 1;  //Need to transfer terminating #0 as well
    
lpData := PChar(Edit1.Text)
  end;
  // Find the destination window for the WM_COPYDATA message
  // Empfänger Fenster anhand des Titelzeilentextes suchen
  
hTargetWnd := FindWindow(nil,PChar('Message Receiver'));
  // send the structure to the receiver
  // Die Struktur an den Empfänger schicken
  
SendCopyData(hTargetWnd, MyCopyDataStruct);
end;

// Send Image1 to other app
// Image1 an andere Anwendung schicken
procedure TForm1.Button2Click(Sender: TObject);
var
  
ms: TMemoryStream;
  MyCopyDataStruct: TCopyDataStruct;
  hTargetWnd: HWND;
begin
  
ms := TMemoryStream.Create;
  try
    
image1.Picture.Bitmap.SaveToStream(ms);
    with MyCopyDataStruct do
    begin
      
dwData := 1;
      cbData := ms.Size;
      lpData := ms.Memory;
    end;
    // Search window by the window title
    // Empfänger Fenster anhand des Titelzeilentextes suchen
    
hTargetWnd := FindWindow(nil,PChar('Message Receiver'));
    // Send the Data
    // Daten Senden
    
SendCopyData(hTargetWnd,MyCopyDataStruct);
  finally
    
ms.Free;
  end;
end;

end.

{*********************************************************************}

{ Receiver Application }
{ Empfänger Application }

unit ReceiverApp;

interface

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

type
  
TForm1 = class(TForm)
    Image1: TImage;
    Label1: TLabel;
  private
    procedure 
WMCopyData(var Msg: TWMCopyData); message WM_COPYDATA;
    { Private-Deklarationen }
  
public
    
{ Public-Deklarationen }
  
end;

var
  
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.WMCopyData(var Msg: TWMCopyData);
var
  
sText: array[0..99] of Char;
  ms: TMemoryStream;
begin
  case 
Msg.CopyDataStruct.dwData of
    
0: { Receive Text, Text empfangen}
      
begin
        
StrLCopy(sText, Msg.CopyDataStruct.lpData, Msg.CopyDataStruct.cbData);
        label1.Caption := sText;
      end;
    1: { Receive Image, Bild empfangen}
      
begin
        
ms := TMemoryStream.Create;
        try
          with 
Msg.CopyDataStruct^ do
           
ms.Write(lpdata^, cbdata);
           ms.Position := 0;
          image1.Picture.Bitmap.LoadFromStream(ms);
        finally
          
ms.Free;
        end;
      end;
  end;
end;

end.

 

printed from
www.swissdelphicenter.ch
developers knowledge base