https://blog.csdn.net/xieyunc/article/details/48738423

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

[delphi] view plain copy
 
  1. unit Unit1;  
  2.   
  3. interface  
  4.   
  5. uses  
  6.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,  
  7.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons;  
  8.   
  9. type  
  10.   TForm1 = class(TForm)  
  11.     BitBtn1: TBitBtn;  
  12.     BitBtn2: TBitBtn;  
  13.     Edit1: TEdit;  
  14.     procedure FormShow(Sender: TObject);  
  15.     procedure BitBtn1Click(Sender: TObject);  
  16.     procedure BitBtn2Click(Sender: TObject);  
  17.   private  
  18.     { Private declarations }  
  19.     strWM:Cardinal;  
  20.     procedure CallAgent(msg:string);  
  21.   public  
  22.     { Public declarations }  
  23.   end;  
  24.   
  25. var  
  26.   Form1: TForm1;  
  27.   
  28. implementation  
  29.   
  30. {$R *.dfm}  
  31.   
  32. procedure TForm1.BitBtn1Click(Sender: TObject);  
  33. var  
  34.   h1: HWND;  
  35. begin  
  36.   h1:= FindWindow(nil,'接收消息窗口');  //发送消息方法一  
  37.   PostMessage(h1,strWM,0,0);  
  38. end;  
  39.   
  40. procedure TForm1.BitBtn2Click(Sender: TObject);  
  41. begin  
  42.   CallAgent(Edit1.Text);   //发送消息方法二  
  43. end;  
  44.   
  45. procedure TForm1.CallAgent(msg: string);  
  46. var  
  47.   HlAgent:HWND;  
  48.   ds:TCopyDatastruct;    //定义一个TCopyDatastruct结构体变量  
  49. begin  
  50.   ds.cbData := (Length(Msg)+1)*SizeOf(Char); //结构体的第一个元素: 长度cbData  
  51.   GetMem(ds.lpData,ds.cbData); //分配内存,结构体的第二个参数:  数据的指针lpDATA  
  52.   try  
  53.     StrCopy(ds.lpData,PChar(Msg)); //复制值到结构指针  
  54.     HlAgent :=FindWindow('TForm2','接收消息窗口');  //查找目标窗体的Handle  
  55.     if  HlAgent <> then  
  56.     begin  
  57.       //ShowMessage('主' + IntToStr(Cardinal(@ds)));  
  58.       SendMessage(HlAgent,WM_COPYDATA,0,Cardinal(@ds));   //发送WM_COPYDATA消息,并带上参数 @ds  
  59.     end;  
  60.   finally  
  61.     FreeMem(ds.lpData); //释放数据内存  
  62.   end;  
  63. end;  
  64.   
  65. procedure TForm1.FormShow(Sender: TObject);  
  66. begin  
  67.   strWM:= RegisterWindowMessage('UserDefMessage');  
  68. end;  
  69.   
  70. end.  
////////////////////////////////////////////////////////////////////程序2/////////////////////////////////////////////////////////////////////
[delphi] view plain copy
 
  1. unit Unit2;  
  2.   
  3. interface  
  4.   
  5. uses  
  6.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,  
  7.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;  
  8.   
  9. //const  
  10. //  My_MousL = WM_USER+100;  
  11. type  
  12.   TForm2 = class(TForm)  
  13.     Edit1: TEdit;  
  14.     Label1: TLabel;  
  15.     procedure FormShow(Sender: TObject);  
  16.   private  
  17.     { Private declarations }  
  18.     strWM:Cardinal;  
  19.   public  
  20.     { Public declarations }  
  21.     procedure WndProc(var m:TMessage);override;  
  22.     procedure MyMessage(var m:TWmCopyData);message WM_CopyData;   //定义一个消息响应过程,并传入一个TWmCopyData的参数  
  23.   end;  
  24.   
  25. var  
  26.   Form2: TForm2;  
  27.   
  28. implementation  
  29.   
  30. {$R *.dfm}  
  31.   
  32. { TForm2 }  
  33.   
  34. procedure TForm2.FormShow(Sender: TObject);  
  35. begin  
  36.   strWM := RegisterWindowMessage('UserDefMessage');  
  37. end;  
  38.   
  39. procedure TForm2.MyMessage(var m: TWmCopyData);  
  40. var  
  41.   msg:String;  
  42.   pStr:PChar;  
  43. begin  
  44.   pStr := m.CopyDataStruct^.lpData;  
  45.   msg := system.SysUtils.StrPas(pStr);    //获取参数数据  
  46.   Edit1.Text := msg;  //显示或者作其他处理  
  47. end;  
  48.   
  49. procedure TForm2.WndProc(var m: TMessage);  
  50. begin  
  51.   if m.Msg = strWM then  
  52.     Edit1.Text := Format('得到方式一发送的消息:%d',[m.Msg])  
  53.   else  
  54.     inherited;  
  55. end;  
  56.   
  57. end.  

至此,应用程序间通信就完成了,这里需要注意:FindWindow一定要找到你想要得到消息的应用程序,也就是说如果用FindWindow(nil,'Form2'),你一定得保证窗体的caption:= Form2的程序是唯一的。

---------------------------------------------------------------------------------------------------------------------------------

另:delphi 进程间通信的两种方法

WIN下面进程间通信的最常用办法就是消息了.

下面记录两种消息通信的方式:
 --------------------------------------------------------------------------------------------
一.第一种办法,利用注册Windows全局的消息.并覆盖wndProc过程来监听消息处理.
1. 发送消息方:

[delphi] view plain copy
 
  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.      
  19. end;  

2. 接收消息方:
[delphi] view plain copy
 
  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(meg.lparam))); //这样写会报错的.但可以处理其它无参数的事情  
  13. end;  

----------------------------------------------------------------------------------------------
二.第二种办法,发送一个WM_COPYDATA的消息.并且可以带一个TCopyDataStruct的结构类型参数.

 

 1. 发送消息方:

[delphi] view plain copy
 
  1. unit Unit1;  
  2.   
  3. interface  
  4.   
  5. uses  
  6.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,  
  7.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons;  
  8.   
  9. type  
  10.   TForm1 = class(TForm)  
  11.     BitBtn1: TBitBtn;  
  12.     BitBtn2: TBitBtn;  
  13.     Edit1: TEdit;  
  14.     procedure FormShow(Sender: TObject);  
  15.     procedure BitBtn1Click(Sender: TObject);  
  16.     procedure BitBtn2Click(Sender: TObject);  
  17.   private  
  18.     { Private declarations }  
  19.     strWM:Cardinal;  
  20.     procedure CallAgent(msg:string);  
  21.   public  
  22.     { Public declarations }  
  23.   end;  
  24.   
  25. var  
  26.   Form1: TForm1;  
  27.   
  28. implementation  
  29.   
  30. {$R *.dfm}  
  31.   
  32. procedure TForm1.BitBtn1Click(Sender: TObject);  
  33. var  
  34.   h1: HWND;  
  35. begin  
  36.   h1:= FindWindow(nil,'接收消息窗口');  //发送消息方法一  
  37.   PostMessage(h1,strWM,0,0);  
  38. end;  
  39.   
  40. procedure TForm1.BitBtn2Click(Sender: TObject);  
  41. begin  
  42.   CallAgent(Edit1.Text);   //发送消息方法二  
  43. end;  
  44.   
  45. procedure TForm1.CallAgent(msg: string);  
  46. var  
  47.   HlAgent:HWND;  
  48.   ds:TCopyDatastruct;    //定义一个TCopyDatastruct结构体变量  
  49. begin  
  50.   ds.cbData := (Length(Msg)+1)*SizeOf(Char); //结构体的第一个元素: 长度cbData  
  51.   GetMem(ds.lpData,ds.cbData); //分配内存,结构体的第二个参数:  数据的指针lpDATA  
  52.   try  
  53.     StrCopy(ds.lpData,PChar(Msg)); //复制值到结构指针  
  54.     HlAgent :=FindWindow('TForm2','接收消息窗口');  //查找目标窗体的Handle  
  55.     if  HlAgent <> then  
  56.     begin  
  57.       //ShowMessage('主' + IntToStr(Cardinal(@ds)));  
  58.       SendMessage(HlAgent,WM_COPYDATA,0,Cardinal(@ds));   //发送WM_COPYDATA消息,并带上参数 @ds  
  59.     end;  
  60.   finally  
  61.     FreeMem(ds.lpData); //释放数据内存  
  62.   end;  
  63. end;  
  64.   
  65. procedure TForm1.FormShow(Sender: TObject);  
  66. begin  
  67.   strWM:= RegisterWindowMessage('UserDefMessage');  
  68. end;  
  69.   
  70. end.  

2.接收方程序:
[delphi] view plain copy
 
  1. unit Unit2;  
  2.   
  3. interface  
  4.   
  5. uses  
  6.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,  
  7.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;  
  8.   
  9. //const  
  10. //  My_MousL = WM_USER+100;  
  11. type  
  12.   TForm2 = class(TForm)  
  13.     Edit1: TEdit;  
  14.     Label1: TLabel;  
  15.     procedure FormShow(Sender: TObject);  
  16.   private  
  17.     { Private declarations }  
  18.     strWM:Cardinal;  
  19.   public  
  20.     { Public declarations }  
  21.     procedure WndProc(var m:TMessage);override;  
  22.     procedure MyMessage(var m:TWmCopyData);message WM_CopyData;   //定义一个消息响应过程,并传入一个TWmCopyData的参数  
  23.   end;  
  24.   
  25. var  
  26.   Form2: TForm2;  
  27.   
  28. implementation  
  29.   
  30. {$R *.dfm}  
  31.   
  32. { TForm2 }  
  33.   
  34. procedure TForm2.FormShow(Sender: TObject);  
  35. begin  
  36.   strWM := RegisterWindowMessage('UserDefMessage');  
  37. end;  
  38.   
  39. procedure TForm2.MyMessage(var m: TWmCopyData);  
  40. var  
  41.   msg:String;  
  42.   pStr:PChar;  
  43. begin  
  44.   pStr := m.CopyDataStruct^.lpData;  
  45.   msg := system.SysUtils.StrPas(pStr);    //获取参数数据  
  46.   Edit1.Text := msg;  //显示或者作其他处理  
  47. end;  
  48.   
  49. procedure TForm2.WndProc(var m: TMessage);  
  50. begin  
  51.   if m.Msg = strWM then  
  52.     Edit1.Text := Format('得到方式一发送的消息:%d',[m.Msg])  
  53.   else  
  54.     inherited;  
  55. end;  
  56.