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//////////////////////////////////////////

 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;

版权声明:本文为博主原创文章,未经博主允许不得转载。