在Wince和Windows Moblie 下的程序間通信可以由以下幾種技術實作。
1. Windows Message
2. Point-to-Point Message Queues
3. MSMQ
下面使用講述.NET Compact Framework下使用Windows Message進行程序間的通信。
在CF.net下進行Windows Message的開發需要引用Microsoft.WindowsCE.Forms,該DLL一般存放于C:\Program Files\Microsoft.NET\SDK\CompactFramework\v2.0\WindowsCE\Microsoft.WindowsCE.Forms.dll

using Microsoft.WindowsCE.Forms;
public partial class MsgForm : Form
{
[DllImport("coredll.dll", EntryPoint = "RegisterWindowMessage", SetLastError = true)]
private static extern uint RegisterWindowMessage(string lpString);
private uint msgUid = RegisterWindowMessage("MESSAGE_UID");
public static int MSG_BROADCAST = 0xFFFF;
private void SendMessage(object sender)
{
Message msg = Message.Create((IntPtr)MSG_BROADCAST, (int)msgUid , IntPtr.Zero, IntPtr.Zero);
MessageWindow.SendMessage(ref msg);
}
}

首先需要P/Invoke RegisterWindowMessage 函數,每個發送的message都有唯一的UID,這樣接收方才能根據UID進行監聽和接收該Message。
發送之前先create一個Message對象,參數一為接收對象,如果為程序間通信可以使用廣播的形式(MSG_BROADCAST),第二個參數為message的UID,接收方利用這一表示辨識message。第三和第四分别為WParam和LParam,這是标準windows message的傳遞參數。

public class MsgWindow : MessageWindow
[DllImport("coredll.dll", EntryPoint = "RegisterWindowMessage", SetLastError = true)]
private static extern uint RegisterWindowMessage(string lpString);
private uint msgUid = RegisterWindowMessage("MESSAGE_UID");
protected override void WndProc(ref Message msg)
{
if (msg.Msg == msgUid )
{
//handle the message.
}
}

接收消息需要定義一個繼承類,繼承于MessageWindow,同時他同樣需要P/Invoke RegisterWindowMessage 函數,定義接收message的唯一UID。
重寫WndProc,然後通過msg.Msg 來辨識關心的消息。
如果接收方接收到message需要更新到form的話就定義一個form的reference,這樣可以利用form來處理消息。其實不一定使用Form來處理message,使用Form就能比較友善的利用ui來反映message的接收和處理情況。

private MsgWindow MsgWin;
public MsgForm()
{
//pass the form reference to messagewindow
this.MsgWin = new MsgWindow(this);
}
private MsgForm msgForm;
public MsgWindow(MsgForm msgForm)
{
this.msgForm= msgForm;
}
protected override void WndProc(ref Message msg)
if (msg.Msg == msgUid )
{
//call form to handle the message.
msgForm.HandleMsg();

MsgWindow 儲存MsgForm 的引用,這樣當MsgWindow 接收到消息就可以使用form來處理。
如果在消息中傳遞對象,就不可以使用.NET Compact Framework裡面的MessageWindow.SendMessage函數了,需要使用P/Invoke來進行發送。發送端的關鍵是把要傳遞的對象封裝到COPYDATASTRUCT Structure裡面,然後通過API SendMessageW進行發送,接收方辨識WM_COPYDATA消息,從LParam中分拆出對象。

public struct COPYDATASTRUCT
public int dwData;
public int cbData;
public IntPtr lpData;
class cMsgStrings
const int LMEM_FIXED = 0x0000;
const int LMEM_ZEROINIT = 0x0040;
const int LPTR = (LMEM_FIXED | LMEM_ZEROINIT);
const int WM_COPYDATA = 0x004A;
[DllImport("coredll.dll")]
public static extern IntPtr LocalAlloc(int flag, int size);
public static extern IntPtr LocalFree(IntPtr p);
public static extern int SendMessageW(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
public static IntPtr AllocHGlobal(int cb)
IntPtr hMemory = new IntPtr();
hMemory = LocalAlloc(LPTR, cb);
return hMemory;
public static void FreeHGlobal(IntPtr hMemory)
if (hMemory != IntPtr.Zero)
LocalFree(hMemory);
public static void SendMsgString(IntPtr hWndDest, string sScript)
COPYDATASTRUCT oCDS = new COPYDATASTRUCT();
oCDS.cbData = (sScript.Length + 1) * 2;
oCDS.lpData = LocalAlloc(LPTR, oCDS.cbData);
Marshal.Copy(sScript.ToCharArray(), 0, oCDS.lpData, sScript.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);
//send the message with string
private void button1_Click(object sender, EventArgs e)
unsafe
{
cMsgStrings.SendMsgString((IntPtr)MSG_BROADCAST, textBoxMsg.Text);
}

上面為發生端的代碼,通過cMsgStrings.SendMsgString進行發送,可以把任何managed的object封裝到COPYDATASTRUCT 進行發送。

private FormReceiver msgForm;
public MsgWindow(FormReceiver msgForm)
this.msgForm = msgForm;
protected override void WndProc(ref Message msg)
if (msg.Msg == WM_COPYDATA)
string str = GetMsgString(msg.LParam);
msgForm.HandleMsg(str);
public static string GetMsgString(IntPtr lParam)
if (lParam != IntPtr.Zero)
COPYDATASTRUCT st = (COPYDATASTRUCT)Marshal.PtrToStructure(lParam, typeof(COPYDATASTRUCT));
string str = Marshal.PtrToStringUni(st.lpData);
return str;
else
return null;

上面為接收端的代碼,辨識WM_COPYDATA的消息從LParam中取出傳遞的對象。
<a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.message.create.aspx" target="_blank">Message.Create Method</a>
<a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.message.create.aspx" target="_blank">COPYDATASTRUCT Structure</a>
測試環境:Wince 5 + CF.net 2.0
本文轉自Jake Lin部落格園部落格,原文連結:http://www.cnblogs.com/procoder/archive/2009/03/16/1413176.html,如需轉載請自行聯系原作者