虽然NETCF设计为运行在WINCE上面,但它实际上是一个完整版Framework的一个子集,确实可以运行在PC上面,有时候项目会要求能够同时运行在PDA和PC上面。但是,使用NETCF编写PDA,PC兼容的托管应用程序并不是一件简单的事情,近期的几篇文章将会通过实际项目中遇到的问题,介绍相应的处理方法。
在WinCE中,有时需要控制软键盘,这个可以通过Microsoft.WindowsCE.Forms.InputPanel().Enabled属性来进行简单的设置。这种解决方法在硬件设备和模拟器中运行良好,因为他们是由精装版的Framework来执行的。问题是有的应用会要求程序能够在PC上面兼容运行,此处命名空间Microsoft.WindowsCE并不存在与PC上完整的Framework中,因此,这样编出来的程序在PC上面直接运行的话是会出现无法预料的异常的。由于在PC上运行时,已经失去了软键盘的特性,界面上也不会有软键盘存在,而我们的目标是使应用程序尽可能的能够兼容的运行在PDA和PC上面,因此在此我们尝试放弃Microsoft.WindowsCE.Forms.InputPanel而寻找更合适的方案。
有人也许会说,在运行的时候判断是否运行在WINCE上,如果是,再调用该属性控制软键盘,如果不是,就什么都不错。答案是不行,我自己做过测试,还是会弹出异常,似乎只要这种代码存在于程序中,只要执行到该代码段所在的函数体中,不管是否执行该段代码,都会抛出异常,可能是完整版的Framework在处理这种代码时产生的问题。
目前我发现的行之有效的方法是使用P/Invoke方法直接调用底层API函数,类似于DllImport("coredll")]声明的函数在PC上时,我们可以通过避免该函数执行的方法来避免异常的抛出,从而达到期望的兼容性。
经过查询,SipShowIM是可以控制软键盘的底层函数,我们将代码包装如下,注意Framework.IsNetCF是另外一个辅助类,用于判断代码是否运行在WinCE上面,目前有很多中方法可以判断,在该blog中有2篇文章对此有介绍。 代码如下:
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace MiniCafe.Util
{
public class Keyboard
{
/// <summary>
/// don't use Microsoft.WindowsCE.Forms.InputPanel().Enabled,
/// it will throw exception in pc
/// </summary>
/// <param name="flags"></param>
/// <returns></returns>
[DllImport("coredll")]
public static extern bool SipShowIM(long flags);
public static void Show()
{
if (Framework.IsNetCF)
{
SipShowIM(1);
}
}
public static void Close()
{
if (Framework.IsNetCF)
{
SipShowIM(0);
}
}
}
}