Capture and respond to user input to a notification bubble

October 30th, 2007

A popup notification showing an HTML based form for ordering a Pizza.In my previous blog entry about notifications I mentioned that we had not covered the ResponseSubmitted event. Subscribing to this event allows you to respond to user input entered within a notification bubble. This blog entry discusses how you can capture and process user input within notifications.

Creating an HTML based form
The contents of a notification bubble is formatted using HTML. To request user input within a notification bubble we can utilise a HTML based form.

A simple form specified within HTML may look like the following example:

<form>
  Name: <input name="name" /><br />
  <input type="submit" />
</form>

Similar to a System.Windows.Forms base application there are a range of controls which can be used within an HTML based form. These controls are typically specified via an <input /> element, although there are some exceptions as shown in the following table:

Name HTML Syntax
Hidden Field
<input type="hidden" name="fieldname" value="default" />
Textbox (single line)
<input type="text" name="fieldname" value="default" />
Textbox (single line password)
<input type="password" name="fieldname" value="default" />
Textbox (multi line)
<textarea name="fieldname" cols="40" rows="5">
    default value
</textarea>
Radio buttons
<input type="radio" name="fieldname" value="1" />
<input type="radio" name="fieldname" value="2" />
<input type="radio" name="fieldname" value="3" />
Checkbox
<input type="check" name="fieldname" checked="true" />
Combobox
<select name="fieldname">
    <option value="1">option 1</option>
    <option value="2">option 2</option>
    <option value="3">option 3</option>
</select>

A sample form with two textbox controls could be specified within C# source code as follows:

Notification notif = new Notification();
notif.Text = @"<form>
    Field 1: <input type=""text"" name=""fieldname1"" /><br />
    Field 2: <input type=""text"" name=""fieldname2"" />
  </form>";

Buttons
Using the controls specified above allows a notification to accept input from the user. However it does not provide the user with a mechanism to submit a completed form to the application for further processing.

A form is typically submitted when the user presses a submit button. A submit button can be specified within HTML via the use of an <input type=”submit” /> element. Whenever the user presses the submit button the ResponseSubmitted event will be triggered, allowing the form to be processed by the application.

Buttons can also be utilised within a notification to temporarily hide or permanently close a notification without submitting a form (useful for cancel or postpone style buttons etc). These actions can be specified via the use of button elements within the HTML as demonstrated below:

<!-- This button will minimise the notification -->
<input type="button" name="cmd:2" value="Hide" />
 
<!-- This button will permanently close the notification -->
<input type="button" name="something" value="Close" />

The value attribute contains the text displayed on the button, while the name (i.e. “cmd:2″) controls the action which occurs when the button is pressed. The name “cmd:2″ is a special value indicating to the operating system that the notification should be minimised and displayed as an icon that can be clicked to redisplay the notification. Having a button with any other name will cause the notification to permiantly be dismissed without the ResponseSubmitted event firing. All other “cmd:n” style button names are reserved by Microsoft for future use.

Hyperlinks
A HTML form can also contain traditional hyperlinks such as the following example:

<a href="help">Display further help</a>

Whenever such a link is pressed within the notification, the ResponseSubmitted event will trigger and the response string will be the string specified as the href attribute (”help” in this example).

Many of the built in operating system notifications utilise hyperlinks to provide access to settings or customisation dialogs.

Processing the response
When a HTML form within a notification is submitted the ResponseSubmitted event will trigger and this is the ideal opportunity for an application to process the contents of a form. The ResponseEventArgs parameter passed to this event handler contains a Response property that includes the current values of all fields within the form encoded in a format known as application/x-www-form-urlencoded.

Section 17.13.4 of the HTML 4.01 standard discusses application/x-www-form-urlencoded form data with the following description of the encoding process.

This is the default content type. Forms submitted with this content type must be encoded as follows:

  • Control names and values are escaped. Space characters are replaced by `+’, and then reserved characters are escaped as described in [RFC1738], section 2.2: Non-alphanumeric characters are replaced by `%HH’, a percent sign and two hexadecimal digits representing the ASCII code of the character. Line breaks are represented as “CR LF” pairs (i.e., `%0D%0A’).
  • The control names/values are listed in the order they appear in the document. The name is separated from the value by `=’ and name/value pairs are separated from each other by `&’.

As an example, if the form specified above contained the strings “Hello World” and “Good Bye” it would be encoded and appear within the Response property as follows:

?fieldname1=Hello+World&fieldname2=Good+Bye

The Microsoft documentation for the Response property contains an example of how to parse such response strings. It does this via some rather brittle string search and replace style operations. The sample code is not very generic, as it will break if you change the structure of your form even a little (such as renaming a field) and it does not deal with decoding hex escaped characters.

Within the sample application mentioned below I have implemented a function called ParseQueryString which performs the application/x-www-form-urlencoded decode process and returns a more easily used Dictionary of field control names to value mappings. This allows you to write a ResponseSubmitted event handler which looks something like the following:

private void notification1_ResponseSubmitted(object sender,
    ResponseSubmittedEventArgs e) 
{ 
  // This dictionary contains a mapping between 
  // field names and field values. 
  Dictionary<string, string> controls = ParseQueryString(e.Response); 
 
  // Make use of the field values, in this case pulling the
  // values out of the textboxes and displaying a message
  // box.
  MessageBox.Show(String.Format("first field = {0}, second field = {1}", 
	controls["fieldname1"], controls["fieldname2"]); 
}

This should make the intention of the ResponseSubmitted event handler easier to determine, and makes for more easily maintained code. The “hard” part of the response parsing logic is now hidden away within the ParseQueryString function, leaving you with an easy to use collection of field values to play with.

Including images within a notification
Sometimes it is helpful to include a small image within a popup notification. This is possible, but as Keni Barwick found out, the syntax of your HTML has to be fairly precise for the notification balloon to locate the image (a similar situation to images within HTML help files).

You should have good success if you use the file:// protocol, and include a full path to your image using backward slashes to separate directories, i.e. use the format:

<img src="file:///path/to/image.bmp" />

For example to include the image \windows\alarm.bmp you would use the following HTML:

<img src="file:///windows/alarm.bmp" />

You could hard-code the path to your image file but this could cause problems if the user decides to install your application in a different location (on an SD card for example). If your images are stored in the same folder as your main executable you can determine the path to your images at runtime by using a function similar to the following code snippet:

using System.Reflection; 
using System.IO;
 
public string GetPathToImage(string fileName)
{
  // Determine the exe filename and path
  Assembly assembly = Assembly.GetExecutingAssembly();
  string executablePath = assembly.GetName().CodeBase;
 
  // Trim off the exe filename from the path
  executablePath = Path.GetDirectoryName(executablePath);
 
  // Add the specified filename to the path
  return Path.Combine(executablePath, fileName);
}
 
string imageURL = GetPathToImage("foo.bmp");

Sample Application

[Download notificationuserresponsesample.zip - 16KB]

A sample application is available for download. The sample demonstrates using a notification to specify the details of a pizza order. It also demonstrates the inclusion of an image within a notification.

When targeting a Windows Mobile 5.0 or above device, you could extend the sample by using the custom soft keys feature mentioned in a previous blog entry to submit the notification by pressing a subkey instead of pressing a button within the body of the notification.

Please feel free to make use of the ParseQueryString method and any associated functionality within your own applications.

Neat custom controls, comming your way soon…

October 9th, 2007

For the past few days I have been working on a University assignment due Monday, as well as helping organise the next .NET User Group Code Camp being ran on November the 3rd and 4th. As such progress has been slow on my personal projects.

As mentioned earlier I have started work on improving my .NET Compact Framework Notification wrapper to support arbitrarily complex soft key menus. Progress has been quite good, with custom menus now largely working. Along the way however I have learnt a number of interesting things about the implementation of SHAddNotification (and SHCreateMenuBar). I’ll discuss some of these later and their impact on the wrapper, which hopefully I will be able to complete once my assignment is submitted.

Another project I have toyed with this week is porting SWI-Prolog’s text console window (plterm.dll) to Windows Mobile as part of improving the editor window within PythonCE. Rainer Keuchel has ported an older version of SWI-Prolog, so I took the source code for the latest version of SWI-Prolog and applied a similar set of changes. Initial progress looks good, the console widget has really been designed for easy reuse in other applications. I might even try to create a .NET Compact Framework wrapper for it, as being able to chuck up a text prompt can be a handy debugging interface at times.

Today I also noticed that João Paulo Figueira has provided an initial demonstration of a list-based form control library he has been working on. This library for native C++ developers is designed to give a user interface similar to the Pocket Outlook UI seen on Pocket PC devices. I took his code and compiled it for Windows Mobile 6 Standard edition (i.e. a smartphone). It seems with a little work this control could also work on smartphones. The main issues were reasonably minor ones such as lack of support for using the keypad to interact with some of the controls, which look like they would be reasonably easy to resolve.

PythonCE-2.5-20071004 Released

October 5th, 2007

Yesterday I uploaded to the PythonCE SourceForge project downloads page a new PythonCE release.

This one is slightly better than my previous release, since it has been built from a known code base, which allows it to be rebuilt and expanded upon in the future.

If you are using a Pocket PC device you should also see that you have a new context sensitive popup menu on the main editor window. This provides cut/copy/paste options which you may find handy while developing short programs directly on the device.

This release also includes an optional patch which provides initial support for building with Visual Studio 2005 instead of Embedded Visual C v4. This patch needs refinement before it can be included in the main release, since it has essentially been hacked into the existing msevc.py file and lacks auto-detection of the location of your Visual Studio 2005 and Device SDK installations etc (what has happened to the batch files that used to be present in EVC???).

The main aim of this release is to start to increase the device compatibility of PythonCE. If anyone downloads this release I would appreciate feedback on whether it works on your device type or not. It should work on any Windows Mobile Pocket PC or Smartphone device running Windows Mobile 2003 or later.

Custom soft keys for Notifications

October 4th, 2007

Screenshot of custom notification displayed on the screen with two custom soft key menu items.Since my previous posting about Notifications within the .NET Compact Framework I have seen the question of how to provide custom menu items at the bottom of a notification come up a number of times. Today I am going to provide you with one solution to this challenge.

The short answer is that the Microsoft.WindowsCE.Forms.Notification class provided by the .NET Compact Framework does not expose the required functionality. Although the native notification API allows custom menus to be associated with a notification, for some reason this hasn’t be exposed to managed developers. With a little bit of work however (i.e. some PInvoking) you can produce your own managed wrapper around the Notification APIs to expose the required functionality.

I have done this and produced a class called NotificationWithSoftKeys. You can download a copy of this class, along with a sample application which demonstrates it’s various features below.

[Download notificationsoftkeys.zip 32KB]

The rest of this blog entry will demonstrate how you can utilise the class within your own applications. It is designed to be a stand in replacement for the existing class, but adds some additional properties and events.

Adding Spinners
Screenshot of custom notification showing the use of spinnersSpinners are the first additional functionality the NotificationWithSoftKeys control exposes. A notification spinner is a little bit of text on the right hand side of a notification which sits in-between a pair of < and > buttons. The user can tap on these buttons to “spin” through a series of related notifications.

Here is a brief example of how to enable this feature within your notification.

private NotificationWithSoftKeys notification;
 
private void btnCreateNotification_Click(object sender, EventArgs e)
{
  notification = new NotificationWithSoftKeys();
  notification.Icon = Properties.Resources.Icon;
  notification.Caption = "This is my notification";
  notification.Text = "Spinner Test\t1 of 5";
  notification.Spinners = true;
  notification.SpinnerClicked +=
      new SpinnerClickEventHandler(notification_SpinnerClicked);
  notification.Visible = true;
}

The main thing you need to do is set the Spinners property to True in order to enable the Spinner functionality. After this any text within the Caption property after the first tab (\t) character will be displayed on the right hand side of the notification’s caption.

When the user presses the < or > buttons the SpinnerClicked event will fire. Within your event handler you should update your Notification’s Caption and Text properties to give the illusion that another notification has been displayed.

Display Current Time on Caption
Screenshot of custom notification showing the use of the TitleTimer propertyDisplaying the current system time on the caption is very straight forward. All you need to do is set the TitleTime property to true.

Custom Buttons
This is the feature which will probably generate the most interest. The standard notification has a “Hide” button on the left soft key. Some built in applications however display notifications with alternative softkeys and perform different actions depending upon which softkey was selected. Using the NotificationWithSoftKey class we can achieve the same effect as demonstrated with the following example.

private NotificationWithSoftKeys notification;
 
private void btnCreateNotification_Click(object sender, EventArgs e)
{
  notification = new NotificationWithSoftKeys();
  notification.Icon = Properties.Resources.Icon;
  notification.Caption = "This is my notification";
  notification.Text = "A soft key test";
  notification.LeftSoftKey =
      new NotificationSoftKey(SoftKeyType.Dismiss, "Close");
  notification.RightSoftKey =
      new NotificationSoftKey(SoftKeyType.StayOpen, "View");
  notification.RightSoftKeyClick +=
      new EventHandler(notification_rightSoftKeyClick);
  }
 
  notification.Visible = true;
}

This example will display a notification with two soft keys. The left soft key will be labeled “Close” and will remove the notification, while the right soft key will be labeled “View” and trigger the RightSoftKeyClick event when selected.

Within this event handler you could open up a second form, delete something from a database or perform any other task you would like to in response to the user pressing the soft key.

There are a number of soft key types to choose from as shown below:

Type Description
Dismiss Remove the notification when the soft key is pressed
Hide Hide the notification when the softkey is pressed (but do not dismiss)
StayOpen Do not dismiss or hide the notification when the softkey is pressed.
Submit Submit the HTML form in the notification instead of calling the click event handler
Disabled The softkey is disabled (grayed out)

Backwards Compatibility
The additional features discussed today are only available on devices running Windows Mobile 5.0 or higher. If your application is targeting multiple device types, and you need to run on Pocket PC 2003 devices the new functionality will not work.

The NotificationWithSoftKeys class utilises techniques outlined in my blog posting on device and platform detection to fail gracefully on older devices. When the class detects an older device type, it will simply ignore all the soft key related properties and revert back to the old notification style.

Sometimes you may want to check if this fallback has occurred. For instance you may want to utilise the soft key buttons for user input. In this case you would need to use an alternative approach (such as HTML based buttons) when running on Pocket PC 2003 or older devices which don’t have softkeys. You can do this by checking the PlatformSupportsCustomSoftKeyButtons property and altering the other properties of the NotificationWithSoftKeys class as required.

Summary
This is still only scratching the surface of what is possible with the native notification APIs. There are a number of notification features which are not exposed by this wrapper. For example there are the following flags which could easily be exposed as properties.

  • SHNF_DISPLAYON – the display is forced to turn on for the notification
  • SHNF_SILENT – the notification is forced to be silent and not vibrate, regardless of system settings

Please feel free to download the sample project and have a play around with it. I would be keen to hear from anyone who attempts to use it or modifies it to expose additional functionality etc.

Will the following C# compile?

October 3rd, 2007

While reviewing some code earlier his week, I came across a C# function which when reduced to its core essentials boiled down to the following sample:

public void SomeMethod()
{
     http://www.christec.co.nz  

     MessageBox.Show("hello world");
}

Off the top of your head do you think a C# compiler would happily accept this source code, or would you expect a syntax error?

The answer is that the above example function is completely valid C# source code. It is easier to see why once syntax highlighting has been applied to it.

The // characters after the http: prefix cause the rest of the URL to be interpreted as a comment, and the bit which is left (http:) is in the correct syntax to be interpreted as a label for use with the goto statement.

I had accidentally pasted a URL into my source code and checked it into our source control system. I didn’t notice for a few weeks since the code compiled and executed perfectly…

An amusing (but somewhat useless) application of this fact can be found in the following program

using System;
 
public class MyDumbApplication
{
  public static void Main() 
  { 
     http://www.christec.co.nz  
 
     Console.WriteLine("Hello World!");  
 
     goto http; 
  }
}

I wonder if this fact could be used to advantage in a International Obfuscated C Code Contest style C# program?

Add Cut/Copy/Paste functionality to a Textbox

October 2nd, 2007

Earlier I discussed how you could manually get the software keyboard (SIP) to display whenever a TextBox control gained focus. There was potentially a lot of event handlers to write, two for every control on a form. Today I will show you an alternative approach that utilises less code but also has some additional benefits.

A common thing I do while testing new Windows Mobile applications, is to tap-and-hold on a text field. Very well behaved applications should popup a context sensitive menu containing cut/copy/paste style options for the current control. Surprisingly, very few applications actually pass this test, even though it is a feature that has been built into the operating system for a while.

Within Windows CE the SIPPREF control can be used to automatically implement default input panel behavior for a dialog. It provides the following features:

  • The Input Panel is automatically shown/hidden as controls gain and loose focus.
  • Edit controls have an automatic context menu with Cut, Copy, Paste type options.
  • The SIP state is remembered if the user switches to another application and later returns to this form.

In my mind this has three advantages over the process I previously discussed.

  1. You add the SIPPREF control once and it automatically hooks up event handlers for each of your controls. With the manual event handler approach it’s easy to add a new control and forget to hook up the events required to handle the SIP.
  2. You get free localisation. Although you could create a custom context menu for cut/copy/paste, you would need to localise the text into multiple languages yourself (if you are concerned with true internalisation that is) and it’s another thing thing to hook up for each control.
  3. You get standardised behavior. By using functionality provided by the operating system you are ensuring that your application has a natural and expected behavior to it. If the platform ever changes the conventions of SIP usage, your application will automatically be updated.

For the rest of this blog entry I will discuss how to go about utilising the SIPPREF control within your application. I have split my discussion into two sections. The first section will be of interest to native developers developing in C or C++, while the second section is intended for .NET Compact Framework developers.

Each section contains a small example application which demonstrates the behaviour of the SIPPREF control within the respective environment. When you run the sample applications you will notice that the SIP does not popup up when you click within a text box. And a tap-and-hold operation yields nothing. This behaviour changes when a SIPPREF control is added to the dialog, which can be achieved by clicking the sole button.

Native Developers

[Download sipprefcontrolnativeexample.zip 16KB]

In order to use the SIPPREF control we must first request the operating system to register the SIPPREF window class. We do this by calling the SHInitExtraControls function. This step only needs to be done once, so is typically done during your application’s start up code. It is very easy to call, as the following example demonstrates:

#include <aygshell.h>
 
SHInitExtraControls();

Since SHInitExtraControls lives within aygshell.dll, we also need to modify our project settings to link with aygshell.lib, otherwise the linker will complain that it can not find the SHInitExtraControls function.

Once we have registered the SIPPREF window class, we simply create a SIPPREF control as a child of our dialog. When the SIPPREF control is created it will enumerate all sibling controls and subclass them in order to provide the default SIP handling behaviour. The SIPPREF control must be the last control added to your dialog, as any controls added after the SIPPREF control will not be present when the SIPPREF control enumerates its siblings, and hence will not be subclassed to provide the proper SIP handling.

If dynamically creating the SIPPREF control, a good place to do this is within the WM_CREATE or WM_INITDIALOG message handler, as the following code sample demonstrates:

case WM_INITDIALOG:
  // Create a SIPPREF control to handle the SIP. This
  // assumes 'hDlg' is the HWND of the dialog.
  CreateWindow(WC_SIPPREF, L"", WS_CHILD,
       0,  0, 0, 0, hDlg, NULL, NULL, NULL);

As an alternative to dynamically creating the SIPPREF control, we can place the control within our dialog resource by adding the following control definition to the end of a dialog within the project’s *.rc file.

CONTROL  "",-1,WC_SIPPREF, NOT WS_VISIBLE,-10,-10,5,5

Depending upon your developer environment you may even be able to do this entirely from within the Resource Editor GUI. For example within Visual Studio 2005 you could drag the “State of Input Panel Control” from the Toolbox onto your form to cause a SIPPREF control to be added.

sip-toolbox.png

.NET Compact Framework Developers

[Download sipprefcontrolexample.zip 16KB]

The process of using the SIPPREF control for a .NET Compact Framework application is fairly similar to that of a Native application. Since the .NET Compact Framework does not natively support the use of dialog templates, we must use the CreateWindow approach to create a SIPPREF control dynamically at runtime.

The first step is to declare a number of PInvoke method declarations for the various operating system APIs we need to call.

using System.Runtime.InteropServices;
 
[DllImport("aygshell.dll")]
private static extern int SHInitExtraControls();
 
[DllImport("coredll.dll")]
private static extern IntPtr CreateWindowEx(
  uint dwExStyle,
  string lpClassName,
  string lpWindowName,
  uint dwStyle,
  int x,
  int y,
  int nWidth,
  int nHeight,
  IntPtr hWndParent,
  IntPtr hMenu,
  IntPtr hInstance,
  IntPtr lpParam);
 
  private static readonly string WC_SIPPREF = "SIPPREF";
  private static readonly uint WS_CHILD = 0x40000000;

One interesting fact is that we PInvoke a function called CreateWindowEx, while the native example above called CreateWindow. If you dig deeper into the Window Header files you will notice that CreateWindow is actually a macro which expands into a call to CreateWindowEx. At the operating system level the CreateWindow function doesn’t actually exist.

With this boiler plate code out of the way, the solution is very similar to the native one…

protected override void OnLoad()
{
     // Initialise the extra controls library
     SHInitExtraControls();
 
     // Create our SIPPREF control which will enumerate all existing
     // controls created by the InitializeControl() call.
     IntPtr hWnd = CreateWindowEx(0, WC_SIPPREF, "", WS_CHILD,
          0, 0, 0, 0, this.Handle, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
}

In the above example we simply create the SIPPREF control within the OnLoad method of our form. Within the downloadable sample project I have wrapped up this code into a static method called SIPPref.Enable(Form f) to enable to it easily be reused between forms.

Hopefully today I have shown you that having knowledge of the underlying operating system is still a useful skill to have for .NET Compact Framework developers. Knowing the features provided by the operating system can allow you to add some neat functionality to your applications with little additional effort on your behave.

Creating non full screen forms and custom MessageBoxes

October 1st, 2007

A screenshot of a custom message box form which is not full screen.Every now and then someone asks how to create a .NET Compact Framework form which does not cover the fullscreen. Here is my solution to this problem.

This solution is built upon details discussed by other bloggers, including:

The trick is to set the form’s FormBorderStyle property to None. This disables the .NET Compact Framework’s built in functionality which forces a form to become fullscreen (on Windows Mobile devices), but also has the side effect of removing the border around the edge of the form. We can add the border (and a caption) back via the use of some PInvoke calls into the native operating system.

Points of interest

I decided to create my solution as two classes which are designed to be reusable within your own applications. One class enables the non full screen functionality, while the other provides an implementation for a common reason why non full screen forms are requested. These classes are as follows:

  1. NonFullScreenForm – a base class which you can use instead of Form. This base class allows you to have a form which does not cover the entire screen, and will optionally automatically center the form in the middle of the screen.
  2. MessageBoxForm – this is a subclass of NonFullScreenForm which provides a static method called Show. This method behaves in a similiar way to the standard MessageBox.Show API, with a few extensions such as the ability to use custom buttons.

Example Application

[Download nonfullscreendemo.ZIP 32Kb]

The example application available for download demonstrates the use of the NonFullScreenForm and MessageBoxForm classes via a series of buttons.

The first two buttons compare the behaviour of the standard MessageBox.Show API against our custom MessageBoxForm implementation for a number of message box styles. You will notice that the look and feel of our custom message boxes are similiar, but often have a slightly different layout.

The button labeled “Auto Centered Form” demonstrates the effect of setting NonFullScreenForm’s CenterFormOnScreen property to True. Whenever you tap the “Expand” or “Collapse” buttons the form changes size, and the NonFullScreenForm base class automatically changes the location of the form to ensure it is centered at all times. It will even re-center the form when the device switches between landscape and portrait modes.

How to use the NonFullScreenForm class

To use the NonFullScreenForm class within your own applications follow these steps:

  1. Add NonFullScreenForm.cs to your project.
  2. Set the FormBorderStyle property of your form to None.
  3. Set the Size and Location properties of your form to the desired size and position on the screen.
  4. View your form’s source code and change the form to derive from NonFullScreenForm instead of Form.
  5. If you want your form automatically centered on the screen set the CenterFormOnScreen property to true.
  6. If you don’t want an [OK] button in the caption, set the ControlBox property to false.

There are a number of areas where these custom controls could be improved. MessageBoxForm’s compatability could be improved. It does not support displaying an icon within the MessageBox at present for instance. There is also a slight flickering on the navbar (the bar at the top of the device which contains the start menu etc) when a non full screen dialog is created which would be nice to eventually remove. This is caused by the .NET Compact Framework dispaying the form before we have had a chance to change it’s window style to include a caption.

These controls were quickly put together to demonstrate what could be possible with a little bit of work. If anyone is interested in collaborating to improve these controls, I would be keen to hear from them.

PythonCE for Windows Mobile Smartphone

October 1st, 2007

Screenshot of PythonCE About dialog box running on a Windows Mobile 6 powered SmartphonePythonCE is a port of the Python programming language to the Windows Mobile Pocket PC platform. I became interested in this project a couple of months ago and released a couple of patches to allow the application to run on Smartphone devices (such as Motorola Qs or Samsung Blackjacks).

Over the last month or two I have had numerious requests for a PythonCE CAB file which runs on a Windows Mobile smartphone.

The patches I submitted have not yet been included in the builds available via the main downloads page for PythonCE, so today I decided to host my unofficial PythonCE build on my blog. I hope this helps people who are looking at getting a working Python development environment up and running for their smartphone.

The cab file should run on any Windows Mobile 5.0 or above Pocket PC or Smartphone device.

[Download pythoncesp2005_armcab.zip 3.09 MB]

Edited: October 5th 2007 – An official build has been released by the PythonCE project. You can obtain it from their downloads page.

Please be aware that this is just a “random” build I had on my harddrive. I lost interest in PythonCE after finding development had been quiet for a while. Since I’ve had a number of requests for Smartphone compatible builds recently, I decided to take a look at what I had, and I found this CAB file. Taking a look at it, it seems this build has all the patches I submitted upstream, plus a couple I didn’t get around to submitting. It doesn’t however have some of the features I was working on just before I lost interest. It’s a case of “user beware”, I take no responsibility with respect to the usability of this particular build…

I would be interested to hear feedback from anyone using PythonCE, especially anyone interested in further development. There seems to be a keen community of PythonCE users, but this doesn’t seem to be matched by people keen on developing PythonCE further. Is this just a case of the existing builds satisfying most people’s needs?

Creating a Tab Control for the Smartphone

September 29th, 2007

Screenshot of sample application demonstrating the tab control I developed for Windows Mobile Smartphone devicesThe .NET Compact Framework does not support a Tab Control when targeting a Windows Mobile Smartphone device. Today I present a sample custom control designed to provide a suitable replacement for System.Windows.Forms.TabControl when you are building a Smartphone application.

I am not sure using such a control is good from a usability perspective, but it has been asked for enough times within the developer community, that this time I decided to provide a working solution. This was especially true once I determined the custom tab control would also provide some benefits for Pocket PC developers.

My development background was originally in the native world writing applications in C and C++. As such I know the raw Win32 APIs provided by the Windows Mobile operating system pretty well. The smartphone OS actually provides the standard Commctrl.h Tab Control, however the .NET Compact Framework has decided not to expose this functionality. So this custom control simply uses quite a lot of Platform Invoke calls to wrap up the native tab control provided by the operating system in a .NET Compact Framework friendly manor.

Benefits of this control

  • Works on both Smartphone and Pocket PC devices.
  • Allows tabs to have an optional bitmap displayed beside the text.
  • Exposes a SelectedIndexChanging event which allows the programmer to cancel a tab change if the application logic desires.

Sample Application

A sample application which runs on both Pocket PC and Smartphone devices is available for download. This download also contains the file SmartphoneTabControl.cs which contains the source code for the custom control itself.

[Download smartphonetabcontrol.zip 48KB]

The sample application has three tabs and demonstrates how you can navigate the tabs via the left and right arrow keys. Once you have selected the third tab, you can use the up and down arrow keys to select the various textbox controls, and return to the tab control to select another tab.

Another neat feature demonstrated in the sample application is a way to have an animated icon displayed on a tab. This may be useful for a tabbed interface where a tab is displaying the results of an asynchronous or lengthy operation (such as a file download). The tab’s icon could be animated while the operation is still in progress, allowing the user to determine the state of the operation with a quick glance.

How to use the control

  1. Add SmartphoneTabControl.cs to your solution.
  2. Compile your project (needed to get the control into your toolbox).
  3. Drag a SmartphoneTabControl from your toolbox onto your form.
  4. Dock the tab control to the bottom and make it 26 pixels high.
  5. Add one or more Panel controls to your form (one for each tab page) and set the DockStyle property of each one to ‘Fill’.
  6. Populate the panels with the controls you want visible on each tab.
  7. Within your form’s constructor call the SmartphoneTabControl’s AddTab() method to create each tab, passing in the name of the tab, an optional image, and the panel which contains it’s controls.

There are a couple of outstanding bugs/missing features with this control. The biggest being the lack of design time support and device resolution independance. This control was quickly put together to demonstrate what could be possible with a little bit of work. If anyone is interested in collaborating to improve this control, I would be keen to hear from them.

Free games for your Windows Mobile PDA or Smartphone

September 26th, 2007

It has been a long time since my last blog posting. I am trying to get back into the habit of regular posting, so I thought I would start off again with a beta release of a project that I have been working upon recently.

Introduction

As I mentioned previously Simon Tatham’s Portable Puzzle Collection is a high addictive collection of 27 logic puzzles that can be used on Windows, Mac OS , Unix and PalmOS powered devices. I have picked up the existing Windows Mobile PDA support found within the SVN repository and improved the port, making it more functional and compatible with a wider range of Windows Mobile devices.

I am at the stage where I am getting ready to make an initial release. As such I have decided to make a beta release, in the hope that it generates some feedback which will allow me to further improve device compatibility and iron out any kinks.

Installation Process

[Download puzzles.zip - 741KB]

Download the attached ZIP file and extract the CAB file called Puzzles.ARMV4.CAB located within it. Once you transfer this CAB file to your device, you can install the games as you would with any other CAB file.

Once installed, you should see a Puzzles folder underneath the Games section of your device’s Start Menu which contains 27 new games to occupy your time with.

The single CAB file should be usable on any Windows Mobile 2003 or above device – Smartphone or Pocket PC, QVGA or VGA, Landscape, Portrait or Square screen. It would probably even work on the OFone if one actually existed! The user interface dynamically adapts at run time to its current situation. For instance it uses a slightly different menu layout on Pocket PC 2003 devices, and hides a toolbar if it finds itself running on a smartphone with a numeric keypad.

On the device compatibility front, if anyone has a Windows Mobile Standard (smartphone) device with a QWERTY keyboard such as a Moto Q or Samsung BlackJack which I could borrow for a short time, I would love to hear from them… especially something running WM6.

Further details

From anyone who downloads this beta release I would be interested in hearing feedback on:

  1. Any bugs and/or device compatibility issues
  2. If there is interest in a localised version (i.e. having the UI in French, German or Japanese etc)?
  3. If there is interest in support for “raw” Windows CE based devices?

As with all beta releases there are a couple of known issues which you will need to be aware of. Many will hopefully be resolved before I make a final release. These issues include:

  1. The lack of proper start menu icons.
  2. Usability issues with many of the games on non touch-screen enabled devices.
  3. Some Cosmetic issues within the custom game configuration dialog.
  4. The game “filling” has some corrupt pixels on the edges of the game board.
  5. The game “inertia” is currently unplayable via keyboard, due to not being able to move on diagonals.

My next steps

Within the next day or so I will clean up my patch to Simon Tatham’s original source code and post it to this blog along with compilation instructions (for Visual Studio 2005) etc. Then I will start producing a plan for the additional work required to make a proper v1.0 release.

In developing this port I have also came up with some ideas for future blog topics. These blog topics will be of interest to native (C and C++) developers, instead of Compact Framework developers, and will focus on topics such as SIP handling, Smartphone and Pocket PC UI differences, and cross platform development tips.

I also have a couple of blog postings about popup notification balloons to follow on from my previous entry on the subject. So hopefully I’ll get back into the swing of things over the next few days.