WPF实战⼩技巧(三):使⽤SendMessage实现进程间通信
(含⽰例代码)
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 int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, ref COPYDATASTRUCT lParam);
// 导出FindWindow函数,⽤于到⽬标窗⼝所在进程
[DllImport("User32.dll",EntryPoint = "FindWindow")]
private static extern int FindWindow(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, ref cds2);
进程通信方式}
}
6.接收消息
接收消息的程序需要在MainWindow.xaml.cs⽂件中重写OnSourceInitialized函数,设置钩⼦,⽤于截获消息函数,⽰例代码如下:protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;
if(hwndSource != null)
{
IntPtr handle = hwndSource.Handle;
hwndSource.AddHook(new HwndSourceHook(WndProc));
}
}
⽤于接收消息并执⾏⾃定义⾏为的消息函数⽰例代码如下:
IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, 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;
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。