做WM上的進程間通信,使用WindowMessage實現(xiàn)兩個進程間的通信,感覺MessageWindow不太好用,所以就用別的方法實現(xiàn)接收WindowsMessage。
先來封裝一下需要使用的功能,命名為Cls_Message:
view plaincopy to clipboardprint?
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.WindowsCE.Forms;
using System.Windows.Forms;
class Cls_Message
{
private struct COPYDATASTRUCT
{
public int dwData;
public int cbData;
public IntPtr lpData;
}
//-------------------------------------------------------------------------------
private const int WM_COPYDATA = 0x004A;
private const int GWL_WNDPROC = -4;
private const int LMEM_FIXED = 0x0000;
private const int LMEM_ZEROINIT = 0x0040;
private const int LPTR = (LMEM_FIXED | LMEM_ZEROINIT);
private IntPtr oldWndProc = IntPtr.Zero;
private WndProcDelegate newWndProc;
private IntPtr formHandle;
//-------------------------------------------------------------------------------
delegate IntPtr WndProcDelegate(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
[DllImport("coredll.dll")]
static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("coredll.dll", EntryPoint = "GetWindowLong")]
private static extern IntPtr GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("coredll.dll")]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr newWndProc);
[DllImport("coredll.dll", EntryPoint = "FindWindow")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("coredll.dll")]
private static extern int SendMessageW(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
[DllImport("coredll.dll")]
private static extern IntPtr LocalAlloc(int flag, int size);
[DllImport("coredll.dll")]
private static extern IntPtr LocalFree(IntPtr p);
/// <summary>
/// 初始化消息類
/// </summary>
/// <param name="handle">接受消息的窗體的句柄</param>
public Cls_Message(IntPtr formHandle)
{
this.formHandle = formHandle;
newWndProc = new WndProcDelegate(WndProc);
oldWndProc = GetWindowLong(formHandle, GWL_WNDPROC);
int success = SetWindowLong(formHandle, GWL_WNDPROC, Marshal.GetFunctionPointerForDelegate(newWndProc));
}
/// <summary>
/// 消息處理
/// </summary>
private IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{
if (msg == WM_COPYDATA)
{
COPYDATASTRUCT st = (COPYDATASTRUCT)Marshal.PtrToStructure(lParam, typeof(COPYDATASTRUCT));
string str = Marshal.PtrToStringUni(st.lpData);
MessageBox.Show(str);
}
return CallWindowProc(oldWndProc, this.formHandle, msg, wParam, lParam);
}
static private IntPtr AllocHGlobal(int cb)
{
IntPtr hMemory = new IntPtr();
hMemory = LocalAlloc(LPTR, cb);
return hMemory;
}
static private void FreeHGlobal(IntPtr hMemory)
{
if (hMemory != IntPtr.Zero)
LocalFree(hMemory);
}
/// <summary>
/// 發(fā)送消息
/// </summary>
/// <param name="formTitle">目標窗體的名稱</param>
/// <param name="message">消息內(nèi)容</param>
static public void SendMessage(String formTitle,String message)
{
IntPtr hWndDest = FindWindow(null, formTitle);
COPYDATASTRUCT oCDS = new COPYDATASTRUCT();
oCDS.cbData = (message.Length + 1) * 2;
oCDS.lpData = LocalAlloc(LPTR, oCDS.cbData);
Marshal.Copy(message.ToCharArray(), 0, oCDS.lpData, message.Length);
oCDS.dwData = 1;
IntPtr lParam = AllocHGlobal(oCDS.cbData);
Marshal.StructureToPtr(oCDS, lParam, false);
SendMessageW(hWndDest, WM_COPYDATA, IntPtr.Zero, lParam);
LocalFree(oCDS.lpData);
FreeHGlobal(lParam);
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.WindowsCE.Forms;
using System.Windows.Forms;
class Cls_Message
{
private struct COPYDATASTRUCT
{
public int dwData;
public int cbData;
public IntPtr lpData;
}
//-------------------------------------------------------------------------------
private const int WM_COPYDATA = 0x004A;
private const int GWL_WNDPROC = -4;
private const int LMEM_FIXED = 0x0000;
private const int LMEM_ZEROINIT = 0x0040;
private const int LPTR = (LMEM_FIXED | LMEM_ZEROINIT);
private IntPtr oldWndProc = IntPtr.Zero;
private WndProcDelegate newWndProc;
private IntPtr formHandle;
//-------------------------------------------------------------------------------
delegate IntPtr WndProcDelegate(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
[DllImport("coredll.dll")]
static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("coredll.dll", EntryPoint = "GetWindowLong")]
private static extern IntPtr GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("coredll.dll")]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr newWndProc);
[DllImport("coredll.dll", EntryPoint = "FindWindow")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("coredll.dll")]
private static extern int SendMessageW(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
[DllImport("coredll.dll")]
private static extern IntPtr LocalAlloc(int flag, int size);
[DllImport("coredll.dll")]
private static extern IntPtr LocalFree(IntPtr p);
/// <summary>
/// 初始化消息類
/// </summary>
/// <param name="handle">接受消息的窗體的句柄</param>
public Cls_Message(IntPtr formHandle)
{
this.formHandle = formHandle;
newWndProc = new WndProcDelegate(WndProc);
oldWndProc = GetWindowLong(formHandle, GWL_WNDPROC);
int success = SetWindowLong(formHandle, GWL_WNDPROC, Marshal.GetFunctionPointerForDelegate(newWndProc));
}
/// <summary>
/// 消息處理
/// </summary>
private IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{
if (msg == WM_COPYDATA)
{
COPYDATASTRUCT st = (COPYDATASTRUCT)Marshal.PtrToStructure(lParam, typeof(COPYDATASTRUCT));
string str = Marshal.PtrToStringUni(st.lpData);
MessageBox.Show(str);
}
return CallWindowProc(oldWndProc, this.formHandle, msg, wParam, lParam);
}
static private IntPtr AllocHGlobal(int cb)
{
IntPtr hMemory = new IntPtr();
hMemory = LocalAlloc(LPTR, cb);
return hMemory;
}
static private void FreeHGlobal(IntPtr hMemory)
{
if (hMemory != IntPtr.Zero)
LocalFree(hMemory);
}
/// <summary>
/// 發(fā)送消息
/// </summary>
/// <param name="formTitle">目標窗體的名稱</param>
/// <param name="message">消息內(nèi)容</param>
static public void SendMessage(String formTitle,String message)
{
IntPtr hWndDest = FindWindow(null, formTitle);
COPYDATASTRUCT oCDS = new COPYDATASTRUCT();
oCDS.cbData = (message.Length + 1) * 2;
oCDS.lpData = LocalAlloc(LPTR, oCDS.cbData);
Marshal.Copy(message.ToCharArray(), 0, oCDS.lpData, message.Length);
oCDS.dwData = 1;
IntPtr lParam = AllocHGlobal(oCDS.cbData);
Marshal.StructureToPtr(oCDS, lParam, false);
SendMessageW(hWndDest, WM_COPYDATA, IntPtr.Zero, lParam);
LocalFree(oCDS.lpData);
FreeHGlobal(lParam);
}
}
接下來貼出調(diào)用代碼,實現(xiàn)自發(fā)自收,如果要發(fā)給別的進程,只需要把SendMessage的第一個參數(shù)改為目標窗體的名稱即可(當然目標窗體也必須引用了Cls_Message實現(xiàn)收信息處理):
view plaincopy to clipboardprint?
Cls_Message clsMessage;//初始化
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
clsMessage = new Cls_Message(this.Handle);//使本窗體能夠接收WindowMessage
}
private void button1_Click(object sender, EventArgs e)
{
Cls_Message.SendMessage("Form1", "hello form1");
}
(審核編輯: 智匯小新)
分享