Delphi跨进程间消息通讯

摘要:
不要等待结果直接返回;它一般适用于过程中的信息传输处理=WM_ COPYDATA;{指定消息类型}12CopyDataStruct。cbData:=长度(tmpInfo);整数(@CopyDataStruct));{在LParam上发送数据}14end;字符串;=StringOf(tmpInfo);9mmo_1.行.附加(tmpJson);

多个不同进程之间的消息传递有多种方式,但若传递的信息量不大,借用WINDOW的消息机制不失为一种简易有效的方法,

01. 注意 PostMessage  与 SendMessage 之间的异同;

  PostMessage: 异步消息模式,负责向指定的句柄发送消息,不等待结果直接返回;

        一般适用于进程内的信息传递处理;(如多个不同线程向主线程汇报状态和结果等);

  SendMessage:同步消息模式,负责缶指定的句柄发送消息,等消息处理完了再返回;

        可以完成PostMessage相应的功能,同时可借用 TCopyDataStruct 达成跨进程的消息处理;

02. 消息发送 (在与设备对接过程中,因涉及到许多不同规则的自定义数据内容,所以习惯使用字节和指针做数据传递了,

  而不直接使用PAnsichar这种对#0有特殊要求的指针)  

 1 procedure SendDaemonMsg(pMsg: string; pHWND: THandle);
 2 var
 3   CopyDataStruct: TCopyDataStruct;
 4   tmpInfos: TBytes;
 5 begin
 6   if pHWND = 0 then
 7     Exit;
 8   tmpInfos := BytesOf(pMsg);
 9   //
10   CopyDataStruct.lpData := @tmpInfos[0];     { 要发送的字符串, #0 表示 PChar 结束}
11   CopyDataStruct.dwData := WM_COPYDATA;      { 指定消息类型 }
12   CopyDataStruct.cbData := Length(tmpInfos); { 指定要发送的数据的大小 }
13   SendMessage(pHWND, WM_COPYDATA, 0, Integer(@CopyDataStruct)); { 发送 数据在 LParam 上}
14 end;

  消息接收:

 1 procedure WMCopyData(var Message: TWMCopyData);
 2 var
 3   tmpInfos: TBytes;
 4   tmpJson: string;
 5 begin
 6   SetLength(tmpInfos, Message.CopyDataStruct.cbData);
 7   Move(Message.CopyDataStruct.lpData^, tmpInfos[0], Message.CopyDataStruct.cbData);
 8   tmpJson := StringOf(tmpInfos);
 9   mmo_1.Lines.Append(tmpJson);
10 end;

对于消息处理函数的定义,也可以将Message定义为TMessage,

 1 procedure WMCopyData(var Msg: TMessage);
 2 var
 3   cdds : TcopyDataStruct;
 4 begin
 5   if msg.Msg = WM_COPYDATA then
 6   begin
 7     cdds := PcopyDataStruct(Msg.LParam)^;
 8     //之后再依据cdds 来处理业务  (后面与procedure WMCopyData(var Message: TWMCopyData); 一致)
9   end;
10 end;

03. 关于软件运行权限对消息传递的影响(依据实测情况总结)

  为便于理解,将二个不同的程序定义为:  PA, PB

    测试情况如下:   (详情见Demo:    >>> 21013.Daemon  )
    Delphi跨进程间消息通讯第1张

04. 若在PA,PB之间的某个程序,有信息等待的处理情况

      如: PA 为守护程序时,给PB发消息,PB在收到消息后,再给PA传个消息,

    若PA需要依据PB传递的数据的情况分情况处理后续内容;

     对于这种需求,需要注意几点:

  a. PB在接收到消息后,最好新开线程来向PA发消息;

  b. PA发消息后,如果此时在等待PB的消息数据,(例如:使用了TEvent来等信号)

   这个时候,PA在向PB发消息的时候,最好也是走线程,要不然,会出现信号等待超时等问题;

 05. 关于 守护程序 与 服务器程序 在相互守护时,对另一程序的路径问题的说明

  >> 使用绝对路径, 而不是只使用 程序名称   xxx.exe;

  >> 原因说明:

    a. 在窗口模式下,绝对路径与文件名称这二种方式,都可以达到相互守护的效果;

    b. 在电脑重新开机后,若只有程序名称,无法有效的守护;问题点在于:文件不存在;

     若提供绝对路径,可以很好的达成相互守护;

  >>关于 ShellExecute函数原型及参数含义如下:       

1 ShellExecute(
2   hWnd: HWND; {指定父窗口句柄}
3   Operation: PChar; {指定动作, 譬如: open、runas、print、edit、explore、find[2]  }
4   FileName: PChar; {指定要打开的文件或程序}
5   Parameters: PChar; {给要打开的程序指定参数; 如果打开的是文件这里应该是 nil}
6   Directory: PChar; {缺省目录}
7   ShowCmd: Integer {打开选项}
8 ): HINST;

    ShowCmd 参数可选值:

      SW_HIDE = 0; {隐藏}
      SW_SHOWNORMAL = 1; {用最近的大小和位置显示, 激活}
      SW_NORMAL = 1; {同 SW_SHOWNORMAL}
      SW_SHOWMINIMIZED = 2; {最小化, 激活}
      SW_SHOWMAXIMIZED = 3; {最大化, 激活}
      SW_MAXIMIZE = 3; {同 SW_SHOWMAXIMIZED}
      SW_SHOWNOACTIVATE = 4; {用最近的大小和位置显示, 不激活}
      SW_SHOW = 5; {同 SW_SHOWNORMAL}
      SW_MINIMIZE = 6; {最小化, 不激活}
      SW_SHOWMINNOACTIVE = 7; {同 SW_MINIMIZE}
      SW_SHOWNA = 8; {同 SW_SHOWNOACTIVATE}
      SW_RESTORE = 9; {同 SW_SHOWNORMAL}
      SW_SHOWDEFAULT = 10; {同 SW_SHOWNORMAL}
      SW_MAX = 10; {同 SW_SHOWNORMAL}

    WIN8系统调用此函数打开文件无效。
    
    执行成功会返回应用程序句柄
    返回的HINSTANCE可以将它转换为一个整数(%d),并比较它的值大于还是小于32或比较它的错误代码
    返回值大于32表示执行成功
    返回值小于32表示执行错误
    返回值可能的错误有: = 0 {内存不足}
      ERROR_FILE_NOT_FOUND = 2; {文件名错误}
      ERROR_PATH_NOT_FOUND = 3; {路径名错误}
      ERROR_BAD_FORMAT = 11; {EXE 文件无效}
      SE_ERR_SHARE = 26; {发生共享错误}
      SE_ERR_ASSOCINCOMPLETE = 27; {文件名不完全或无效}
      SE_ERR_DDETIMEOUT = 28; {超时}
      SE_ERR_DDEFAIL = 29; {DDE 事务失败}
      SE_ERR_DDEBUSY = 30; {正在处理其他 DDE 事务而不能完成该 DDE 事务}
      SE_ERR_NOASSOC = 31; {没有相关联的应用程序}

     

 

免责声明:文章转载自《Delphi跨进程间消息通讯》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇C# EF增删改查HTTP请求行、请求头、请求体详解下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

python网络编程——IO多路复用之select

1 IO多路复用的概念         原生socket客户端在与服务端建立连接时,即服务端调用accept方法时是阻塞的,同时服务端和客户端在收发数据(调用recv、send、sendall)时也是阻塞的。原生socket服务端在同一时刻只能处理一个客户端请求,即服务端不能同时与多个客户端进行通信,实现并发,导致服务端资源闲置(此时服务端只占据 I/O,...

Linux学习之Linux目录及文件系统

以往的 Windows 一直是以存储介质为主的,主要以盘符(C 盘,D 盘...)及分区来实现文件管理,然后之下才是目录,目录就显得不是那么重要,除系统文件之外的用户文件放在任何地方任何目录也是没有多大关系。所以通常 Windows 在使用一段时间后,磁盘上面的文件目录会显得杂乱无章(少数善于整理的用户除外吧)。然而 UNIX/Linux 恰好相反,UNI...

美多商城项目之商品模块

1. FastDFS和Docker      1.0 为什么要使用FastDFS和Docker?         因为商品数据分为了商品图片数据(文件),还有商品信息数据(字符串:商品名称,价格,...)        商品图片数据(文件)需要使用单独的文件存储服务器进行管理            文件存储服务器:FastDFS            如何...

python setup.py 构建

摘要:这篇文章描述了自己动手把需要的代码封装成python模块的方法。完成后,我们可以直接使用pip install xxx下载自己的模块并使用内置的函数。 介绍python作为一门鼎鼎大名的语言,最有优势的地方就是它拥有无数第三方的模块可以直接拿来使用。以numpy(一个用于实现科学计算的模块)为例,常见的用法一般是这样,相信写过python的肯定是见得...

C#简单一句代码,实现pictureBox的照片另存为磁盘文件不出错

开发人事档案系统时,一般都要利用pictureBox对人员的照片进行操作,包括选择保存照片、另存照片、删除照片,如下图:                         将照片保存到数据库和从数据库中删除,网友写了很多实用代码,非常好用。但是要将pictureBox上显示的照片另存为磁盘文件时,非常容易出现“GDI+ 发生一般性错误”。网上有很多建议,都不...

VS 2010配置Qt 4.8.5

     由于早上偶然的一个念想,今天的宝贵时光就奉献给了Qt的安装及其和VS 2010的配置上了。   说实话,开始时真的查找了资料,包括博客、文库、知道等等,作者们写得都很全面,细致。 但自己动手尝试就是错误百出,本人的装备是win7系统+VS2010旗舰+惠普老机子。   所实话,总共试了多少建议方案已经记不清了,总之有点头晕,朋友们都知道杭州的暑期...