两个应用程序之间的通信实际上是两个进程之间的通信。由于本人知识有限,决定应用消息来实现。需要用到的知识:
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//////////////////////////////////////////
1 unit Unit1; 2 3 interface 4 5 uses 6 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 7 Dialogs, StdCtrls, Buttons; 8 9 type 10 TForm1 = class(TForm) 11 Button2: TButton; 12 Button3: TButton; 13 BitBtn1: TBitBtn; 14 procedure Button2Click(Sender: TObject); 15 procedure FormShow(Sender: TObject); 16 procedure BitBtn1Click(Sender: TObject); 17 private 18 { Private declarations } 19 20 I: Integer; 21 22 public 23 { Public declarations } 24 25 end; 26 27 var 28 Form1: TForm1; 29 30 implementation 31 32 33 {$R *.dfm} 34 35 { TForm1 } 36 procedure TForm1.FormShow(Sender: TObject); 37 begin 38 I:= RegisterWindowMessage('MyMessage'); 39 end; 40 procedure TForm1.BitBtn1Click(Sender: TObject); 41 var 42 h1: HWND; 43 begin 44 h1:= FindWindow(nil,'Form2'); 45 PostMessage(h1,I,0,1); 46 end;
///////////////////////////程序2//////////////////////////////////////////////
1 unit Unit1; 2 3 interface 4 5 uses 6 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 7 Dialogs, StdCtrls, AppEvnts, Buttons,QExtCtrls, ExtCtrls; 8 const 9 My_MousL = WM_USER+100; 10 type 11 TForm2 = class(TForm) 12 Button1: TButton; 13 ApplicationEvents1: TApplicationEvents; 14 BitBtn1: TBitBtn; 15 BtnCreatePanel: TBitBtn; 16 BitBtn2: TBitBtn; 17 BitBtn3: TBitBtn; 18 Panel1: TPanel; 19 Button2: TButton; 20 procedure FormShow(Sender: TObject); 21 private 22 { Private declarations } 23 J: Integer; 24 public 25 { Public declarations } 26 procedure WndProc(var Message: TMessage); override; 27 end; 28 29 var 30 Form2: TForm2; 31 32 implementation 33 34 {$R *.dfm} 35 36 procedure TForm1.FormShow(Sender: TObject); 37 begin 38 J:= RegisterWindowMessage('MyMessage'); 39 end; 40 41 procedure TForm1.WndProc(var Message: TMessage); 42 begin 43 if Message.Msg = J then 44 ShowMessage('得到消息') 45 else
46 inherited; 47 end;
至此,应用程序间通信就完成了,这里需要注意:FindWindow一定要找到你想要得到消息的应用程序,也就是说如果用FindWindow(nil,'Form2'),你一定得保证窗体的caption:= Form2的程序是唯一的。
---------------------------------------------------------------------------------------------------------------------------------
另附上一个Delphi进程间通信的两种方法:
WIN下面进程间通信的最常用办法就是消息了,下面记录两种消息通信的方式:
--------------------------------------------------------------------------------------------
一.第一种办法,利用注册Windows全局的消息.并覆盖wndProc过程来监听消息处理.
1. 发送消息方:
1 private 2 strWM:Cardinal; //定义一个局部变量 3 //...
4 proccedure Form1.Create(sender:TObject); 5 begin 6 strWM:= RegisterWindowMessage('newspopMessage'); //注册一个windows全局消息,通过这个消息与其它进程通信 7 end; 8 9 10 procedure Form1.Button1Click1(Sender:TObject); 11 var 12 h:Cardinal; 13 begin 14 //通信的步骤得先找到要通信的信息窗口Handle 15 h:=findWindow('目标进程窗口类名','窗口Caption'); 16 //发送消息消息类型为自定义的strWM 17 SendMessage(h,strWM,0,0); //这里同样可以带参数:wParam,lParam。但我传一个PChar,读取的时候总报错,不知道为啥 18 end;
2.接收消息方:
1 private 2 strWM:Cardinal; //定义一个局部变量 3 procedure wndProc(var msg:Tmessage);override; //覆盖这个方法,可以监听所有的Windows消息回调函数 4 ... 5 proccedure Form1.Create(sender:TObject); 6 begin 7 strWM:= RegisterWindowMessage('newspopMessage'); //注册一个windows全局消息,这个相当于暗号 8 end; 9 procecure form1.wndProc(var msg:TMessage); 10 begin 11 //在这里处理这个消息就行了 12 showmessage(strpas(PChar(msg.lparam))); //这样写会报错的.但可以处理其它无参数的事情 13 end;
----------------------------------------------------------------------------------------------
二.第二种办法,发送一个WM_COPYDATA的消息.并且可以带一个TCopyDataStruct的结构类型参数.
1.发送消息方:
1 procedure TMainForm.CallAgent(msg: string); 2 var 3 HlAgent:HWND; 4 ds:TCopyDatastruct; //定义一个TCopyDatastruct结构体变量 5 begin 6 //AgentMsg := msg; 7 ds.cbData := (Length(msg)+1)*SizeOf(char); //结构体的第一个元素: 长度cbData 8 GetMem(ds.lpData,ds.cbData); //分配内存,结构体的第二个参数: 数据的指针lpDATA 9 StrCopy(ds.lpData,PChar(msg)); //复制值到结构指针 10 11 HlAgent :=FindWindow('TmsgpopMainCaller','调用者'); //查找目标窗体的Handle 12 if HlAgent <> 0 then 13 begin 14 //ShowMessage('主' + IntToStr(Cardinal(@ds))); 15 SendMessage(HlAgent,WM_COPYDATA,0,Cardinal(@ds)); //发送WM_COPYDATA消息,并带上参数 @ds 16 end; 17 FreeMem(ds.lpData); //释放数据内存 18 end;
2.接收方程序:
1 public 2 procedure MyMessage(var m:TWmCopyData);message WM_CopyData; //定义一个消息响应过程,并传入一个TWmCopyData的参数 3 ... 4 procedure TmsgpopMainCaller.MyMessage(var m: TWmCopyData); //实现响应 5 var 6 msg:string; 7 begin 8 msg :=StrPas(m.CopyDataStruct^.lpData); //获取参数数据 9 ShowMessageForm := TShowMessageForm.Create(self,msg); //处理 10 end;
版权声明:本文为博主原创文章,未经博主允许不得转载。