Building Portable Windows Mobile-based Applications

来源:百度文库 编辑:神马文学网 时间:2024/04/28 10:20:00

Building Portable Windows Mobile-based Applications

 

Paul Yao

July 2005

Applies to:
   Windows Mobile–based devices
   Visual Studio 2005
   eMbedded Visual C++
   Windows Mobile version 5.0

Summary: This article summarizes key concepts and practices for building binary portability into Windows Mobile–based applications. (17 printed pages)

Contents

Introduction
Visual Studio 2005
Code Reuse
Uber Integration in Windows Mobile
Platform-Specific UI Objects
Conclusion

Introduction

An assumption underlying Microsoft‘s Windows Mobile development tools is that developers want to target one specific platform (for example, either Pocket PC or Smartphone — but not both). For developers who target multiple platforms, one solution is to ship a different set of executables for each platform. With just a bit more effort, however, a developer can build a single set of executables to support multiple platforms. This article discusses steps that you can take toward building a single executable — or set of executables — to target multiple Windows Mobile–based platforms.

Although Microsoft development tools are often geared toward single-platform targeting, Microsoft, as a company, tends to prefer a more integrated approach. In other words, the company‘s products suggest an approach that minimizes redundancy. Some people refer to this approach as "über-integration."

Visual Studio 2005

Microsoft‘s über-integration strategy is part of the DNA of Microsoft Visual Studio. When the first version was designed, the plan was to grow Visual Studio to support multiple programming languages and multiple target platforms. It was built as the foundation for a single tool that would work everywhere.

When Microsoft Visual Studio .NET 2003 was released, the journey for mobile device developers was only half over. Visual Studio .NET 2003 was the version that supported managed code development (the Microsoft .NET Compact Framework version 1.0) for devices — but not native code development. Another tool, Microsoft eMbedded Visual C++, supported native code development. With Microsoft Visual Studio 2005, the journey is complete. Visual Studio 2005 supports the complete range of application programming interfaces (APIs) and application types for Windows Mobile–based platforms.

  • Native application development*
    • Microsoft Win32 API
    • Microsoft Foundation Class (MFC) version 8.0 library
    • Microsoft ActiveX Template Library (ATL) version 8.0
  • Managed application development
    • The .NET Compact Framework version 1.0
    • The .NET Compact Framework version 2.0
    • ASP.NET Mobile Controls
*Another native application development option is the Microsoft Windows Template Library (WTL). Although not supported by Microsoft, it has a broad following as a native development API.

For developers who have used eMbedded Visual C++, the change to Visual Studio 2005 is going to be fairly easy. Visual Studio 2005 is not identical to eMbedded Visual C++, but it is similar enough so that it should not take much time to be productive. Visual Studio 2005 supports a superset of the features found in eMbedded Visual C++, which is of particular importance

Visual Studio 2005 is a very mature, and very complete, Integrated Development Environment (IDE). Experienced eMbedded Visual C++ developers will require little time to be productive with the whole range of IDE tools: text editors, context-sensitive help, rich source-level debugger, build tools, and device-emulation support. Visual Studio 2005 provides a unified development environment that promises to benefit every C and C++ programmer who writes code for mobile devices.

C++ Class Library Support: MFC, ATL, and WTL

C++ programmers are going to find that Microsoft provides the richest set of C++ class libraries in Visual Studio 2005 that the company has ever shipped. Previously, developers of mobile device software had to work with an earlier version of MFC and ATL (for example, when any version of MFC shipped in the read-only memory (ROM) of a Windows Mobile–based device, it was MFC version 3.0). Therefore, that was the version of MFC that shipped with eMbedded Visual C++. Compared to what was shipping for the desktop computer, however, MFC 3.0 was several years old. As the differences between the desktop computer and device versions of MFC increases, so does the difficulty of porting MFC application code between desktop computers and devices.

New to Microsoft Technologies?

MFC was developed as a C++ class library for building desktop computer applications. With the rise of the Internet and Web browsers, Microsoft created ATL to allow the creation of lightweight controls that could run inside a browser. For example, an ActiveX control in MFC might be 200 KB or larger; a comparable ATL–based control might be 50 KB.

Visual Studio 2005 ships with MFC 8.0 and ATL 8.0. These libraries have grown together over the years, such that MFC now relies on some ATL templates. The desktop computer versions of these libraries have been modified to support desktop computer development and device development — more integration with less porting pain. These two libraries can be used together or separately, depending on your needs.

Developers of Smartphone applications are going to be pleased to see that MFC now supports Smartphone development. This is, in fact, the first version of MFC for which that support exists. Anyone who wants to port MFC code to a Smartphone from desktop computer or Pocket PC code still must do some work because each platform has its own unique qualities. But the effort required to do this port is now much less than it was when MFC provided no support for Smartphone application development.

Microsoft released WTL in 2000 with very little fanfare. WTL is built by the same group that created ATL and was meant to be an extension to ATL. Some windowing features and other features that are needed to create full-blown desktop computer applications have been added. Although still lacking official support, WTL has gained a following. In May 2004, Microsoft released WTL onto the sourceforge Web site as an open source project. The release includes support for Visual Studio 2005 for Smart Devices. When you download and install WTL, the New Platform Wizard in Visual Studio 2005 lets you create WTL–based projects for both Pocket PC and Smartphone.

Platform-Specific Code

Whatever software you are developing, it makes sense to have a single code base. However, you may need to adapt to special-case code to address unique requirements. Perhaps the requirements are based on a specific version of an operating system, a specific device driver, or, in the case of Windows Mobile, to account for the differences between a Pocket PC and a Smartphone.

As shown in Table 1, there are a set of standard preprocessor symbols that you can use. These symbols are defined in the various include files for Microsoft Windows CE. By using these symbols, you can include a block of code, exclude a block of code, or have two (or more) alternative code blocks to include or exclude during the software build process.

Table 1. Standard preprocessor symbols

SymbolComments_WIN32_WCEVersion of Windows CE
  • Windows Mobile 2003 software for Pocket PC: 420
  • Windows Mobile version 5.0: 501
WIN32_PLATFORM_PSPCBuilding for any version of Pocket PC.SMARTPHONE2003_UI_MODELSmartphone user interface (UI). Visual Studio creates this symbol to support the source-code portability of the code that its wizards generate.POCKETPC2003_UI_MODELPocket PC UI. Visual Studio creates this symbol to support the source-code portability of the code that its wizards generate.WIN32_PLATFORM_WFSPBuilding for any version of Smartphone._DEVICE_RESOLUTION_AWAREApplication written for Windows Mobile 2003 Second Edition software or later that can adjust to dynamic changes to the screen size or the screen orientation.UNDER_NTTargeting desktop computer and server versions of the Windows operating system.UNDER_CETargeting Windows CE._WIN32Targeting the Win32 API.__cplusplusCurrent program is being compiled following C++ compiler syntax._DEBUGDebug build enabled.SHELL_AYGSHELLAny Windows Mobile–based device or any Windows CE embedded device that incorporates AYGSHELL.DLL.UNICODE / _UNICODEUsing 16-bit Unicode character set.

Visual Studio 2005 provides more details than eMbedded Visual C++ does about the actual values of these preprocessor symbols. You just have to know where to look.

To find the list of preprocessor symbols

  1. On the Project menu, click Properties.
  2. On the left of the Property pages, expand Configuration Properties, C/C++, and Preprocessor.
  3. On the right of the Property pages, find Preprocessor Definitions, and then click it. A button appears that contains an ellipsis.
  4. Click the Ellipsis button to open the Preprocessor Definitions dialog box.
  5. Click Macros. A dialog box shows a window pane with all of the preprocessor symbol details, as shown in the following figure.

    Platform-Specific Resources

One way that Visual Studio 2005 helps you develop Windows Mobile–based applications is by creating platform-specific resources. The Smart Device Application Wizard can create one set of resources for Pocket PC and another set for Smartphone. When you build for a specific platform, only the related resource files are included.

New to Microsoft Technologies?

A resource is a collection of read-only data that is defined in a resource file (*.rc and *.rc2). For example, the definitions for menus and dialog boxes are stored as resources. When the application is built, resources are put in a special read-only section of an executable file. Because resources do not change, the memory manager can read them when they are needed and discard them when they are not needed. By contrast, read/write data cannot be discarded so easily.
In addition to memory management, resources help support software localization. In addition to its UI objects, a resource file often contains a string table. By isolating an application‘s strings from other type of data, resource files simplify the task of localizing every part of an application.

Files that target Pocket PCs have a suffix of ".ppc". Files that target Smartphones have a suffix of ".sp". For example, if you build a project named test, it would contain the following Pocket PC-specific files:

  • Testppc.rc
  • Testppc.rc2
  • Resourceppc.h

If Smartphone files are also part of the project, Visual Studio 2005 adds these two files:

  • Testsp.rc
  • Testsp.rc2
  • Resourcesp.h

Code Reuse

Perhaps the best way to improve productivity is to reuse existing code. The assumption is that existing code does something useful and that the hard work of designing, developing, and testing already has been done.

In the best of circumstances, existing code provides a big productivity boost. The boost is provided when previous work is used and put to a second use. For this to happen, the code must be written in a way that makes it portable. Code does not become automatically portable or become portable by accident (that would contradict Murphy‘s Law). Instead, portability is something that you must plan for and build in by following some deliberate practices.

Reuse and Non-Portable Code

To enhance code portability, you have to deal with non-portable code. In only the rarest of cases, you will find applications, device drivers, or operating systems that do not have some non-portable code. The simplest approach is to clearly separate code that is meant to be portable from non-portable code — or platform-specific code, as it was referred to earlier.

One example of platform-specific code is code that is intended for a specific CPU. Another example of platform-specific code is the code that supports a program‘s UI. The following sections introduce specific examples of these two types of platform-specific code.

Platform-Specific Code: Supporting a CPU

A CPU‘s power-on sequence is typically a sequence of computer instructions that are specific to a given CPU (or CPU family). It would be counterproductive to require the same startup sequence for two different CPUs from different CPU families. For example, an Athlon processor from Advanced Micro Devices, Inc. (AMD) and an MIPS R5000 processor are quite different from each other and naturally have different startup instructions (in addition to having completely different instruction sets).

The startup instructions that a CPU requires to start up is analogous to breakfast that people eat upon waking each day. In some parts of the world, fish and rice are standard for breakfast; in other parts of the world, bread and coffee are more common. Just as different cultures have different norms for breakfast, the CPUs in different processor families have different startup instructions. A given CPU‘s startup sequence is established to meet the architectural requirements of that CPU. Of course, relatively few developers work at that low level; those developers who do probably prefer writing software to eating breakfast! Code that touches the hardware — be it the CPU, a network, or display adapter — is typically platform specific.

Platform-Specific Code: Interacting with a User

One very common place to find platform-specific code is in a program‘s UI. You can see an obvious example in the difference between a Web-based interface and a local client. Whatever Web server may be in use, the browser gets some combination of HTML and an interpreted script. A local client, by contrast, would use an API like Win32, MFC, or .NET.

Even focusing on the local client story, platform-specific hardware requires platform-specific code to take advantage of unique platform features. For example, a Tablet PC has a high-resolution digitizer behind the display screen. Making the most of the digitizer requires developers to make a portion of the UI code be platform specific. (The Tablet PC runs a superset of Microsoft Windows XP, but it is mentioned because many companies are starting to deploy them alongside Pocket PC and Smartphones.)

Between a Pocket PC and a Smartphone, which support virtually identical programming interfaces, hardware-specific differences exist. One device has a touch screen, but the other does not. A Pocket PC may have a larger screen (320x240 or even 640x480), but a Smartphone typically has a smaller screen (176x220). A Pocket PC has only a few input buttons, but a Smartphone has phone-specific buttons. From these differences comes the need for platform-specific UI code.

These differences aside, the common subset of APIs actually makes it quite easy to both share code and also to port from one platform to another. Getting the most from sharing code between a Pocket PC and a Smartphone, or a Smartphone and a Tablet PC, requires that you identify the unique features and support them in code that is separate from the common shared code.

Portability is an important requirement when the goal is to reuse code. But not all code must be reused. To write portable code, a software developer must know where the boundary lies between non-portable code and code that must be portable. To get code reuse, the software design must include an architecture that clearly and unambiguously defines this boundary so all team members understand it.

Tip   Portable code requires a clear boundary between portable code and platform-specific code.

Validating Code Portability

Simply defining what portability you want, however, does not get the job done. It is a good start and a necessary condition, but it is not sufficient. Developers need to check whether the portability goals have been met. In other words, developers need a way to validate the portability; the easier it is to validate, the more likely that portability will be achieved. To understand this concept better, an example of how validation helped achieve portability follows.

Recently, Microsoft Windows XP Professional x64 Edition has released. It took several years for 64-bit hardware to be ready, but the operating system port to 64-bit was straightforward. The reasons are largely because of practices that were put into place with the first 32-bit version of Windows, Microsoft Windows NT version 3.1.

Today, all desktop computers and server systems that run on the Windows operating system run on the x86 architecture; this was not always the case. The 32-bit versions of Windows were designed with portability in mind, and Windows NT has run on the following processor architectures:

  • Intel IA-32 x86
  • Digital Equipment Corporation (DEC) Alpha
  • MIPS R4000
  • PowerPC
  • Intergraph Clipper (never publicly released)
  • SPARC (never publicly released)

Success in building a portable operating system was possible because the platform-specific elements were isolated in the hardware abstraction layer (HAL).

Success in achieving portability goals was aided by a development process that involved parallel development efforts on two processors: Intel and MIPS. By building and testing for both architectures at the same time, portability issues were addressed as early as possible. Early changes enhanced the overall portability of the code base. Ports to subsequent CPUs were, therefore, much easier. An operating system is a very large — and atypical — project, but an important lesson can be learned from it.

Tip   To enhance portability, test early and test often on the target platforms.

When targeting multiple platforms, be sure to test early and test often on each of the platforms. You can make changes early to accommodate any unwanted non-portable code.

In the context of Windows Mobile development, for code to run on both Pocket PC and Smartphone, you want to develop for both devices simultaneously and test on both devices regularly. Although the emulator is convenient, make sure your development work is not limited to just working with the emulator. If you expect your users to have actual devices, you should conduct tests on those actual devices.

Make sure to test your code on different versions of a platform. If you have a Smartphone application, be sure to test it on Smartphones that run Windows Mobile 2003 software for Smartphones and Windows Mobile 5.0 (assuming those are the devices you expect your users to have). These two platforms have a lot of compatibility, but you want to be sure that you do not rely on some feature that behaves one way on one platform and another way on the other.

The goal is not to eliminate non-portable code. Instead, you should make sure that non-portable code is kept separate from portable code. Non-portable code is undesirable when it is located inside a body of code that is supposed to be portable. When you discover non-portable code, you should not eliminate it. Instead, you should move that code to the appropriate location — presumably with similar non-portable code.

Best Practices for Writing Portable Code

Some people may learn from successes, but some people learn more from their mistakes. Better still, however, is to learn from the mistakes of others — you get knowledge without the pain. In writing some Win16 code, a developer made a number of mistakes that made the port to Win32 quite difficult.

During the transition years from Win16 to Win32, the lowest level of the operating system was written from scratch. The system applications, however, were ported from Windows version 3.1 applications. The Windows 3.1 Notepad, for example, was ported to Windows NT 3.1 as a 32-bit application. Most ports were quick because Win32 was designed with portability from Win16 in mind. Also, most programs were developed using portability practices that have been well known for many years.

But not all programs were well written, including the Windows 3.1 Program Manager, which was the main UI shell for Windows 3.1. (When the Start menu was introduced, Microsoft retired the Program Manager.) It should have taken a few days, but the port of the Program Manager took several weeks — what went wrong?

The Program Manager was a simple program: it displayed icons for programs, and groups of programs were displayed in their own windows. There was nothing inherently platform-specific about the work Program Manager did — no low-level CPU code and no hardware-specific features. The Win16-to-Win32 port should have been easy; it was not. Why? Because the original developer did not follow standard Windows API coding practices. To help you avoid this problem, the following is a summary of today‘s best practices for building portable code to run on platforms that are powered by the various members of the Microsoft Windows family of operating systems:

  • Type portability: Use uppercase types instead of native C-language, lowercase types. In other words, use WCHAR and LPWSTR instead of unsigned short and unsigned short *.
  • String type portability: Use the T variation of string types for portability between Unicode and non-Unicode platforms. Use TCHAR and LPTSTR instead of CHAR and LPSTR.
  • C-runtime string function portability: Use the _t variation of string functions, as defined in tchar.h. For example, use _tcslen, _tcscpy, and _tcscat instead of strlen, strcpy, and strcat.
  • String and character constants: Use the _T() macro. For example, use _T("string") and _T(‘s‘) instead of L"string" and L‘s‘.
  • Operating system independent source: To enhance the portability of a given source file, include windef.h instead of windows.h. A windef.h file has the definitions for basic Win32 types.
  • Multiple platform code: When targeting two or more platforms, make sure that every developer has access to each platform so they can build and debug on each one as required.
  • Emulation versus real hardware: Emulators can be very helpful, but make sure that you test your code on actual hardware.
Note   A Web search yields many guidelines for writing portable code. Make sure that the goals for a particular set of guidelines match your goals before you adopt any set. It is not too difficult to find guidelines that contradict each other, which is the case for the first guideline.

Uber Integration in Windows Mobile

Developers who target Windows Mobile see the result of this approach — and benefit from it — in several areas:

  • Common Windows Mobile API set: Enables development of common native executables that target both Pocket PC and Smartphone.
  • Common .NET Compact Framework: Enables development of common managed executables that target both Pocket PC and Smartphone.
  • Common ARM instruction set (for all Windows Mobile platforms): Enables the emulator to host ARM emulation, so identical binaries run on actual devices in addition to and emulators.

To maximize the potential of Pocket PCs and Smartphones, while minimizing the confusion that two different devices may otherwise cause, these two Windows Mobile devices have identical programming interfaces. On the surface, the hardware and UI are different; inside, the supported APIs are exactly identical. They have, in other words, a unified architecture (über integration at work).

Why is this important? This unified architecture reduces the cost of supporting both platforms because a single binary (or set of binaries) can be built to support both platforms. This cost savings exists for all installable components, including applications and device drivers. This economy of scale benefits all development activities along the software development pipeline — design, coding, test, and stabilization.

Because this article is about building portable applications, it makes sense to describe what is meant by portability. For the purposes of this article, two types of portability are interesting: source-code portability and binary portability. This article focuses on binary portability, but for the sake of completeness, this article will briefly explain source-code portability.

Source-Code Portability

Source-code portability means build-time portability. You start with a common source code base to build multiple executables for different platforms. The Visual Studio 2005 New Project Wizard generates code that provides this type of portability. Source-code portability is a good thing because it lets you get significant code reuse. This portability is driven by the following two things:

  • Preprocessor symbols
    These symbols control the conditional compilation of portions of the source code. Two symbols play two roles: WIN32_PLATFORM_PSPC for Pocket PC–specific code and WIN32_PLATFORM_WFSP for Smartphone-specific code.
  • Resource files
    The read-only data that drive user interface objects, like menus and dialog boxes, and they also centralized string table. Source code portability is supported by means of having a duplicate set of resource files: one for Pocket PCs and another for Smartphones. As provided by the New Project wizard, either one set or the other set — but not both — are included when a Windows Mobile project is built.

Four platforms — and not just two — are implicitly supported by the New Platform Wizard. In addition to the two Windows Mobile platforms, there is also Windows on the desktop computer (for example, Windows XP), in addition to Windows CE in embedded platforms.

Binary Portability

Binary portability means run-time portability — that is, a single binary file (or set of files) can run on two or more platforms. At the lowest level, your target platforms need a common CPU instruction set. For native code, a common instruction set is easy because all Windows Mobile platforms are built on ARM cores that support the same ARM4TI instruction set.

The other piece you need for binary portability is minor tweaks to your program for variations in platforms. Because the New Platform Wizard provides source-level portability, the tweaks involve undoing what the wizard has done for you. Undoing this work is not difficult to do because the changes are easy to find. The required changes fit into one of the following two categories:

  • Conditionally compiled code
    To get binary portability, find conditionally compiled code; modify it so that run-time checks are performed instead of build-time checks.
  • Resources
    Modify resource files so all resources, and not just a subset, get incorporated into the executable file.

Run-Time Checks

To set up things to work properly on every target platform, locate all of the conditionally compiled code. For example, the following is code that the New Platform Wizard puts in place for Pocket PC targets.

#ifdef WIN32_PLATFORM_PSPC    SHInitExtraControls();#endif // WIN32_PLATFORM_PSPC

To get binary compatibility, make this a run-time test instead. The preceding code changes to:

if (bPocketPC){    SHInitExtraControls();}

For this code to work properly, a flag — bPocketPC — must be set when the program runs on a Pocket PC. The following code detects different Windows Mobile–based devices and the different versions of Windows CE.

// Platform flags.BOOL bPocketPC     = FALSE;BOOL bSmartphone   = FALSE;BOOL bWinMoFiveOh  = FALSE;BOOL bWinMo2003    = FALSE;BOOL bWinMo2003_SE = FALSE;// InitPlatformFlags - query system and set flags.void InitPlatformFlags(HWND hwnd){    // Query platform name.    TCHAR atchPlat[64];    SystemParametersInfo(SPI_GETPLATFORMTYPE, 64, (PVOID)atchPlat, 0);    if (_tcsncmp(atchPlat, L"PocketPC", 64) == 0)    {        bPocketPC = TRUE;    }    if (_tcsncmp(atchPlat, L"SmartPhone", 64) == 0)    {        bSmartphone = TRUE;    }    OSVERSIONINFO osvi;    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);    GetVersionEx(&osvi);    if ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 01))         bWinMoFiveOh = TRUE;    if ((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion == 20))         bWinMo2003 = TRUE;    if ((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion == 21))         bWinMo2003_SE = TRUE;}

Incorporating All of the Resources

The second step in building a Windows Mobile application that has binary portability is to include all of the required resources. Though not strictly required, you can simplify the process in the Smart Device Project Wizard by requesting multiple types of platforms. In Figure 1, for example, the target software development kits (SDKs) are set to include both Pocket PC and Smartphone platforms.

Figure 1. The Smart Device Project Wizard that creates multiple target platforms

When both types of Windows Mobile platforms are targeted, the New Project Wizard creates two sets of resource files. Figure 2 shows the Solution Explorer for a project that targets both Pocket PCs and Smartphones. Two of the resource files are for Pocket PC (testppc.rc and testppc.rc2), and two are for Smartphone (testsp.rc and testsp.rc2). A red minus sign in the following figure shows that the Pocket PC resource file is excluded from the build.

Figure 2. Solution Explorer that shows two sets of resource files

If you simply enable both resource (*.rc) files, you get error messages. The problem is that there are many redundant resources between the Pocket PC resources (testppc.rc) and the Smartphone resources (testsp.rc). A close look at the resources themselves, however, shows that most resources have only a minimum of dependency on the specific platform. The two exceptions are menus and dialog boxes, which are discussed next.

Platform-Specific UI Objects

The Add Resource dialog box in Visual Studio 2005 shows nine types of resources, as shown in Figure 3. Most are platform independent, which means you can create a single set that can be shared between Pocket PCs and Smartphones. The two exceptions are menus and dialog boxes.

Figure 3. The Add Resource dialog box shows nine types of resources

Menus

Menus on Smartphones and Pocket PCs are inherently different. A Smartphone can only have two top-level menu items; by convention, the left menu is not a pop-up menu item but rather a stand-alone menu item. A Pocket PC, on the other hand, can have multiple menus on its menu bar. In addition, a Pocket PC can have buttons on its menu bar. The user interface for each of these two platforms was designed to make the most of its respective platform.

It is, however, quite possible to create menus that are identical on both platforms. In the context of this article, when you build a single binary for both platforms, you can have the same menu on both platforms. It means settling for a simpler set of menus on Pocket PC. There are a few benefits to this approach; the most obvious is that someone familiar with an application on one of the platforms is going to be immediately familiar with that application on the second platform. A second benefit is that the simpler menu structure makes single-handed operation easier to accomplish.

In fact, a common menu style for both platforms is an approach that Microsoft is now advocating. Figure 4 shows the screen of a Smartphone that runs Windows Mobile 5.0 software for Smartphones. Figure 5 shows the screen of a Pocket PC that runs Windows Mobile 5.0 software for Pocket PCs. With the introduction of Windows Mobile 5.0, the UI logo guidelines have changed so both devices have a command bar with two menu items: a one-level button on the left and a pop-up menu on the right.

Figure 4. Smartphone that runs Windows Mobile 5.0 software for Smartphones. Click the thumbnail for a larger image.

Figure 5. Pocket PC that runs Windows Mobile 5.0 software for Pocket PCs. Click the thumbnail for a larger image.

Dialog Boxes

Assuming that your goal is binary portability between Pocket PCs and Smartphones, most of your development time will be spent adjusting for the different screen resolutions and orientations. And it turns out that only one UI object is tightly tied to screen resolution and orientation: dialog boxes.

Early Pocket PCs had a 240 x 320 screen in portrait mode. Early Smartphones had a 176 x 220 screen also in portrait mode. These resolutions started to change with Windows Mobile 2003 Second Edition. To run on the current and expected future Windows Mobile 5.0 devices, a program must be ready to accommodate a range of resolutions that include full VGA (640 x 480) and a square screen (240 x 240).

There are several ways to address this issue. One approach is to avoid using dialog boxes although this is realistic only for applications with the simplest UI. A second approach is to programmatically modify the location and size of controls based on the screen size and orientation. A drawback to this approach is the time and energy required.

The simplest approach is to have multiple dialog box templates. How many sets of templates do you need for each dialog box? At present, the answer is six, which are as follows:

  • 176 x 220 – Smartphone
  • 240 x 320 – Smartphone, Pocket PC portrait
  • 320 x 240 – Pocket PC landscape
  • 240 x 240 – Pocket PC square
  • 640 x 480 – Pocket PC landscape
  • 480 x 640 – Pocket PC portrait

This list includes both portrait and landscape orientations. For more information about how to handle this issue, see Developing DPI-Aware Applications

Differences in Handling Input

When attempting to build a single executable file that works on both Pocket PC and Smartphone, consider differences in how input is handled. A Pocket PC has a touch screen; a Smartphone does not. A Pocket PC has neither the numeric keypad or the Call and Disconnect buttons of a Smartphone.

Beyond physical hardware differences, there are issues related to how that hardware is used in a typical application. A common action in a Pocket PC involves the user tapping the device to make a selection. There is no direct equivalent on a Smartphone, so another approach is needed. It may involve the user having to navigate the selection by using arrow keys. What is needed is an alternative approach that gives equal capabilities to program users — regardless of the specific platform.

Another common action that a user does on a Pocket PC is to tap and hold to open a pop-up menu — sometimes known as a shortcut menu. Again, some means must be found so that a program on a Smartphone has equal capabilities as the same program on a Pocket PC. In this case, an additional menu item or a dialog box may address the issue.

Conclusion

And that‘s the way it is, this twenty-second of July, 2005. I am not Walter Cronkite. Goodnight (Gracie…). (Okay, didn‘t like that? How about this…)

This article covered portability in Windows Mobile application development. Writing portable code helps make you more productive; however, you must decide whether you want source code portability or binary portability. The various wizards and code generators in Visual Studio 2005 help facilitate source code portability when building native applications. With a fairly modest amount of effort, you can achieve binary portability in your smart device applications. Developers targeting multiple platforms will find that binary portability streamlines almost every aspect of their development, deployment, and support efforts for smart devices.