How to detect Windows Mobile 6.1 (Detecting AKUs)

April 7th, 2008

Screenshot showing the AKU of a Windows Mobile 6.1 device being reportedWindows Mobile 6 and 6.1 both share the same version of the Windows CE kernel (5.2) meaning that previous techniques to determine the version of Windows Mobile on a device need to be modified to differentiate between these two most recent versions. It is not enough to compare the major and minor version numbers of the kernel. One possible technique is to programatically determine the current AKU in use by the Windows Mobile device as outlined by this blog posting.

What is an AKU?

An Adoption Kit Update (AKU) is an update to the Windows Mobile operating system which is akin to a service pack for a desktop version of Microsoft Windows. An AKU is usually a vehicle to ship an extra feature or fix required by a specific Windows Mobile device under development.

Typically the features enabled by an AKU require specific hardware (such as a new type of keyboard) meaning it does not make sense to make AKUs available to older devices. Occasionally an AKU enables significant features which are of a software nature. For example AKU 2.0 for Windows Mobile 5.0 introduced the Messaging and Security Feature Pack (MSFP) which enabled closer integration with Exchange Server 2003.

Determining the AKU

Since an AKU typically needs specific hardware and generally doesn’t alter the end user behaviour of a device it isn’t typical to need to detect a device’s AKU. However when you must detect the AKU of a device you can look within the HKLM\SYSTEM\Versions registry key for a string value called not surprisingly Aku.

An example of how you may access this registry value is shown below:

using Microsoft.Win32;
 
private string GetAKUVersion()
{
  RegistryKey key = null;
  string aku;
 
  try
  {
    key = Registry.LocalMachine.OpenSubKey(@"SYSTEM\Versions");
    aku = (string)key.GetValue("Aku");
    // Most of the time the AKU string is prefixed with a .
    // so remove it.
    if (aku.StartsWith("."))
      aku = aku.Substring(1);
  }
  finally
  {
    if (key != null)
      key.Close();
  }
 
  return aku;
}

The Channel9 Windows Mobile Developer Wiki contains a list of AKUs that enables you to match up AKUs with OS build numbers which is another way to determine which AKU is present.

Sample Application

[Download akudetection.zip - 10 KB]

A small example application is available for download that demonstrates making use of the GetAKUVersion function outlined above to display the Windows CE Kernel and Adoption Kit Update version numbers for the device the application is currently running on.

If you run this application on a Windows Mobile 6.1 device you will notice that the AKU version is reported as 1.0 (or higher) compared to older Windows Mobile 6 devices which have an AKU version below 1.0 (such as 0.4.2). Both versions of Windows Mobile report the use of various builds of the Windows CE 5.2 kernel.

Introducing the Christchurch Embedded .NET User Group (EDNUG)

April 6th, 2008

Update: We have had to change the date of this presentation – it is now booked for the 22nd of April instead of the 16th.

I have recently became involved in starting up a new user group within the Christchurch area. Andrew Leckie, Andy Scrase, Bryn Lewis and myself are organising a user group to cover embedded development topics within the Microsoft environment.

If you work with or have an interest in embedded device solutions using technologies such as the .NET Micro Framework, Windows Embedded CE, Windows Mobile, the .NET Compact Framework, Embedded XP, or Microsoft Robotics Studio etc, then this is the user group for you!

At the moment we are organising our first user group event for the 16th of April. This first session will give an overview of the above technologies and give a synopsis of the future sessions and intended agenda for the user group. It will also be a chance for you to provide some early feedback on what else you may wish to have presented from local experts as future topics.

So please help spread the word, the more we get along to our first meeting the better!

Further details will be able to be found via the newly created Christchurch Embedded .NET User Group website available at http://www.embedded.net.nz (one of my current tasks is to help flesh out this website). If you have any questions about this user group please don’t hesitate to contact me.

Visual Studio Tip: Selecting a Deployment Device

April 5th, 2008

Screenshot of Target Device combo box located on Visual Studio 2008 toolbarHere is a small tip for C++ Smart Device developers who use Visual Studio. While developing native applications it is common to target an older version of the Device SDK in order to produce a single executable that will run on a wide range of devices. For example you may purposely target the Pocket PC 2003 Device SDK in order for your executable to be compatible with any Windows Mobile 2003, 5.0, 6 or 6.1 device.

One problem with this technique is that by default the target device drop down used to select the device used for deployment and debugging purposes is filtered to only show the devices that match the selected version of the Device SDK.

If your application makes use of functions such as LoadLibrary and GetProcAddress to conditionally take advantage of functionality present in newer versions of the Windows Mobile operating system (as discussed previously) it can be handy to debug your application on a more recent version of Windows Mobile while still compiling against the older version of the Device SDK.

Luckily this can easily be achieved, but the feature is slightly hidden. If you open the Project Properties dialog (right click on the project within Solution Explorer and select Properties) you will be able to find a “Deployment Device” setting within the “Deployment” section. You will notice that this combo box displays all currently installed emulators for all versions of Windows Mobile. By selecting an emulator from this list and clicking OK you will notice that the Target Device combo box updates to reflect your selection even if the selected emulator is for a different version of Windows Mobile.

Screenshot of project settings dialog showing deployment device settings

Creating custom animated wait cursors

April 4th, 2008
Screenshot of standard Windows Mobile 6 wait cursor Screenshot of example animated wait cursor Screenshot of example animated wait cursor

Most .NET Compact Framework developers will be familiar with the Cursor.Current property and how to display the standard Wait Cursor, but did you know that you could easily display your own custom cursor? This blog entry discusses how you can replace the standard wait cursor with your own application specific cursor. This is an ideal way to brand kiosk style applications for example.

Creating a custom cursor

Recent versions of the Windows CE operating system (and hence Windows Mobile) support an OS API called LoadAnimatedCursor. This API enables you to specify a sequence of individual bitmap frames and will convert them into an animated cursor. For example an animated cursor of a rotating monkey could be made up of the following 4 bitmaps.

101 102 103 104

The more frames the cursor consists of the smoother the animation will be. Individual frames within the animation should be 48×48 pixel bitmap resources within a *.dll or *.exe file. The bitmap resources are identified by a numeric ID and must be in sequential order (such as the values 101, 102, 103 and 104 used in the example above).

The id of the first bitmap, the total number of frames and the period of time to delay between frames is then passed into the LoadAnimatedCursor API which will return a handle to the newly created cursor (an HCURSOR). Passing this handle to the SetCursor API will then make the cursor visible on the screen.

Screenshot showing bitmap resources within the CustomCursors dllUnfortunately the LoadAnimatedCursor function is not as easy to use from managed code as it should be. The API expects the bitmap images to be native bitmap resources meaning you can not store them within a *.resx resource file within your .NET Compact Framework application. The easiest way to store the bitmaps in the correct format is to create a native C++ DLL project. You can then remove all the C++ source files, leaving a sole Win32 *.rc resource file to which you can add the bitmaps to (as will be demonstrated later).

Sample Application

[Download animatedcursortest.zip - 37KB]

The sample application available for download consists of two projects. The first (called AnimatedCursors) demonstrates how to create a resource only DLL that contains the bitmap images required for the two custom cursors shown above.

The second project is a C# example demonstrating how to use Platform Invoke to access theLoadAnimatedCursor and SetCursor APIs to display the custom cursors. This second project loads the custom cursors from the AnimatedCursors.dll file built by the first project.

The C# sample wraps up the required Platform Invoke code within a class called AnimatedWaitCursor. This class implements the IDisposable interface so that the following syntax can be used to display a custom cursor. This code structure should be familiar to anyone who has used MFC’s CWaitCursor class.

// Use the animated cursor that has 4 frames starting with
// bitmap id 101, delaying 125 milliseconds between each frame.
string dll = @"\path\to\some.dll";
using (AnimatedWaitCursor cursor = new AnimatedWaitCursor(dll, 101, 4, 125))
{
  // do some long running task
}

Using VB.NET with the .NET Micro Framework

April 1st, 2008

This blog entry explores if it is possible to run VB.NET code on a .NET Micro Framework device. The current Visual Studio integration for the .NET Micro Framework only supports C# development, but since the framework is based upon the CLR runtime it theoretically supports development in any language that can be compiled down to Microsoft Intermediate Language (MSIL) code. So can we compile a VB.NET application for a .NET Micro Framework device and if so what kind of limitations or issues are we likely to come across? Read on to find out the results of some early experiments…

A sample application

The first thing we need is some VB.NET code to attempt to compile. For this I have written the following WPF application.

Imports System
Imports Microsoft.Spot
Imports Microsoft.SPOT.Presentation
Imports Microsoft.SPOT.Presentation.Media
Imports Microsoft.SPOT.Presentation.Shapes
 
NameSpace HelloWorldVB
  Public Class Program
    Public Shared Sub Main()
      Dim app as Application = New Application()
 
      ' Create a window object and set the size to
      ' the size of the display
      Dim mainWindow as Window= New Window()
      mainWindow.Height = SystemMetrics.ScreenHeight
      mainWindow.Width = SystemMetrics.ScreenWidth
 
      ' Add a green rectangle as the sole child
      ' control of the window
      Dim rect As Rectangle = new Rectangle()
      rect.Fill = new SolidColorBrush(CType(&HFF00, Color))
      mainWindow.Child = rect
 
      ' Make the window visible
      mainWindow.Visibility = Visibility.Visible
      app.Run(mainWindow)
   End Sub
  End Class
End Namespace

This application simply displays a full screen window that is coloured Green. This is a reasonably simple application that doesn’t make use of too many VB.NET language or .NET Micro Framework features so is an ideal starting point.

Compiling the application

The first step is to use the standard VB.NET command line compiler (vbc.exe) to compile the source code into a standard executable. We can do this by using the following commands at a command prompt:

SET NET_BIN=C:\Windows\Microsoft.NET\Framework\v2.0.50727
SET MF_BIN=C:\Program Files\Microsoft .NET Micro Framework\v2.0.3036\Tools
SET MF_LIB=C:\Program Files\Microsoft .NET Micro Framework\v2.0.3036\Assemblies
 
"%NET_BIN%\vbc.exe"
  /netcf
  /define:_MYTYPE=\"EMPTY\"
  /reference:"%MF_LIB%\Microsoft.SPOT.Graphics.dll"
  /reference:"%MF_LIB%\Microsoft.SPOT.TinyCore.dll"
  /out:HelloWorldVB.exe
  /target:exe Program.vb

This is all fairly standard stuff for command line VB.NET compilation, however there are two things to note. First we have used the /netcf argument which causes the compiler to target the .NET Compact Framework. This removes language functionality (such as late binding) that depend upon aspects of the full .NET framework.

The second thing to note is the define which sets _MYTYPE to EMPTY. As discussed by the “Customizing Which Objects are Available in My” article on MSDN setting this define to EMPTY will cause the VB.NET compiler to not generate a My namespace. The My namespace is typically used by VB.NET developers to get quick access to convenience functions for things such as File IO and networking functionality, but the code emitted by the VB.NET compiler is not suitable for the .NET Micro Framework base class libraries.

Transforming the executable

Now that we have compiled the VB.NET code into MSIL we need to run the executable through an application called the Meta Data Processor. This pre-processes the MSIL based executable into a more efficient and smaller format that is suitable for use by the interpreter that forms the core part of the .NET Micro Framework runtime.

The following command line will convert the HelloWorldVB.exe executable into a HelloWorldVB.pe file that is suitable for execution by the .NET Micro Framework.

"%MF_BIN%\MetaDataProcessor.exe"
  -loadHints mscorlib "%MF_LIB%\mscorlib.dll"
  -parse HelloWorldVB.exe
  -minimize
  -compile HelloWorldVB.pe

You should notice that HelloWorldVB.pe is significantly smaller than HelloWorldVB.exe and even while viewing it using Notepad it clearly shows that there is less unnecessary “baggage”. For instance there is no string stating “This program cannot be run in DOS mode”.

Running the application

Now that we finally have what appears to be a compiled VB.NET application in a form that is usable by the .NET Micro Framework we need to figure out a way to load it into our .NET Micro Framework emulator or device.

The following command line launches HelloWorldVB.pe within the sample emulator that comes with the .NET Micro Framework SDK.

"%MF_BIN%/Microsoft.SPOT.Emulator.Sample.SampleEmulator.exe"
  /load:HelloWorldVB.pe
  /load:"%MF_LIB%\mscorlib.pe"
  /load:"%MF_LIB%\Microsoft.SPOT.Native.pe"
  /load:"%MF_LIB%\Microsoft.SPOT.TinyCore.pe"
  /load:"%MF_LIB%\Microsoft.SPOT.Graphics.pe"

At this point in time I have not investigated how to deploy *.pe files to actual devices.

Conclusion

This experiment demonstrates that at a technical level it should be possible for the .NET Micro Framework to eventually support the execution of applications written in VB.NET. It does however demonstrate that at present there are a couple of hurdles to overcome, mainly in the code generated by the VB.NET compiler having dependencies on framework functionality not present by the .NET Micro Framework. Not being a VB.NET expert I wonder how far you can go before finding other problems? My next step is to figure out how to deploy *.pe files to an actual device so that I can verify that HelloWorldVB.pe actually does run on a physical device.

I am also interested in investigating the MetaDataProcessor.exe application in further depth. Is anyone aware of additional documentation for this tool? By running it from the command line it is apparent that it has a wide range of command line arguments, but I have presently been unable to find information about it usage.

Community Interview: Steve Hegenderfer

March 28th, 2008

Photo of Steve Hegenderfer1) Who are you? Where are you located?

My name is Steve Hegenderfer. I am a Technical Evangelist, Group Manager for Solutions Delivery within Windows Mobile, all around great guy…located out of the Mothership, in Redmond WA.

2) What does the Solutions Delivery group within the Windows Mobile unit do?

My new role is running what we are calling Solutions Delivery within Windows Mobile. I focus on the enterprise and business side of things. Think of it like this; we have a lot of things we want to build as MS, but we can’t (nor do we want to) build all of them. My group’s job is to go out, find 3rd party solutions to fill those needs, and take them to market with us.

3) What does this job involve?

Wow…what does the job NOT involve :)

I’m still active with the blogs (my partner in crime is Reed Robison); but, that’s more something I really like to do to send out some info and thoughts. My team is actually pretty cool. You can think of it as a microcosm of the larger MS. We have folks on my team that look at the market and the needs, and go out and find partners to fill those needs. We have folks on my team that work out the business plans (who gets paid what and when and how we split the pie). We also have some people who work on the go to market materials and the integration with our field and the mobile operators’ sales force. So, we have the full gamut.

And, I’m hiring :)

4) What did you do before working for Microsoft with Windows Mobile?

Wow, what DIDN’T I do :) Funny, I spent about 10 years going from start-up to start-up, mostly in the San Jose, CA. area. I would just keep going from job to job, doing things that really interested me. That’s one of the reasons I ended up here at MS; and I have no plans on leaving THIS group any time soon…too much cool stuff going on :)

5) So how did mobile devices catch your eye and keep your attention?

Kinda funny…I used to develop old WAP apps on the first few wireless Palms that came out. But it really started when I read an article about how Reebok was using embedded systems in some of their shoes. I thought, “Man, that is some seriously cool stuff…think of the possibilities!”

One thing led to another, and here I am.

6) It’s been announced that MEDC2007 was the last Mobile and Embedded Developers Conference (MEDC) event, and that from 2008 onwards MEDC content will be rolled into two streams of the Tech·Ed conference. Is this a sign that mobile device development is becoming more mainstream, or is it more the case of there not being enough support for a standalone event?

This is a good thing. It means that mobility is going main-stream. I talk to HUGE enterprise customers all the time, and by a long shot they are ALL asking how they start doing this stuff; how can they extend their existing assets and infrastructure into the mobile world.

MEDC was more like preaching to the converted; don’t get me wrong, we still need to, and will be. But we need to take the message broader to more folks who are interested in this, who wouldn’t necessarily go to MEDC, but do go to Tech·Ed et al.

So, in the end, while I WILL miss MEDC, this is a good thing.

7) How can small Windows Mobile ISVs best engage with Microsoft?

First of all, look at joining the Microsoft Partner Program (MSPP) at the certified or gold level. And take a look at the ISV competency within it; there is a mobility skew to it if you don’t think that the Windows Mobile specific Mobility Solutions competency is the right one for you. So, step one, get in there.

8) You seem to be excited about the possibilities the new System Center Mobile Device Manager (SCMDM) application offers enterprises deploying mobile devices. What is this product and how does it help enterprises deploying or developing Windows Mobile based solutions?

MDM is actually VERY cool. It provides security to the device (device-side encryption as well as SD card encryption/white and black listing, etc,), the ability to manage the device (think asset/inventory/policy/etc). But one of the coolest features for the business developer is an always-on mobile VPN that makes accessing all of your company’s assets securely for your apps a cake walk.

9) SCMDM is arguably a business oriented feature, and enterprise mobility has always been a main stay of the Windows Mobile platform. Do you think with the announcement of devices such as the Sony Ericsson Experia X1 that Windows Mobile is also starting to make inroads into the consumer market?

That is a loaded question :) I think the X1 is more of a business device (even though it’s sexy as all get out). But, we ARE focusing on the consumer and the experience that those individuals have. Expect more devices like the X1 and more experiences like that in the future.

10) Do you carry a Windows Mobile powered device with you? If so what feature couldn’t you live without, and if you had to pick one feature it had missing (or was less than ideal) what would it be?

I do, in fact! I carry it with me everywhere. There are a few things that I love, but access to push email via Exchange is one of the tops; now that we’re dog-fooding MDM, access to some of the apps we are rolling out internally is very cool.

One missing feature…hmmm…I think it might be something more compelling in the interface. Having said that, the horizon is near for some of those features as well :)

11) If you had one thing to say to potential developers of Windows Mobile applications what would it be?

Just start doing it. If you know VB, C#, or C++, and are familiar with Visual Studio, you already know the essentials of developing for Windows Mobile. Sure, the memory and form-factor constraints are there, but you will get a feel for those over time. The emulators are decent, and the SDK is good, so you should just hop in with ‘Hello World’ and then go from there…if I can develop for the platform, ANYONE can :)

Some folks say it’s too difficult to develop for Windows Mobile…I say rubbish, you just have to watch yourself and make sure you are doing the right things.

12) Any predications for 2008?

Being an insider, I’m not sure I can make any predictions for 2008 :)

I will say that this space is REALLY heating up; more players, cooler devices, better HW in general…and MS will be right there in the thick of it. Personally, I am VERY excited for WM in 2008 and 2009…you should all be prepared for some nice innovation in both the business world and the consumer world!

Windows Mobile Tip: Creating shortcuts

March 27th, 2008

Shortcuts are small files containing the location of another file, or the command line required to launch an application. They are commonly placed within the Windows Start Menu as a convenient way to access common functions of your device. By creating and organising your own shortcuts you can customise the features you have quick access to on your device.

Creating a shortcut

You can create shortcuts directly on the device by using the built in File Explorer application. In order to create a shortcut first navigate to the file you want a shortcut for and tap and hold the stylus over the file to display a context sensitive popup menu. From the menu select the “Copy” option.

Now navigate to the location where you want to place the shortcut and tap and hold the stylus over a blank area (such as after the last file in the directory listing). This displays a similar context sensitive popup menu from which you can select a “Paste Shortcut” option.

A shortcut to the file will be created. By default the newly created shortcut will have the name “Shortcut to XYZ” where XYZ was the original file name. By using the standard file rename functionality you can rename the shortcut to a more suitable name.

Uses of shortcuts

Shortcuts are used within the Windows Mobile operating system for a wide range of purposes. By placing your shortcuts into specific folders you can obtain special functionality. Some examples include:

  • \Windows\StartUp – shortcuts to applications placed in this directory will automatically be started whenever the Windows Mobile device is reset.
  • \Windows\Start Menu – shortcuts placed in this directory will appear in the Windows start menu.
  • \Windows\Start Menu\Settings – as discussed in a previous blog entry shortcuts placed in this folder will appear on the System tab of the Settings application that is accessible via the Start Menu.

Early adopters of the Pointui shell replacement for Windows Mobile devices are using similar techniques to customise the functionality of the built in menus to launch phone dialler applications etc.

Technical Details

Behind the scenes File Explorer is creating a shortcut file (probably via the SHCreateShortcut API). A shortcut is a file that has the extension *.lnk and contains details of the command line or file that the shortcut should open.

Pavel Bánský discusses in his blog the technical details on the contents of a *.lnk file. As an alternative to creating the shortcut file manually, you can also utilise an API called SHCreateShortcut as shown below:

using System.Runtime.InteropServices;
 
[DllImport("coredll.dll")]
public static extern void SHCreateShortcut(
  string target,
  string shortcut);
 
// Create a shortcut to tmail.exe within the
// windows start menu.
SHCreateShortcut(
  @"\windows\start menu\programs\my email.lnk",
  @"\windows\tmail.exe");

Shortcuts can also be created as part of a CAB file installation package for your applications, as discussed in the .NET CF Deployment section of the Microsoft Visual Studio 2005 Professional Guided Tour.

Shortcuts can also have other purposes, one of these I will discuss in greater depth in a future blog posting…

Visual Studio Tip: Open containing folder

March 26th, 2008

A handy feature while editing files within Visual Studio is to open up a Windows Explorer window for the folder that contains the selected file (perhaps to rename a set of files, or to change the attributes etc). This feature has been within the Visual Studio IDE for a few revisions. The easiest way to access it is to open a file in the editor, then right click on the file’s tab and select the “Open Containing Folder” menu option.

Extended Functionality

One problem with this feature is that it requires the file to be opened within the editor in order to be able to right click on its tab. For forms and other project files with complex editor behaviour it can be a timely exercise waiting for the file to load into the editor just to be able to right click on it.

A handy solution to this problem within Visual Studio 2008 is an add-on called the “PowerCommands for Visual Studio 2008“. This extension, written by Microsoft, adds a set of additional functionality to various context menus within the IDE. The two most relevant to this discussion are the “Open Command Prompt” and “Open Containing Folder” options available while right clicking files within the Solution Explorer window (as seen in the screenshot to the right). This saves needing to load the file within the editor in order to access this option and is a great productivity boost. For more details check out the Visual Studio Extensibility (VSX) team blog. The PowerCommands extension is worth installing for just this feature, but also introduces a range of additional ones you will soon not be able to live without.

Going even further

IDE productivity fanatics and keyboard power users may be interested in the following additional things which may further maximise the use of this feature:

  • You could follow the “How to: Work with Shortcut key Combinations” article on MSDN in order to bind the feature to a keyboard shortcut. The command is “File.OpenContainingFolder”.
  • You could add this feature as a menu item within the Tools menu by following the instructions recently given on the .NET Tip of The Day blog. I for one didn’t think about using Visual Studio environment variables such as $(ItemPath) within this dialog.

If you like these kinds of IDE productivity tips, you might like to subscribe to Sara Ford’s blog.

How to make your ListView columns reorderable

March 18th, 2008

Another finishing touch that I like to see in applications that use ListViews is the ability for the end user to re-order the columns to suit their own preferences. This blog entry discusses one approach for adding this functionality to the ListView control present within the .NET Compact Framework. Although it is difficult to convey in a static screenshot, the screenshot above shows a user dragging the stylus over the header of the listview control to move the position of the “First Name” column.

Obtaining Draggable Columns

The System.Windows.Forms.ListView control is a wrapper over top of the native ListView control. The native ListView control supports the notion of extended styles, which allow various optional features to be enabled or disabled as desired. One of the extended styles is called LVS_EX_HEADERDRAGDROP. If this extended style is enabled the user can re-order the columns by dragging and dropping the headers shown at the top of the listview while it is in report mode.

Although the .NET Compact Framework ListView control does not expose a mechanism to enable extended styles, we can use a technique discussed in a previous blog entry of mine to add or remove the LVS_EX_HEADERDRAGDROP extended style as desired.

private const int LVM_SETEXTENDEDLISTVIEWSTYLE = 0x1000 + 54;
private const int LVS_EX_HEADERDRAGDROP = 0x00000010;
 
public static void SetAllowDraggableColumns(this ListView lv, bool enabled)
{
  // Add or remove the LVS_EX_HEADERDRAGDROP extended
  // style based upon the state of the enabled parameter.
  Message msg = new Message();
  msg.HWnd = lv.Handle;
  msg.Msg = LVM_SETEXTENDEDLISTVIEWSTYLE;
  msg.WParam = (IntPtr)LVS_EX_HEADERDRAGDROP;
  msg.LParam = enabled ? (IntPtr)LVS_EX_HEADERDRAGDROP : IntPtr.Zero;
 
  // Send the message to the listview control
  MessageWindow.SendMessage(ref msg);
}

This method allows the drag feature to be turned on and off for a given ListView control. Notice that this method makes use of a C# 3.0 feature called Extension Methods. The “this” keyword in front of the first parameter means that this method can be called as if it was part of the standard ListView control, meaning the following code snippet will work (assuming listView1 is an instance of the System.Windows.Forms.ListView control).

listView1.SetAllowDraggableColumns(true);

This is pure syntactic sugar, behind the scenes the C# compiler is simply passing in listView1 as the first parameter to the SetAllowDraggableColumns method.

Persisting Column Order Preferences

Once you have reorder-able columns it can be desirable to persist the user’s preferred layout across multiple executions of your application. It would be a pain if the columns always defaulted back to a standard order everytime the form was displayed.

The native ListView control provides two window messages, LVM_GETCOLUMNORDERARRAY and LVM_SETCOLUMNORDERARRAY that can be used to implement this feature. The code sample available for download wraps up these two window messages to allow you to query the current order of the columns by using a statement such as the following:

int[] columnOrder = listView1.GetColumnOrder();
// TODO: save 'columnOrder' to the registry
// or another persistent store

When columns are added to a ListView they are given an index. The first column is column 0 while the second is column 1 and so on. When columns are re-ordered they keep their index value but their position on screen changes. The array returned by the GetColumnOrder function contains the index for each column in the order that they are visible on screen. For example if the array contains the values 2, 0, and 1 it means that the last column (column 2) has been dragged from the right hand side of the listview to become the left most column.

Once we have obtained the order of the columns we can store the data in any persistent storage mechanism such as a file, a database table, or registry key. When the form is reloaded we can initialise the default order of the columns by calling the equivalent SetColumnOrder method with the value we previously saved:

// TODO: should read 'columnOrder' from the registry
// or other persistent store
int[] columnOrder = new int[]{2, 0, 1};
 
listView1.SetColumnOrder(columnOrder);

Sample Application

[Download ListViewExtenderTest.zip - 11 KB]

The sample application displays a list of three columns. While running on a Windows Mobile Professional device you should be able to re-order the columns by dragging and dropping the column headers with your stylus. If you exit and restart the application you should see that your custom column ordering is persisted. Via the left soft key menu item you can select an option that will disable the user from re-ordering the columns.

Most of the magic occurs within a file you can reuse in your own applications called ListViewExtender.cs. The sample application targets .NET CF 3.5 and hence requires Visual Studio 2008. With minor tweaks the source code would also be usable within .NET CF 2.0 projects. I would be keen to hear what your thoughts are about this. Is it time to shift code samples to .NET CF 3.5/Visual Studio 2008 or are you still wanting .NET CF 2.0 and Visual Studio 2005 compatible samples?

Create a SQL Server 2005 Compact Edition database by using Query Analyzer 3.0

March 12th, 2008

Screenshot of Query Analyzer about dialog boxSQL Server 2005 Compact Edition Query Analyzer is a small application that can run directly on a Windows Mobile PDA and allows you to create and manipulate SQL Server Compact Edition databases. It is a handy tool to add to your toolbox, as it can help diagnose and correct small database errors while you are away from your development PC.

First a word of warning… Query Analyzer is prehaps the worst application with respect to conforming to the “Designed For WIndows Mobile” logo certification requirements. The application is not supported on Windows Mobile Standard (smartphone) devices, and many dialogs are unusable on small or square resolution Windows Mobile Professional (PocketPC) devices. The application appears to be more at home on devices running the standard Windows CE shell as evidenced by its heavy reliance on non fullscreen dialogs.

Installing Query Analyzer

If your .NET Compact Framework based application makes reference to the System.Data.SqlServerCe assembly Visual Studio will automatically install the query analyser tool when you deploy your project via the IDE.

If you are a native developer or want to utilise the tool without deploying via Visual Studio you will need to manually install the Query Analyzer tool which is part of SQL Server Compact Edition’s developer support cab file.

The SQL Server Compact Edition Books Online documentation has a “How to: Install Query Analyzer (SQL Server Compact Edition)” section that covers this process.

Essentially you need to install the following CAB files on your device:

  • .NET Compact Framework – NETCFversion.platform.processor.cab
  • SSCE runtime – sqlce30.platform.processor.cab
  • SSCE dev tools – sqlce30.dev.ENU.platform.processor.cab

You should be able to find the required CAB files within the %programs%\Microsoft Visual Studio 8\SmartDevices\SDK\SQL Server\Mobile\v3.0\platform\processor\ folder. One tricky bit is the fact that references to “platform” and “processor” in file and directory names above need to be replaced with values specific to the version of Windows Mobile your target device is utilising.

In most cases you can use wce500\armv4i\sqlce30.ppc.wce5.armv4i.CAB and wce500\armv4i\sqlce30.dev.ENU.ppc.wce5.armv4i.cab for Windows Mobile 5 Pocket PC or higher devices. Further instructions can be found in the “How to: Install SQL Server Compact Edition on a Device” article available on MSDN.

One tip to correctly determine the correct CAB files to install is to hard reset a PDA and have Visual Studio deploy your project to the PDA. After the deployment you should be able to refer to the output window to see which CAB files Visual Studio deployed and installed to configure SQL Server Compact Edition.

Opening a database

After installing the SQL Server Compact Edition developer tools CAB file you should be able to find a new Query Analyzer application within the start menu of your Windows Mobile device.

The initial window that appears after this application is started should show a series of tabs with the one labelled “Objects” selected. This tab is similiar to the Object Explorer of SQL Server 2005 Management Studio on the desktop and shows each database you have connected to in the past and the database objects contained within them.

Screenshot showing main screen of Query Analyzer application

To open a connection to an existing database you need to click the toolbar button at the bottom of the screen. This will display the following “Connect to SQL Server Compact Edition Database” dialog.

Screenshot showing Connect To Sql Server Compact Edition dialog

You need to enter the full path to your database (i.e. \Program Files\MyApplication\test.sdf) and a password if the database is password protected. Selecting the [...] button will display a file open dialog that allows you to graphically select a database file. This dialog unfortunately is restricted to database files located within the My Documents folder structure. If your database is not located within this hierarchy you will have to manually type it in.

Once the database connection details have been entered you can select the Connect button. This will return the user to the main Query Analyzer window with the specified database added to the tree view.

When you have completed your tasks with the database you should select the database within the treeview and select the toolbar button to disconnect from the database. If you do not do this it may not be possible for other applications to access the database due to Query Analyzer having a lock on the database file.

Creating a database

A new database can also be created directly on the PDA. To do this you follow the same process to open an existing database. However when the Connect to SQL Server Compact Edition database dialog appears you select the “New Database” button which will expand the connection window to include a couple of additional fields.

Screenshot showing Connect To Sql Server Compact Edition dialog after Create Database button has been pressed

The details you can enter via this dialog include:

  • Path – The full path to where the *.sdf database file should be created.
  • Password – An optional password that must be provided whenever an attempt is made to connect to the new database.
  • Sort – The sort order applied to indexes on tables within the database.
  • Encrypt – If encryption is enabled data within the database file will be encrypted. Enabling this feature will make a password mandatory since the password is the key used to decrypt the database.

After the new database has been configured clicking the Create button will return the user to the main Query Analyzer window with the newly created database added to the treeview.

Creating Tables

Screenshot showing main window of Query Analyzer after database has been created (or opened)

There are two ways to create a table within Query Analyzer. The first is to select the toolbar button while the Tables node of a database is selected. This will bring up the following Table Definition dialog that enables the user to specify a table name and define the columns within the table. These dialogs in particular are difficult to utilise on devices with small square screens.

Screenshot showing Table Definition dialog used to create a new database table graphically

An alternative to the GUI dialogs is to switch to the SQL tab of the main Query Analyzer window and enter a T-SQL data definition language (DDL) statement to create the table programatically, as shown in the screenshot below:

Screenshot showing creating a table via TSQL query execution

Once you have entered the CREATE TABLE statement you can select the toolbar button to execute the query. Query Analyzer will automatically switch to the Notes tab and inform you of the duration and outcome of the operation.