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 网页操作自动化, 图像分析破解,游戏开发
  • 相关阅读:
    PATA 1071 Speech Patterns.
    PATA 1027 Colors In Mars
    PATB 1038. 统计同成绩学生(20)
    1036. 跟奥巴马一起编程(15)
    PATA 1036. Boys vs Girls (25)
    PATA 1006. Sign In and Sign Out (25)
    读取web工程目录之外的图片并显示
    DOS命令
    java连接oracle集群
    servlet
  • 原文地址:https://www.cnblogs.com/delphi-xe5/p/9499542.html
Copyright © 2011-2022 走看看