我们知道在Win9x/NT下运行的每个应用程序都有自己单独的虚拟存储空间,一个程序的崩溃退出,不会影响其他的程序的正常运行。同样一个程序也不能改变另一个应用程序虚拟存储空间中的代码及数据。可是有时确有必要在两个应用程序之间共享或交换数据,怎么办呢?在WIN32中提供了一些诸如剪贴板、动态数据交换DDE及OLE等高级技术来达到在不同应用程序之间交换数据的目的。然而除此外有其他的方法吗?这里有一个利用消息机制实现数据交换的低层技术。
在WIN32中有一个特殊的WM_COPYDATA的WINDOWS消息可在两个应用程序间传递数据,这个消息需要传递两个参数为:其中一个参数为发送数据的窗口句柄;另一个参数为指向一个TCOPYDATASTRUCT数据结构的指针,这个结构的定义如下:
PCopyDataStruct = TCopyDataStruct;
tagCOPYDATASTRUCT = packed record
dwData:DWORD;//附加的32位参数;
cbData:DWORD;//为待发送数据申请的缓冲区大小;
lpData:Pointer;//指向待发送数据申请的缓冲区的指针;
end;
TCopyDataStruct = tagCOPYDATASTRUCT;
这个结构没有在Delphi帮助文件中归类,位于Windows.pas文件中。具体实现如下:
在Delphi的IDE环境下建立一个发送数据的应用程序(包括一个窗体FORM1),如

。
其中,发送按钮(name为ButtonSend)的响应方法为:
procedure TForm1.ButtonSendClick(Sender:TObject);
var
Cdstr:TCopyDataStruct;
H:THandle;
s:String;
begin
s:=edit1.Text;
//先填充TCopyDataStruct数据结构
//附加的32位参数
Cdstr.dwData:= 111;
//待传递的数据或信息的长度(按字符型计算)
Cdstr.cbData:= Length(s)+ 1;
//申请相应大小的缓冲区并填充数据
GetMem (Cdstr.lpData, Cdstr.cbData);
StrCopy(Cdstr.lpData, PChar (s));
//查找接受数据窗口的句柄;
h:= FindWindow ('TForm2', 'Form2');//查找窗体名称为Form2的窗口的句柄
if h <> 0 then
begin
//成功找到则发送消息
if SendMessage (h, WM_COPYDATA, Handle, Cardinal(@Cdstr))= 1 then
//如果成功;
label2.Caption:='成功发送';
end
else
//不成功显示信息;
ShowMessage ('没有成功发送数据');
//释放申请的内存
FreeMem (Cdstr.lpData);
end;
再建立一个接收数据的应用程序(窗体为Form2),如

。不需要太多的编码,只需要在窗体的单元文件中的Public部分增加一个定制的消息响应对象方法,以响应WM_COPYDATA消息,形式为:
procedure GetCopyData (var Msg: TWmCopyData);
message wm_CopyData;
.
.
.
方法实现如下:
procedure TForm2.GetData(var Msg:TWmCopyData);
var
s:string;
begin
Memo1.Clear;
SetLength (s, 100);
GetWindowText(Msg.From, PChar(s),1000);
s:= pChar(s);
Memo1.Lines.Add('数据来自:' +s);
with Memo1.Lines, Msg.CopyDataStruct^ do
begin
Add ('接收到的数据大小: ' + IntToStr (cbData));
Add ('接收的数据为: ' + PChar(lpData));
end;
//返回成功接收标志
Msg.Result:= 1;
end;
相比较剪贴板、动态数据交换(DDE)及OLE的实现方法,这个方法比较简单。以上程序在Delphi 5下运行通过。