Delphi 两个应用程序(进程)之间的通信
两个应用程序之间的通信实际上是两个进程之间的通信。由于本人知识有限,决定应用消息来实现。需要用到的知识:
1.RegisterWindowMessage(); //参数类型:pchar;返回值:LongInt;
注册全局消息函数。
2.FindWindow(
lpClassName, {窗口的类名}
lpWindowName: PChar {窗口的标题}
): HWND; {返回窗口的句柄; 失败返回 0}
检索欲接收消息的窗体函数。
3.Wndproc();
每个窗口会有一个称为窗口过程的回调函数(WndProc),它带有四个参数,分别为:窗口句柄(Window Handle),消息ID(Message ID),和两个消息参数(wParam, lParam)
4.PostMessage();
该函数将一个消息放入(寄送)到与指定窗口创建的线程相联系消息队列里,不等待线程处理消息就返回,是异步消息模式。消息队列里的消息通过调用GetMessage和PeekMessage取得。取得后交由WndProc进行处理。
好了,需要的知识都在这里了,现在开始我们的应用程序之间通信。
首先在两个应用程序的主窗体的创建过程注册消息,消息编号一定要不小于WM_USER,然后在发送消息的程序1中得到接收消息的程序2中主窗体句柄,并通过PostMessage向其发送消息;接下来在程序2的主窗体创建过程注册和程序1相同编号的消息,然后重载程序2的Wndproc过程。废话就不多说了,直接贴代码:
////////////////////////////////////发送消息的程序1//////////////////////////////////////////
unit Unit1; interface uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons; type
TForm1 = class(TForm)
Button2: TButton;
Button3: TButton;
BitBtn1: TBitBtn;
procedure Button2Click(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
private
{ Private declarations } I: Integer; public
{ Public declarations } end; var
Form1: TForm1; implementation {$R *.dfm} { TForm1 }
procedure TForm1.FormShow(Sender: TObject);
begin
I:= RegisterWindowMessage('MyMessage');
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
var
h1: HWND;
begin
h1:= FindWindow(nil,'Form2');
PostMessage(h1,I,,);
end;
///////////////////////////程序2//////////////////////////////////////////////
unit Unit1; interface uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, AppEvnts, Buttons,QExtCtrls, ExtCtrls;
const
My_MousL = WM_USER+;
type
TForm2 = class(TForm)
Button1: TButton;
ApplicationEvents1: TApplicationEvents;
BitBtn1: TBitBtn;
BtnCreatePanel: TBitBtn;
BitBtn2: TBitBtn;
BitBtn3: TBitBtn;
Panel1: TPanel;
Button2: TButton;
procedure FormShow(Sender: TObject);
private
{ Private declarations }
J: Integer;
public
{ Public declarations }
procedure WndProc(var Message: TMessage); override;
end; var
Form2: TForm2; implementation {$R *.dfm} procedure TForm1.FormShow(Sender: TObject);
begin
J:= RegisterWindowMessage('MyMessage');
end; procedure TForm1.WndProc(var Message: TMessage);
begin
if Message.Msg = J then
ShowMessage('得到消息')
else
inherited;
end;
至此,应用程序间通信就完成了,这里需要注意:FindWindow一定要找到你想要得到消息的应用程序,也就是说如果用FindWindow(nil,'Form2'),你一定得保证窗体的caption:= Form2的程序是唯一的。
---------------------------------------------------------------------------------------------------------------------------------
另附上一个Delphi进程间通信的两种方法:
WIN下面进程间通信的最常用办法就是消息了,下面记录两种消息通信的方式:
--------------------------------------------------------------------------------------------
一.第一种办法,利用注册Windows全局的消息.并覆盖wndProc过程来监听消息处理.
1. 发送消息方:
private
strWM:Cardinal; //定义一个局部变量
//...
proccedure Form1.Create(sender:TObject);
begin
strWM:= RegisterWindowMessage('newspopMessage'); //注册一个windows全局消息,通过这个消息与其它进程通信
end; procedure Form1.Button1Click1(Sender:TObject);
var
h:Cardinal;
13 begin
//通信的步骤得先找到要通信的信息窗口Handle
h:=findWindow('目标进程窗口类名','窗口Caption');
//发送消息消息类型为自定义的strWM
SendMessage(h,strWM,,); //这里同样可以带参数:wParam,lParam。但我传一个PChar,读取的时候总报错,不知道为啥
end;
2.接收消息方:
private
strWM:Cardinal; //定义一个局部变量
procedure wndProc(var msg:Tmessage);override; //覆盖这个方法,可以监听所有的Windows消息回调函数
...
proccedure Form1.Create(sender:TObject);
begin
strWM:= RegisterWindowMessage('newspopMessage'); //注册一个windows全局消息,这个相当于暗号
end;
procecure form1.wndProc(var msg:TMessage);
begin
//在这里处理这个消息就行了
showmessage(strpas(PChar(msg.lparam))); //这样写会报错的.但可以处理其它无参数的事情
end;
----------------------------------------------------------------------------------------------
二.第二种办法,发送一个WM_COPYDATA的消息.并且可以带一个TCopyDataStruct的结构类型参数.
1.发送消息方:
procedure TMainForm.CallAgent(msg: string);
var
HlAgent:HWND;
ds:TCopyDatastruct; //定义一个TCopyDatastruct结构体变量
begin
//AgentMsg := msg;
ds.cbData := (Length(msg)+1)*SizeOf(char); //结构体的第一个元素: 长度cbData
GetMem(ds.lpData,ds.cbData); //分配内存,结构体的第二个参数: 数据的指针lpDATA
StrCopy(ds.lpData,PChar(msg)); //复制值到结构指针 HlAgent :=FindWindow('TmsgpopMainCaller','调用者'); //查找目标窗体的Handle
if HlAgent <> then
begin
//ShowMessage('主' + IntToStr(Cardinal(@ds)));
SendMessage(HlAgent,WM_COPYDATA,,Cardinal(@ds)); //发送WM_COPYDATA消息,并带上参数 @ds
end;
FreeMem(ds.lpData); //释放数据内存
end;
2.接收方程序:
public
procedure MyMessage(var m:TWmCopyData);message WM_CopyData; //定义一个消息响应过程,并传入一个TWmCopyData的参数
...
procedure TmsgpopMainCaller.MyMessage(var m: TWmCopyData); //实现响应
var
msg:string;
begin
msg :=StrPas(m.CopyDataStruct^.lpData); //获取参数数据
ShowMessageForm := TShowMessageForm.Create(self,msg); //处理
end;
版权声明:本文为博主原创文章,未经博主允许不得转载。
Delphi 两个应用程序(进程)之间的通信的更多相关文章
- python全栈开发 * 进程之间的通信,进程之间数据共享 * 180726
进程之间的通信(IPC)队列和管道一.队列 基于管道实现 管道 + 锁 数据安全(一).队列 队列遵循先进先出原则(FIFO) 多用于维护秩序,买票,秒杀 队列的所有方法: put()(给队列里添加数 ...
- c# IPC实现本机进程之间的通信
IPC可以实现本地进程之间通信.这种用法不是太常见,常见的替代方案是使用wcf,remoting,web service,socket(tcp/pipe/...)等其他分布式部署方案来替代进程之间的通 ...
- Python并发编程03 /僵孤进程,孤儿进程、进程互斥锁,进程队列、进程之间的通信
Python并发编程03 /僵孤进程,孤儿进程.进程互斥锁,进程队列.进程之间的通信 目录 Python并发编程03 /僵孤进程,孤儿进程.进程互斥锁,进程队列.进程之间的通信 1. 僵尸进程/孤儿进 ...
- 进程之间的通信(multiprocess.Queue)
一.进程间通信 进程之间的数据是相互隔离的,例如 from multiprocessing import Process def task(): global n # 声明全局变量 n = 999 p ...
- day34——僵尸进程和孤儿进程、互斥锁、进程之间的通信
day34 僵尸进程和孤儿进程 基于unix环境(linux,macOS) 主进程需要等待子进程结束之后,主进程才结束 主进程时刻监测子进程的运行状态,当子进程结束之后,一段时间之内,将子进程进行回收 ...
- 《Python》进程之间的通信(IPC)、进程之间的数据共享、进程池
一.进程间通信---队列和管道(multiprocess.Queue.multiprocess.Pipe) 进程间通信:IPC(inter-Process Communication) 1.队列 概念 ...
- python进程之间的通信——Queue
我们知道进程之间的数据是互不影响的,但有时我们需要在进程之间通信,那怎么办呢? 认识Queue 可以使用multiprocessing模块的Queue实现多进程之间的数据传递,Queue本身是一个消息 ...
- python网络编程中互斥锁与进程之间的通信
一.互斥锁 进程之间数据隔离,但是共享一套文件系统,因而可以通过文件来实现进程直接的通信,但问题是必须自己加锁处理. 注意:加锁的目的是为了保证多个进程修改同一块数据时,同一时间只能有一个修改,即串行 ...
- Linux_进程之间的通信
一.进程间的通信 1️⃣:进程间通信(IPC:Inter Process Communication) 2️⃣:进程之间通信方式: 同一主机 共享内存 信号:Signal 不同主机 rpc:remot ...
随机推荐
- HTML笔记1
HTML和css技术 HTML和css技术 html的介绍 网页的基本结构 今天学习的标签 标签属性 浏览器 DW快捷键 相对路径和绝对路径 HTML当中的颜色模式 网页当中常用的图片格式 html的 ...
- Read / Write Excel file in Java using Apache POI
Read / Write Excel file in Java using Apache POI 2014-04-18 BY DINESH LEAVE A COMMENT About a year o ...
- http错误码大全
响应码由三位十进制数字组成,它们出现在由HTTP服务器发送的响应的第一行.响应码分五种类型,由它们的第一位数字表示:1.1xx:信息,请求收到,继续处理2.2xx:成功,行为被成功地接受.理解和采纳3 ...
- oracle优化辅助SQL语句
--查询正在执行的SQL语句 select a.program, b.spid, c.sql_text,c.SQL_FULLTEXT,c.SQL_ID from v$session a, v$proc ...
- log4net保存到数据库系列四、完整代码配置log4net
园子里面有很多关于log4net保存到数据库的帖子,但是要动手操作还是比较不易,从头开始学习log4net数据库日志一.WebConfig中配置log4net 一.WebConfig中配置log4ne ...
- Activity生命周期-Android
Activity常见的三种生命周期: 1.完整生命周期 oncreate-->onstart-->onresume-->onpause-->onstop-->ondest ...
- python:浅析python 中__name__ = '__main__' 的作用
有句话经典的概括了这段代码的意义: “Make a script both importable and executable” 意思就是说让你写的脚本模块既可以导入到别的模块中用,另外该模块自己也可 ...
- 15个最新加速 Web 开发的框架和工具
我们为开发人员挑选了15个最新的 Web 开发框架,你肯定尝试一下这些新鲜的框架,有的可能略微复杂,有的提供了很多的配置选项,也有一些窗口小部件和界面交互的选择.他们将帮助你创建更优秀的网站,提供给用 ...
- 转帖:使用TortoiseGit处理代码冲突
原址:http://www.cnblogs.com/jason-beijing/p/5718190.html 场景一 user0 有新提交 user1 没有pull -> 写新代码 -&g ...
- 配置drbd高可用集群
前期准备: 同步时间 (两个节点) 节点一(172.16.21.6) [root@stu21 heartbeat2]# ntpdate 172.16.0.1 31 Dec 20:59:25 ntpda ...