.NET Compact Framework下的进程间通信之Windows Message

在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的传递参数。

 

接收消息

复制代码
using  Microsoft.WindowsCE.Forms;

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 来辨别关心的消息。

 

 

使用Form处理Message

如果接收方接收到message需要更新到form的话就定义一个form的reference,这样可以利用form来处理消息。其实不一定使用Form来处理message,使用Form就能比较方便的利用ui来反映message的接收和处理情况。

复制代码
public   partial   class  MsgForm : Form
{
    
private  MsgWindow MsgWin;

    
public  MsgForm()
    {
        
// pass the form reference to messagewindow
         this .MsgWin  =   new  MsgWindow( this );
    }
}

public   class  MsgWindow : MessageWindow
{
     
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);
        [DllImport(
" coredll.dll " )]
        
public   static   extern  IntPtr LocalFree(IntPtr p);
        [DllImport(
" coredll.dll " )]
        
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 进行发送

 

 

复制代码
public   class  MsgWindow : MessageWindow
    {
        
const   int  WM_COPYDATA  =   0x004A ;

        
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中取出传递的对象。

 

参考文献

Message.Create Method

COPYDATASTRUCT Structure

 

源代码:WindowsMessageSender.rar 源代码展现进程间传递string的例子。
测试环境:Wince 5 + CF.net 2.0



    本文转自Jake Lin博客园博客,原文链接:http://www.cnblogs.com/procoder/archive/2009/03/16/1413176.html,如需转载请自行联系原作者


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值