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:
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| type TCopyDataStruct = packed record dwData: DWORD; cbData: DWORD; lpData: Pointer; 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:
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}
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;
procedure TForm1.Button1Click(Sender: TObject); var MyCopyDataStruct: TCopyDataStruct; hTargetWnd: HWND; begin with MyCopyDataStruct do begin dwData := 0; cbData := StrLen(PChar(Edit1.Text)) + 1; lpData := PChar(Edit1.Text) end; hTargetWnd := FindWindow(nil,PChar('Message Receiver')); SendCopyData(hTargetWnd, MyCopyDataStruct); end;
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; hTargetWnd := FindWindow(nil,PChar('Message Receiver')); SendCopyData(hTargetWnd,MyCopyDataStruct); finally ms.Free; end; end;
end. |
Empfänger Application:
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; public 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: begin StrLCopy(sText, Msg.CopyDataStruct.lpData, Msg.CopyDataStruct.cbData); label1.Caption := sText; end; 1: 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