WM_COPYDATA消息类型属于windows系统标准消息类型,主要用于进程间或不同窗口间进行信息传递,使用此消息的同时在接收端需要重写窗口的消息处理函数DefWndProc,以便读取消息内容。
为便于使用,本人写了个MySendMessage及MySendMessageByte辅助类实现消息功能。MySendMessage类可传递string类型消息,MySendMessageByte类可传递byte[]类型消息。
里面提供了3种发送方法:窗口句柄、窗口名称(标题)、进程ID等方式传递消息。以下是源代码(代码结尾处有使用示例参考):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace test
{
/// <summary>
/// 使用本类发生窗口消息,需要接收窗口重写消息处理函数DefWndProc,以便读取消息内容
/// </summary>
class MySendMessage
{
public struct COPYDATASTRUCT
{
/// <summary>
/// 消息附加标识(可自定义用途)
/// </summary>
public IntPtr dwData;
/// <summary>
/// 消息内容长度
/// </summary>
public int cbData;
/// <summary>
/// 消息内容
/// </summary>
[MarshalAs(UnmanagedType.LPStr)] public string lpData;
}
[DllImport("User32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage(IntPtr hWnd, // handle to destination window
uint Msg, // message
uint wParam, // first message parameter
ref COPYDATASTRUCT lParam // second message parameter
);
[DllImport("User32.dll", EntryPoint = "FindWindow")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
public const int WM_COPYDATA = 0x004A;//系统特定的消息类型
/// <summary>
/// 向指定窗体发送消息
/// </summary>
/// <param name="hWnd">窗体句柄</param>
/// <param name="msg">要发送的消息内容</param>
/// <param name="flag">可选项:消息附加标识(可自定义用途)</param>
/// <returns></returns>
public static int send(IntPtr hWnd,string msg, int flag = 0)
{
COPYDATASTRUCT cds = new COPYDATASTRUCT();
cds.dwData = (IntPtr)flag;
cds.cbData = System.Text.Encoding.Default.GetByteCount(msg)+1;
cds.lpData = msg;
return SendMessage(hWnd, WM_COPYDATA,0,ref cds);
}
/// <summary>
/// 向指定进程的主窗体发送消息
/// </summary>
/// <param name="processID">进程ID号</param>
/// <param name="msg">要发送的消息内容</param>
/// <param name="flag">可选项:消息附加标识(可自定义用途)</param>
/// <returns></returns>
public static int send(int processID,string msg, int flag = 0)
{
System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(processID);
IntPtr hWnd = p.MainWindowHandle;
return send(hWnd, msg,flag);
}
/// <summary>
/// 向指定窗体发送消息
/// </summary>
/// <param name="title">目标窗体的标题</param>
/// <param name="msg">要发送的消息内容</param>
/// <param name="flag">可选项:消息附加标识(可自定义用途)</param>
/// <returns></returns>
public static int send(string title,string msg, int flag = 0)
{
IntPtr hWnd = FindWindow(null, title);
return send(hWnd, msg, flag);
}
}
/// <summary>
/// 使用本类发生窗口消息,需要接收窗口重写消息处理函数DefWndProc,以便读取消息内容
/// </summary>
class MySendMessageByte
{
public struct COPYDATASTRUCT
{
/// <summary>
/// 消息附加标识(可自定义用途)
/// </summary>
public IntPtr dwData;
/// <summary>
/// 数据大小
/// </summary>
public int cbData;
/// <summary>
/// 数据地址(指针)
/// </summary>
public IntPtr lpData;
}
[DllImport("User32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage(IntPtr hWnd, // handle to destination window
uint Msg, // message
uint wParam, // first message parameter
ref COPYDATASTRUCT lParam // second message parameter
);
[DllImport("User32.dll", EntryPoint = "FindWindow")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
public const int WM_COPYDATA = 0x004A;//系统特定的消息类型
/// <summary>
/// 向指定窗体发送消息
/// </summary>
/// <param name="hWnd">窗体句柄</param>
/// <param name="data">要发送的消息内容</param>
/// <param name="flag">可选项:消息附加标识(可自定义用途)</param>
/// <returns></returns>
public static int send(IntPtr hWnd, byte[] data, int flag=0)
{
COPYDATASTRUCT cds = new COPYDATASTRUCT();
cds.dwData = (IntPtr)flag;
cds.cbData = data.Length;
cds.lpData = Marshal.UnsafeAddrOfPinnedArrayElement(data,0);
return SendMessage(hWnd, WM_COPYDATA, 0, ref cds);
}
/// <summary>
/// 向指定进程的主窗体发送消息
/// </summary>
/// <param name="processID">进程ID号</param>
/// <param name="data">要发送的消息内容</param>
/// <param name="flag">可选项:消息附加标识(可自定义用途)</param>
/// <returns></returns>
public static int send(int processID, byte[] data, int flag = 0)
{
System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(processID);
IntPtr hWnd = p.MainWindowHandle;
return send(hWnd, data,flag);
}
/// <summary>
/// 向指定窗体发送消息
/// </summary>
/// <param name="title">目标窗体的标题</param>
/// <param name="data">要发送的消息内容</param>
/// <param name="flag">可选项:消息附加标识(可自定义用途)</param>
/// <returns></returns>
public static int send(string title, byte[] data, int flag = 0)
{
IntPtr hWnd = FindWindow(null, title);
return send(hWnd, data, flag);
}
}
/* 使用示例一:发送字符串消息
MySendMessage.send(process.MainWindowHandle, str);//向窗口发送字符串消息
//接收窗口要重写消息处理函数DefWndProc,以便处理消息内容
protected override void DefWndProc(ref System.Windows.Forms.Message m)
{
switch (m.Msg)
{
case MySendMessage.WM_COPYDATA:
MySendMessage.COPYDATASTRUCT cds = new MySendMessage.COPYDATASTRUCT();
Type mytype = cds.GetType();
cds = (MySendMessage.COPYDATASTRUCT)m.GetLParam(mytype);
string str=cds.lpData;
break;
default:
base.DefWndProc(ref m);
break;
}
}
//*/
/* 使用示例二:发送字节型数据
MySendMessageByte.send(process.MainWindowHandle, System.Text.Encoding.Default.GetBytes(str));//向窗口发送字节数据
//接收窗口要重写消息处理函数DefWndProc,以便处理消息内容
protected override void DefWndProc(ref System.Windows.Forms.Message m)
{
switch (m.Msg)
{
case MySendMessageByte.WM_COPYDATA:
MySendMessageByte.COPYDATASTRUCT cds = new MySendMessageByte.COPYDATASTRUCT();
Type mytype = cds.GetType();
cds = (MySendMessageByte.COPYDATASTRUCT)m.GetLParam(mytype);
byte[] data = new byte[cds.cbData];
Marshal.Copy(cds.lpData, data, 0, cds.cbData);
string str=System.Text.Encoding.Default.GetString(data);
break;
default:
base.DefWndProc(ref m);
break;
}
}
//*/
}