作者:Yaroslav Goncharov(如需转载请联系原作者)
2002年5月22日
原文链接:http://www.codeguru.com/Cpp/W-P/ce/smartphone/article.php/c3531/
介绍
有很多Windows CE 3.0的应用程序可以证明这个操作系统对于Smartphone 2002平台的重要性。这个平台基于Windows CE 3.0;对于软件的移植来说,这可是一个好兆头。不过,这一新的移动平台仍然有很多特殊的地方,例如较小的屏幕、不支持触摸屏和一些其它的用户界面概念,这些概念可能会成为软件开发者的潜在问题。关于这些平台间主要的区别,在Introduction to Smartphone 2002 for Pocket PC developers中已经列出了。
为了感受一下将各种方面到新平台,我决定移植一个已有的Pocket PC应用程序,它没有使用MFC。Pocket PC 2002 SDK中有一个简单的注册表查看工具例程,名字是“PSPCMonkey”,本文就描述了这个程序的移植过程,包括从用户界面设计到详细实现的各个部分。
本文还示范了Smartphone 2002平台上较为特别的技术,例如:
·使用新的菜单条资源,包括它一个已知的相关问题及其解决方法。
·创建可扩展的编辑框和列表框。
·实现“回退”键的支持。
·创建标准的Smartphone 2002标签。
Pocket PC
SmartPhone 2002
开始
最初的第一步是在Smartphone 2002平台下不做任何的改动来编译应用程序。它是使用纯粹的API编写的,因此我们有机会从编译器得到一个很好的结果。
我们得到了一个完美的结果——0 error(s) and 0 warning(s),就像先前我们所期望的那样。现在让我们来运行这个应用程序,从Smartphone 2002的角度来看看它吧。
这个结果看起来并不是太好。快速回顾一下这个程序,我们会发现还有以下的事情要做:
·列表框。根据Smartphone 2002的指导方针,列表框应该只包括一行。
·菜单条。这个应用程序应该包含一个它自己的菜单条。
·回退键。应用程序应该支持一个“回退”键。
·按钮。Smartphone 2002下是不支持按钮的。
·屏幕区域。控件并不适合屏幕。对话框能够使用垂直滚动来定位所有的控件。
·标签。标签应该和标准的Smartphone 2002标签看起来一样。
·标题条。标题条应该显示应用程序的名称,消息框的标题不应该太长。
·控件的行为。Smartphone是没有触摸屏的。
用户界面设计
用户界面的设计是移植中最重要的方面。较小的屏幕、没有触摸屏以及这另一组控件都应该考虑。用户界面设计应该分为几步。
布局设计
在Smartphone 2002屏幕上放置控件最主要的规则是“一个控件应该占据一行”。建议你使用标签来表示控件中所显示何种类型的信息。标签应该直接放置在控件的上方。
控件
根据Smartphone 2002的指导方针,列表框应该只包括一行。浏览可以用两种方法实现:使用一个带有左/右按钮的微调控件以及使用列表的展开视图。列表的展开视图在我们这种情况下非常有用,因为列表中会拥有很多的项目。
在Smartphone 2002平台下是不支持按钮的,一个好的解决方法是将它们替换为菜单条上的菜单项。
菜单条的动作按钮(左边的软键)将代替鼠标的点击。用户将使用这个键来进入注册表的键中。第二个软键通常用于菜单,但是我们现在这个简单的应用程序中还没有菜单。因此,在菜单条中我们还需要另外一个键:“回退”项来代替原应用程序的“回退/向上”按钮。
行为
通常,应用程序的用户界面是依赖于鼠标(手写笔)事件的。Smartphone 2002则并不会有产生点击事件的机会,因为它没有触摸屏。在我们这种情况下,我们拥有一个非常简单的应用程序,但在没有触摸屏的情况下它是无法工作的!问题就在于列表框是利用点击来浏览的。我们将使用菜单条中特殊的菜单项来代替这些点击。
实现
可扩展的列表框和编辑框
我们需要减少列表框的高度,并添加微调控件来实现项目的选择和扩展。以下的资源代码根据这些需求创建了一个列表框资源。
LISTBOX IDL_LISTBOX,4,15,131,10,
WS_TABSTOP | WS_VISIBLE | LBS_NOINTEGRALHEIGHT
CONTROL "", IDC_UPDOWN, UPDOWN_CLASS,
WS_VISIBLE | UDS_AUTOBUDDY | UDS_HORZ | UDS_ALIGNRIGHT |
UDS_ARROWKEYS | UDS_SETBUDDYINT | UDS_WRAP | UDS_EXPANDABLE,
0,0,0,0
以下的资源代码创建了一个可扩展的编辑框,因为这是一个查看工具应用程序,所以使用了只读的标记。
EDITTEXT IDE_TEXTOUT,4,70,131,12,ES_MULTILINE | ES_AUTOVSCROLL |
ES_AUTOHSCROLL | ES_READONLY | WS_TABSTOP
CONTROL "", IDC_UPDOWN, UPDOWN_CLASS, UDS_AUTOBUDDY |
UDS_ALIGNRIGHT | UDS_EXPANDABLE | UDS_NOSCROLL,
0, 0, 0, 0
菜单条
菜单条资源是一种新的资源,并且资源编辑器不能够正确地处理它。关于菜单条资源,已知的两个问题是:一个未定义的I_IMAGENONE关键字,以及资源编辑器将菜单条资源转换为二进制格式。
为了解决这些问题,我将菜单条资源放到了一个单独的自定义资源文件之中。要这么做,我创建了一个单独的文本文件,并添加了以下的菜单条代码。
IDR_MENUBAR RCDATA
BEGIN
IDR_MAINMENU,
2,
I_IMAGENONE, IDM_ENTER, TBSTATE_ENABLED,
TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE, IDS_ENTER, 0, NOMENU,
I_IMAGENONE, IDM_BACK, TBSTATE_ENABLED,
TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE, IDS_BACK, 0, NOMENU,
END
然后我将文件保存为PSPCMonkey.rc2,并将其添加入工程。最后的一步是使用View->Resource Includes菜单项,在compile time resource includes中包含这个文件。
这个方法使用自定义资源解决了这一问题。现在菜单条资源不能在资源编辑器中编辑,它应该作为一个文本文件来编辑。
同样,我们需要在字串表中添加用于菜单条显示的字符串,就像下面这样。
STRINGTABLE DISCARDABLE
BEGIN
IDS_BACK "Back"
IDS_ENTER "Enter"
END
回退键
回退键应该使用户返回前一个屏幕。在编辑控件中,它还要作为退格键来使用。在我们的应用程序中所有的编辑框都是只读的,因此,在主窗口按下回退键应该隐藏我们的应用程序。我推荐你每一次应用程序执行的时候都使用户返回到一个“更新”的状态。那么,回退键应该关闭我们的对话框。
要实现这一行为,我们不应该在我们的对话框中改写回退键。在这种情况下,回退键应该向对话框发送WM_COMMAND/IDCANCEL消息。我们只需要向DialogProc的主switch之中添加标准的处理器。
...
case WM_COMMAND:
switch (LOWORD(wParam))
{
// 用户选择了关闭对话框
case IDCANCEL: // 处理回退键
EndDialog(hDlg, TRUE);
break;
...
标题条
由于任务栏的尺寸有限,应用程序的标题应该尽可能地简洁明了。而且,标题可以根据子窗口来更换。例如,一个消息框将在标题条显示它的标题。在我们的应用程序中,标题条在主窗口的情况显示“Registry Editor”,在错误信息的消息框情况下显示“Error”。
标签
标准的Smartphone 2002应用程序(例如,收件箱)为标签使用了11号加粗的Nina,而不是当前对话框的字体。以下的代码创建了这一字体。
HFONT CreateLabelFont()
{
LOGFONT lf;
memset(&lf, 0, sizeof(LOGFONT));
HDC hdc = ::GetDC(NULL);
lf.lfHeight = -11 * GetDeviceCaps(hdc, LOGPIXELSY) / 72;
::ReleaseDC(NULL, hdc);
lf.lfWeight = FW_SEMIBOLD;
return CreateFontIndirect(&lf);
}
现在我们就可以在WM_INITDIALOG消息处理器中将这个创建好的字体指派给各个标签了。
g_hLabelFont = CreateLabelFont();
::SendDlgItemMessage(hDlg, IDC_STATIC1, WM_SETFONT, (int) g_hLabelFont, 0);
::SendDlgItemMessage(hDlg, IDC_STATIC2, WM_SETFONT, (int) g_hLabelFont, 0);
::SendDlgItemMessage(hDlg, IDC_STATIC3, WM_SETFONT, (int) g_hLabelFont, 0);
::SendDlgItemMessage(hDlg, IDC_STATIC4, WM_SETFONT, (int) g_hLabelFont, 0);
并且,当不再需要这个字体的时候(在WM_DESTROY处理器中)销毁它。
case WM_DESTROY:
DeleteObject(g_hLabelFont);
break;
总结
从编译器的观点来看,将一个没有使用MFC的Windows CE应用程序移植到Smartphone 2002平台是很简单的。但是,移植并不是这么简单的。你最主要的努力将会花费在用户界面的设计上。你应该为这个小屏幕来设计你的窗口;考虑这些不能使用鼠标点击的新控件、新行为,回退键以及标题条。
看起来,大多数的应用程序都应该保证它们的可用性。我们失去了触摸屏、大屏幕以及一些控件,但是我们得到了可扩展的列表框和编辑框、微调控件、可滚动的对话框以及很多的硬件按键。我认为这些新的方面应该可以补偿这些失去的东西,在Smartphone 2002平台的应用程序上发挥作用。
下载