30 Days of Windows Mobile – Day 03: GPS Compass

June 9th, 2008

Screenshot of GPS Compass applicationThe third application in Chris Craft’s 30 Days of .NET is a GPS based Compass.

Interacting with GPS Devices

Windows Mobile 5.0 and above provides a unified API called the GPS Intermediate Driver that enables multiple applications to concurrently share a single GPS device. This API is highlevel and abstracts away the need to manually parse NEMA sentences etc.

To create a connection to the GPS Device we can include gpsapi.h and make use of the GPSOpenDevice API.

// Open a connection to the GPS Intermediate Driver
HANDLE hGPS = GPSOpenDevice(NULL, NULL, NULL, 0);

This API is reference counted. Each call to GPSOpenDevice must eventually be matched with a call to GPSCloseDevice. The GPS Hardware is only powered down when the last client closes it’s handle.

// Close our connection to the GPS Intermdiate Driver
GPSCloseHandle(hGPS);

Once a connection has been established we can call GPSGetPosition or GPSGetDeviceState to retrieve location and GPS device status information respectively. For example we can query the current location using a code sample such as the following:

GPS_POSITION pos;
 
// Setup the data structure
memset(&pos, 0, sizeof(pos));
pos.dwVersion = GPS_VERSION_CURRENT;
pos.dwSize = sizeof(pos);
 
// Ask the GPS intermediate driver to
// fill out the structure.
GPSGetPosition(hGPS, &pos, 500000, 0);

One thing to note is that the GPS_POSITION data structure contains a field named dwValidFlags. This field is a bitmask that tells you which fields contain valid data. For example if the dwValidFlags field does not contain the GPS_VALID_LATITUDE flag it means you can not rely on the dblLatitude field (perhaps a location fix has not been made yet).

The GPS Compass application makes use of an optional feature. By passing in two event handles to GPSOpenDevice we do not need to periodically call GPSGetPosition to gather new position updates. Instead we can wait until the GPS Intermediate Driver signals our events and only then call GPSGetPosition, safe in the knowledge that it will definatly return different results than the last call. This helps us be slightly more efficient with respect to battery lifetime due to less CPU load.

String Concatenation

By default we do not have access to a nice string class such as System.String. A string within a C or C++ application is essentially a fixed size character array that uses a NULL character as a terminator.

To copy a string from one string buffer into another we can make use of a function called wcscpy.

// Allocate a string buffer capable of storing
// 31 characters (the 32nd element is used to store a NULL
// terminator) and then copy the string "Hello World" into
// the buffer
WCHAR szMyBuffer[32];
wcscpy(szMyBuffer, L"Hello World");

Likewise to append a string onto the end of another we can make use of the wcscat function as follows:

// Add the string "Goodbye World" onto the end
// of the string already in 'szMyBuffer'
wcscat(szMyBuffer, L" Goodbye World");

While using these functions memory management is much more explicit than it is in C#. For example when you allocate a string buffer you must specify its maximum length and there is no bounds checking to ensure you don’t attempt to store 200 characters in a 100 character buffer. This leads to so called buffer overrun errors if you are not careful.

You may be more familiar with string functions called strcpy (string copy) and strcat (string concatenate). wcscpy and wcscat are essentially identical except that they work on “wide characters” (UTF16 encoded data) instead of ANSI.

Moving a Window

To move or resize a control (or any window for that matter) you can make use of the MoveWindow function.

// Move and resize the window 'hWnd'
MoveWindow(hWnd, // the window to move
  10,  // new x location
  20,  // new y location
  30,  // new width
  40); // new height

One problem with using the MoveWindow function is that you always need to specify both the window’s new location and size. Sometimes it can be useful to use a different function called SetWindowPos. This function accepts a few additional parameters, the most important one being a flags argument that enables you to specify which parameters should be taken notice of. For example to move a window without resizing it you may use a code snippet like the following:

SetWindowPos(hWnd,
  NULL, // hWndInsertAfter
  10,   // new x
  20,   // new y
  0,    // new width
  0,    // new height
  SWP_NOSIZE); // flags

The SWP_NOSIZE flag tells the SetWindowPos function that it should ignore the width and height parameters and leave the window at its current size. If you wanted to resize a window yet keep it’s current location you could use a similar SWP_NOMOVE flag.

Creating a Menu

This is the first sample application that has required the use of a menu. A menu is designed in the resource editor and loaded by the SHCreateMenuBar API. The call to SHCreateMenuBar is typically placed in the handler for the WM_INITDIALOG window message. This is convenient since this window message is received just before the dialog is made visible.

case WM_INITDIALOG:
  // Configure the menu
  SHMENUBARINFO mbi;
  memset(&mbi, 0, sizeof(mbi));
  mbi.cbSize = sizeof(mbi);
  mbi.hWndParent = hWnd; // the dialog's handle
  mbi.nToolBarId = IDR_MENU; // the menu resource id
  mbi.hInstRes = GetModuleHandle(NULL);
  mbi.dwFlags = SHCMBF_HMENU;
 
  // Create the menu
  SHCreateMenuBar(&mbi);
  break;

Once a menu is visible there is a range of menu APIs that enable you to interact with the menu. For example to enable or disable a particular menu item you can make use of the EnableMenuItem API as shown below:

// Disable a menu item with id 'IDC_SOME_ITEM'
EnableMenuItem(hMenu, IDC_SOME_ITEM,
  MF_BYCOMMAND | MF_GRAYED);
 
// Enable a menu item with id 'IDC_SOME_ITEM'
EnableMenuItem(hMenu, IDC_SOME_ITEM,
  MF_BYCOMMAND | MF_ENABLED);

Notice that the EnableMenuItem function is used to both enable and disable menu items, The MF_GRAYED or MF_ENABLED flags passed as part of the last argument determines which action you want to perform.

A handy place to put code that configures the state of menu items is the message handler for the WM_INITMENUPOPUP window message. This message is sent to the menu’s owner just before a menu becomes visible.

Menu items behave very similiar to buttons and send a WM_COMMAND window message when they are selected by the user. This fact can be used to your advantage. If you want a button and menu item to both perform the same task you can assign them the same command ID.

Sample Application

[Download gpscompass.zip - 96KB]

30 Days of Windows Mobile – Day 02: Bluetooth Manager

June 8th, 2008

Screenshot of Bluetooth Manager applicationThe second sample application produced by Chris Craft is a small utility to toggle the power of a Bluetooth radio. Leaving the power on to the bluetooth radio for extended periods of time can be a drain on the battery life of your device.

Accessing Bluetooth

This application only works on devices that utilise the Microsoft Bluetooth stack. Unlike other aspects of the operating system there is no standardised API for bluetooth development, leading OEMs to be free to pick the bluetooth stack they think best serves the requirements of their device.

The Microsoft Bluetooth APIs are designed for use with C and C++. To use them you need to include the header file “bthutil.h” and link to a library called “bthutil.lib”. You can determine these requirements by looking at the bottom of the MSDN documentation page for functions such as BthSetMode.

To change the state of the Bluetooth radio we can use the BthSetMode function as shown below:

// Turn the bluetooth radio off
BthSetMode(BTH_POWER_OFF);

BthSetMode accepts a single parameter which is the desired radio state. It can be one of the following three values:

Value Description
BTH_POWER_OFF The bluetooth radio is off
BTH_CONNECTABLE The bluetooth radio is on and other devices can connect to it
BTH_DISCOVERABLE The bluetooth radio is on and other devices can discover (find) it as well as connect to it

We can also query the current state of the bluetooth radio by calling a function called BthGetMode.

DWORD dwMode = BTH_POWER_OFF;
BthGetMode(&dwMode);
 
if (dwMode == BTH_CONNECTABLE)
{
  // Do something here if the radio
  // is currently connectable
}

Using the State and Notification Broker

Rather than periodically polling the BthGetMode function to determine when the radio changes state we can ask the operating system to proactively tell us when the bluetooth mode changes.

The State and Notification Broker (SNAPI) is built on top of an infrastructure that allows you to monitor the value of any registry key and obtain notifications whenever it changes. There are two header files involved.

  • regext.h – Provides functions that allow us to watch for registry value changes
  • snapi.h – Provides definitions of various registry values that store system state information

Our sample application makes use of a function defined in regext.h called RegistryNotifyWindow. This function monitors a registry value and posts a window message to a specified window whenever the value changes. We set this up using a code snippet that looks similar to the following:

HREGNOTIFY hregNotify;
 
// We are interested in any change to the registry value.
NOTIFICATIONCONDITION condition = {
  REG_CT_ANYCHANGE,
  SN_BLUETOOTHSTATEPOWERON_BITMASK, 0
};
 
// We want to listen to the BLUETOOTHSTATEPOWERON
// registry value and have a WM_BLUETOOTH_STATE_CHANGE
// window message posted to 'hdlg' whenever it changes.
RegistryNotifyWindow(SN_BLUETOOTHSTATEPOWERON_ROOT,
  SN_BLUETOOTHSTATEPOWERON_PATH,
  SN_BLUETOOTHSTATEPOWERON_VALUE,
  hDlg,
  WM_BLUETOOTH_STATE_CHANGED,
  0,
  &condition,
  &hregNotify);

By modifying the contents of the NOTIFICATIONCONDITION structure we can also produce more complex scenarios such as only being notified when the specified SNAPI property increases above a certain value.

Using a button control

This application uses two buttons. When the user presses a button the dialog is sent a WM_COMMAND window message to allow it to respond to the event. One of the parameters of the WM_COMMAND window message allows us to determine which button has been pressed. For example:

case WM_COMMAND:
   // Determine which button was pressed
   switch (LOWORD(wParam))
   {
     case IDC_BUTTON_POWERON:
       // turn the bluetooth radio on
       break;
 
     case IDC_BUTTON_POWEROFF:
       // turn the bluetooth radio off
       break;
   }
   break;

Using an edit control

To replace the entire contents of an edit (textbox) control you can use the SetWindowText function just like you would for a static control.

HWND hWndCtrl = GetDlgItem(hDlg, IDC_EDIT_LOG);
SetWindowText(hWndCtrl, L"This is the new content");

To append text to the end of the existing contents of an edit control is a two part process. First we can move the selection (cursor) to the end of the textbox via the EM_SETSEL window message and then we can replace that selection with the text we desire via the EM_REPLACESEL window message, as shown below:

// Move the cursor to the end of the edit control
SendMessage(hWndCtrl, EM_SETSEL, -1, -1);
 
// Replace that selection with the text we want
// to append to the end of the edit control
SendMessage(hWndCtrl, EM_REPLACESEL, FALSE,
  (LPARAM)L"Text to add");

Displaying an image

The static control is commonly used like a Label control would be within a .NET Compact Framework application however it can also be used like a Picturebox control.

To change the image displayed by the static control we can use the STM_SETIMAGE window message as demonstrated by the following code sample.

// Get the status bitmap control
HWND hWndCtrl = GetDlgItem(hDlg, IDC_STATUS_BITMAP);
 
// Load the desired image from a bitmap resource
HBITMAP hBitmap = LoadBitmap(GetModuleHandle(NULL),
  MAKEINTRESOURCE(IDB_POWER_OFF));
 
// Then send the STM_SETIMAGE window message
// to the static control
SendMessage(hWndCtrl, STM_SETIMAGE, IMAGE_BITMAP,
  (LPARAM)hBitmap);

The other thing we need to do for this code sample is to make the image click-able. By default a static control does not respond to stylus taps. Within the dialog resource editor you can set the Notify property for a static control to True. When this is done a WM_COMMAND message will be generated whenever the static control is clicked, just like a button would.

Sample Application

[Download bluetoothmanager.zip - 99KB]

The Bluetooth State and Notification broker properties are new to Windows Mobile 6.0 so ideally we should set the minimum OS version property in the CAB file to disallow installation on previous versions of the operating system. This is left as a learning experience for the reader (one hint is that the OS version you want to specify isn’t 6.0…).

Another reader exercise may be to download the Broadcom Bluetooth SDK and modify the sample application to work on devices that use this alternative Bluetooth stack.

30 Days of Windows Mobile – Day 01: Minutes to Midnight Countdown

June 8th, 2008

Screenshot of Minutes to Midnight applicationA great resource is starting to develop on Chris Craft’s blog. Chris has started a series of blog posts designed to produce 30 .NET applications for beginner Windows Mobile developers to explore and learn from. Chris has written his applications in C# targeting the .NET Compact Framework and Lou Vega has offered to produce VB.NET conversions.

Neil Roodyn recently commented on the general lack of native C and COM based knowledge shown by new developers in the .NET community. Personally I would find it difficult to understand things like the need for the Control.Invoke method without having an understanding of the APIs and mechanisms the System.Windows.Forms framework is attempting to abstract.

For these reasons I have decided it would be neat to convert Chris’s examples into native C++ as a way to compare the advantages and disadvantages of native code. It should also help increase the number of Windows Mobile code samples available in C or C++, something João Paulo Figueira has also noted as becoming increasingly difficult to find.

Chris’s first application is a countdown timer that counts down the amount of time left before midnight. This blog post covers some details of how I re-implemented it in C++.

Designing the dialog

The easiest way to create a small native application is to create a dialog based GUI. This allows us to graphically layout the dialog and write a little less code.

Like System.Windows.Forms based applications there is a clear distinction between form layout and code. The layout of one or more dialogs lives within a Resource File (*.rc) while the code is placed within *.cpp files. Each dialog resource is assigned an ID such as IDD_MYDIALOG that allows the two parts to be matched up.

To display a dialog we can make use of the DialogBox API

DialogBox(hInstance, (LPCSTR)IDD_MYDIALOG, NULL, MyDialogProc);

This displays the dialog stored within the IDD_MYDIALOG resource and waits until it is closed. The last parameter is the name of a dialog procedure. This function written by you will be called to process window messages sent to the dialog. These window messages are similar in nature to the various events and virtual methods available on classes such as System.Windows.Forms.Control.

The basic structure of a Dialog Procedure would look something like the following:

INT_PTR CALLBACK MyDialogProc(HWND hDlg,
  UINT message, WPARAM wParam, LPARAM lParam)
{
  switch (message)
  {
    case WM_INITDIALOG:
      // this is similar to the Load event so we
      // can perform dialog initialisation code here
      break;
 
    case WM_CLOSE:
      // this is similar to the Close event so we
      // can perform dialog shutdown logic here
      break;
 
    ...
  }
}

Using labels

The equivalent of a System.Windows.Forms.Label control for native code is the static control.

In order to interact with a control placed on a dialog we must obtain a window handle for it. Within a Win32 (User32) GUI application controls are in fact a special type of window. What makes them a control is the fact that they are a child of another window.

To get the window handle of a control we can use the GetDlgItem function, passing in the window handle for the dialog and the ID we assigned the control in the dialog resource editor.

// Get the window handle for the control
// with an ID of IDC_MESSAGE
HWND hwndCtrl = GetDlgItem(hWnd, IDC_MESSAGE);

Having obtained a window handle for the control we can now send it window messages. This serves a similar purpose to the various properties and methods seen on classes such as System.Windows.Forms.Label. Sometimes there are even helper functions available to make this process slightly easier. For example we can change the text displayed on a static control by calling the SetWindowText function

// Change the label to display "Hello World"
SetwindowText(hwndCtrl, L"Hello World");

Using progress bars

Progress bars are interacted with in a similar way to static controls except the set of window messages they understand is different.

For example to set the minimum and maximum values of a progress bar we can send it a PBM_SETRANGE or PBM_SETRANGE32 message as demonstrated below.

// Set the progress bar referenced by ‘hWndCtrl’
// to have the range 25 to 75
SendMessage(hWndCtrl, PBM_SETRANGE, 0, MAKELPARAM(25, 75));

Looking at the documentation for PBM_SETRANGE and PBM_SETRANGE32 can you determine why there are two messages that can set the progress bar’s range? This is an example of an implementation detail that the .NET Compact Framework abstracts away for you.

To set the current value of a progress bar we can send it a PBM_SETPOS window message.

// Set the progress bar referenced by ‘hWndCtrl’
// to the value 45
SendMessage(hwndCtrl, PBM_SETPOS, 45, 0);

Using a timer

Instead of dragging and dropping a timer component onto a form a C++ developer must create the timer via code.

To start a timer we can use the SetTimer function:

// Create a timer with ID 1234 and
// an interval of 1000 milliseconds (1 second)
SetTimer(hWnd, 1234, 1000, NULL);

When we no longer need the timer we can call the matching KillTimer function to stop it.

// Stop the timer with ID 1234
KillTimer(hWnd, 1234);

You will notice that timers are associated with a window (the first parameter is a window handle). Every time the timer interval occurs the associated window will receive a WM_TIMER message which is similar in nature to the Timer.Tick event.

case WM_TIMER:
  if (wParam == 1234)
  {
      // timer 1234's interval has occurred so
      // we can do something here...
  }
  break;

The purpose of giving a timer an ID is to allow a single window to have multiple timers associated with it. The WM_TIMER window message provides the ID of the timer which caused the message to be sent and hence allows us to respond differently to different timers.

Colouring the background

To seperate the different sections of the user interface Chris used a shaded background. The easiest way to do this is to handle the WM_PAINT window message. This is sent to a window when it is time to paint its contents.

Once a little house keeping is taken care of we can colour the three regions by painting three rectangles. To paint a rectangle we can make use of the FillRect function as shown below.

// Define a rectangle at x=40, y=10 with size 40x10
RECT rcBounds;
rcBounds.top = 10;
rcBounds.bottom = 20;
rcBounds.left = 40;
rcBounds.right = 80;
 
// Create a red brush and fill the
// area of the rectangle
HBRUSH hbrRed = CreateSolidBrush(RGB(255, 0, 0));
FillRect(hdc, &rcBounds, hbrRed);
DeleteObject(hbrRed);

Collectively the operating system drawing APIs are called the Graphics Device Interface (GDI). You will notice that GDI functions such as CreateSolidBrush have a strong resemblance to elements within the System.Drawing namespace such as the System.Drawing.SolidBrush class.

Time calculations

There is no equivalent to the System.DateTime structure, so time calculations have to be performed via a more manual process.

To get the current date and time we can call a function called GetLocalTime which returns a SYSTEMTIME data structure. This structure does not lend itself to calculations so we can then use the SystemTimeToFileTime function to convert it into a FILETIME structure which is essentially a 64bit integer representing time as the number of 100-nanosecond intervals since January 1, 1601.

This allows us to use division and other simple math operators to perform time-span calculations. For example given the current time we can perform the following calculations to determine how far we are away from midnight:

__int64 amount_of_today_past = current_time % ONE_DAY;
__int64 amount_of_today_left = ONE_DAY - amount_of_today_past;

Given this value we can then easily convert it into other units such as hours or minutes as desired. For example the following expression will return the same value as the TimeSpan.Minutes property.

__int64 minutes = (amount_of_today_left / ONE_MINUTE) % 60

Sample Application

[Download minutes2midnight.zip – 29 KB]

The C++ source code and a CAB file for this sample application can be downloaded. If you have any questions about the source code or would like to discuss native Windows Mobile development further please leave a comment on this blog entry.

Leading the Christchurch .NET User Group

May 26th, 2008

Photo of a man extending his hand for a handshakeMay has been a busy month for me (you may have noticed the distinct lack of blog posts) and I’m only now getting back to being able to tend to my blog. One exciting piece of news I haven’t mentioned is that I am now the leader of the Christchurch .NET User Group!

Daniel Wissa, the current user group leader, is leaving for Melbourne and I feel honored that he suggested I pick up the reins in his absence. I feel that it is going to be a challenging but rewarding experience and I look forward to being able to serve and help grow the community.

If anyone wants to present at the user group or has ideas on how we can better help you please feel free to comment on this post or contact me in private. Even if just to say hello, I would love to hear from others in the local developer community.

This new commitment has not changed my involvement in helping to organise the Christchurch Embedded .NET User Group.

One year of blogging… how can I help you?

May 5th, 2008

Photo of same candles on a birthday cakeA year ago to this day I was sitting in a cafe within the Venetian Hotel in Las Vegas and writing my very first blog post. I had just attended the Mobile and Embedded Developers Conference (MEDC) for the first time and was inspired by seeing industry leaders in person to start being more involved within the developer community myself.

I decided that starting to blog would be a good initial step and it has been a challenging and beneficial experience since. In the year that followed I have managed to write 104 blog posts and readers (that’s you!) have contributed 202 comments.

The 5 top posts so far have been:

This clearly shows a preference for posts which include custom controls or frameworks that extend the built in capabilities of the .NET Compact Framework.

Complementing my blogging I have also been active in the Compact Framework newsgroups and the MSDN Forums website. In fact in the latter I have made 1386 posts in this timeframe and I am extremely close (perhaps tomorrow!) in gaining my 5th star within their member ranking scheme due to the number of answers I provide.

Moving forwards I would like your help in further shaping this blog. How best am I able to help you?

  • How do you learn? Are short posts with small code snippets, longer articles, screen-casts or detailed sample applications best for you?
  • Are you looking for many shorter beginner how-to information or less but really technical and in depth exposes?
  • What kind of topics and technologies would you like to see covered?
  • What’s the best thing about this blog?
  • What’s the worst thing about this blog?

My immediate blogging goals will be to:

  • Finish the improved version of my popup notifications class.
  • Renew my effort to complete my 70-540 Study Guide.
  • Continue to develop the today screen plugin framework.
  • Continue to tidy up some loose ends on a couple of posts.

Many of these are sitting partially completed on my laptop and I just need to find the time to polish them up for general distribution…

I can’t wait to see what sort of opportunities my second year of blogging leads to. The first year has been a real hoot!

Embedded .NET User Group: Meeting 1 – Summary

April 25th, 2008

On Tuesday the Christchurch Embedded .NET User Group (EDNUG) held its first meeting. A good turnout of over 20 people attended bringing with them a wide range of experience and interest levels in embedded development. It was good to see a few people getting their first exposure to embedded development!

Andrew Leckie, Bryn Lewis, and myself decided to kick off the user group with a general introduction to the various Microsoft technologies and platforms for embedded development. There was a lot of interest in the audience for the .NET Micro Framework and many questions around how extendable it was from a third party perspective. During the presentation Bryn raised many interesting examples of previous projects he has worked on, including GPS enabled versions of the game DOOM and Windows CE based telemetry systems for Trains.

In the end due to time constraints we split the presentation up into two sessions. With the second half to be presented at our next meeting. I have attached the slides from the first session which covered an introduction of the .NET Micro Framework, .NET Compact Framework, Windows Embedded CE and Windows Mobile below.

It was great to chat with many of you during the meeting. One thing that was discussed was the “SPARK Your Imagination” promotion and the possibility of organising a group shipment of development boards. If you would be interested, have any comments or are able to offer support to the user group, please don’t hesitate to contact me.

SPARK your (Windows CE) Imagination

April 17th, 2008

Microsoft Windows Embedded SPARK Your Imagination logo

First announced with the release of Windows Embedded CE 6.0 R2 the SPARK initiative is designed to provide a source of cheap Windows CE development tools to hobbyists and other non commercial users such as academics.

As Mike Hall mentions in a recent blog entry the first development boards packages under this initiative are finally starting to become available. This announcement neatly dove tails into yesterday’s discussions about low cost development tools for Windows Mobile. In Mike Hall’s own words:

Windows CE has traditionally focused on professional embedded developers, sure we’ve had the evaluation kits for developers to try out the development tools and operating system, but these time out after 180 days, which is ok for commercial developers to make a decision about moving forward with a Windows CE based project but isn’t ideal for the community/academic/hobbyist developer.

The Spark Your Imagination program offers non-commercial developers low cost development boards (both X86 and ARM based options available) combined with fully licensed copies of Visual Studio 2005, and the latest release of Windows CE (i.e. Platform Builder) for essentially the cost of the hardware.

More details, including links to the available hardware options, can be found on the Spark Your Imagination website.

Free Windows Mobile Development Tools?

April 16th, 2008

What tools do you use to develop your Windows Mobile applications? Today I received the following question:

I am looking to develop VB.NET applications for WM5, but I am on far too tight a budget to afford Visual Studio. Is there a way to use VS2008 Express for WM5 development, or is there another free way to do this?

How would you answer this question?

When I first started developing applications as a hobbyist for Palm OS (and then eventually Windows Mobile) I utilised free tools. Free (or at-least cheaply) available IDEs and compilers were a large factor in getting me started in this area of development that has now turned into a professional career. A lot of my friends got started in the same way and Dale Lane mentioned a similar scenario in his recent interview.

I am interested in discussing what tools hobbyists are currently utilising as they discover they can develop custom applications for their PDAs.

At present the main options for Windows Mobile development are most likely as follows:

  • Embedded Visual C++ v4.0 – A free download that supports C and C++ development only. Doesn’t provide full support for newer versions of Windows Mobile and is fairly unsupported these days. A number of open source projects use this tool specifically because it’s a free download.
  • Visual Studio 2005 Standard Edition (or above) – A non free IDE that supports native (C/C++) and managed (C#/VB.NET) development.
  • Visual Studio 2008 Professional Edition (or above) – A non free IDE that supports native (C/C++) and managed (C#/VB.NET) development (adds support for .NET CF 3.5 development).

This means to develop a VB.NET application for a Windows Mobile PDA you require to purchase a copy of Visual Studio. The free Express editions of the IDE are not suitable.

If someone was interested in mucking around on an occasional Saturday afternoon and slowly learning about Windows Mobile development how would you suggest they go about it without occurring “significant” expense? I guess the 90 day trial version of Visual Studio 2008 Professional is possibly an option, but that does not leave too many weekends before the free license expires.

Is the lack of low cost development tools a problem? Are hobbyists an important part of the Windows Mobile ecosystem? What sort of developer would you classify yourself as? What helped you get started in programming PDA applications? Did you get started in your spare time or as part of your day job? Are there alternative development tools worth taking a look at?

I’m interested in your thoughts on this topic. Please post a comment to this blog entry and join the debate!

Windows Mobile Tip: ActiveSync Add/Remove Programs

April 11th, 2008

Screenshot of ActiveSync main window highlighting Add/Remove Programs optionAre you aware of the Add/Remove Programs menu option within ActiveSync? When you have a PDA connected to your desktop PC you can use the dialog to install new applications onto your PDA as well as uninstall existing software.

For example when you install the .NET Compact Framework 3.5 Redistributable on your desktop PC it will register the .NET CF 3.5 CAB files with ActiveSync. This means you can install the .NET CF 3.5 on as many PDAs as you require by using the Add/Remove Programs dialog. You don’t need to re-install the redistributable package for each newly connected PDA.

Adding your own application to ActiveSync’s list

With a little bit of additional effort it is possible for application developers to register their own application CAB file(s) with ActiveSync so that they are installable via the Add/Remove Programs dialog. This provides an easy way for non technical users to install your application as they do not need to be able to manually copy a file to the PDA or select it within File Explorer. You can even get this to occur automatically when your desktop setup application runs.

The following resources will help you implement this feature:

Community Interview: Raffaele Limosani

April 9th, 2008

1) Can you tell us a little about yourself?

Photo of Raffaele LimosaniMy name is Raffaele Limosani, I’m a Support Engineer at Microsoft CSS (Customer Service and Support) and I’m located in Milan, in the “Sunny” Italy — not so “sunny” btw compared to where I come from! (Rome) :-)

2) Can you tell us a little about what your role as a Support Engineer involves? What kind of developers do you help support?

I help ISV Application Developers “realize their potential” when working on the Windows Mobile and CE platforms: basically, if you have a Technical Support contract (including the one you got buying a Visual Studio box!) and need help while developing Smart Device projects, if you’re located in Europe-Middle East-Africa chances are that I’ll be your contact at Microsoft. I deal with “Premier” Customers (big contracts), Partners, MSDN Subscribers or developers who bought a Visual Studio box… are you aware that together with Visual Studio you bought Technical Support Incidents? Test us! :-)

3) You have recently started blogging about Windows Mobile development. What was your emphasis for doing this?

I felt that a blog was missing in the Windows Mobile-related blogosphere, related to Technical Support: that’s where the subtitle comes from… (”Support Side Story”) Basically I’m facing issues that for example didn’t find an answer in newsgroups and forums, or developers asking for advice about how to architect their applications. Sometimes I find myself repeating the usual suggestions (especially for .NET CF Memory Leaks or Kiosk-mode applications), and therefore I thought that a good investment for the community would be to publish my usual suggestions and solutions.

4) Your blog shows some real insightful glimpses into not only technical aspects of the Windows Mobile OS, but also how the Windows Mobile ecosystem is structured and functions. Would you mind briefly explaining the major players involved from the time Microsoft develops a new OS feature until the time the device reaches a shop or third party developer?

Microsoft provides device manufacturers (OEMs) with a tool called “Adaptation Kit for Windows Mobile” (a special edition of “Platform Builder”): this contains about 90% of the source-code for the Operating System and device driver sample source code. OEMs use this tool to adapt the Operating System to their hardware. They physically BUILD the platform after possibly having developed their own DRIVERS based on the samples that Microsoft provides. Apart from building the bits, it’s completely up to the OEMs to configure the OS, in terms of Security configuration, connections and so on (especially when a Mobile Operator brands the device). This is why it may happen that a problem is reproducible on one device and not another, with the same OS: in terms of Technical Support, many times the best initial step involves verifying if the issue is reproduced on the Emulators as well – if that’s true, it’s much easier for us to troubleshoot as we can also package a DEBUG build of the platform, or instrument parts of the RETAIL build with some specific debugging info. This is not available for ISVs purely because they don’t have the Adaptation Kit and this is for example one of the added values given by Technical Support.

5) Would you mind briefly explaining the difference between Windows Mobile and Windows CE?

Windows Mobile is based on Windows CE: it’s a special configuration of Windows CE modules put together by OEMs, which must pass a certification process in order to have the “Windows Mobile-Logo”. For example, every Windows Mobile device must have the Connection Manager: this is simply one of the requirements that must be fulfilled. But the bits in many cases are the same, and that’s why it’s so useful for ISVs to download the Evaluation Edition of Windows CE 5.0 to have plenty of native sample source code available. Despite the names, Windows Mobile 6 is NOT based on Windows Embedded CE 6.0 – probably the next version will be, so ISVs will finally have plenty of Virtual Memory to leak! :-) [Christopher - see the following post for further details]

6) I notice your blog posts are currently fairly evenly split among managed (.NET CF) and unmanaged (C / C++) posts. In your job supporting third party developers what do you see developers utilising out in the field?

Many have switched to managed development, but on Windows CE and Windows Mobile there are many topics that are better covered by native development. And that’s why OpenNETCF’s Smart Device Framework has been so successful.

7) When you are personally coding what language / environment do you prefer?

I prefer C#, now on Visual Studio 2008. My background was C/C++, not VB — therefore I found it easier to migrate to. Obviously there are many VB developers out there and I can handle requests about .NET CF applications written in VB.NET.

8) Do you carry a Windows Mobile PDA or Smartphone with you? If so what model?

Sure! And more than one! :-) Many times we have to deal with test devices with test platforms running on them. For example, lately I was carrying a very old HTC Tornado running the now just-released Windows Mobile 6.1! You see, “just-released” means “just-released to OEMs”: now they’re packaging ROM Upgrades for some existing Windows Mobile 6 devices and also will ship brand new devices, internally it’s been tested for a while.

9) What Windows Mobile feature couldn’t you live without (or conversely what feature do you find the most lacking or missing)?

I really enjoy using Windows Live for Mobile. Regarding missing or lacking feature I can’t express myself knowing the ones that will be introduced in the future! :-)

10) Due to supporting other developers are there any resources (or tools) that you would recommend for developers new to the Windows Mobile environment?

There are many tools available to programmers, but probably the one I use the most is the Device Emulator. Obviously if you have to deal with specific “real” features, say barcode-scanning, the emulator can’t help. But all the new features introduced in v3.0 and in the Windows Mobile 6 SDKs help a lot, and remember that if an issue is reproducible on the emulator then it’s sure that that it’s not related to a customisation of the OS done by the OEM: hence, it’s easier to troubleshoot. Then, surely every serious development should include Hopper in their tests. For managed development, you can’t live without the NETCF v3.5 Power Toys, while for native development remember you have the Application Verifier for Windows Mobile. And sometimes I find myself still using the (quite old) Windows Mobile Developer Power Toys!

Then I think having a repository of sample source code is always good. Re-using code is obviously something that a developer should do… why re-invent the wheel each time? And that’s why I usually prefer posts with some code in them… :-) So, here are some sources of sample source code:

Native:

Managed:

Finally since you asked about “developers new to the Windows Mobile environment“ I can’t omit the Webcasts and the “How do I”-videos!

11) Do you have any closing comments?

A comment about Microsoft Technical Support. It’s simply great that nowadays many developers rely on newsgroups and forums! I was there when Microsoft newsgroups were born and personally helped them to grow up, until they became auto-sufficient thanks to the great support given by Microsoft MVPs. When you don’t find an answer through your favourite Microsoft newsgroup or MSDN forums (or whatever!), just give the Microsoft Technical Support the chance to show what added value it can offer. If you have a contract (“Premier” or “Partner”) you will already be using it. If you have a MSDN Subscription or simply bought a Visual Studio box, chances are that you don’t know that you have the opportunity to open Service Requests thanks to a certain number of so-called “incidents”… so my suggestion is: make sure you use everything you’ve paid for! :-)