|
|
Delphi 版的两种常用进程间消息通信示例:WM_COPYDATA 和命名管道(Named Pipe)
下面给出 Delphi 版的两种常用进程间消息通信示例:WM_COPYDATA 和命名管道(Named Pipe)。 WM_COPYDATA(小块数据/文本,窗口间)
- uses Windows, Messages, SysUtils;
- type
- TMainForm = class(TForm)
- private
- procedure WMCopyData(var Msg: TWMCopyData); message WM_COPYDATA;
- end;
- procedure TMainForm.WMCopyData(var Msg: TWMCopyData);
- var
- S: AnsiString;
- begin
- if (Msg.CopyDataStruct <> nil) and (Msg.CopyDataStruct.cbData > 0) then
- begin
- SetString(S, PAnsiChar(Msg.CopyDataStruct.lpData), Msg.CopyDataStruct.cbData - 1);
- OutputDebugString(PChar('Recv: ' + string(S)));
- Msg.Result := 1;
- end
- else
- Msg.Result := 0;
- end;
- // 发送端
- procedure SendIpc(const TargetClass, TargetCaption: string; const Text: AnsiString);
- var
- H: HWND;
- CDS: TCopyDataStruct;
- begin
- H := FindWindow(PChar(TargetClass), PChar(TargetCaption));
- if H <> 0 then
- begin
- CDS.dwData := 1; // 自定义标识
- CDS.cbData := Length(Text) + 1; // 包含结尾 #0
- CDS.lpData := PAnsiChar(Text);
- SendMessage(H, WM_COPYDATA, 0, LPARAM(@CDS));
- end;
- end;
复制代码 命名管道(双向、可发较大量数据)- uses Windows, SysUtils, Classes;
- const
- PIPE_NAME = '\\.\pipe\MyPipe';
- procedure PipeServer;
- var
- hPipe: THandle;
- Buf: array[0..1023] of AnsiChar;
- ReadBytes, Written: DWORD;
- Reply: AnsiString;
- begin
- while True do
- begin
- hPipe := CreateNamedPipe(PChar(PIPE_NAME),
- PIPE_ACCESS_DUPLEX,
- PIPE_TYPE_BYTE or PIPE_READMODE_BYTE or PIPE_WAIT,
- PIPE_UNLIMITED_INSTANCES, 4096, 4096, 0, nil);
- if hPipe = INVALID_HANDLE_VALUE then Exit;
- if ConnectNamedPipe(hPipe, nil) or (GetLastError = ERROR_PIPE_CONNECTED) then
- begin
- if ReadFile(hPipe, Buf, SizeOf(Buf) - 1, ReadBytes, nil) then
- begin
- Buf[ReadBytes] := #0;
- OutputDebugString(PChar('Server recv: ' + string(AnsiString(Buf))));
- Reply := 'ACK';
- if Length(Reply) > 0 then
- WriteFile(hPipe, Reply[1], Length(Reply), Written, nil);
- end;
- FlushFileBuffers(hPipe);
- DisconnectNamedPipe(hPipe);
- end;
- CloseHandle(hPipe);
- end;
- end;
- procedure StartPipeServer;
- begin
- TThread.CreateAnonymousThread(
- procedure
- begin
- PipeServer;
- end).Start;
- end;
- // 客户端
- function PipeClientSend(const Msg: AnsiString): Boolean;
- var
- h: THandle;
- Wrote, ReadBytes: DWORD;
- Buf: array[0..1023] of AnsiChar;
- begin
- Result := False;
- if not WaitNamedPipe(PChar(PIPE_NAME), 5000) then Exit;
- h := CreateFile(PChar(PIPE_NAME), GENERIC_READ or GENERIC_WRITE, 0, nil,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
- if h = INVALID_HANDLE_VALUE then Exit;
- try
- if Length(Msg) > 0 then
- WriteFile(h, Msg[1], Length(Msg), Wrote, nil);
- if ReadFile(h, Buf, SizeOf(Buf) - 1, ReadBytes, nil) then
- begin
- Buf[ReadBytes] := #0;
- OutputDebugString(PChar('Client recv: ' + string(AnsiString(Buf))));
- Result := True;
- end;
- finally
- CloseHandle(h);
- end;
- end;
复制代码要点 - WM_COPYDATA 适合同机窗口间小数据;命名管道更通用、可双向收发。
- Delphi 新版 String 为 Unicode;通过 AnsiString 携带字节并用 PAnsiChar 传输更稳。
|
|