How to Send Information (String, Image, Record) Between Two Delp...
###如何使用WM_COPYDATA在两个Delphi应用程序之间发送信息(字符串、图像、记录)本文将详细介绍如何利用WM_COPYDATA消息在两个Delphi应用程序之间进行数据传输,包括字符串、图像和记录等不同类型的信息。这种方法特别适用于运行在同一台计算机上的两个应用,避免了使用TCP/IP或套接字通信的复杂性。 #### WM_COPYDATA与TCopyDataStruct **WM_COPYDATA**消息允许一个应用程序向另一个应用程序发送数据。接收方通过**TCopyDataStruct**记录接收数据。该记录定义在Windows.pas单元中,封装了一个名为COPYDATASTRUCT的结构体,用于存储待传递的数据。下面是**TCopyDataStruct**记录的声明及其成员的描述: ```pascal type TCopyDataStruct = packed record dwData: DWORD; //可以传递最多32位的数据到接收方应用cbData: DWORD; //指向的数据大小(字节) lpData: Pointer; //指向要传递给接收方应用的数据。此成员可以为nil。 end; ``` ####发送字符串为了使“发送者”应用程序能够向“接收者”应用程序发送数据,需要填充**TCopyDataStruct**并通过**SendMessage**函数传递。以下是如何通过WM_COPYDATA发送字符串值的示例: ```pascal procedure TSenderMainForm.SendString(); var stringToSend: string; copyDataStruct: TCopyDataStruct; begin stringToSend := 'About Delphi Programming'; copyDataStruct.dwData := 0; //可用于标识消息内容copyDataStruct.cbData := 1 + Length(stringToSend); //包括null终止符copyDataStruct.lpData := PChar(stringToSend); SendData(copyDataStruct); end; procedure TSenderMainForm.SendData(const copyDataStruct: TCopyDataStruct); var receiverHandle: THandle; res: integer; begin receiverHandle := FindWindow(PChar('TReceiverMainForm'), PChar('ReceiverMainForm')); if receiverHandle = 0 then begin ShowMessage('接收窗口未找到!'); Exit; end; res := SendMessage(receiverHandle, WM_COPYDATA, Integer(self.Handle), LPARAM(@copyDataStruct)); if res = 0 then ShowMessage('数据发送失败!'); end; ``` ####接收字符串接收方应用需要处理**WM_COPYDATA**消息来读取发送过来的数据。下面是一个简单的接收字符串的例子: ```pascal procedure TReceiverMainForm.WMCopyData(var Message: TWMMCopyData); begin inherited; // Message.CopyData是TCopyDataStruct类型的参数//可以从中读取数据if (Message.CopyData.cbData > 0) and Assigned(Message.CopyData.lpData) then begin ShowMessage(PChar(Message.CopyData.lpData)); end; ``` ####发送图像可以通过将图像数据序列化为字节流,并将其作为字符串传递的方式实现。这里给出一个简化版本的示例代码: ```pascal procedure TSenderMainForm.SendImage(Image: TImage); var Stream: TMemoryStream; CopyDataStruct: TCopyDataStruct; begin Stream := TMemoryStream.Create; try Image.Picture.Graphic.SaveToStream(Stream); Stream.Position := 0; CopyDataStruct.dwData := 0; CopyDataStruct.cbData := Stream.Size + 1; //包括null终止符CopyDataStruct.lpData := Stream.Memory; SendData(CopyDataStruct); finally Stream.Free; end; ```接收方同样需要读取字节流并还原成图像: ```pascal procedure TReceiverMainForm.WMCopyData(var Message: TWMMCopyData); var Stream: TMemoryStream; Image: TImage; begin inherited; if (Message.CopyData.cbData > 0) and Assigned(Message.CopyData.lpData) then begin Stream := TMemoryStream.Create; try Stream.Memory := Message.CopyData.lpData; Stream.Size := Message.CopyData.cbData - 1; Stream.Position := 0; Image := TImage.Create(Self); try Image.Picture.LoadFromStream(Stream); Image.Show; finally Image.Free; end; finally Stream.Free; end; ``` ####发送记录时,可以先将记录转换为字节流,然后像发送字符串那样发送。这里提供一个简化的示例代码: ```pascal type TMyRecord = record Field1: Integer; Field2: string[255]; end; procedure TSenderMainForm.SendRecord(Rec: TMyRecord); var Stream: TMemoryStream; CopyDataStruct: TCopyDataStruct; begin Stream := TMemoryStream.Create; try Stream.WriteBuffer(Rec, SizeOf(TMyRecord)); Stream.Position := 0; CopyDataStruct.dwData := 0; CopyDataStruct.cbData := Stream.Size; CopyDataStruct.lpData := Stream.Memory; SendData(CopyDataStruct); finally Stream.Free; end; ```接收记录时,需要从字节流中读取数据,并将其还原为原始记录: ```pascal procedure TReceiverMainForm.WMCopyData(var Message: TWMMCopyData); var Stream: TMemoryStream; Rec: TMyRecord; begin inherited; if (Message.CopyData.cbData > 0) and Assigned(Message.CopyData.lpData) then begin Stream := TMemoryStream.Create; try Stream.Memory := Message.CopyData.lpData; Stream.Size := Message.CopyData.cbData; Stream.Position := 0; Stream.ReadBuffer(Rec, SizeOf(TMyRecord)); finally Stream.Free; end; //处理记录Rec end; ``` ####总结通过使用**WM_COPYDATA**消息,可以在同一台计算机上运行的两个Delphi应用程序之间简单有效地发送字符串、图像和记录等不同类型的数据。这种方法避免了复杂的网络编程,并且提供了灵活而强大的通信机制。对于开发需要进行进程间通信的应用程序来说,这是一项非常有用的技术。
142.84KB
文件大小:
评论区