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 ...
随机推荐
- iOS 定位系统 知识
最近在做考勤定位系统 总结一些定位系统的知识. 后期会出一份算法主要攻克地球坐标和火星坐标转换的 1.关于百度的火星坐标定位策略 地图SDK/定位SDK的定位策略: WIFI + 基站 +GPS 三者 ...
- OC 实现的几个排序算法
和在VC++6.0里相比 在OC里面实现 不算困难 可是我用惯了C/C++呢 快速排序,冒泡排序,直接插入排序和折半插入排序,希尔排序,堆排序,直接选择排序 /******************** ...
- request.getHeader("Referer")理解【转载】
request.getHeader("Referer")用于获取来源页地址,但有时却为空值,这是怎么回事.原因如下: getHeader("Referer")要 ...
- Oracle基础 存储过程和游标
一.带游标的存储过程 游标作为参数有两种类型: 1.声明系统游标类型 SYS_REFCURSOR 1)游标作为存储过程的参数: --带游标的存储过程 CREATE OR REPLACE PROCEDU ...
- ASP.NET入门(1) - 建立和开发ASP.NET 5 项目
原文转载自:http://www.cnblogs.com/zergcom/p/4493358.html 建立项目 首先,目前只有VS 2015支持开发最新的ASP.NET 5 程序,所以我们首先需要下 ...
- 控制HTML元素的显示与隐藏——display和visibility
有些时候我们需要根据某些条件来控制Web页面中的HTML元素显示还是隐藏,可以通过display或visibility来实现.通过下面的例子了解display和visibility的区别,简单的例子代 ...
- HTML标签大全
HTML标签解释大全 一.HTML标记 标签:!DOCTYPE 说明:指定了 HTML 文档遵循的文档类型定义(DTD). 标签:a 说明:标明超链接的起始或目的位置. 标签:acronym 说明:标 ...
- 跟我学习dubbo-简介(1)
1. Dubbo是什么? Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案.简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需 ...
- django 学习-16 Django会话Cookie
1.django.admin.py startproject cs3 cd cs3 django.admin.py startapp blog 2. vim urls.py url ...
- 快速调试的VS设置
这是2013年“惹”的“祸”. 自己一直使用着VS2012,以前的调试是相当方便的,或许是之前的同事设置好的VS,我一直不会去注意我停掉调试(停掉调试的意思是:将状态1正在调试的状态,变更为状态2待启 ...