1 实现帮助
实现帮助内容对应用程序开发来说是一项关键步骤,但经常被拖延到开发的后期再进行。虽然如何写帮助内容不在本书所讨论的范围之内,但我们必须指出,保持内容的简洁,并合理地将内容拆分成简短的主题,以便适应滚动的需要,相当重要。由于屏幕空间有限,不宜阅读大量文字。不仅如此,相比桌面上的Microsoft Windows操作系统,设备上的搜索与导航功能也是有限的。如图1.1
图1.1帮助视图
1.1.1 创建基于html的帮助
自Windows Embedded Compact 7第一个版本开始,这个平台就支持基于超文本标记语言(HTML)的帮助引擎。Windows Embedded Compact 7也使用了相同的技术。不像在桌面上,设备帮助只能在“开始”菜单中打开。当窗体可见时,用户可以在“开始”菜单中,通过点选来打开特定的帮助主题。如果您未实现这个功能,显示的将是系统帮助内容。不管怎样,由于帮助格式为对标准HTML的拓展,虽然添加了一些标记,但用任何常规的Web页面编辑软件都可以创建帮助内容。这个引擎支持的标签与Microsoft Internet Explorer Embedded所支持的完全相同。
每个帮助文件是一个单独的.htm文件,它可以包含若干帮助主题。通过标准的HTML锚(anchor)便可以在一个文件中的不同主题间进行链接。锚必须包含在文件中来指明目录的位置——帮助引擎通过这个锚提供到内容部分的永久链接,如下所示:
<A NAME="Main_Contents"></A>
目录本身只是包含在文档中链接到不同主题的超链接(hyperlink)列表。有一个特殊的标签放在页首,以提示帮助程序哪个主题用于呈现目录。这个标记必须与页面中目录的锚名吻合;否则,帮助程序会显示错误,提示无法找到帮助文件。
<meta http-equiv="Htm-Help" content="kiosk.htm#Main_Contents"/>
在HTML文件中,每个帮助页都由一个特殊的注释标记分隔。这个注释标记名称来源于Windows Embedded Compact 7 1.0,它的代号为Pegasus(神马),这样PegHelp应运而生:
<!-- PegHelp --><hr/>
由于这是一个注释标记,因此它仍然是有效的HTML,可以在任何浏览器中显示;它指示Windows Embedded Compact 7“帮助”程序,主题的开始与结束,保证每个主题能够显示在一个独立的页面中。后面的水平标尺(horizontal rule)标记是可选的,这更利于桌面上查看这个 文件。
帮助文件可以包含关键字的定义,内建的搜索程序可以使用它来查找其中的主题。这些关键字的定义应采用如下形式,并在<HEAD>节中指定:
<keyword value="kiosk;screen"
title="Kiosk Settings"
href="Kiosk.htm#kiosk" />
这里的value属性是一个用分号隔开的关键字列表,在此例中,我们将关键字kiosk 和screen与这个主题联系在一起。title属性存储了对特定主题的描述,且会显示给用户。最后的href指定了到帮助主题的链接。注意,“#”用于提示指向文档中某个已命名的锚。由于帮助引擎不会处理相对路径,因此,按照习惯,应将.htm文件放在设备的Windows文件夹下。
Windows Embedded Compact 7的帮助内容还有一点需要注意。与Internet Explorer Mobile一样,这里也广泛支持各种HTML标记。但有一个令人诧异的限制,即只能使用位图(bitmap image),它必须在<IMG>标记中指定其绝对路径。这实际上意味着,帮助文件与相关图片通常都要部署到设备的Windows文件夹下。下面是完整的帮助文件内容。如图1.2
图1.2帮助视图
<html>
<head>
<title>Kiosk Sample</title>
<LINK rel="stylesheet" type="text/css" href="file://WindowsDeviceHelp.css" />
<meta http-equiv="Htm-Help" content="kiosk.htm#Main_Contents"/>
<keyword title="Kiosk Mode" value="Kiosk;Fullscreen" href="kiosk.htm#kiosk"/>
<keyword title="Hardware Buttons" value="Hardware;Button" href="kiosk.htm#buttons"/>
<keyword title="Help Links" value="Help;Context" href="kiosk.htm#help"/>
</head>
<body><!-- PegHelp -->
<a name="Main_Contents"></a><h1>Table of Contents</h1>
<p><a href="kiosk.htm#kiosk">Kiosk Mode</a></p>
<p><a href="kiosk.htm#buttons">Hardware Buttons</a></p>
<p><a href="kiosk.htm#help">Help Links</a></p>
<!-- PegHelp --><hr/>
<a name="kiosk"></a><h1 class="dtH1">Kiosk Mode</h1>
<p>SHFullScreen is used to enable/disable various user interface features such as the start menu.</p>
<ol>
<li>Hide StartMenu will disallow the user from tapping Start or any of the notification tray icons.</li>
<li>Hide Taskbar will remove the entire taskbar. This only works if the Form has WindowState = Maximized</li>
<li>Hide SIP will hide the Soft Input Panel button. On Windows Mobile 5.0, this will reappear if you tap on the menu bar.</li>
<li>Hide Control Box changes the property to hide the OK button used to close the form.</li>
</ol>
<h4 class="dtH4">See also</h4>
<p><a href="kiosk.htm#buttons">Hardware Buttons</a></p>
<p><a href="kiosk.htm#help">Help</a></p>
<!-- PegHelp --><hr/>
<a name="buttons"></a><h1 class="dtH1">Hardware Buttons</h1>
<p>Six Hardware Button controls are used to override their default behavior so that the user cannot easily "escape" from our application.</p>
<h4 class="dtH4">See also</h4>
<p><a href="kiosk.htm#kiosk">Kiosk Mode</a></p>
<p><a href="kiosk.htm#help">Help Links</a></p>
<!-- PegHelp --><hr/>
<a name="help"></a><h1 class="dtH1">Help</h1>
<p>The sample implements help links from both the Start menu and through a main application menu (so that it is accessible even in Kiosk mode).</p>
<p>The System.Windows.Forms.Help class is used to start the help system (Not supported on Smartphone).</p>
<h4 class="dtH4">See also</h4>
<p><a href="kiosk.htm#kiosk">Kiosk Mode</a></p>
<p><a href="kiosk.htm#buttons">Hardware Buttons</a></p>
<!-- PegHelp --><hr/>
</body>
</html>
在正确创建带有多个主题的帮助文件之后,可以将其挂到“帮助”菜单项上,这样一来,这些“帮助”主题就会呈现给用户。
1.1.2 在代码中启动帮助主题
.NET Compact Framework 2.0版引入了桌面System.Windows.Forms.Help类的一个子集来与帮助引擎进行交互。使用ShowHelp方法,您可以指定要显示的文件名,也可以有主题名。主题名是作为标准HTML的锚追加的,如下所示:
Help.ShowHelp(this, "MyApp.htm#MyTopic");
一般情况下,要在HelpRequested事件处理函数中调用这个方法,但也可在程序中再提供一个帮助链接。
private void Form1_HelpRequested(object sender, HelpEventArgs hlpevent)
{
Help.ShowHelp(this, "Kiosk.htm#Main_Contents");
}
在VC++代码中启动帮助主题代码如下:
PROCESS_INFORMATION pi;TCHAR szAppName[_MAX_PATH] = TEXT("peghelp.exe");//系统帮助程序,PC上是在c:WINDOWS目下的winhlp32.exeTCHAR szCmdLine[_MAX_PATH] = TEXT("NOVAII.htm");//自己制作的帮助文档,甚至是系统原有的帮助文件,如wince.htm、bluetooth.htm等等。myhelp.html应该放在Windows目录下int nReturn = CreateProcess(szAppName,szCmdLine, NULL, NULL,FALSE, 0, NULL, NULL, NULL, &pi);
如果想获得更多的灵活性,可以将主题名称存储在字符串变量中,这样便能基于对程序的上下文活动的感知而做出响应。
1.1.3 母目录
最后一步是将帮助内容挂到设备的母目录(master table of contents)。这个母目录是在没有可用程序时,用户点选“开始”|“帮助”后显示的列表。要将“帮助”内容挂到母目录上,可以将一个快捷方式(shortcut)添加到设备的WindowsHelp文件夹下。在Windows Mobile 5.0和更新版本中,帮助引擎从您的文件中读取标题,并将其追加到“已添加的程序帮助”主题中,这个主题显示在主目录(main table of contents)的底端。在之前的版本中,自定义“帮助”文件是按字母顺序添加到目录中的。如图1.3
图1.3帮助文档视图
可以在设备安装程序中创建这些快捷方式,这将在本章后面详细讲解。如果需要,也可手动创建快捷方式。在Windows Embedded Compact 7中,快捷方式是一个带有.lnk扩展名的文件,内容如下:
18#WindowsKiosk.htm
这个数字表示井号(#)后面的字符个数,这些字符表示文件的完整路径。如果手动创建这个文件,需要自行计算这个长度。如果路径包含空格,那么这个路径必须用双引号引上,引号也要计入这个字符统计中。可以调用应用程序编程接口(API)以编码的方式创建快捷方式:SHCreateShortcut。
1.1.4 Windows Embedded Compact 7 设备上的联机帮助
如果需要将帮助内容分发到Windows Embedded Compact 7设备,最简单的方法就是撰写HTML内容那样的“帮助”。内容最好按照主题和目录分成若干独立的.htm文件。虽然可以使用为Pocket PC创建的.htm文件,但它会完整地显示出来,而不会拆分成若干主题单独显示,因而会带来一定的不便。
要在程序中启动.htm文件格式的帮助主题,可以使用System.Diagnostics 命名空间下的Process类。下面的ShowHelp方法的行为与System.Windows.Forms.Help.ShowHelp方法十分形似,但后者在Smartphone不可用。您应将帮助内容的HTML文件完整路径传到这个方法中。
public static void ShowHelp(string url)
{
Process.Start(url, "");
}
这个代码会在Internet Explorer Mobile窗口中打开那个主题。用户可以使用“后退”硬件按钮回到程序。如果要提供用于Smartphone程序的联机帮助,应尽量保持帮助内容的简洁,也不妨考虑提示用户直接去阅读桌面计算机或Web上的说明。
1.2 锁定程序
部署某个企业应用程序时,经常希望限制用户,使其仅能进入您的应用程序,而其他任何程序和设置将被屏蔽。要达到这个目的,可以对设备进行设置,调整程序以防止控制权从您的窗体中移走。由于不同制造商设备的配置方式不同,您可以配置设备的选项,但这根据所部署设备的不同而有所差异。
1.2.1 kiosk模式
从本质上看,Windows Embedded Compact 7平台具备综合适应性,因此,用户接口被设计得可以方便地进入内建的应用程序。用户可以通过多种方式使用系统功能,其中许多都无法控制(例如,“通知气球”[notification bubble]在应用程序上方打开)。
编写kiosk模式的应用程序,您有两个选项可以控制。第一个是.NET Compact Framework 2.0的新功能,可以将Form.WindowState属性设置为Maximized。这将隐藏整个任务栏,并将使您的窗体填满整个屏幕空间(如果您再将默认的MenuBar从窗体中删除,便会得到真正的全屏状态)。使用这个选项要谨慎,因为会无法切换到其他应用程序,也无法查看通知区(包括时钟)。
第二个选项保留了基本的外壳组件,但关闭了“开始”菜单,并限制用户点选通知区域的图标,但它仍可以用来显示状态。您可以使用SHFullScreenAIP函数,将一些状态字传给它以关闭“开始”菜单和软件的输入框(SIP)按钮。图6.4演示了SHFullScreen各种选项和窗体最大化的效果。.NET Compact Framework尚未包含调用SHFullScreen的托管API,为此,您只能自己编写“平台调用服务”( PInvoke)定义。
[DllImport("aygshell.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SHFullScreen(IntPtr hwndRequester, SHFS dwState);
[Flags()]
internal enum SHFS
{
SHOWTASKBAR = 0x0001,
HIDETASKBAR = 0x0002,
SHOWSIPBUTTON = 0x0004,
HIDESIPBUTTON = 0x0008,
SHOWSTARTICON = 0x0010,
HIDESTARTICON = 0x0020,
}
1.2.2 硬件按钮
.NET Compact Framework 2.0支持对设备上的程序按钮做出反应。如果在程序中注册了这些硬件按钮,就可以阻止用户,使其使用这些按钮无法切换到其他应用程序上。设备对那些程序按钮的支持没有标准,按钮在设备上的排列顺序可能不会与按钮所对应的内部编号吻合。
要使用HardwareButton组件,您可以将它拖放到设计器的窗体上。每个HardwareButton组件只能对应一个硬件按钮,这样,您可能需要在窗体上添加几个HardwareButton控件。然后,必须设置AssociatedControl(设置为您的窗体)和HardwareKey属性,控件会以KeyDown事件的形式将按键动作传入您的窗体中。如果您只想限制这些硬件按钮,不让它们执行其他的功能,那就不要编写KeyDown事件处理函数。不像常规的按键动作,HardwareButton组件不会引发与KeyUp等价的事件。
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
switch ((HardwareKeys)e.KeyCode)
{
case HardwareKeys.ApplicationKey1:
MessageBox.Show("Hardware Key 1");
break;
case HardwareKeys.ApplicationKey2:
MessageBox.Show("Hardware Key 2");
break;
case HardwareKeys.ApplicationKey3:
MessageBox.Show("Hardware Key 3");
break;
case HardwareKeys.ApplicationKey4:
MessageBox.Show("Hardware Key 4");
break;
case HardwareKeys.ApplicationKey5:
MessageBox.Show("Hardware Key 5");
break;
case HardwareKeys.ApplicationKey6:
MessageBox.Show("Hardware Key 6");
break;
}
}
1.2.3 用户接口的锁定
防止进入其他程序的简单但并非无懈可击的一个方法是,删除设备“程序”( Programs)文件夹下的应用程序快捷方式。删除 “文件浏览器”的快捷方式,便可以防止用户浏览应用程序文件。而您不能在安装项目中,将已存在于设备上的文件删除或重命名,唯一的方法是将它们覆盖成空(zero-byte)文件,那将有效地隐藏它们。可以在自定义安装程序的.dll文件中,或在您的应用程序代码中将文件删除。
1.2.4 第三方解决方案
要想进一步控制设备锁定,您可以使用一些第三方工具,它们迫使Windows Mobile设备处在kiosk模式上。例如,您可以使用Symbol公司提供的AppCenter工具,将设备锁定到某个单一应用程序上。SPB Software House也有一个可以用在Pocket PC上的产品,它可以通过密码来管理进入多个受信任的应用程序,要了解更多信息,请访问www.spbsoftwarehouse.com/products/kioskengine/?en。
1.3 部署运行库
在运行Windows Embedded Compact 7设备的只读存储器(ROM)中,需要定制 Compact Framework。
因为框架的发布对性能做了改进,并修正了一些错误,因此,在最新版本上运行程序会更优越。在目前的设备中,如果没有定制.NET Compact Framework 2.0或者3.5,运行托管代码会发生错误。
微软发布的Compact Framework运行库安装前是若干.cab文件安装程序,不同的文件针对不同的系统(Windows Embedded Compact 7和Windows Mobile)和中央处理单元(CPU)架构(例如,ARM,X86,MIPS)。微软将所有.cab文件安装程序一齐捆绑到.NET Compact Framework 可再发行程序包中。这个可再发行程序包通过Microsoft ActiveSync启动相关.cab文件,并将运行库的正确版本部署到当前连接的设备上。引导您的用户使用这种方法,无需使桌面上的安装程序携带运行库,也不必将其打包到程序中,就能确保用户总是可以安装到最新的版本。
如果想快速地在设备上测定可用的运行库版本,可以打开Cgacutil.exe程序,它在Windows文件夹下。此程序将显示一个窗口,其中将列出已安装框架的版本,如图1.4
图1-4
Cgacutil工具显示的已安装框架版本
1.4 安装工程
Windows Embedded Compact 7支持一般的基于Microsoft Cabinet的安装程序格式(程序包的扩展名为.cab文件)。这些.cab文件包含程序文件和安装脚本,脚本用于指定文件安装的位置,并用于设置快捷方式与注册表。
1.4.1 visual studio安装程序工具
Visual Studio 2008引入了特定的模板,可以直接在集成开发环境(IDE)中生成.cab文件安装程序。而在过去,只能一次性生成.cab文件,若要做任何改动,不得不手动修改.inf文件,重新生成.cab文件。虽然新的方法并不完美,但它带来的体验更接近于桌面项目安装程序的生成。
1.4.2 设备安装程序项目类型
要创建新的设备安装程序,在“文件”菜单中选择“新建”|“项目”。依次找到“其他类型项目”|“安装和部署”|“智能设备CAB项目”。在“解决方案资源管理器”中选择设备后,您可以设置很多项目范围的选项。例如,Manufacturer和ProductName将合并显示在“设置”中的“删除程序”列表中。出于这个原因,我们建议,组合后的字符串总长度不要超过36个(英文)字符,因为,大多数设备使用纵向屏幕,这个字符串多出来字符可能会超出显示区。在极少数情况下,可能不希望用户卸载您的产品,可以通过将NoUninstall属性设置为True,便不会添加到“删除程序”列表中。
1.4.3 文件添加与目标设置
要安装文件,在安装项目中,可以将其粘贴到“文件系统编辑器”(如图1.5所示)。您可以使用各种标准的固定文件夹,将其内容正确部署到设备的本地文件夹中。也可创建新的文件夹或子文件夹。
图1-5“文件系统编辑器”,可以将要部署到目标设备的程序文件直接拖放到指定位置
1.4.4 添加快捷方式
快捷方式只是文件而已,也可以按照同样的方式使用“文件系统编辑器”。要为项目文件创建快捷方式,可以在那个文件上单击右键,并选择“创建快捷方式”。您可以对这个快捷方式重命名,将其设置为需要显示的名称,并移动到相应的文件夹中,例如,如果您想让它显示在“开始”菜单的程序列表中,将它移动到“Programs 文件夹”下即可。
1.4.5 写入注册表设置
桌面Windows安装项目一样,移动开发项目也提供内建的注册表预置功能。打开“注册表编辑器”会看到预加载的一些根键(项),如图15-6所示。您可以按照需求,在预加载的值下创建自己的键(项)。如果它们不在目标设备上,将会创建。
图1-6“编辑器”,可以使用它为应用程序设置键(项)和值
1.4.6 压缩
所有运行Windows Embedded Compact 7设备,都支持压缩的.cab文件。选择您的.cab文件项目,您可以在项目的“属性”窗口中激活压缩功能。您可能想将项目生成两次(第一个版本打开了压缩功能,另一个关闭),这样便支持所有设备类型。不幸的是,Visual Studio2008尚未提供此项操作的自动方式。
1.5 安全策略与代码签名
代码签名(code signing)最早是针对Smartphone平台引入的,曾用于确保移动设备运营商从某种程度上防止恶意软件对其移动网络造成影响。如表1-1所示。
表1-1Windows Embedded Compact 7安全配置
身份验证级别 |
双层安全模型 |
单层安全模型 |
用特权证书签名 |
应用程序可以使用特权的和普通的API与注册表项 |
应用程序可以使用特权的和普通的API与注册表项 |
用非特权证书签名 |
应用程序不可以使用特权的和普通API与某些注册表位置 |
应用程序可以使用特权的和普通的API与注册表项 |
未签名 |
不允许应用程序运行 |
不允许应用程序运行 |
大多数设备在默认情况下,会在程序的第一次运行时提示用户未签名。然后用户可以选择信赖这个程序,再次运行就不会再提示了。开发Windows Embedded Compact 7应用时,您需要考虑哪个API需要特权,这些API在Microsoft MSDN站点上被归入文档,网址为http://msdn2.microsoft.com/en-us/library/aa455835.aspx。在某些设备上,特权证书只能从制造设备的网络运营商那里获得。特权证书一般也可以从Mobile2Market签名计划中获得。
微软发布了Security Configuration Manager,可以使用它来查询或设置连接设备的安全策略。此功能将集成到Visual Studio 2008中。如图1-7
图1-7Security Configuration Manager可以方便地更改设备的安全策略
您可以方便地在各种安全模式下进行切换,包括关闭安全功能,那将允许任何应用程序的运行,而不会做出提示。您可以到Microsoft“下载中心”下载Security Configuration Manager,网址为www.microsoft.com/downloads/details.aspx?familyid= 7E92628C-D587-47E0-908B-09FEE6EA517A&displaylang=en。Visual Studio 2008将标配此功能。
1.5.1 代码签名
要对程序进行签名,必须有一个账户和代码签名主体,如VeriSign。这个费用根据您所申请签名事件的量来计算。一个签名事件意味着一个需要签名的程序文件(.dll,.exe或.cab)。如果要对大量独立文件进行签名,这个费用会十分可观。
建立一个带有签名权限的账户后,您会得到一个私有密钥,您必须用它来对所有的程序文件进行签名。在您生成并对文件进行签名后,将它们提交给提供商。提供商会检查所有的文件,并将这些签名替换成您的官方签名(根据Mobile2Market根密钥生成)。只有在文件得到最终签名后,才能被设备上的安全系统合理组织,且不会提示用户是否允许其运行。