首页  编辑  

两个程序之间用消息传递数据

Tags: /超级猛料/Message.消息和事件/   Date Created:

两个程序之间用消息传递数据。

问题:我想用SendMessage和自定义消息在两个程序之间传递一个字符串,问题是如果这个字符串是一个常量,SendMessage(h,CM_MYMESSAGE,0,integer(pchar('abcdef')));另外一个程序对CM_MYMESSAGE进行处理可以收到'abcdef',然而,把abcdef变成一个pchar或者string进行传递,就无法正常使用了!如何解决呢?

解答:可以利用WM_COPYDATA来做。

下面代码仅仅演示,细节错误不予考虑

procedure Init;

var

 s                 : pchar;

 h                 : hwnd;

 buf:tagCOPYDATASTRUCT;

begin

 h := FindWindow('TForm1', 'Form1');

 if h <> 0 then

 begin

   GetMem(s,100);

   buf.lpData :=s;

   buf.cbData:=100;

   buf.dwData :=100;

   strpcopy(s, ParamStr(0));

   SendMessage(h, WM_COPYDATA, 0, integer(@buf));

 end;

end;

procedure TForm1.WM_COPYDATA(var msg: TMessage);

var

 P:^tagCOPYDATASTRUCT;

begin

 p:=Pointer(Msg.lParam);

 ShowMessage(strpas(p.lpData));

end;

***********************************************************************************

{

 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:

}

type

 TCopyDataStruct = packed record

   dwData: DWORD; // anwendungsspezifischer Wert

   cbData: DWORD; // Byte-Lder zu übertragenden Daten

   lpData: Pointer; // Adresse der Daten

 end;

{ Sender Application }

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

 // EmpfFenster anhand des Titelzeilentextes suchen

 hTargetWnd := FindWindow(nil,PChar('Message Receiver'));

 // send the structure to the receiver

 // Die Struktur an den Empfschicken

 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

   // EmpfFenster 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 }

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.