WPF应用程序使用SendMessage实现进程间通信(含示例代码)

来源:互联网 发布:刷qq会员软件 编辑:程序博客网 时间:2024/05/16 11:06

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 structCOPYDATASTRUCT

{

publicIntPtr dwData; // 任意值

publicint cbData;    // 指定lpData内存区域的字节数

[MarshalAs(UnmanagedType.LPStr)]

publicstring lpData; // 发送给目标窗口所在进程的数据

}

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

5.发送消息

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

 

// 待发送消息

string s = "start";

// 枚举进程

Process[] procs = Process.GetProcesses();

foreach (Process pin 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(newHwndSourceHook(WndProc));

            }

        }

 

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

IntPtr WndProc(IntPtrhwnd,int msg, IntPtrwParam,IntPtr lParam, refbool handled)

{

if(msg == WM_COPYDATA)

{

COPYDATASTRUCT cds = (COPYDATASTRUCT)Marshal.PtrToStructure(lParam,  typeof(COPYDATASTRUCT));// 接收封装的消息

string rece = cds.lpData;// 获取消息内容

//自定义行为

if(rece =="start")

{

   

}

}

return hwnd;

}

阅读全文
0 0