寻找在进程间通信中使用的Windows消息的替代方法 [英] Looking for an alternative to windows messages used in inter-process communication

查看:125
本文介绍了寻找在进程间通信中使用的Windows消息的替代方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



MAIN FORM


$ b我有一个多线程应用程序(MIDAS)使用Windows消息与自己进行通信。 $ b

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



由于使用Windows消息,它们具有以下属性


  1. 收到的邮件是不可分割的

  2. 收到的邮件按照发送的顺序排队

QUESTION:



你能建议一个更好的方法在不使用Windows消息的情况下执行此操作?



主表格代码

  const 
UM_LOGDATA = WM_USER + 1002;

type

TLogData = Record
Msg:TMsgNum;
Src:整数;
数据:字符串;
结束
PLogData = ^ TLogData;


TfrmMain = class(TForm)
//
private
程序LogData(var Message:TMessage);消息UM_LOGDATA;
public
//
end;


程序TfrmMain.LogData(var Message:TMessage);
var LData:PLogData;
begin
LData:= PLogData(Message.LParam);
SaveData(LData.Msg,LData.Src,LData.Data);
处理(LData);
结束

RDM代码

 程序TPostBoxRdm.LogData(DataToLog:String); 
var
WMsg:TMessage;
LData:PLogData;
消息:TMsgNum;
begin
Msg:= MSG_POSTBOX_RDM;
WMsg.LParamLo:=整数(Msg);
WMsg.LParamHi:=长度(DataToLog);
new(LData);
LData.Msg:= Msg;
LData.Src:= 255;
LData.Data:= DataToLog;
WMsg.LParam:=整数(LData);
PostMessage(frmMain.Handle,UM_LOGDATA,Integer(Msg),WMsg.LParam);
结束

编辑:



为什么我想摆脱Windows消息:




  • 我想将应用程序转换为Windows服务

  • 系统忙时,Windows消息缓冲区已满,事情减慢了


解决方案

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



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



我使用Russell Libby的免费(和开源)命名管道组件。配有一个TPipeServer和一个TPipeClient可视化组件。他们使用命名管道非常简单,命名管道非常适合进程间通信(IPC)。



您可以在这里获取组件。来源的描述是://描述:为Delphi设置客户端和服务器命名的管道组件,如
//好的控制台管道重定向组件。



此外,Russell帮助我在Experts-Exchange上使用旧版本的此组件,在控制台应用程序中通过命名管道发送/接收消息。这可能有助于作为使用他的组件让您开始运行的指南。请注意,在VCL应用程序或服务中,您不需要像我在此控制台应用程序中编写自己的消息循环。

 程序CmdClient; 
{$ APPTYPE CONSOLE}

使用
Windows,Messages,SysUtils,Pipes;

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

程序TPipeEventHandler.OnPipeSent(发件人:TObject;管道:HPIPE;大小:DWORD);
begin
WriteLn('On Pipe Sent已执行!');
结束

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

begin

//为应用程序创建消息队列
PeekMessage(lpMsg,0,WM_USER,WM_USER,PM_NOREMOVE);

//创建客户端管理程序
pcHandler:= TPipeClient.CreateUnowned;
//资源保护
尝试
//创建事件处理程序
peHandler:= TPipeEventHandler.Create;
//资源保护
尝试
//设置clien管道
pcHandler.PipeName:='myNamedPipe';
pcHandler.ServerName:='。';
pcHandler.OnPipeSent:= peHandler.OnPipeSent;
//资源保护
尝试
//连接
如果pcHandler.Connect(5000)然后
begin
//为管道客户端发送消息
while PeekMessage(lpMsg,0,0,0,PM_REMOVE)do DispatchMessage(lpMsg);
//设置发送
myString:='我发送的消息';
iLength:=长度(myString)+ 1;
StringToWideChar(myString,wideChars,iLength);
//发送管道消息
如果pcHandler.Write(wideChars,iLength * 2)然后
begin
//刷新管道缓冲区
pcHandler.FlushPipeBuffers;
//获取消息
如果GetMessage(lpMsg,pcHandler.WindowHandle,0,0)then DispatchMessage(lpMsg);
结束
end
else
//无法连接
WriteLn('无法连接到',pcHandler.PipeName);
finally
//显示完成
写('完成...');
//延迟
ReadLn;
结束
finally
//断开事件处理程序
pcHandler.OnPipeSent:= nil;
//自由事件处理程序
peHandler.Free;
结束
finally
// Free pipe client
pcHandler.Free;
结束

结束。


I a have a multithread application (MIDAS) that makes uses of windows messages to communicate with itself.

MAIN FORM

The main form receives windows messages sent by the RDM LogData(‘DataToLog’)

Because windows messages are used they have the following attributes

  1. Received messages are Indivisible
  2. Received messages are Queued in the order they are sent

QUESTION:

Can you Suggest a better way doing this without using windows messages ?

MAIN FORM CODE

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 CODE

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;

EDIT:

Why I want to get rid of the windows messages:

  • I would like to convert the application into a windows service
  • When the system is busy – the windows message buffer gets full and things slows down

解决方案

Use Named Pipes. If you don't know how to use them, then now is the time to learn.

With named pipes, you can send any type of data structure (as long as both the server and the client know what that data structure is). I usually use an array of records to send large collections of info back and forth. Very handy.

I use Russell Libby's free (and open-source) named pipe components. Comes with a TPipeServer and a TPipeClient visual component. They make using named pipes incredibly easy, and named pipes are great for inter-process communication (IPC).

You can get the component here. The description from the source is: // Description : Set of client and server named pipe components for Delphi, as // well a console pipe redirection component.

Also, Russell helped me out on Experts-Exchange with using an older version of this component to work in a console app to send/receive messages over named pipes. This may help as a guide in getting you up and running with using his components. Please note, that in a VCL app or service, you don't need to write your own message loop as I did in this console app.

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.

这篇关于寻找在进程间通信中使用的Windows消息的替代方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆