如何向多个进程发送数据?
机器上同时运行了5个ABC.EXE,希望有其中一个向其他所有是ABC.EXE的进程发送一个int类型的‘1024’数据,所有的ABC.EXE接收到这个数据以后,把Label1.Caption设置成那个数据即‘1024’
该如何做啊?
[解决办法]
可以利用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-L?nge der 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
// 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 }
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.
[解决办法]
可以用得消息机制, 发送一个HWND_BROADCAST类型的消息:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
MyMessage : DWORD;
procedure WndProc(var Message: TMessage); Override;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
MyMessage := RegisterWindowMessage( 'MyMessage ');
end;
procedure TForm1.WndProc(var Message: TMessage);
begin
inherited;
if Message.Msg = MyMessage then
begin
Self.Caption := Format( '%d ', [Message.WParam]);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
SendMessage (HWND_BROADCAST, MyMessage, Random(1000), 0);
end;
end.
[解决办法]
LRESULT SendMessage(
HWND hWnd,// handle of destination window
UINT Msg,// message to send
WPARAM wParam,// first message parameter
LPARAM lParam // second message parameter
);
hWnd
接收消息的窗口句柄, 可设为HWND_BROADCAST使得消息发送给目前系统中所有的顶层窗口
Msg
Specifies the message to be sent.
发送的消息(32bit的整数)
wParam
Specifies additional message-specific information.
附加的信息(32bit的整数)
lParam
Specifies additional message-specific information.
另一个附加的信息(32bit的整数)
[解决办法]
SendMessage (HWND_BROADCAST, MyMessage, Random(1000), 0);
第三个参数只是举个例子, 每次发送一个随机整数
如果要实现楼主发送1024这个整数的话, 可以改成:
SendMessage (HWND_BROADCAST, MyMessage, 1024, 0);