zoukankan      html  css  js  c++  java
  • 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;

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

  • 相关阅读:
    Hibernate实体对象三种状态
    tar命令: 对某目录文件打tar包时,排除指定的目录或文件
    开发项目时,提示 找不到类的解决方法,以及如何设置编译源目录
    当html中存在url中如: onclick="toView('参数1')", 参数1是特别字符,如&asop;&quot;' "等时,浏览器解析时会报错。解决方法如文中描述
    oracle表分区心得
    启动系统相关服务笔记整理
    使用PSD设计网页页面
    JAR、WAR、EAR 区别
    设置 MyEclipse 默认打开文件方式
    前端性能优化
  • 原文地址:https://www.cnblogs.com/xieyunc/p/4839584.html
Copyright © 2011-2022 走看看