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

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons;

type
  TForm1 = class(TForm)
    BitBtn1: TBitBtn;
    BitBtn2: TBitBtn;
    Edit1: TEdit;
    procedure FormShow(Sender: TObject);
    procedure BitBtn1Click(Sender: TObject);
    procedure BitBtn2Click(Sender: TObject);
  private
    { Private declarations }
    strWM:Cardinal;
    procedure CallAgent(msg:string);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.BitBtn1Click(Sender: TObject);
var
  h1: HWND;
begin
  h1:= FindWindow(nil,'接收消息窗口');  //发送消息方法一
  PostMessage(h1,strWM,0,0);
end;

procedure TForm1.BitBtn2Click(Sender: TObject);
begin
  CallAgent(Edit1.Text);   //发送消息方法二
end;

procedure TForm1.CallAgent(msg: string);
var
  HlAgent:HWND;
  ds:TCopyDatastruct;    //定义一个TCopyDatastruct结构体变量
begin
  ds.cbData := (Length(Msg)+1)*SizeOf(Char); //结构体的第一个元素: 长度cbData
  GetMem(ds.lpData,ds.cbData); //分配内存,结构体的第二个参数:  数据的指针lpDATA
  try
    StrCopy(ds.lpData,PChar(Msg)); //复制值到结构指针
    HlAgent :=FindWindow('TForm2','接收消息窗口');  //查找目标窗体的Handle
    if  HlAgent <> 0 then
    begin
      //ShowMessage('主' + IntToStr(Cardinal(@ds)));
      SendMessage(HlAgent,WM_COPYDATA,0,Cardinal(@ds));   //发送WM_COPYDATA消息,并带上参数 @ds
    end;
  finally
    FreeMem(ds.lpData); //释放数据内存
  end;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  strWM:= RegisterWindowMessage('UserDefMessage');
end;

end.
程序2/
unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

//const
//  My_MousL = WM_USER+100;
type
  TForm2 = class(TForm)
    Edit1: TEdit;
    Label1: TLabel;
    procedure FormShow(Sender: TObject);
  private
    { Private declarations }
    strWM:Cardinal;
  public
    { Public declarations }
    procedure WndProc(var m:TMessage);override;
    procedure MyMessage(var m:TWmCopyData);message WM_CopyData;   //定义一个消息响应过程,并传入一个TWmCopyData的参数
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

{ TForm2 }

procedure TForm2.FormShow(Sender: TObject);
begin
  strWM := RegisterWindowMessage('UserDefMessage');
end;

procedure TForm2.MyMessage(var m: TWmCopyData);
var
  msg:String;
  pStr:PChar;
begin
  pStr := m.CopyDataStruct^.lpData;
  msg := system.SysUtils.StrPas(pStr);    //获取参数数据
  Edit1.Text := msg;  //显示或者作其他处理
end;

procedure TForm2.WndProc(var m: TMessage);
begin
  if m.Msg = strWM then
    Edit1.Text := Format('得到方式一发送的消息:%d',[m.Msg])
  else
    inherited;
end;

end.

至此,应用程序间通信就完成了,这里需要注意:FindWindow一定要找到你想要得到消息的应用程序,也就是说如果用FindWindow(nil,'Form2'),你一定得保证窗体的caption:= Form2的程序是唯一的。

---------------------------------------------------------------------------------------------------------------------------------

另:delphi 进程间通信的两种方法

WIN下面进程间通信的最常用办法就是消息了.

下面记录两种消息通信的方式:
 --------------------------------------------------------------------------------------------
一.第一种办法,利用注册Windows全局的消息.并覆盖wndProc过程来监听消息处理.
1. 发送消息方:

    private
            strWM:Cardinal;  //定义一个局部变量
    ...   
    proccedure Form1.Create(sender:TObject);
    begin
        strWM:= RegisterWindowMessage('newspopMessage'); //注册一个windows全局消息,通过这个消息与其它进程通信
    end;

    ...
    procedure Form1.Button1Click1(Sender:TObject);
    var
        h:Cardinal;
    begin
        //通信的步骤得先找到要通信的信息窗口Handle
        h:=findWindow('目标进程窗口类名','窗口Caption');
        //发送消息消息类型为自定义的strWM
        SendMessage(h,strWM,0,0);  //这里同样可以带参数.wParam,lParam.但我传一个PChar,读取的时候总报错.不知道为啥
       
    end;

2. 接收消息方:
        private
            strWM:Cardinal;  //定义一个局部变量
            procedure wndProc(var msg:Tmessage);override; //覆盖这个方法,可以监听所有的Windows消息回调函数  
         ...   
        proccedure Form1.Create(sender:TObject);
        begin
            strWM:= RegisterWindowMessage('newspopMessage'); //注册一个windows全局消息,这个相当于暗号
        end;
        procecure form1.wndProc(var msg:TMessage);
        begin
            //在这里处理这个消息就行了
            showmessage(strpas(PChar(meg.lparam))); //这样写会报错的.但可以处理其它无参数的事情
        end;

----------------------------------------------------------------------------------------------
二.第二种办法,发送一个WM_COPYDATA的消息.并且可以带一个TCopyDataStruct的结构类型参数.

 1. 发送消息方:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons;

type
  TForm1 = class(TForm)
    BitBtn1: TBitBtn;
    BitBtn2: TBitBtn;
    Edit1: TEdit;
    procedure FormShow(Sender: TObject);
    procedure BitBtn1Click(Sender: TObject);
    procedure BitBtn2Click(Sender: TObject);
  private
    { Private declarations }
    strWM:Cardinal;
    procedure CallAgent(msg:string);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.BitBtn1Click(Sender: TObject);
var
  h1: HWND;
begin
  h1:= FindWindow(nil,'接收消息窗口');  //发送消息方法一
  PostMessage(h1,strWM,0,0);
end;

procedure TForm1.BitBtn2Click(Sender: TObject);
begin
  CallAgent(Edit1.Text);   //发送消息方法二
end;

procedure TForm1.CallAgent(msg: string);
var
  HlAgent:HWND;
  ds:TCopyDatastruct;    //定义一个TCopyDatastruct结构体变量
begin
  ds.cbData := (Length(Msg)+1)*SizeOf(Char); //结构体的第一个元素: 长度cbData
  GetMem(ds.lpData,ds.cbData); //分配内存,结构体的第二个参数:  数据的指针lpDATA
  try
    StrCopy(ds.lpData,PChar(Msg)); //复制值到结构指针
    HlAgent :=FindWindow('TForm2','接收消息窗口');  //查找目标窗体的Handle
    if  HlAgent <> 0 then
    begin
      //ShowMessage('主' + IntToStr(Cardinal(@ds)));
      SendMessage(HlAgent,WM_COPYDATA,0,Cardinal(@ds));   //发送WM_COPYDATA消息,并带上参数 @ds
    end;
  finally
    FreeMem(ds.lpData); //释放数据内存
  end;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  strWM:= RegisterWindowMessage('UserDefMessage');
end;

end.


2.接收方程序:
unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

//const
//  My_MousL = WM_USER+100;
type
  TForm2 = class(TForm)
    Edit1: TEdit;
    Label1: TLabel;
    procedure FormShow(Sender: TObject);
  private
    { Private declarations }
    strWM:Cardinal;
  public
    { Public declarations }
    procedure WndProc(var m:TMessage);override;
    procedure MyMessage(var m:TWmCopyData);message WM_CopyData;   //定义一个消息响应过程,并传入一个TWmCopyData的参数
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

{ TForm2 }

procedure TForm2.FormShow(Sender: TObject);
begin
  strWM := RegisterWindowMessage('UserDefMessage');
end;

procedure TForm2.MyMessage(var m: TWmCopyData);
var
  msg:String;
  pStr:PChar;
begin
  pStr := m.CopyDataStruct^.lpData;
  msg := system.SysUtils.StrPas(pStr);    //获取参数数据
  Edit1.Text := msg;  //显示或者作其他处理
end;

procedure TForm2.WndProc(var m: TMessage);
begin
  if m.Msg = strWM then
    Edit1.Text := Format('得到方式一发送的消息:%d',[m.Msg])
  else
    inherited;
end;

end.



 

转载于:https://www.cnblogs.com/xieyunc/p/9126532.html

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Creating Windows CreateMDIWindow CreateWindow CreateWindowEx RegisterClass RegisterClassEx UnregisterClass Message Processing BroadcastSystemMessage CallNextHookEx CallWindowProc DefFrameProc DefMDIChildProc DefWindowProc DispatchMessage GetMessage GetMessageExtraInfo GetMessagePos GetMessageTime GetQueueStatus InSendMessage PeekMessage PostMessage PostQuitMessage PostThreadMessage RegisterWindowMessage ReplyMessage SendMessage SendMessageCallback SendMessageTimeout SendNotifyMessage SetMessageExtraInfo SetWindowsHookEx TranslateMessage UnhookWindowsHookEx WaitMessage Window Information AnyPopup ChildWindowFromPoint ChildWindowFromPointEx EnableWindow EnumChildWindows EnumPropsEx EnumThreadWindows EnumWindows FindWindow FindWindowEx GetClassInfoEx GetClassLong GetClassName GetClientRect GetDesktopWindow GetFocus GetForegroundWindow GetNextWindow GetParent GetProp GetTopWindow GetWindow GetWindowLong GetWindowRect GetWindowText GetWindowTextLength IsChild IsIconic IsWindow IsWindowEnabled IsWindowUnicode IsWindowVisible IsZoomed RemoveProp SetActiveWindow SetClassLong SetFocus SetForegroundWindow SetParent SetProp SetWindowLong SetWindowText WindowFromPoint Processes and Threads CreateEvent CreateMutex CreateProcess CreateSemaphore CreateThread DeleteCriticalSection DuplicateHandle EnterCriticalSection ExitProcess ExitThread GetCurrentProcess GetCurrentProcessId GetCurrentThread GetCurrentThreadId GetExitCodeProcess GetExitCodeThread GetPriorityClass GetThreadPriority GetWindowThreadProcessId InitializeCriticalSection InterlockedDecrement InterlockedExchange InterlockedIncrement LeaveCriticalSection OpenEvent OpenMutex OpenProcess OpenSemaphore PulseEvent ReleaseMutex ReleaseSemaphore ResetEvent ResumeThread SetEvent SetPr

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值