Category: Desktop Code

Desktop ActiveSync Registry Settings

In March I showed how to get the version of a connected device from the desktop. This post documents the rest of the registry settings used to store device information. There are two registry locations, the first at HKEY_CURRENT_USERSoftwareMicrosoftWindows CE Services contains information about the currently connected device. The second, HKEY_CURRENT_USERSoftwareMicrosoftWindows CE ServicesPartners contains information for each of the partnerships established on the desktop PC.

When the device is docked, regardless of whether a partnership is established, the following keys are populated in HKEY_CURRENT_USERSoftwareMicrosoftWindows CE Services:-

  • DeviceHardwareId -String containing a unique Guid for the device

  • DeviceOemInfo – OEM specific string (as returned by SystemParametersInfo using SPI_GETOEMINFO) e.g. WIZA200 (HTC Wizard)

  • DeviceProcessorType – DWORD value – 2577 (ARM) for all Windows Mobile devices

  • DeviceType – string containing platform type (as returned by SystemParamtersInfo using SPI_GETPLATFORMTYPE) e.g. PocketPC or SmartPhone

  • DeviceVersion – DWORD value – see my previous post.

The partnerships are stored with a unique DWORD partnership id e.g.

HKEY_CURRENT_USERSoftwareMicrosoftWindows CE ServicesPartners12345678

There are additional values to describe sync behaviour and some Windows Mobile Device Center specific values e.g. to specify the display icon for a device. Otherwise all of the above values are duplicated here for the partner device, except with some naming differences:-

  • DeviceHardwareId

  • OemInfo

  • ProcessorType

  • DeviceType

  • Version

Each partnership has a directory containing any resources used, this includes the icon etc. The path is retrieved from the DataFolder value. This is a path beneath the users roaming application data folder which you would get using System.Environment.GetFolder(System.Environment.SpecialFolder.ApplicationData)

The icon is specified in DeviceIconFile and if you append this to the path you’ll have the full filename of the icon.

Bluetooth Remote Control

Mike Hall posted a link on his blog to a channel9 interview with Anil Dhawan from the Windows Mobile team discussing Bluetooth programming, which I recommend you check out. Anil gave a demo of a native code application to remote control PowerPoint on a desktop PC. This inspired me to put some finishing touches to a test application I built for the Bluetooth .NETCF library – It is by no means finished but it works (with the wind blowing in the right direction!).

There are two components, on the Smartphone an application which you first select Search from the menu and it will do a lookup of local discoverable devices, then select one and select the Connect menu option. Once connected any d-pad or number keys are captured and sent over bluetooth. As I said it was an unfinished project, key items missing are:-

  • Store desktop address in the registry so we only have to search once

  • More intuitive interface 🙂

  • Support for key mapping – map the device keys to application specific commands e.g. for media player etc

On the desktop a simple listener which listens on a custom service, incoming data is received as keycodes which are broadcast on the system using the SendKeys.Send method.

On an unrelated note, thanks to Sergey Bogdanov who has contributed an implementation of the SendKeys class to be included in the upcoming SDF v1.3 release.

With the listener application running and the Smartphone client connected you can automate (within reason) whatever app has the focus. It works great for Powerpoint browsing between slides using the d-pad on the phone. The usual disclaimer applies – this works only with the Microsoft Bluetooth stack on both device and desktop, I tested with an Orange SPV C500.

The two projects are available to download here.

System.Net.IrDA for the desktop (Part 2)

Following my previous post, I did some further development to the code to make it fully match the .NETCF assembly (yes, in my haste I’d missed a few properties and cut a couple of corners). So now I have compiled a System.Net.IrDA.dll assembly which has exactly the same classes and methods as is available in device projects. So you can easily move device code over to Tablet and laptop PCs.

Download the DLL here (zip 7kb)

The package includes just the dll and xml documentation. The next task for the project is to build an installer for both the source and binaries…

This was a useful learning experience since I’ve based the Bluetooth code on the existing model of the IrDA library, so it was useful to spend some time studying this particular library and the classes it contains.

The functionality is now part of 32feet.NET a library for personal area networking for .NET. The downloads are here:-

System.Net.IrDA for the desktop

Following on from a question which cropped up on today’s MVP chat. I did some investigation into IrDA support on the desktop framework. Turns out you can’t use System.Net.IrDA.dll from .NETCF on the desktop as I had read on some blog, but since the basic Socket class supports the IrDA address family, it is necessary to build a couple of helper classes for the IrDAEndPoint and IrDAClient and IrDAListener to match the .NETCF implementation. I built these rather hastily and therefore have omitted a few overrides and non critical items. I intend to flesh this out later to fully match the .NETCF class. However the code zipped up below will give you the classes necessary to migrate your .NETCF IrDA code to the desktop. It was tested using the sample code in the .NETCF Quickstart on the subject to Discover my Pocket PC and send it a file. When I get the chance I’ll compile it into a System.Net.IrDA.dll, for now you’ll have to make do with C# source, and I didn’t really stop to write comments this evening – sorry 🙂

Download Source

Hosting a Native Windows Control – The desktop approach

Following Neil’s recent post on my control hosting article, I realised that the article had not gone into detail on the differences between the Control class in the full framework and Compact Framework. The Control class in the full .NET framework is incredibly powerful, and when I built the ControlEx class to enable hosting I tried to work to the same model where possible. Generally the Compact Framework follows the design of it’s larger cousin and therefore if the functionality of the Control class is enhanced in future revisions of the Compact Framework it will likely follow a subset of the desktop functionality.

There is a key difference with the Control class on the desktop, than any custom Control derived class on the Compact Framework. On the desktop you can override the protected CreateParams property to force the control to create any window class (remember that in Win32 terms any control is considered a window with it’s own unique handle and based on a specific window class). It’s possible to create an intrinsic windows control like the SysAnimate32 with almost no need to resort to Platform Invoke. If you view the running program with a tool like Spy++ you’ll see the SysAnimate32 window is a direct child of the form it sits on. We can pass it messages entirely in managed code by simply calling it’s WndProc method. The Handle property for the control is the handle for the SysAnimate itself.

On the Compact Framework this behaviour is only true for the standard set of Controls in System.Windows.Forms. For all other controls a standard window class is created (and this we have no control over), any native window class we wish to use must be added as a child to this window. However the next main hurdle with the .NETCF Control class is that there is no WndProc method we can override, so if we create a window as a child of this control, we have no way of capturing it’s window messages (Unless we capture them in the application message loop itself using ApplicationEx). Therefore to implement a WndProc for the control we use an additional layer.

The MessageWindow class is specific to the Compact Framework and serves only one purpose, it allows us to receive messages within managed code. By default the MessageWindow is a hidden 0x0 pixel window. With some P/Invoke magic it is possible to alter the size and position of the MessageWindow to make it a visible control – this is our empty canvas. We now create the native window as a child of this window and we have a native control, housed within a managed control with the ability to both send messages to the control and, most importantly, receive notification messages and process them.

There are a few house-keeping chores required to keep this three-layer solution working. Whenever the control is resized we must resize both the child (MessageWindow) and grandchild (native control) to fit. In order to hide as much of this plumbing as possible, and to avoid re-inventing the wheel, the ControlEx class was built to do all this work for you. Like the Control class on the desktop it exposes a CreateParams property which you can override with your class type. Notification messages received from the native control by the MessageWindow are passed to the OnNotifyMessage method of the ControlEx. It’s not quite as powerful as the full WndProc of the desktop but it allows us to receive events such as item selections within the native control. The WebBrowser sample within the article download uses these to expose events when the user taps a link.

The HtmlViewer, MonthCalendar and InkX controls within SDF v1.2 are all built using this technique, however they use a less transparent approach to the new ControlEx class. I’ll be upgrading these to use the ControlEx class, and of course you can use the class yourself to wrap other native windows controls of your choice.

You can download a sample “Trash It!” project here which is a desktop .NET project which wraps the SysAnimate32 control to display a delete animation. The only P/Invoke required is LoadLibrary / FreeLibrary to load the dll containing the AVI animation resource. This should provide some contrast with the WebBrowser class in the article.