.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,如需转载请自行联系原作者


相关文章
|
8月前
|
API C++ Windows
Visual C++运行库、.NET Framework和DirectX运行库的作用及常见问题解决方案,涵盖MSVCP140.dll丢失、0xc000007b错误等典型故障的修复方法
本文介绍Visual C++运行库、.NET Framework和DirectX运行库的作用及常见问题解决方案,涵盖MSVCP140.dll丢失、0xc000007b错误等典型故障的修复方法,提供官方下载链接与系统修复工具使用指南。
1868 2
|
8月前
|
Linux 网络安全 iOS开发
Metasploit Framework 6.4.95 (macOS, Linux, Windows) - 开源渗透测试框架
Metasploit Framework 6.4.95 (macOS, Linux, Windows) - 开源渗透测试框架
933 1
Metasploit Framework 6.4.95 (macOS, Linux, Windows) - 开源渗透测试框架
|
9月前
|
Linux 网络安全 iOS开发
Metasploit Framework 6.4.90 (macOS, Linux, Windows) - 开源渗透测试框架
Metasploit Framework 6.4.90 (macOS, Linux, Windows) - 开源渗透测试框架
581 1
Metasploit Framework 6.4.90 (macOS, Linux, Windows) - 开源渗透测试框架
|
8月前
|
开发框架 安全 .NET
Microsoft .NET Framework 3.5、4.5.2、4.8.1,适用于 Windows 版本的 .NET,Microsoft C Runtime等下载
.NET Framework是Windows平台的开发框架,包含CLR和FCL,支持多种语言开发桌面、Web应用。常用版本有3.5、4.5.2、4.8.1,系统可同时安装多个版本,确保软件兼容运行。
1939 0
Microsoft .NET Framework 3.5、4.5.2、4.8.1,适用于 Windows 版本的 .NET,Microsoft C Runtime等下载
|
9月前
|
安全 Linux 网络安全
Metasploit Framework 6.4.88 (macOS, Linux, Windows) - 开源渗透测试框架
Metasploit Framework 6.4.88 (macOS, Linux, Windows) - 开源渗透测试框架
687 0
|
9月前
|
C++
提示缺少.NET Framework 3.5 安装错误:0x80070002、0x800F0950\0x80004002
.NET Framework常见问题及解决方法汇总,
1061 0
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
910 0
|
监控 前端开发 API
一款基于 .NET MVC 框架开发、功能全面的MES系统
一款基于 .NET MVC 框架开发、功能全面的MES系统
743 5
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
457 7
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
381 0