delphi - 寻找进程间通信中使用的 Windows 消息的替代方案

标签 delphi winapi windows-vista window-messages

我有一个多线程应用程序(MIDAS),它利用 Windows 消息与其自身进行通信。

主要表格

主窗体接收RDM发送的windows消息 LogData('DataToLog')

因为使用了windows消息,所以它们具有以下属性

  1. 收到的消息是不可分割的
  2. 收到的消息按照发送顺序排队

问题:

您能建议一种不使用 Windows 消息的更好方法吗?

主表单代码

const
    UM_LOGDATA      = WM_USER+1002;

type

  TLogData = Record
      Msg        : TMsgNum;
      Src        : Integer;
      Data       : String;
  end;
  PLogData = ^TLogData;


  TfrmMain = class(TForm)
  //  
  private
    procedure LogData(var Message: TMessage);        message UM_LOGDATA;
  public
  //        
  end;


procedure TfrmMain.LogData(var Message: TMessage);
var LData : PLogData;
begin
    LData  :=  PLogData(Message.LParam);
    SaveData(LData.Msg,LData.Src,LData.Data);
    Dispose(LData);
end;

RDM 代码

procedure TPostBoxRdm.LogData(DataToLog : String);
var
  WMsg  : TMessage;
  LData : PLogData;
  Msg   : TMsgNum;
begin
  Msg := MSG_POSTBOX_RDM;
  WMsg.LParamLo := Integer(Msg);
  WMsg.LParamHi := Length(DataToLog);
  new(LData);
    LData.Msg    := Msg;
    LData.Src    := 255;
    LData.Data   := DataToLog;
  WMsg.LParam := Integer(LData);
  PostMessage(frmMain.Handle, UM_LOGDATA, Integer(Msg), WMsg.LParam);
end;

编辑:

为什么我想摆脱 Windows 消息:

  • 我想将应用程序转换为 Windows 服务
  • 当系统繁忙时 - Windows 消息缓冲区已满并且速度变慢

最佳答案

使用命名管道。如果您不知道如何使用它们,那么现在是学习的时候了。

使用命名管道,您可以发送任何类型的数据结构(只要服务器和客户端都知道该数据结构是什么)。我通常使用一组记录来来回发送大量信息。非常方便。

我使用 Russell Libby 的免费(开源)命名管道组件。附带 TPipeServer 和 TPipeClient 可视组件。它们使命名管道的使用变得异常简单,并且命名管道非常适合进程间通信 (IPC)。

You can get the component here 。来源的描述是://描述:Delphi 的客户端和服务器命名管道组件集,如 //一个控制台管道重定向组件。

此外,Russell 帮助我解决了 Experts-Exchange 问题,使用该组件的旧版本在控制台应用程序中工作,通过命名管道发送/接收消息。这可能有助于指导您启动并运行他的组件。请注意,在 VCL 应用程序或服务中,您不需要像我在这个控制台应用程序中那样编写自己的消息循环。

program CmdClient;
{$APPTYPE CONSOLE}

uses
  Windows, Messages, SysUtils, Pipes;

type
  TPipeEventHandler =  class(TObject)
  public
     procedure  OnPipeSent(Sender: TObject; Pipe: HPIPE; Size: DWORD);
  end;

procedure TPipeEventHandler.OnPipeSent(Sender: TObject; Pipe: HPIPE; Size: DWORD);
begin
  WriteLn('On Pipe Sent has executed!');
end;

var
  lpMsg:         TMsg;
  WideChars:     Array [0..255] of WideChar;
  myString:      String;
  iLength:       Integer;
  pcHandler:     TPipeClient;
  peHandler:     TPipeEventHandler;

begin

  // Create message queue for application
  PeekMessage(lpMsg, 0, WM_USER, WM_USER, PM_NOREMOVE);

  // Create client pipe handler
  pcHandler:=TPipeClient.CreateUnowned;
  // Resource protection
  try
     // Create event handler
     peHandler:=TPipeEventHandler.Create;
     // Resource protection
     try
        // Setup clien pipe
        pcHandler.PipeName:='myNamedPipe';
        pcHandler.ServerName:='.';
        pcHandler.OnPipeSent:=peHandler.OnPipeSent;
        // Resource protection
        try
           // Connect
           if pcHandler.Connect(5000) then
           begin
              // Dispatch messages for pipe client
              while PeekMessage(lpMsg, 0, 0, 0, PM_REMOVE) do DispatchMessage(lpMsg);
              // Setup for send
              myString:='the message I am sending';
              iLength:=Length(myString) + 1;
              StringToWideChar(myString, wideChars, iLength);
              // Send pipe message
              if pcHandler.Write(wideChars, iLength * 2) then
              begin
                 // Flush the pipe buffers
                 pcHandler.FlushPipeBuffers;
                 // Get the message
                 if GetMessage(lpMsg, pcHandler.WindowHandle, 0, 0) then DispatchMessage(lpMsg);
              end;
           end
           else
              // Failed to connect
              WriteLn('Failed to connect to ', pcHandler.PipeName);
        finally
           // Show complete
           Write('Complete...');
           // Delay
           ReadLn;
        end;
     finally
        // Disconnect event handler
        pcHandler.OnPipeSent:=nil;
        // Free event handler
        peHandler.Free;
     end;
  finally
     // Free pipe client
     pcHandler.Free;
  end;

end.

关于delphi - 寻找进程间通信中使用的 Windows 消息的替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/360289/

相关文章:

windows-7 - 如何检测我的进程是否正在运行 UAC 提升的进程?

C# 可以读取不存在的文件吗?

德尔福:F2084 内部错误 T2575

delphi - 我可以与 Free Pascal 交叉编译(不链接)其他平台吗?

java - JNA映射以将输入/输出缓冲区传递给winapi函数

SetLayeredWindowAttributes 和 BitBlt 之间的 C++ WinAPI 冲突

ios - Delphi XE4 和 Xamarin Monotouch 在针对 iOS 的方式上有何不同?

delphi - Delphi XE3 DataSnap Server 中的访问请求 header

c++ - 处理 GetSidIdentifierAuthority 函数的返回值

visual-studio - Visual Studio(6.0、2003和2008)与Windows Vista 64位(x64)的兼容性