我用WM_COPYDATA在两个独立的程序中传递消息,主要是传递字符串,遇到一个问题.有时候连续发送几个消息过去接收方接收不到消息,一定要先激活一次接收方的窗体才能正常接收消息,也就是发送一次消息后,点击一下接收方的窗体再通过发送方程序发送消息接收方才能收到下一个消息.
发送方代码:
_________________________________procedure TForm1.btnSendMessageClick(Sender: TObject);
var
ds: TCopyDataStruct;
hd: THandle;
temp:string;
begin
temp := trim(edt1.text);
ds.cbData := Length(temp) + 1;
GetMem (ds.lpData, ds.cbData );
StrCopy (ds.lpData, PChar (temp));
Hd := FindWindow (nil, '测试窗体');
if Hd <> 0 then
SendMessage (Hd, WM_COPYDATA, Handle,
Cardinal(@ds))
else
ShowMessage ('目标窗口没找到!');
FreeMem (ds.lpData);
end;---------------------------------------------接收方代码:-----------------------
procedure TForm2.Mymessage(var t:TWmCopyData);
var
tempstr:string;
begin
tempstr :=trim ((StrPas(t.CopyDataStruct^.lpData)));
edt1.text := tempstr;
end;
unit Main;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TMainForm = class(TForm)
MemoData: TMemo;
ButtonExit: TButton;
ButtonTransfer: TButton;
procedure ButtonExitClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure ButtonTransferClick(Sender: TObject);
private
{ Private declarations }
protected
procedure WMCopyData(var Message: TMessage);
procedure WMRequest(var Message: TMessage);
procedure WMSend(var Message: TMessage);
procedure WMAcknowledge(var Message: TMessage);
procedure WndProc(var Message: TMessage); override;
public
{ Public declarations }
end;var
MainForm: TMainForm;implementation{$R *.dfm}const
SReqMsg = 'JuCopyData.Request';
SAckMsg = 'JuCopyData.Acknowledgement';
SSendMsg = 'JuCopyData.Send';var
FormTitle: string = 'Copy Data';var
ReqMsgId, AckMsgId, SendMsgId: Cardinal;
Recipients: DWORD = BSM_APPLICATIONS;procedure TMainForm.ButtonExitClick(Sender: TObject);
begin
Application.Terminate();
end;procedure TMainForm.ButtonTransferClick(Sender: TObject);
begin
Windows.BroadcastSystemMessage(BSF_IGNORECURRENTTASK or BSF_POSTMESSAGE, @Recipients, ReqMsgId, Self.Handle, Application.Handle);
end;procedure TMainForm.WMAcknowledge(var Message: TMessage);
begin
Perform(SendMsgId, Message.WParam, Message.LParam);
Caption := FormTitle + ' - Server';
end;procedure TMainForm.WMCopyData(var Message: TMessage);
begin
Caption := FormTitle + ' - Client - From Window $' + IntToHex(Message.WParam, 8);
if PCopyDataStruct(Message.LParam)^.dwData = SendMsgId then
begin
Self.MemoData.SetTextBuf(PChar(PCopyDataStruct(Message.LParam)^.lpData));
end;
end;procedure TMainForm.WMRequest(var Message: TMessage);
begin
PostMessage(HWND(Message.WParam), AckMsgId, Handle, Application.Handle);
Caption := FormTitle + ' - Client';
end;procedure TMainForm.WMSend(var Message: TMessage);
var
Data: TCopyDataStruct;
Buffer: PChar;
BufferSize: Integer;
begin
BufferSize := Self.MemoData.GetTextLen + SizeOf(Char);
Buffer := AllocMem(BufferSize);
try
Self.MemoData.GetTextBuf(Buffer, BufferSize);
Data.dwData := SendMsgId;
Data.cbData := BufferSize;
Data.lpData := Buffer;
SendMessage(HWND(Message.WParam), WM_COPYDATA, Handle, Longint(@Data));
finally
FreeMem(Buffer);
end;
end;procedure TMainForm.WndProc(var Message: TMessage);
begin
if Message.Msg = ReqMsgId then Self.WMRequest(Message)
else if Message.Msg = AckMsgId then Self.WMAcknowledge(Message)
else if Message.Msg = SendMsgId then Self.WMSend(Message)
else if Message.Msg = WM_COPYDATA then Self.WMCopyData(Message)
else inherited WndProc(Message);
end;procedure TMainForm.FormCreate(Sender: TObject);
begin
Caption := FormTitle;
end;initialization
ReqMsgId := RegisterWindowMessage(SReqMsg);
AckMsgId := RegisterWindowMessage(SAckMsg);
SendMsgId := RegisterWindowMessage(SSendMsg);end.
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons;type
TForm1 = class(TForm)
Memodata: TMemo;
BitBtn1: TBitBtn;
procedure BitBtn1Click(Sender: TObject);
private
{ Private declarations }
procedure WMSend();
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.WMSend();
var
Data: TCopyDataStruct;
Buffer: PChar;
BufferSize: Integer;
begin
BufferSize := Self.MemoData.GetTextLen + SizeOf(Char);
Buffer := AllocMem(BufferSize);
try
Self.MemoData.GetTextBuf(Buffer, BufferSize);
Data.cbData := BufferSize;
Data.lpData := Buffer;
SendMessage(FindWindow(nil, 'Form2'), WM_COPYDATA, Handle, Longint(@Data));
finally
FreeMem(Buffer);
end;
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
WMSend;
end;end.
程序二(接收消息):
unit Unit2;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
memodata: TMemo;
private
{ Private declarations }
procedure WMCopyData(var Message: TMessage);
public
procedure WndProc(var Message: TMessage); override;
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}
procedure TForm1.WndProc(var Message: TMessage);
begin
if Message.Msg = WM_COPYDATA then Self.WMCopyData(Message)
else inherited WndProc(Message);
end;
procedure TForm1.WMCopyData(var Message: TMessage);
begin
Caption := 'Get Data from Form1' ;
Self.MemoData.SetTextBuf(PChar(PCopyDataStruct(Message.LParam)^.lpData));
end;
end.