Archive for July, 2007

Google Gears CE progress (workerpool now works!)

Sunday, July 22nd, 2007

I have been a little slack recently on my port of Google Gears to Windows CE powered devices. However progress is still being made and I feel that I am getting closer to a version which has all features fully functional.

I have checked in changes to the google-gears-ce SVN repository which enable the worker pool feature of Google Gears to operate correctly on Windows CE. Once again it was a minor bug fix once I tracked down the problem. Windows CE will not allow a window with a client rectangle of 0×0 pixels to be created. Google Gears was creating such a window for thread syncronisation purposes to enable it to pass asynchronous results back to the main GUI thread. The solution was to change the code to create a window of 5×5 pixels. Although the window now has a larger client rectangle, it is still invisible due to the window being created without the WS_VISIBLE window style being set.

I have also checked in an initial build script (build-ppc.bat) which attempts to build a Google Gears CE executable for Windows Mobile powered PDAs. At present this won’t even compile due to missing header files within the Windows Mobile SDK etc, but it’s a start down the road of my initial aim for this project.

The most significant outstanding bug still to be resolved, is the issue I am having around getting the offline mode to work. Obviously this is a major part of the google gears solution and it is a bit disappointing that it has held out on me for so long. The Asyncronous Pluggable Protocol implementation Google Gears utilises to hook into requests for http:// and https:// URLs, is failing to initialise due to some differences between the platforms. The good news is that it appears that I am not the only one finding this problem and it does look solveable. It may however require a far amount of new code to be written (rather than the existing bug fixes which have turned out to be one or two lines here or there).

Once this final hurdle is overcame, it should be fairly easy to tidy up a couple of minor lose ends and have a fully functional version of Google Gears working on Windows CE.

What device is my application running on?

Saturday, July 21st, 2007

Windows Mobile comes in two main variants, traditionally called Pocket PC and Smartphone. If your application must run on both platforms, it may be necessary to detect at runtime what type of device your application is running on. This blog entry will discuss techniques .NET Compact Framework developers can use to achieve this.

Detecting the Platform
The .NET Compact Framework does not have any built in support for determining the type of device the application is running on, so we need to develop a small class library to query this information ourself.

The first platform we can check for is the desktop PC. We may want to determine if a user is attempting to run our Compact Framework application on their laptop, Tablet PC or Ultra Mobile PC (UMPC) for example.

// Returns true if the application is running on a
// desktop version of the Windows operating system
public static bool IsDesktopWindows
{
  get { return Environment.OSVersion.Platform != PlatformID.WinCE; }
}

As you can see it is reasonably straight forward to determine if we are running on a desktop version of Microsoft Windows. We simply query for the platform id of the operating system via the Environment.OSVersion property and return true if it does not equal Windows CE.

By switching the conditional around we can also detect if we are running on a device that utilises a Windows CE based operating system. This is what the IsWindowsCE property does, as shown below.

  // Returns true if the application is running on a
  // device powered by some form of Windows CE based
  // operating system.
  public static bool IsWindowsCE
  {
    get { return Environment.OSVersion.Platform == PlatformID.WinCE; }
  }

As discussed in my blog entry “Is Windows Mobile 6 powered by Windows Embedded CE 6.0?“, Windows CE is an operating system that can be further customised to develop particular variants, such as Windows Mobile. Once we know that a device is a Windows CE powered device, we can query the OS for some additional information which will help us narrow down the type of device even further.

  // Returns true if the application is running on a
  // Windows Mobile Standard (i.e. Smartphone) device
  public static bool IsWindowsMobileStandard
  {
    get
    {
      return IsWindowsCE()
        && (NativeMethods.GetPlatformType() == "SmartPhone");
    }
  }
 
  // Returns true if the application is running on a
  // Windows Mobile Professional (i.e. Pocket PC Phone
  // Edition) device. Also returns true for Windows
  // Mobile Classic devices (no cellular radio).
  public static bool IsWindowsMobileProfessional
  {
    get
    {
      return IsWindowsCE()
        && (NativeMethods.GetPlatformType() == "PocketPC");
    }
  }

The NativeMethods.GetPlatformType() method used in the last two properties is one which we will have to develop ourself. It utilises a Platform Invoke (PInvoke) call to access the SystemParametersInfo operating system API. By querying the SPI_GETPLATFORMTYPE system parameter we can get a string back which enables us to differentiate between the Pocket PC or Smartphone platforms. Since the implementation of NativeMethods.GetPlatformType() is rather long I have not included the source code here, please see the sample project available for download for its implementation.

Notice that as it stands our IsWindowsMobileProfessional property also returns a false positive, since it will return true if the device is a Windows Mobile Classic device (i.e. a Pocket PC without a cellphone). We will correct this issue in a couple of moments.

Detecting the Emulator
By querying yet another system parameter (SPI_GETOEMINFO) we can determine if our application is running on a physical device, or within a Device Emulator running on a desktop PC.

This can be a useful thing to tell. For example, you could disable device specific code (such as barcode scanner interfacing logic) while running within the emulator.

  public static bool IsEmulator()
  {
    return (NativeMethods.GetOEMInfo() == "Microsoft DeviceEmulator");
  }

Detecting device specific features
If possible you should detect specific device features (such as cellular radio presence, screen size or orientation) instead of detecting platform types. This will make your application more robust, since over time it is possible that some of the differentiating features between the platforms will disappear.

To differentiate between Windows Mobile Professional (with cellphone) and Windows Mobile Classic (without cellphone) devices, we will have to detect the presence of a cellular radio.

For some device features there are no nice APIs available to detect their presence. In this case you need to probe the device to determine if DLLs or registry keys specific to that device capability are present on a given device.

Prior to Windows Mobile 5.0 the recommended method to determine if a device had a built in cellular radio was to detect if a DLL called phone.dll was present within the device. This could be achieved as follows:

using System.IO;
 
public static bool HasPhone()
{
  return File.Exists(@"\Windows\Phone.dll");
}

With this additional method we can now alter our implementation of the IsWindowsMobileProfessional property to check that a cellular radio is present. Likewise we can create a new IsWindowsMobileClassic property which returns true only if HasPhone() returns false.

As the Windows Mobile platform grows, and new versions are released, the number of device features with standardised detection mechanisms typically improves. With Windows Mobile 5.0 or above, the OS provides us with a nice managed API we can call to determine if a cellular radio is present, as can be seen in this alternative implementation of the HasRadio() method.

using Microsoft.WindowsMobile.Status;
 
public static bool HasPhone()
{
  return SystemState.PhoneRadioPresent;
}

There are a number of other properties available within the SystemState class which can be used to detect other device features, such as a camera. If developing for Windows Mobile 5.0 or above it is defiantly worth looking into this class.

Detecting Platform Versions
Sometimes detecting that you are running on a Windows Mobile Professional device is not enough. You may desire to display a warning prompt for example, if you application is running on an operating system version newer than the one you officially support.

To do this you must use the properties we have developed above (IsWindowsMobileProfessional, IsWindowsMobileClassic etc) to determine the platform your application is running on and then compare the current operating system version number, obtained via the Envrionment.OSVersion property, against a list of known Windows CE versions for that platform.

For example with the Windows Mobile releases we know that the following Windows CE operating systems were utilised:

Platform Release Windows CE kernel version
Windows Mobile 6 5.2
Wndows Mobile 5.0 5.1
Windows Mobile 2003 SE 4.21

So we could determine if an application was running on a Windows Mobile 5.0 Pocket PC by implementing the following check:

  if (IsWindowsMobileProfessonal 
    && Environment.OSVersion.Version.Major == 5
    && Envrionment.OSVersion.Version.Minor == 1)
  {
    MessageBox.Show("This is a Windows Mobile 5.0 Pocket PC");
  }

In the future
As discussed by Daniel Moth the next version of the .NET Compact Framework (v3.5) will have a new property within the SystemSettings class called WinCEPlatform. This property contains one of the following enumerated values:

  • WinCEGeneric
  • PocketPC
  • Smartphone

This will allow you to detect the platform your application is running on quite easily, without needing to write custom code as we have needed to do.

Example

I have put together a
small demonstration application which demonstrates how to detect the various platforms your .NET Compact Framework application may run on.

If you load the application up within Visual Studio 2005 you should be able to switch between the various platforms via the “Change Target Platform…” option within the “Project” menu. When you then launch the application within different emulators you should be able to see the code detecting which platform the application is currently running on.

If you have a need for detecting the type of platform your application is running on feel free to use a copy the “Platform.cs” file within your own projects.

Provide Help for an application

Friday, July 20th, 2007

Yesterday I provided a tip about using the context sensitive help feature within Windows Mobile. I finished the post with a gotcha, mentioning that it worked in few third party applications. This was due to the feature needing to be explicitly handled by the application developer. This blog entry is designed to discuss how .NET Compact Framework developers can implement integrated help within their own applications.

Integrating help into your application
Help within Windows Mobile is implemented by an application called peghelp.exe. This application is essentially a host for a web browser control which renders an HTML based help file.

There is typically one HTML help file per application. A special structure is used within the HTML file to determine where to split topics.

As a demonstration of how this works you may like to use the run dialog tip mentioned yesterday to run “peghelp \windows\calc.htm#Main_Contents”. This will view the help file associated with the built in calculator application.

Within the .NET Compact Framework the System.Windows.Forms.Help class helps wrap up this functionality and hide the specifics of launching peghelp.exe.

The ShowHelp method will display a specified topic within a help file. It can be invoked from within a button click event handler reasonably easily, as the following example demonstrates:

private void button1_Click(object sender, EventArgs e) 
  { 
  Help.ShowHelp(this, @"\windows\calc.htm#Main_Contents"); 
  }

Notice the ‘#’ character which seperates the path of the HTML help file and the name of the topic.

The first code sample is ideal for launching help from a button or menu item within our application. To launch your help by using the context sensitive help feature within the Windows Start Menu you need to listen to the form’s HelpRequested event as shown below.

private void Form1_HelpRequested(object sender, HelpEventArgs hlpevent) 
{ 
  Help.ShowHelp(this, @"\windows\calc.htm#pptskusecalculator"); 
}

By using unique topic names within the event handler associated with each form, you can obtain context sensitive help. In an advanced application you may even place conditional logic within your HelpRequested event handler. This enables you to display different help topics, depending upon the state of your user interface.

Creating your own help file
The help file for your application is a simple HTML file. However there are a couple of special tags you must utilise, in order for the help application to be able to split up your single file into multiple topics.

To create your first topic within an HTML help file, insert the following elements within the <body> element of the file.

<!-- PegHelp --> 
<a name="SomeTopic" title="SomeTopic" />    
 
.... HTML contents of topic goes here ....

The value of the name attribute (in this case set to “SomeTopic”) is the unique name for the topic, and is the value you should use to link to this topic.

The only special topic name that you should use is “Main_Contents” which should point to a topic which is suitable for use as a table of contents. Other than this topic name, you are free to use what ever names suit you.

To create additional topics, simply repeat this structure as many times as required. After the last topic it is very important to place another <!– PegHelp –> comment to mark the end of the help file. It is a common mistake for this comment to be missed and this has the effect of hiding the last topic.

Links between topics
Typically you will want to refer to other topics from within a topic. For example, at the bottom of each topic you may want to have a “see also” section, which lists other relevant topics.

To refer to another topic within your help file you use standard HTML anchor functionality, referring to the anchor name of the topic you want to jump to. This syntax is shown below, and is basically the path of your help file and the desired topic name seperated by a ‘#’ character.

<a href="MyHelpFile.htm#main_contents">Table Of Contents</a>

Development Tips
The parser used to break up a single file into multiple topics is not case sensitive, however it is sensitive to whitespace and changes in the format of the HTML elements. My recommendation is to utilise the same formatting of the <A NAME=”…”> and <!– PegHelp –> elements as shown in the examples in this blog entry. If you find that a topic is missing, or the content of more than one topic have become merged, double check that you have not accidently inserted additional whitespace between attributes etc.

When creating your help file you are most likely going to be using a desktop web browser which will show all your topics in one large page. When doing this it can become tricky to determine where one topic ends and another begins.

There is a special trick which will help resolve this issue. If you place an <hr> element immediately after each <!– PegHelp –> comment you will get nice divider lines separating each topic when you view your HTML help file within a desktop web-browser. However when you view the help file from within the Windows Mobile Help application they will have been removed.

Adding Keyword Search
Screen-shot showing search results including topics within the HTML help fileWithin the <head> element of your help file it can be handy to list a series of help topics and their matching keywords by using the <keyword> element. These keyword definitions are utilised by the Windows Mobile Find application when the user searches for help on a given topic (i.e. the find application does not search through your entire help file, it relies upon your explicitly listing all relevant keywords).

Some example keyword enteries may look like the following two example entries.

<keyword value="Puzzle;Games" title="Tetris 2000" href="tetris.htm#main_contents" />
<keyword value="High Score;Internet" title="Tetris 2000 High Score" href="tetris.htm#highscore"  />

The value element contains a list of keywords separated by semi colons, while the title element contains the title which will be displayed within the Find application when a match is found. Finally the href element contains the topic reference of the topic which should be displayed when a matching keyword is found.

Including Images
Images are displayed within the HTML help file using standard <img> HTML elements. However there are a couple of limitations to be aware of. The documentation on MSDN states that all images must be bitmaps with the *.2bp file extension. I believe that this document is purely a historical reference. I have had no problem using standard bitmaps with the *.bmp file extension, and I notice some of the included system help files do the same. You can not however utilise other image file formats, such as JPEGs or PNGs from within your help file.

URLs used to reference images are also relative to the \Windows directory, not the folder your HTML help file is located within.

Deploying your custom help file
Realistically your HTML help file must be located within the \windows directory. The help application can have problems if you place your help file in other locations, due to the need to use hardcoded file paths to refer to additional topics and images. These hard coded references will break if the user chooses to install your application in a different location, or your application is installed on a localised version of Windows Mobile (which will have different names for folders such as “My Documents”).

If you want the help file to show up in the main list of help files you should also place a shortcut link to your help file within the \windows\help folder. On a Windows Mobile 5.0 device this means that the help file will be accessable by selecting the “Help for Added Programs” entry within the help application’s table of contents.

If you are using a Smart Device CAB Project within Visual Studio 2005 to build your application cab you can include your help file within the CAB file by using the following procedure:

  1. Right click on your deployment project within the Solution Explorer and select “File System” from the “View” submenu.
  2. On the “File System on Target Machine” entry on the left hand side of the window, right click and select “Windows Folder” from the “Add Special Folder” submenu.
  3. Right click on the newly created “Windows Folder” directory and select “Folder” from the “Add” submenu.
  4. Type in “Help” and press enter
  5. Click on “Windows Folder” to select it
  6. On the right side of the window right click and select “File…” from the “Add” submenu
  7. Browse to your HTML help file and click “Open”
  8. Right click on the help file and select “Create Shortcut to ….”
  9. Rename the shortcut to remove the “shortcut to…” prefix
  10. Drag the shortcut to the “Help” subdirectory created above

Example Application
An example application which demonstrates how to create a properly formatted HTML help file, and launch it from a .NET Compact Framework application is available for download.

I have included the source code for the application, as well as a pre-built cab file. I would suggest you install the CAB file onto your device and have a play around with how it integrates the application’s help within the help application.

As a starter, try searching for “transport” or “chris” within the Find utility (you can find this within the “Programs” start menu option) and see how this produces links to the help file installed along with the application.

Revision History
26 July 2007 – updated the example application to include examples of using images within help topics in response to a recent forum thread.

Windows Mobile Tip: Context Sensitive Help

Thursday, July 19th, 2007

An image of the Windows Mobile start menu on a Windows Mobile 6 Professional DeviceDid you know that Windows Mobile applications have context sensitive help integrated into them? If so, congratulations, as I feel this is a reasonably unknown feature, even if it is right there in the Start Menu!

Within any application you can obtain context sensitive help for the current window by selecting the “Help” item from within the Windows Start Menu. Selecting this option will launch the help viewer application (peghelp.exe) and load a page specific to the current state of the application you are in.

A good place to see a demonstration of this feature is the Settings or Control Panel Applets part of the shell. As you switch between the various tabs and popup dialogs you will notice that each time you select the “Help” menu option a different help page, specific to the particular set of tasks you can achieve on the current dialog will be displayed.

An image of the Windows Mobile help viewer application on a Windows Mobile 6 Professional deviceAnother help feature of use is the search feature. Within the Windows Start Menu you will be able to find a “Programs” entry. Clicking on this will display a list of all currently installed applications. The one of interest to us is simply called “Search”.

The Search utility is most often used to search for documents, files and PIM data stored within Pocket Outlook. However it also searches help files. As an example search for “Delete” and you will get a bunch of references to help files, outlining how to delete digital certificates, delete folders, uninstall programs etc.

The Gotcha
Integrated help will not work within all third party applications. A developer of an application must write a small amount of additional support code within their application to support the feature, and since many application developers are not aware of this feature, it is of no great surprise that many applications don’t support it. When it’s not supported tapping on the “Help” menu entry within the Windows Start Menu will simply close the menu.

Windows Mobile Tip: Accessing the Run dialog

Wednesday, July 18th, 2007

Picture of Windows Mobile Pocket PC Today Screen showing the Run dialogWindows Mobile has had a run dialog similiar to the one found in desktop versions of Windows since Windows 95 for as long as I can remember. This feature is not well known however.

On the main Today screeen of a Windows Mobile powered Pocket PC (Windows Mobile Professional or Classic for those up with the current lingo) you can tap and hold down the ‘Action’ key while tapping and holding the stylus on the clock shown on the nav bar. The ‘Action’ key is usually the center of the D-Pad or Ctrl if you are using the emulator.

Picture of popup menu displayed when user taps and holds on clock When you release the ‘Action’ key a small popup menu will appear, and you can select the ‘Run’ option which will display a small dialog.

Within this dialog you can enter the path to any executable, as well as any required command line parameters.

Examples you may like to try out are as follows:

  • calc.exe
  • iexplore.exe
  • ctlpnl.exe cplmain.cpl,4,0

For more details on accessing control panel applets from the command line, like the last example demonstrates refer to the Using Control Panel article on the Pocket PC Developer Network website.

This feature can be handy during development of applications for tasks such as re-registering COM dlls, however it is rather impractical for day to day use due to the typical slowness of entering the command line and the fact that unlike on the desktop there is no history of previous commands.

As an additional tip, did you know that if you tap and hold without the ‘Action’ key being pressed a different popup menu will appear? This one allowing you to select between an analogue and digital clock being displayed on the navbar.

Beginnings of a 70-540 Study Guide

Wednesday, July 18th, 2007

Late last year I sat and passed the Microsoft Certified Professional exam 70-540 while it was in beta form. Passing the exam is enough to qualify for the Microsoft Certified Technology Specialist: Windows Mobile 5.0 Application Development certification.

While I was studying for this exam there was little study material available. The recent posting on handling the Software-based Input Panel was the start of a series of posts which I hope will act as suitable study material for those wising to take the 70-540 exam. Over time I plan to update an index of relevant posts on the 70-540 Study Guide page within this blog.

If anyone is interested in discussing the 70-540 exam or has feedback on how I could improve the suitablity of study material presented in this blog please feel free to get in contact with me.

For those interested in starting to study for this exam I would recommend to start out by:

Detecting button presses

Tuesday, July 17th, 2007

My post introducing the .NET Micro Framework covered how to use the OutputPort class to interface to a single GPIO output pin as part of an example to blink a LED.

The matching class to interface to a GPIO input pin, is not too surprisingly called the InputPort class. The InputPort class functions very similar to the OutputPort class discussed last time, in fact they share a common base class.

The constructor for the InputPort class has a couple of additional parameters, in addition to the one which specifies which GPIO pin it should be connected to.

The first is a boolean parameter which enables a glitch filter. Mechanical switches can be “noisy”, meaning that a single press by the user could translate into multiple open and close events, which digitial hardware can potentially detect. This problem is commonly refered to as Contact Bounce or Switch Debouncing. At this stage I have not current managed to find out what technique the .NET Micro Framework utilises for glitch filtering, or even if this is device specific (I suspect it is).

The second parameter is of much more interest, since it deals with setting the type of internal pull up resistor present on the GPIO pin. It can have one of following values from the ResistorMode enumeration:

  • ResistorMode.PullUp – A resistor internal to the CPU is connected between the GPIO pin and VCC, i.e. the pin is pulled up to the positive supply rail.
  • ResistorMode.PullDown – A resistor internal to the CPU is connected between the GPIO pin and GND, i.e. the pin is pulled down to ground.
  • ResistorMode.None – no internal resistor is enabled. In this mode if a pin is left unconnected, it could produce spurious readings due to noise induced into the pin.

The pull up and pull down resistor modes can be handy when interfacing to external hardware, in particular push buttons. By relying upon the internal pull up or pull down resistors, you can get by without requiring additional components, as shown in the following schematics.

Schematic showing pull up and pull down resistor configurations for push button interfacing

It is important to note that if a push button is connected with a pull up resistor, it’s logic levels will be inverted. I.e. the GPIO pin will read a logic high (true) logic level when the push button is not pressed, and will read a logic low (false) logic level when the push button is pressed.

Code Sample
Here is a sample program which will write a message to the debug window each time a push button connected to the GPIO_Pin3 pin is pressed.

To reduce the amount of log messages written to the Visual Studio output window, we only sample the push button once every second. This means we do not need to enable the glitch filter because we are sampling it at a slow enough rate that it should not be a significant issue.

using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using System.Threading;
 
namespace InputTestApplication
{
  public class Program
  {
    public static void Main()
    {
      // Monitor the "select" push button
      InputPort button = new InputPort(Cpu.Pin.GPIO_Pin3,
         false, Port.ResistorMode.PullDown);
 
      while (true)
      {
        // Test the state of the button
        if (button.Read())
             Debug.Print("The button is pressed");
 
        // Wait 1 second before sampling the button again
        Thread.Sleep(1000);
      }
    }
  }
}

NOTE: The GPIO pin used for this sample program has been selected for use with the .NET Micro Framework Sample Emulator. If you attempt to run this application on your own .NET Micro Framework module, you may need to adjust the GPIO signal utilised to suit your hardware.

Push Buttons within the Emulator
The “Sample Emulator” released with the .NET Micro Framework SDK has 5 push buttons “wired up” into a D-PAD configuration.

An interesting aspect to the emulated hardware is that the push buttons can be made to act as if there were wired up with pull up or pull down resistors (as outlined above) depending upon the state of the ResistorMode parameter passed into the constructor of the InputPort instance which accesses them. Typical hardware wouldn’t have this flexibility, with the incorrect ResistorMode choice potentially rendering a push button unreadable.

The mapping of emulator buttons to GPIO pins for the Sample Emulator is as follows:

  • Select – GPIO_Pin3
  • Up – GPIO_Pin2
  • Down – GPIO_Pin4
  • Left – GPIO_Pin0
  • Right – GPIO_Pin1

The code sample provided in this blog posting constantly polls the state of the push button. This is not power efficient. It is better to request that the hardware notifies you whenever the GPIO pin changes state. Next time I will discuss how you can use the InterruptPort class to achieve this.

Manage soft input panel (SIP)

Sunday, July 15th, 2007

One final finishing touch to Windows Mobile applications is the proper handling of the Software-based Input Panel (SIP), this can help differentiate your application, and thus your company as one which truely understands the Windows Mobile platform.

The software-based input panel (also known as the popup or software keyboard) allows touch-screen enabled devices that do not have a hardware keyboard to simulate keyboard input by using an onscreen keyboard.

The SIP is a common piece of UI, which enables the use of one or more Input Methods (IMs). Standard Input Methods include Keyboard, Transcriber and Block Recognizer, but additional OEM specific IMs may be included on a given device.

This architecture is extendable, and third parties can create their own IMs by implementing a COM object, as outlined in the book Prorgraming Microsoft Windows CE, Second Edition (see the free sample chapter for step by step instructions). One interesting third party input panel is the Smilies Input Panel by Yin-See Tan which is designed to help users enter similies into MSN messenger.

Tight integration of the SIP within your application typically boils down to handling two scenarios well:

  • Automatically displaying the SIP when keyboard focus passes to a control which requires keyboard data entry.
  • Ensuring all controls are accessible when the SIP is visible.

SIP support within the .NET Compact Framework
Within the .NET Compact Framework the software-based input panel is wrapped up by the Microsoft.WindowsCE.Forms.InputPanel class, which is present in the Microsoft.WindowsCE.Forms.dll assembly.

In order to interact with the software-based input panel, the user can drop the InputPanel component from the Visual Studio toolbox onto a form. A reference to the Microsoft.WindowsCE.Forms.dll assembly will be added automatically to your project.

Most applications utilising the InputPanel component will make use of the following four members of the class.

  • Enabled – A boolean property. If true the SIP is visible (on the screen), if false the SIP is hidden.
  • EnabledChanged – An event which fires whenever the Enabled property changes value.
  • Bounds – A rectangle detailing the amount of screen real estate the current input method occupies.
  • VisibleDesktop – A rectangle detailing the maximum size the current screen real estate the form can cover without being partially covered by the SIP.

Automatic SIP Popup
Within the .NET Compact Framework the easiest way to automatically display the Input Panel is to explicitly enable and disable the input panel whenever a control which requires keyboard focus is activated.

private TextBox txtUserName;
 
private void Form1_Load(object sender, EventArgs e)
{
  txtUserName.GotFocus += txtUserName_GotFocus;
  txtUserName.LostFocus += txtUserName_LostFocus;
}
 
private void txtUserName_GotFocus(object sender, EventArgs e) 
{ 
   // Show the input panel
   inputPanel1.Enabled = true; 
}   
 
private void txtUserName_LostFocus(object sender, EventArgs e) 
{ 
  // Hide the input panel
  inputPanel1.Enabled = false; 
}

Notice: Usually the event hook up code shown within the Form1_Load event handler would occur within the designer generated code. It is only shown here to aid in understanding how this sample code functions.

Dynamic Dialog Layout
Since the SIP is displayed on screen it covers part of your form when visible and potentially makes some of your controls inaccessable. A quality application will alter the layout of its form when the SIP becomes visible to ensure all controls are accessible at all times. There are numerious techniques that can be utilised to achieve this goal.

Technique One:
One approach is to listen to the InputPanel’s EnabledChanged event. This event will trigger whenever the SIP’s visibility changes. Within the event handler we can move controls around to ensure that they are visible within the current space available to the form.

private void InputPanel1_EnabledChanged(object sender, EventArgs e) 
{ 
  int y;
 
  if (inputPanel1.Enabled)
    // SIP visible - position label just above the area covered by the input panel  
    y = Height - inputPanel1.Bounds.Height;
  else
    // SIP not visible - position label just above bottom of form
    y = Height;
 
  // Calculate the position of the top of the label
  y = y - lblMessage.Height;
 
  lblMessage.Location = new Point(0, y);
}

This approach is the most flexiable, but it can become tricky depending upon the number of controls which need to be moved around. Coordinate calculations are never fun, especially when multiple device resolutions etc have to be taken into account.

Technique two:
Another technique which doesn’t involve explict coordinate calculations is to take advantage of the Docking and Anchoring functionality present with .NET Compact Framework v2.0.

The trick is to dock a control to the bottom of the form, and to resize this control’s height to match the current height of the SIP. This has the effect of pushing the rest of the content docked to the bottom of the form to be above the SIP.

This approach is shown in the following example:

private void InputPanel1_EnabledChanged(object sender, EventArgs e) 
{ 
  // Resize the panel docked to the bottom of the form to be
  // the same height as the SIP. This moves other controls also
  // docked to the bottom of the form to be above the area covered
  // by the SIP.
  SuspendLayout();
  panelSIP.Visible = inputPanel1.Enabled;
  panelSIP.Height = inputPanel.Bounds.Height;
  ResumeLayout();
}

This approach can also be extended to cope with larger forms, where the only real solution is to place a vertical scroll bar onto the form. If all the controls are placed onto a panel, you can configure the panel by setting the following properties:

  • AutoScroll – true
  • Dock – fill

With these properties set, you will find a vertical scrollbar automatically appears when required (due to the SIP becomming visible).

An added finishing touch to this technique is to ensure that any controls on the right hand side of the form has the Anchor property set to “Right”. This ensures that the controls are not obsecured by the vertical scrollbar when it is present.

Selecting Input Methods
The InputPanel component can also be used to enumerate a list of available Input Methods, and to determine which one is currently active.

// List the name and class id of each input method
// registered on this device
foreach (InputMethod im in inputPanel1.InputMethods)
{
  MessageBox.Show(im.Name, im.Clsid.ToString());
}
 
// Display the name of the currently active input method
InputMethod currentIM = inputPanel1.CurrentInputMethod;
MessageBox.Show(im.Name, "Current Input Method");

The InputMethod class is a simple key, value pair containing the name of the Input Method (a string shown in the SIP popup menu), and the matching class id. Class identifiers are a COM specific concept which uniquely identify different types of object, and since the software-based input panel architecture is COM based, each input method can be uniquly referred to by its clsid value.

Code Sample
A sample project which demonstrates all the techniques discussed in this article is available for download, and should help clarify the behaviour of the InputPanel control.

VB.NET and InputBox()
Recently a software-based input panel related question came up within an online forum I participate in. As part of answering the question I learnt of a VB.NET function called InputBox. InputBox is a function which provides a basic data entry mechanism, similar to how MsgBox displays simple messages to the user.

It turns out that Microsoft’s implementation of InputBox does not deal with dynamically moving the OK and Cancel buttons around to ensure that they are visible if the software-based input panel is visible. It also does not look too nice on VGA resolution devices.

I have written a replacement InputBox implementation which resolves these issues. My new and improved InputBox, including a sample project is available for download. I hope this control is of use to those wising to utilise InputBox within their applications.

Introduction to the .NET Micro Framework

Sunday, July 15th, 2007

As I mentioned in an earlier posting I have started to become interested in Microsoft’s latest EMCA Common Language Infrastructure (CIL) implementation, aka the .NET Micro Framework.

The .NET Micro Framework is designed for devices where even the .NET Compact Framework requires too many system resources to be feasible. It’s original design specification was to run on a custom ARM7 ASIC running at 27Mhz with 512KB ROM, 384 KB RAM and 8KB EEPROM, without an form of Operating System.

Operating Environment
One feature that makes the .NET Micro Framework unique is it’s ability to optionally run on hardware directly without the need for a traditional operating system. This is achieved by providing two levels of integration within the porting kit utilised to port the .NET Micro Framework to a new device. An OEM may decide to provide support for the .NET Micro Framework, by hooking in at one of two levels, depending upon the capabilities of their device:

  • Platform Adoption Layer (PAL) – This layer is a high level interface which provides a set of high level primitives such as timers, memory management and data structures. These are typically features provided by a host operating system, leading to a reasonably transparent PAL being developed by the OEM.
  • Hardware Abstraction Layer (HAL) – If no host operating system is in use on the target device, the OEM can utilise a standardised PAL, which hooks into the functionality provided by a hardware abstraction layer. The HAL provides a standardised interface to low level hardware features such as GPIO signals, interrupt handlers and power management etc, which the PAL uses to implement it’s own OS like functionality.

Implementing a Hardware Abstraction Layer can lead to the situation where the .NET Micro Framework is running directly on the CPU as the only “process”.

Compilation Process
Another unique feature of the .NET MIcro Framework, is that it has no Just In Timer (JIT) compiler. The framework instead interperts the MSIL bytecode, in a similiar manor to Mono’s mint interpreter.

Similar to the Java Micro Edition platform, the standard bytecode format utilised on the desktop is not understood by a .NET Micro Framework device. Instead, as part of the compilation process, the bytecode is passed through a pre-verification and optomisation stage, which produces an optimised representation of the bytecode understood by the .NET Micro Framework device.

Hello World – Software Developer style
The traditional first program for a software developer learning a new language or development environment is to write an application which simply prints “Hello World” and then exits. This tradition has it’s roots in an example provided in a book called “The C Programming Language” and was apparently sourced from a 1974 Bell Laboratories internal memorandum written by Brian Kernighan (one of the book’s authors).

Within the Visual Studio 2005 environment for the .NET Micro Framework, a Hello World application may be written as follows:

using Microsoft.SPOT;
 
namespace HelloWorldApplication
{
  public class Program
  {
    public static void Main()
    {
      Debug.Print("Hello World!");
    }
  }
}

The Microsoft.Spot.Debug class is somewhat similiar to the System.Diagnostics.Debug class present in the full framework in its intent.

The Debug.Print method can be utilised to emit a string to the standard output stream, which by default is routed to the Visual Studio IDE from the development board while debugging an application.

This code sample is fairly similiar to that produced by the Micro Framework Console Application project wizard within Visual Studio 2005. The main difference being that the project wizard emits code which utilises a string resource to store the string, this aids in internationalisation of the application.

Hello World – Hardware Engineer style
The equvialent to a “Hello World” application for a hardware engineer bringing up a new microprocessor based board is to flash a LED connected to a GPIO pin.

using System.Threading;
using Microsoft.SPOT.Hardware;
 
namespace HelloWorldApplication
{
  public class Program
  {
    public static void Main()
    {
      // The LED is hooked up to GPIO Pin 1. The second parameter
      // within the constructor indicates to set the pin to logic high
      // initially
      OutputPort led = new OutputPort(Cpu.Pin.GPIO_Pin1, true);
 
      while (true)
      {
        // Sleep for 5 seconds (5000 ms)
        Thread.Sleep(5000);
 
        // Toggle the state of the LED
        led.Write(!led.Read());
      }
    }
  }
}

NOTICE: If you attempt to run this sample application on actual hardware, you may need to alter the GPIO Pin assignment to suit your hardware, and add a reference to a device specific assembly.

The Microsoft.Spot.Hardware.OutputPort class accesses a specified pin on the physical hardware and can toggle the pin between the high and low logic levels.

The Read() method queries the pin for it’s current state, while the Write(bool) method allows the user to explicitly set the pin’s current state. For those familiar with traditional Micro-controller firmware development, you will notice that the hardware is accessed in an abstracted sense, where all the bit twiddling typically required to set or reset a single GPIO pin is hidden behind the scenes. This makes for a nice portable application, but is not suitable in applications which need precise real time functionality etc.

Trivia
I initially wondered why the .NET Micro Framework related classes were in namespaces starting with Microsoft.SPOT. SPOT which is an acronym for “Smart Personal Object Technology”, was the Microsoft Research project which initially produced the technology that became the .NET Micro Framework. The Microsoft SPOT group developed a range of devices, with the most well known probably being the smart watch.

One of the proof of concepts the research team produced was a tiny CLR to allow a managed software development environment for their projects. They named the initial namespaces after their group, since this was a technology for internal use only. When it was decided to commercialise the .NET Micro Framework as a seperate product, they decided to keep the namespaces, since a number of internal and external projects were already using them and it helped with backwards compatibility.

I also assume this is why what appears to be the first publically available version of the .NET Micro Framework is versioned as version 2.

It’s a small world after all

Sunday, July 15th, 2007

I have been subscribed to Dale’s blog for the last few days. His blog contains an interesting mix of technical information and ???? about his volunteer work.

Today I was surprised when his post “Windows Mobile has a ‘Run…’ dialog” made reference to my blog. This was a nice warm fuzzy when I stumbled upon it.

It is quite bizarre how small the world is. What are the odds of me finding his blog, and him finding my forum posts within a few days of each other? I would imagine in a world of 6.6 billion people, it would be quite, small.

This is one of the main reasons I started helping out on the MSDN forums, and started my blog, I want to connect with other software developers through-out the world, and share my knowledge, in the hope that it helps others. It is my way to contribute back to the community.

It has also given me an idea for an extra category of posts I can blog about. I am going to start a new category of posts, which briefly cover hidden features (or atleast not well known ones) of Windows Mobile. I will start off by re-blogging the tip I posted to MSDN Forums which Dale found useful.