Application Porting / Development in Windows CE
Introduction
Rapid Application Development is the mantra of modern day programmers. They hesitate to learn newer programming languages and at the same time do not want to unlearn the things they have already learnt. To satisfy their needs, Microsoft has once again come up without committing any blunder with an Operating System called Windows CE. Windows CE unlike its counterparts is a lightweight OS specially designed from scratch to cater the needs of devices ranging from TV Set top boxes, H/PC, P/PC to GPS Receivers(Global Positioning System). Windows CE supports the familiar Win32 API thereby enabling application developers to develop applications quickly and easily.
This paper introduces essential information on application development in Windows CE as well as porting existing applications destined for other Windows OSs to Windows CE.
Developing Applicatioins For WINDOWS CE
Setting the scene
Windows CE is a true 32 bit operating system with features like multitasking and multithreading. It is also a highly customizable OS, in the sense it can be altered to suit the needs of a specific device. In short Windows CE hosts all the good features of a modern day OS while eliminating those features that are not necessary to it. Several tools are available in the market for developing applications for Windows CE. This includes the different add-on kits like VC++ for Windows CE, VB for Windows CE and VJ++ for Windows CE. These are called as add-on kits because they integrate with their respective existing development tools. For example the VC++ for Windows CE when installed integrates with the installed VC++ 5.0 development environment. In other words VC++ 5.0 is mandatory for this toolkit to work. Moreover all these development tools are only for the Windows NT (4.0) platform. To customize the Windows CE OS to suit the needs of a specific device, Microsoft Visual C++ embedded toolkit (also known a s the Microsoft Windows CE Platform builder) can be used. It is this tool that helps in developing an OS that is compact and will serve the specific purpose in hand.
The most widely used devices that primarily use Windows CE are the Handheld PCs (H/PC) and the Palmheld PCs (P/PC). In the rest of the article by target device I refer to either the H/PC or P/PC. Several types of H/PCs and P/PCs are available in the market today, most of them use HITACHI SH3 and MIPS R4000 microprocessors. There are H/PCs and P/PCs that support other processors too but Microsoft generally provides support for SH3 and MIPS only, except for X86 emulation. In order to assist the programmers, Microsoft has provided a Windows CE emulation environment for the Intel X86 processors which provides an emulated shell to develop applications for Windows CE. This eliminates to a good extent the need for a target device for developing applications for Windows CE. Windows CE emulation is almost an exact replica of the original one so that the application developers can develop and test their applications using the emulator before incorporating it on the actual target. All the above mentioned develop ment tools for Windows CE come with a set of handy utilities like remote process viewer, remote registry editor, remote spy, remote object store etc. These utilities assist the programmers during the development and debugging of their applications.
PALM PC And The Hand Held PC
There is not much of a difference between developing applications for Palm PC and H/PC. The differences worth mentioning are those related to the user-interface and then the choice of tools available for developing applications. Applications for H/PC could be developed using any of the available add-on kits like VC, VB or Java or by using the Windows CE platform SDK, Handheld PC Edition. Even MFC support is available for H/PC. Thus developers are not restricted to direct SDK programming rather they can use the familiar Microsoft Foundation Classes library to develop applications for it.
Palm PC as of today has very few development tools. They are the VC++ toolkit for Windows CE and the Windows CE platform SDK, Palm-size PC Edition. Moreover there is no support for MFC in the Windows CE SDK, Palm-size PC Edition. Win32 APIs must be accessed directly for developing applications. Windows CE Platform SDK also doesn't include the cross compilers needed for developing binaries that run on Windows CE based devices. Both Cross-compiler support and MFC support is available only with the VC++ toolkit for Windows CE. For more information on the development tools available for Windows CE please refer to this FAQ on Toolkits.
This article focuses mainly on the VC++ toolkit for Windows CE for application development as well as for porting.
WINDOWS CE VS Rest Of Microsoft's WINDOWS OSs
Win32 APIs
Windows CE's support of the familiar Win32 API is the most significant factor of the OS. Thus rest assured for the programmers with prior knowledge of programming for Windows since they are already accustomed with the Win32 API. This way they can very well envy others saying that they know Windows CE programming too. Microsoft's strategy of providing a common set of APIs for all Windows OSs has once again worked wonders.
Due to the compactness of Windows CE and its differing hardware structure, not all the Win 32 APIs are supported by it as done by the other Windows OSs. Only a subset of the API is supported under Windows CE. But the most essential ones are supported. Moreover not all the supported APIs have all the features in it. Some APIs have reduced features. These differences are mainly due to power, memory and display constraints of the target device. There are also certain additions to the existing set of Win32 APIs. These additions are totally new and they are very specific to Windows CE.
Major changes were with the APIs related with GDI. One of the significant one was the absence of Metafile support. Moreover certain functions like MoveTo() and LineTo() were replaced with a single function called PolyLine(). Also there is no direct function calls for drawing shapes like arc, chord, pie etc. All these shapes could be approximated using the traditional ellipse function call. Redundant functions found in our traditional Win32 OSs are also replaced with a single function call. A typical example is the presence of multiple text output functions viz TextOut(), DrawText() etc. Windows CE eliminates this redundancy by supporting the DrawText() function alone. Windows CE GDI also provides support for True Type fonts. Even raster fonts are supported but only one could be used in any platform and is also OEM selectable. Absence of Print Manager and absence of support for spooling should also be considered. Moreover Printing process is single threaded in Windows CE thereby allowing only one appl ication to print at a time. In the text mapping mode domain Windows CE provides support to the MM-TEXT mapping mode only as opposed to the different modes supported under other Win32 based platforms. Other worth mentioning changes in the APIs includes the support for Windowing. Only fewer Window classes and styles are supported and there is also no support for Multiple Document Interfaces. Absence of the security parameters with certain functions like CreateProcess(), CreateFile() are also noteworthy. Thus to effectively use the GDI a careful analysis of the device capabilities is very essential and this could be accomplished using the GetDevicecaps() function.
MFC for Windows CE
Application development for Windows CE can take two paths one being our customary C programming with the Win32 API that CE exposes to us or by using C++ with the Microsoft Foundation Classes library. The former takes a long time to develop an application whereas the latter with its built in library support for all the routine chores takes only a very little time to develop. MFC actually provides classes that encapsulates the Win32 APIs and also other features like documents, views and even applications. By this way it helps for rapid application development. Windows CE being a compact operating system provides support for only a subset of the standard MFC library. MFC for Windows CE also includes several new classes viz classes for database support provided by the object store, new classes for Window sockets etc. Some of the new classes are provided below. They are CCeDBDatabase, CCeDBRecord, CCeDBProp, CCeDBEnum, CceSocket. There are also several enhancements to the existing classes due to the vari ed hardware / software characteristics of Windows CE. Possible examples could be the inclusion of the new control called command bar which has lead to the addition of several new member functions to the CframeWnd class. Similarly there are several classes that are provided with modifications like the Cbitmap class, Cbrush, Cbutton, Cdialog, Cedit etc. In the same manner several classes of the standard MFC library are not supported in CE. The best example would be the non-availability of the Multiple document classes involving CMDIChildWnd, CMDIFrameWnd and CmultiDocTemplate. Also no support is provided for classes peratining to rich edit controls, Animation controls etc as these controls are not supported under Windows CE. Similarly there is no support for ODBC, DAO and OLE and hence their classes.
Unicode
There is another major difference with Windows CE, it is the native text format of Windows CE, which is nothing but the Unicode format, similar to the one available under Windows NT. This might appear as a trivial information in the beginning but they are real nightmares to developers especially for people porting legacy Windows based applications (applications written for Windows OSs that do not support Unicode) to Windows CE. But with Unicode you have several advantages namely you can make your application to accommodate multilingual characters thereby helping your product to stand in the International arena. Moreover programmers are also educated to stick to Unicode rather than to develop applications for their native character formats. Additional explanations on converting to Unicode will be dealt in the forthcoming paragraphs of this article.
Memory
Memory plays a vital role in application development. Generally programmers tend to overlook this area because of the huge memory capacity of the current day desktop PCs. Windows CE devices in general will have much less RAM than a desktop PC. Moreover they do not have disk drives or other mass storage devices. Hence application developers must always have this constraint in mind while developing applications for Windows CE.
Windows CE devices generally have a RAM and a ROM section. ROM holds all the information decided by the OEMs, which includes the actual OS and other support applications like Pocket Word, Pocket Excel etc that comes integrated with the OS. RAM has two further divisions called the Program Memory & Storage memory (Object Store). Program memory is primarily used for the execution of applications, it generally stores the heaps and stacks of an application. Program memory could be compared with the RAM found in our desktop PCs where all applications are generally loaded for execution. The only exception here (Windows CE) is that ROM based programs are executed in place without being loaded into the RAM section (Program Memory) thereby saving precious RAM space and at the same time accelerating the execution speed too. Storage Memory is equivalent to the RAM disk (also known as RAM drive) which is generally used as a simulated hard disk. The only drawback with it is persistency, which in the case of our H/P Cs and P/PCs are provided by backup batteries thereby creating an illusion of permanent storage. On the other hand RAM drives on our desktop PCs are not persistent since the data held by them is generally lost if there is no power. Even in the suspended mode of Windows CE devices, the data in storage memory are persistent due to the availability of backup batteries. The same is the case during the device reset too. During reset, if any previous copy of object store is available it is generally used by Windows CE devices thereby avoiding any loss of data. The storage memory or the Object store is the place holder for the Windows CE file system, Registry and the Databases. All these objects have their respective APIs for accessing them. All these APIs are almost complete except for the absence of few features. These include the lack of functions that directly reference volumes in the case of file system, the lack of security attributes with functions corresponding to the Registry and the lack of powerful features found in the modern day databases. The database API is unique to Windows CE and is primarily used for storing simple data like address lists or mail folders. The amount of memory earmarked for program memory and object store is manually adjustable by the device user. All the applications that we develop are generally stored in the object store and loaded into program memory during execution.
As far as application development is concerned Windows CE provides almost the full Win32 Memory Management functions. Its support includes the virtual memory allocations, local and separate heaps and also memory mapped files. Windows CE supports the paged virtual memory management system as found in the other Win32s. Under this system each page is allocated either 1024 bytes or 4096 bytes as decided by the manufacturers. The entire 4 GB flat address space of Windows CE is divided among the different memory types with more than half being occupied by Virtual memory (Virtual address space). This is further segregated into 33 32MB slots with each devoted to individual applications. The different applications are protected from interfering with each other using altering page protections. A graphical illustration of the Windows CE memory architecture is provided below.

Another intriguing thing about Windows CE support for virtual memory is its ability to support this feature even with the absence of secondary storage devices like hard disks in Windows CE based devices. In our traditional desktop PCs with other Win32s, hard disks are generally used during the swapping of pages from the secondary memory to the primary memory. But with Windows CE devices all these swapping takes place in the RAM memory area thereby resembling our age old RAM DRIVE tradition. Thus effective usage of a proper memory type with its corresponding memory management function helps in avoiding low memory situations.
Power
Applications for Windows CE must be developed in such a way that it draws less power because Windows CE devices are generally battery operated. Those features of an application that draws more power must be kept to a minimum. Possible illustrations could be excessive use of snazzy graphics (of course within the realm of Windows CE), complex computations involving excessive looping etc. In short, elimination of unnecessary usage of CPU cycles saves power. These are the areas where developers should concentrate much to fine tune their applications. Applications should also host features to handle power shortages gracefully. Windows CE devices in general are equipped with power saving features like the suspended mode that comes with them. This feature uses only very less power than it is usually done with the normal mode. This mode is different from shutting off the system as the Windows CE OS is still running. Any events can be used to trigger it back to the normal mode. Applications could exploit this feature to remain dormant when they are not doing any processing apart from listening for event occurrences. Once the desired event occurs they can switch themselves back to the normal mode. This way an enormous amount of power could be saved.
User Iterface
Windows CE User Interfaces differ from the traditional UIs found in Windows 95 and NT. One of the very obvious differences is the replacement of Menu bars and Tool bars with one single Command bar. This was done mainly to give more room space for the application's primary Window. Inclusion of this new feature has given birth to new APIs which are missing from the Windows 95/NT systems. In other words these APIs are Windows CE specific. Another noteworthy change (not really on second thought) is the Stylus popularly available with all the Windows CE devices. Stylus replaces the Mouse found in traditional desktop PCs. Stylus provides the interface between the user and the touch screen found in Windows CE devices. Stylus represents a one-button mouse or in other words only the left button mouse messages can be trapped with the stylus. To accomodate right button too use of Alt key combined with a tap from the stylus is advised.
Some of the APIs dealing with UI are also revamped due to the differing hardware of Windows CE devices. Major hardware differences include the differing screen size with fewer pixels and with less or no color support. Resulting, for example, in the UIs on the PalmPC not showing the maximize/minimize buttons, in addition to the OK button being on top. In another nuance, CE may not generate PAINT messages in certain operations that you take for granted in vanilla Windows. This means the programmer must explicitly force a PAINT operation. Hence application developers must design and program their UI with utmost caution when dealing with Windows CE.
Networking
Windows CE supports features like Windows Sockets and IrDA Sockets for developing applications that could help communicate better. With Windows Sockets it is possible to develop applications that could use the familiar TCP/UDP and IP protocols. All network-based applications could be developed with this feature. Another major breakthrough with these handheld devices is the ability to use Infrared for communication. Infrared helps creating applications that could use wireless communication. This support is provided by IrSock, which is provided by the same WinSock API. In other words the WinSock API just provides an extension to the Infrared sockets thereby retaining the familiar WinSock interface for application developers. IrDA sockets use the Tiny Transport Protocol (TinyTP) for reliable delivery of messages. Developers could compare it with the TCP protocols that are generally used for data transfers over the Internet. IrDA also offers three different modes of operation namely Slow IR , Medium IR an d Fast IR with each one differing in their data transmission rate. Fast IR offers speeds upto 4Mbps and slow IR offers a maximum of 115.2 kbps with the medium IR falling midway between these two extremes.
More information on Infrared sockets programming could be obtained from the following article. Programming With Infrared Sockets
Debugging
The VC++ toolkit for Windows CE provides support for debugging too. It is possible to debug the applications destined for X86 emulator as well as to other platforms too. The same old traditional debugging features like Watch, Break points & Trace utilities are applicable here. Even remote debugging is possible. Debugging an application destined for the emulator is something similar to debugging an application destined for Windows NT/95. After successfully testing an application in the emulator, it should be downloaded to the target device for final testing. This testing could be done with the assistance of the remote tools that come with the toolkit. Some includes the remote process viewer, remote zoom in, remote connection server etc. For this testing to take place, either the H/PC or P/PC should be connected to the desktop PC through a serial cable. Only then the above mentioned remote tools could be used for testing. For debugging/testing applications destined for non-standard target devices, Windo ws CE APIs includes several debugging interfaces (APIs) that could be used to create a custom debugger.
Porting Applications To WINDOWS CE
Due to Windows CE's support of the Win 32 API there is an excessive zeal among developers to port their existing Windows applications to Windows CE. Applications of all ranges from complex data transfer packages to games are being ported to Windows CE. As far as Windows CE is concerned application development from scratch is minimal as compared to porting existing applications to it. The following pages will explore the major issues involved in porting an application to Windows CE.
Explore your application
The complexity of porting existing applications to Windows CE differs with the development environment used for developing it. In other words porting an application written for Windows 3.1 differs from those written for NT as well as for 95. Hence careful scrutiny of the application is necessary for successful porting.
Porting a 16 bit Windows Application to Windows CE
Porting a 16 bit Windows based application to Windows CE involves the conversion of the application to Win32 in the very first place. The reason behind this is, only Windows 95/NT provides backward compatibility to 16 bit applications where as Windows CE does not. After this conversion, the porting process is almost similar for all development environments. Windows 95/NT are able to support 16 bit applications because they use a concept called thunking wherein it is possible to execute the legacy applications (16 bit) in a Win32 environment (95/NT). Since Windows CE does not support thunking it is not possible for it to support this backward compatibility.
General Porting Issues
The following lines depict the different areas where the developer should concentrate while porting applications to Windows CE.
- Function support
Check if the Win32 functions used in the application are supported under Windows CE. If they are not, try to find an alternative for them in Windows CE else create a work-around. There are also certain Win32 functions that are supported under Windows CE but with limitations. Possible examples involve most of the GDI functions that don't have an equivalent in Windows CE. Functions like CreateWindow() for example supports only a very few styles unlike its implementation in 95/NT.
- Datatype support
Check if any Win32 structures used in the application are supported in Windows CE. All necessary Win32 structures are supported but certain members cannot be used or it may not be complete enough to accept all the available options.
The TIMECAPS structure that holds the information about the resolution of a timer is supported only in Windows 95/NT with no support under CE. The entire multimedia timer structure is totally unsupported under Windows CE. Even support for structures like time_t and _timeb are void.
- Windows Message Support
Not all the Windows Messages are supported under CE and there are also modifications on certain supported messages. Some new messages are also included like the WM_HIBERNATE message. It is only this message that intimates the application during low memory conditions. The programmer should provide an appropriate handler for this message to counter the situation. The handler must adopt certain methods to reduce memory usage and restore them to desired levels. It is considered to be a good programming practice to handle this message. Possible methods to reduce the memory usage could be to free up as many resources as possible like unloading dialogs, destroying windows, freeing up local storage etc. Thus the basic tenet upon receiving the WM_HIBERNATE message should be to free the large chunks of memory allocated using the VirtualAlloc calls, free the resources like bitmaps, windows and device contexts and to free the heap by saving their states. By this way the occurrence of this message could be avoided and memory could be allocated to applications that demand for it.
- Unicode Support
Windows CE is an Unicode environment, hence each character occupies two bytes and strings are terminated with two zeros. Maximal Use of "T" Macros is advised so that the applications have wide recognition in the ASCII environments too. The application must be examined carefully for possible use of ASCII strings and must be converted appropriately.
All ASCII string manipulation functions have their corresponding UNICODE equivalents. For example functions like strlen( ), strcmp( ) etc have equivalents like wcslen( ), wcscmp( ) etc. But it is advisable to use the Microsoft specific generic text mappings in order to enable the code to be compiled for Single byte, multi byte, unicode etc. Say in order to define an unicode variable, TCHAR can be used instead of wchar_T, which helps the code to adapt easily for any environments whether it is ASCII or UNICODE. Similarly when calling functions like wcslen() and wcscmp() it is advisable to use the _tcsxxx() family of functions like _tcslen() and _tcscmp() respectively. These generic text mapping functions and datatypes not only helps porting applications developed for Windows 95/NT to Windows CE easier but also vice-versa. These generic text mappings can be found in the header file TCHAR.H. There are two more functions for developers that will help immensely during application porting, they are WideCharT oMultiByte() and MultiByteToWideChar(). These functions are used specifically for conversions from UNICODE to ASCII and vice-versa.
- IrSockets support
All Windows CE based devices are equipped with built-in support for IR. Thus all legacy Windows based applications written with support for TCP/IP can be easily ported to IR for its low cost & speed. Moreover Wireless communication is the modus operandi for all mobile devices. Hence it is very natural to port applications with TCP/IP support to support infrared. In that case the most essential things to remember are the addressing structure used for IR. It is entirely different from the one used for TCP/IP where IP address is the unique ID for identifying the machines. Here (In IR) it is replaced with device identifiers that help to identify an IR enabled device. The other change in the addressing structure is the service names which represents the traditional port numbers found in the TCP/IP suite. These service names represent the actual service access points in a device.
Another point to be remembered with IrSockets is its support of stream based connections alone for data transfer. No support is provided here for datagrams as it is done by UDP in the TCP/IP suite of protocols. Hence application developers must alter their applications to use the services of TinyTP when porting to IrDA.
Applications supporting serial communication can also be ported to use Infrared with much less or no alteration to the application. This is made possible with the use of IrComm, which actually emulates a serial connection but uses IrSock and IrDA protocols underneath.
WINDOWS CE Porting Tips
The following code snippets illustrate the various issues involved in porting applications to Windows CE. Several tips on general application development issues are also provided here.
- Use TCHARS where ever applicable instead of chars as follows due to its Unicode nature.
To declare Unicode character variables directly use
Similarly use tcslen(), tcscmp() etc instead of their ASCII (strlen(), strcmp() etc) or UNICODE equivalents (wcslen(), wcscmp() etc).
- When using memory allocation functions like malloc() do allocate sufficient memory space as appropriate to Unicode Strings.
The above statement is correct in ASCII supported environments but not in Windows CE since it supports Unicode where the length of each character is 2 bytes.
- To convert between ANSI to UNICODE and vice-versa use
- Windows CE 2.0 does not provide complete support for Run Time Libraries and there is nothing like console Applications available in Windows CE 2.0. Hence expecting for functions like printf() and Scanf() are mere wastage of time.
Note: The latest version of Windows CE (2.10) provides a partial support for run time libraries. Hence it is possible to make calls like printf(), getc() etc. Also console application support is provided
- Relative path names are not supportedin Windows CE. All path names are relative to the root directory. Hence all occurrences of relative path names in the applications should be changed with the full path. In other words there is no concept of current directory under Windows CE, hence any references to any resource without specifying the full path always refers with respect to the root directory. Say we are currently in the directory \\windows and we refer to a file by name readme.txt under this directory. If we refer to it by just its name without giving the full path it will lead to nowhere since it will search for it in the root directory. Hence the full path needs to be specified.
- Asynchronous Window Sockets functions are not available under Windows CE. There is also no support for mail slots and named pipes.
- C++ exception handling mechanism is not supported. Only Win32 structured exception handling support is provided. This involves the use of macros like __try , __finally and __try and __except.
Case Study
Some of Calsoft Labs exposure to Windows CE programming came with its project of porting the HP JetSend's Appliance Development Kit (ADK) for Windows 95/NT to Windows CE. JetSend is a device-to-device communication protocol used primarily in office/mobile appliances from HP. An excerpt on the porting process is provided below to give the developers a realistic view of how an application could be developed / ported to Windows CE.
HP JetSend's Appliance Development Kit
HP JetSend's Appliance Development Kit hereafter called as ADK is a toolkit to accelerate the implementation of the HP JetSend Communication Technology. HP JetSend Communication Technology is a device, device type and transport independent data transfer technology. To obtain more information on HP JetSend point your browser to http://www.hp.jetsend.com
ADK is available as a DLL under Windows 95 and Windows NT platforms. ADK is a single threaded library written using pure 'C' language. It does not provide any GUI features and the current version provides support for only the TCP/IP transport. The ADK houses several string manipulation functions and socket calls for accomplising its goal of device independence, device type independence and transport independent data transfer. Our objective at Calsoft Labs was to port this ADK to Windows CE with support for Infrared Data transport. The major emphasis during porting was on the reduction of the size of the DLL. Its size under 95/NT was 210 KB (prior to porting).
Problems (en)countered
Major issues faced during the porting process were on handling the different string manipulation functions used inside the ADK. All functions accepting ASCII string parameters were altered to accept the Unicode ones. But unfortunately there were a lot of functions accepting ASCII parameters internally inside the ADK, so a special interface or a layer of abstraction was developed whose primary process was to get the incoming Unicode parameters convert them to ASCII as suitable to the ADK functions, process them and if the result is desired, they are then converted back to Unicode as suitable for display.
Another problem was with functions unsupported under Windows CE. ADK involved a lot of C Runtime libraries but there was no support for them under Windows CE. Hence they were replaced with the suitable alternatives. One good illustration could be the clock() function used in NT. This was not available in CE, hence they were written from scratch with the assistance of the GetSystemTime() function available in it.
Another major problem was with the data transportation part of ADK. ADK used the familiar WinSock APIs for transportation using TCP/IP transports. Since Windows CE supported WinSock APIs there was not much difficulty porting them to CE except for few unsupported error codes and absence of asynchronous socket calls.
As far as UI is concerned ADK had no part to play but still we at Calsoft Labs had to develop several sample applications involving UIs for this ported ADK. As discussed in this article we had to take care of the screen size of Windows CE devices and develop the interfaces suitably. Moreover we tried transferring bitmaps with the ported ADK and found that only a limited support was available for bitmaps. Compressed bitmaps were not supported under Windows CE. Hence bitmaps using compression schemes like RLE, TIFF etc were not supported under Windows CE.
Debugging while porting was very easy and comfortable with the emulator since the process was just the same as it is normally done while developing applications for NT and 95.
These were some of our experiences encountered during the porting of the ADK to Windows CE. The size of the ported ADK without performing any optimizations by exploiting the Windows CE specific features was 163 KB.
Conclusion
This paper provides you with just an overview as to what Windows CE is and the different development environments that could be used to develop applications for it. It also provides a clear picture of the differences between CE and the other family of Windows OS's. An overview of the key points to be had in mind while porting applications to CE is also provided along with a case study. With this information developers can start to explore the world of Windows CE.
Happy Windows CE Programming ...
Bibliography
- A Repository of information on Windows CE application programming and development tools.
- The Online MSDN Library has excellent articles on Windows CE especially on very vital areas relating to UI, Memory etc.
- Programming Windows CE - Douglas Boling (Microsoft Press Book)(Provides a detailed knowledge on Windows CE programming without using MFC.)
- Information on Windows CE devices and their features along with several articles devoted to configuring those devices.


