WPF 进程间通信

WPF应用程序使用SendMessage实现进程间通信
1.函数定义

       使用WPF框架的C#窗体应用程序可以使用SendMessage方法实现进程间通信,SendMessage属于Windows API宏,可以将指定的消息发送到一个或多个窗口,直到窗口程序处理完消息再返回,和PostMessage方法不同,PostMessage是将一个消息寄送到一个线程的消息队列后就立即返回。

2.函数原型

       SendMessage的函数原型为:

       LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam)

       参数定义为:

              hWnd:其窗口程序将接收消息的窗口的句柄。如果此参数为HWND_BROADCAST,则消息将被发送到系统中所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口和弹出式窗口,但消息不被发送到子窗口。

              Msg:指定被发送的消息。

             wParam:指定附加的消息特定信息。

             IParam:指定附加的消息特定信息。

             返回值:返回值指定消息处理的结果,依赖于所发送的消息。

3.可能需要的引用

using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
// 导出SendMessage函数
[DllImport("User32.dll",EntryPoint = "SendMessage")]
private static extern intSendMessage(IntPtr hWnd, int Msg, IntPtrwParam, ref COPYDATASTRUCTlParam);
// 导出FindWindow函数,用于找到目标窗口所在进程
[DllImport("User32.dll",EntryPoint = "FindWindow")]
private static extern intFindWindow(string lpClassName, string lpWindowName);

4.自定义消息结构体

使用SendMessage进行进程间通信时,可以发送具有自定义结构体的消息,从而实现更多的通信功能,例如操纵程序的运行,自定义结构体的示例代码如下:

const int WM_COPYDATA= 0x004A; // 固定数值,不可更改
public struct COPYDATASTRUCT
{
public IntPtr dwData; // 任意值
public int cbData;    // 指定lpData内存区域的字节数
[MarshalAs(UnmanagedType.LPStr)]
public string lpData; // 发送给目标窗口所在进程的数据
}

        上述自定义结构体可以将字符串发送给目标进程。

5.发送消息

        发送消息的程序先通过枚举进程获得目标进程句柄,然后将消息封装进自定义结构体并发送给目标进程,示例代码如下:

// 待发送消息

string s = "start";

// 枚举进程
Process[] procs = Process.GetProcesses();
foreach (Process p in procs)
{  
   if(p.ProcessName.Equals("Demo"))
   {
     // 获取目标进程句柄

     IntPtr hWnd = p.MainWindowHandle;

     // 封装消息

     byte[] sarr = System.Text.Encoding.Default.GetBytes(s);

     int len = sarr.Length;

     COPYDATASTRUCT cds2;

     cds2.dwData = (IntPtr)0;

     cds2.cbData = len + 1;

     cds2.lpData = s;

     // 发送消息

     SendMessage(hWnd, WM_COPYDATA, IntPtr.Zero, refcds2);
    }

}

}

6.接收消息

        接收消息的程序需要在MainWindow.xaml.cs文件中重写OnSourceInitialized函数,设置钩子,用于截获消息函数,示例代码如下:

protected override void OnSourceInitialized(EventArgse)
{
    base.OnSourceInitialized(e);
    HwndSourcehwndSource = PresentationSource.FromVisual(this) as HwndSource;
    if(hwndSource != null)
    {
       IntPtrhandle = hwndSource.Handle;
       hwndSource.AddHook(new HwndSourceHook(WndProc));
   }
}

        用于接收消息并执行自定义行为的消息函数示例代码如下:

IntPtr WndProc(IntPtrhwnd, int msg, IntPtrwParam, IntPtr lParam, ref bool handled)
{
   if(msg == WM_COPYDATA)
   {
       COPYDATASTRUCT cds = (COPYDATASTRUCT)Marshal.PtrToStructure(lParam, 
       typeof(COPYDATASTRUCT)); // 接收封装的消息
       string rece = cds.lpData; // 获取消息内容
       // 自定义行为
      if(rece == "start")
      {
       …
      }
   }
   return hwnd;
}


————————————————
版权声明:本文为CSDN博主「Mars Coder」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/WZh0316/article/details/77007048

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值