日前在工作中遇到这样一个问题。
从窜口读取RFID扫描器的扫描结果,并用事件通知UI显示扫描结果。于是编写了一个串口读写类,使用工作线程监视窜口,当从串口读写到数据后,触发事件更新UI(关于在Windows Mobile上执行串口读写,可参考Chris Tacke的《P/Invoking Serial APIs in the Compact Framework》)。问题来了,监视窜口的是工作线程,而工作线程是不应该更新UI的。如何透明的从工作线程切换到UI线程呢?Micrsoft.WindowsCE.Forms提供了一个MessageWindow类,MSDN如是说
“MessageWindow 类提供发送和接收基于 Windows 的消息的能力。此类在本机代码中创建一个窗口句柄,然后调用所需的对本机 Windows 函数的平台调用。
若要在程序中使用 MessageWindow,您需要创建一个从 MessageWindow 派生的类,并重写默认的 WndProc 行为来监视特定的窗口消息。可以使用 Message 类生成消息。可以只接收您使用 MessageWindow 生成的或由本机控件生成的基于 Windows 的消息。
”
这样就有办法了,从串口读到数据后,发送一个Windows消息,在MessageWindows.WndProc方法里分析Windows消息,调用需要的事件。
代码如下:
class
Invoker : MessageWindow
//
继承MessageWindow类
{
public void Invoke(SomeEventHandler e)
{
IntPtr lparam = (IntPtr)GCHandle.Alloc(e);
// 发送一个Windows消息
Message m = Message.Create( this .Hwnd, WM_INVOKEMETHOD, IntPtr.Zero, lparam);
MessageWindow.SendMessage( ref m);
}
protected override void WndProc( ref Message m) // 重写WndProc方法
{
if (m.Msg == WM_INVOKEMETHOD) // 分析Windows消息
{
GCHandle gcHandle
{
public void Invoke(SomeEventHandler e)
{
IntPtr lparam = (IntPtr)GCHandle.Alloc(e);
// 发送一个Windows消息
Message m = Message.Create( this .Hwnd, WM_INVOKEMETHOD, IntPtr.Zero, lparam);
MessageWindow.SendMessage( ref m);
}
protected override void WndProc( ref Message m) // 重写WndProc方法
{
if (m.Msg == WM_INVOKEMETHOD) // 分析Windows消息
{
GCHandle gcHandle