利用WM_COPYDATA在应用程序间传递数据很简单,开销也小
一、传递数据部分
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace ThreeTorches
{
public struct Copydatastruct
{
public IntPtr dwData;
public int cbData;
public IntPtr lpData;
}
public static class XianaoMessage
{
[DllImport("User32.dll", EntryPoint = "FindWindow")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", EntryPoint = "FindWindowEx")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
//发送数据的消息常数
public const int WmCopydata = 0x4A;
///
/// Win32的发送消息函数
///
/// 接收消息的窗口句柄
/// 消息ID
/// 高位信息
/// 低位信息
///
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(System.IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);
///
/// 使用Marshal.AllocCoTaskMem分配空间方法来发送数据
///
/// 目标窗口唯一标题
/// 要发送的消息
/// 源窗口句柄
public static void SendMessageWithDataUsingCOTaskMem(string winCaption, string str, IntPtr srcHandle)
{
IntPtr p = FindWindow(null, winCaption);
SendMessageWithDataUsingCOTaskMem(p, str, srcHandle);
}
///
/// 使用Marshal.AllocCoTaskMem分配空间方法来发送数据
///
/// 目标窗口句柄
/// 要发送的消息
/// 源窗口句柄
public static void SendMessageWithDataUsingCOTaskMem(IntPtr destHandle, string str, IntPtr srcHandle)
{
Copydatastruct cds;
cds.dwData = srcHandle;
str = str + '/0';
cds.cbData = str.Length * 2+ 1; //处理汉字
cds.lpData = Marshal.AllocCoTaskMem(str.Length);
cds.lpData = Marshal.StringToCoTaskMemAnsi(str);
IntPtr iPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(cds));
Marshal.StructureToPtr(cds, iPtr, true);
//发送到指定的窗体
SendMessage(destHandle, WmCopydata, IntPtr.Zero, iPtr);
// 回收所分配的内存
Marshal.FreeCoTaskMem(cds.lpData);
Marshal.FreeCoTaskMem(iPtr);
}
///
/// 使用Marshal.AllocHGlobal分配空间方法来发送数据
///
/// 目标窗口唯一标题
/// 要发送的消息
/// 源窗口句柄
public static void SendMessageWithDataUsingHGlobal(string winCaption, string str, IntPtr srcHandle)
{
IntPtr p = FindWindow(null, winCaption);
SendMessageWithDataUsingHGlobal(p, str, srcHandle);
}
///
/// 使用Marshal.AllocHGlobal分配空间方法来发送数据
///
/// 目标窗口句柄
/// 要发送的消息
/// 源窗口句柄
public static void SendMessageWithDataUsingHGlobal(IntPtr destHandle, string str, IntPtr srcHandle)
{
Copydatastruct cds;
cds.dwData = srcHandle;
str = str + '/0';
cds.cbData = str.Length * 2+ 1; //处理汉字
cds.lpData = Marshal.AllocHGlobal(str.Length);
cds.lpData = Marshal.StringToHGlobalAnsi(str);
IntPtr iPtr = Marshal.AllocHGlobal(Marshal.SizeOf(cds));
Marshal.StructureToPtr(cds, iPtr, true);
//发送到指定的窗体
SendMessage(destHandle, WmCopydata, srcHandle, iPtr);
// 回收所分配的内存
Marshal.FreeCoTaskMem(cds.lpData);
Marshal.FreeCoTaskMem(iPtr);
}
///
/// 获取传递过来的数据
///
/// 指定的消息
///
public static string GetMessageWithData(Message msg)
{
string str = "";
if (msg.Msg == WmCopydata)
{
//获取数据
Copydatastruct cds = new Copydatastruct();
cds = (Copydatastruct)Marshal.PtrToStructure(msg.LParam, typeof(Copydatastruct));
if (cds.cbData > 0)
{
byte[] data = new byte[cds.cbData];
Marshal.Copy(cds.lpData, data, 0, cds.cbData);
Encoding unicodeStr = Encoding.ASCII;
str = new string(unicodeStr.GetChars(data));
//m.Result = (IntPtr)1;
}
}
return str;
}
}
}
二、接收数据部分
重写WndProc
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_COPYDATA: //WM_COPYDATA = 0x4a
listBox1.Items.Add(ThreeTorches.XianaoMessage.GetMessageWithData(m));
break;
default:
base.WndProc(ref m);//调用基类函数处理非自定义消息。
break;
}
}