zoukankan      html  css  js  c++  java
  • Delphi 两个应用程序(进程)之间的通信

    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.  
    delphi lazarus opengl 网页操作自动化, 图像分析破解,游戏开发
  • 相关阅读:
    Python安装的库列表导出到文件和批量安装库文件
    Selenium之浏览器驱动下载和配置使用
    测试面试计算题--python
    软件质量模型
    用例要素和设计方法
    python的层级
    day 14:深浅copy,数据结构 ,函数,set集合,变量作用域、返回值
    day 8:open文件和with的使用
    day 1:计算机发展史和组成部分
    day 2:计算机的基础知识,编程语言分类
  • 原文地址:https://www.cnblogs.com/delphi-xe5/p/9499542.html
Copyright © 2011-2022 走看看