Autor Beitrag
Tino
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Veteran
Beiträge: 9839
Erhaltene Danke: 45

Windows 8.1
Delphi XE4
BeitragVerfasst: Mi 26.02.03 10:30 
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:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
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 Applikation:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
 

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: 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

// Text von Edit1 an andere Anwendung schicken 
procedure TForm1.Button1Click(Sender: TObject); 
var 
  MyCopyDataStruct: TCopyDataStruct; 
  hTargetWnd: HWND; 
begin 
  // 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
  // Empfänger Fenster anhand des Titelzeilentextes suchen 
  hTargetWnd := FindWindow(nil,PChar('Message Receiver')); 
  // Die Struktur an den Empfänger schicken 
  SendCopyData(hTargetWnd, MyCopyDataStruct); 
end

// 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
    // Empfänger Fenster anhand des Titelzeilentextes suchen 
    hTargetWnd := FindWindow(nil,PChar('Message Receiver')); 
    // Daten Senden 
    SendCopyData(hTargetWnd,MyCopyDataStruct); 
  finally 
    ms.Free; 
  end
end

end.


Empfänger Application:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
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..99of 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.

Beitrag von Thomas Stutz