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

    [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.   
  • 相关阅读:
    如何锻炼出最牛程序员的编码套路
    如果仔细观察他们,你会发现他们时时都在锻炼
    单纯地每天埋头于工作并不能算是真正意义上的锻炼
    把全世界的人们都联系在一起,提升人们的社交参与度
    HTML5十五大新特性
    html5的八大特性
    【贪心】【二维偏序】【权值分块】bzoj1691 [Usaco2007 Dec]挑剔的美食家
    【分块】【链表】bzoj2738 矩阵乘法
    【分块】bzoj3343 教主的魔法
    【线段树】bzoj3747 [POI2015]Kinoman
  • 原文地址:https://www.cnblogs.com/westsoft/p/9007676.html
Copyright © 2011-2022 走看看