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

  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 <> 0 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/////////////////////////////////////////////////////////////////////
  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. 发送消息方:

  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. 接收消息方:
  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. 发送消息方:

  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 <> 0 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.
  71.  
     

2.接收方程序:
  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.
  58.