According to Twitter, which Microsoft clearly believes as the best way to communicate to its developer community, the Windows Mobile 6.5 SDK has been pulled.

Note that whilst this acknowledges that the SDK wasn’t properly tested there is apology to a developer community that collectively has probably wasted thousands of man hours installing, uninstall and reinstalling SDKs to get machines back to a working point.
I totally agree that the SDK should have been pulled as soon as there was a known issue with it but for Microsoft to continue to insult its developer audience is just one slap after the other.
The first thing to note about the newly released Windows Mobile 6.5 SDK is that it effectively comes in two parts. If you want to build applications for both the professional (ie touch screen devices) and standard you need to get both versions of the sdk. This way you will get all the emulator images.
For all those who have started working with Visual Studio 2010 the news is not great. As you are not doubt aware from the beta versions there is currently no support within VS 2010 for doing mobile development. This SDK release does not change this, you will continue to have to use Visual Studio 2008 for doing Windows Mobile development, with the exclusion of widgets, which you can do as a web site in VS 2010 and manually package it up for deployment.
Post install I thought I’d take a look at the readme file to see what’s changed in this SDK. Doh! Someone forgot to check this as the title reads “Windows Mobile 6 SDK Refresh”. The contents seem to make the title which made me think that I’d installed the wrong SDK but no, there’s a Start Menu item for “Windows Mobile 6.5 SDK” so I’m guessing that I didn’t get it wrong.
Following the readme “fail” I decided to launch Visual Studio 2008 to see whether I could spot the differences myself. From the New Project dialog (below) you can see that there is a new node “Widgets for Windows Mobile”. Given my recent set of blog posts on building Windows Mobile widgets I was really eager to see what this would entail.

After selecting the SimpleWidget option I was presented with a basic web site layout containing sub folders for css and script files. Personally I would have liked to see another sub folder for images.
Looked like a good starting point so I thought I’d try running it. Before doing so I went to start up a Windows Mobile 6.5 emulator image. I ran up the Device Emulator Manager only to discover that none of the 6.5 professional images (that were all there from when I’d install the 6.5 emulator image pack released last year) were there. Thinking I must be missing something I installed the Standard edition of the 6.5 SDK. This only made matters worse, now I have no Windows Mobile 6 or 6.5 images.
Thinking that something must have gone wrong I uninstalled both 6.5 SDKs and rebooted my machine. After installing the Windows Mobile 6.5 Professional SDK the professional emulator images reappeared (phew!) and I returned to my SimpleWidget project. I noticed that the device toolbar wasn’t enabled, so the widget project doesn’t understand, or wants to use a device/emulator to debug with after all. This got me thinking about what the debug experience was going to be. I pressed F5 to debug and wow, I got the following debugger experience within IE:
After enabling the ActiveX control I got the following output – looks very similar to what I’d expect on the device. Unfortunately the ActiveX prompt appears every time you start the debugger. The simple work around to this issue is to not stop the debugger. Because you are effectively working with a mini web site you can change content (ie htm, css, js) and just refresh the browser to see your changes.
What’s cool is that you can do the following:
- Set breakpoints and then walk through your code inspecting variables.

- Use the “hide” (which changes to “show” when clicked) button to mimic the widget going into the background. The onshow and onhide events get invoked.
- Change the resolution and orientation of your widget to see what it would look like in different perspectives. Changing resolution is particularly important as you need to cater for these devices differently otherwise your widget will be either unusable or look childish.
- You can change most of the System State properties to see what effect it has on your device. See my post on System State (aka Notification Broker) and Device Information for more information on working with this information.
- Even the menus are simulated:

Of course, whilst this is convenient for development, you must and I repeat must test your widgets on real devices.
Returning to Visual Studio, I took a further look at the widget project itself. If you go to Properties on the project you get the following:
I’m not entirely sure what all the parameters mean yet but I’m sure they’re in the help files somewhere (actually, no it appears not. The help files seem to be the standard WM6 SDK files). What does interest me is the Output Path parameter. If I navigate there I notice three files: the first two, Harness.html and Harness.js are what make the debugger happen, the last, SimpleWidget1.widget is of course the widget file which you can copy and install on your device or emulator to see how it runs on your device.
I must admit I expected to see a manifest file editor as part of the project properties. Not seeing it there I thought I’d double-click the config.xml files (which of course is the manifest file for a widget). Wow – notice the nice editor it displays, rather than a basic xml editor.

My only criticism here is that the team haven’t really thought this through. For a widget you would typically supply two icons if you are going to deploy to both professional and standard devices, one being a png, the other being an ico.
That’s enough about widgets. Let’s take a quick look at the emulator. Notice that this isn’t the 6.5 we’re used to see in the emulator. In fact if you look in the second image you’ll see that this is build 23090 which is around the build number that everyone has been talking about for Windows Mobile 6.5.3.
In brief you’ll notice that the start and ok/X buttons are at the bottom of the screen. A number of the menus are now graphical. The notification area drops down to be a graphical set of links and the tabs are no longer tabs, they’re more of a scrolling system (left-right) at the top of the page. These are all moves to better support touch input and going forward capacitive screens.
I’m sure there’s plenty more in the Windows Mobile 6.5 SDK that I haven’t discovered yet. Other than the major FAIL around the installation process (I would recommend uninstalling any previous WM6.5 emulators first) and the readme/help documentation I’m glad to see Microsoft starting to release new tools for us mobile developers.
Just posted to MSDN Downloads is a brand new SDK for doing Windows Mobile development. The SDK is coupled with new emulator image downloads for the following languages GER, FRA, ITA, JPN, CHS and ESP. Go download the bits from the Windows Mobile 6.5 SDK Download page.
Prior posts in this series:
Out of the box the Windows Mobile widget API provides only basic support for saving and retrieving data. The documentation on MSDN shows how you can read and write basic key-value pairs for values up to 4000 bytes but what happens if you want to store more than that? And, what do you do if you want your widget to run as a gadget or on a desktop browser? The following code, which we’ll add to widget.js handles all these scenarios.
-----------------
widget.js
-----------------
//-----------------------------------------------------------------------
// Storage
//-----------------------------------------------------------------------
// saves key-value pair (length restricted, use persistData for long string values)
saveKeyValue: function (key, value) {
if (window.widget) {
window.widget.setPreferenceForKey(value, key);
}
else if (isGadget && isGadget == true){
return System.Gadget.Settings.writeString(key,value);
}
else {
return Cookie.set(key,value,365);
}
},
// retrieves key-value pair
retrieveKeyValue: function (key) {
if (window.widget) {
return window.widget.preferenceForKey(key);
}
else if (isGadget && isGadget == true){
return System.Gadget.Settings.readString(key);
}
else {
return Cookie.get(key);
}
},
// Persists Data (any length)
persistData: function (key, value) {
if (!value || value == null) {
WidgetAPI.saveKeyValue(key, 0);
return;
}
var str = value;
var i = 0;
var j = 0;
while (j < str.length) {
var inc = 2000;
if (j + inc > str.length) {
inc = str.length - j;
}
var tmp = str.substring(j, j + inc);
j += inc;
WidgetAPI.saveKeyValue(key + i, tmp);
i += 1;
}
WidgetAPI.saveKeyValue(key, i);
},
// Checks to see if data exists
dataExists: function (key) {
var count = WidgetAPI.retrieveKeyValue(key);
if (typeof(count)=="undefined" || count == null || count <= 0) {
return false;
}
else {
return true;
}
},
// Retrive data (any length)
retrieveData: function (key) {
var count = WidgetAPI.retrieveKeyValue(key);
if (!count || count == null || count <= 0) {
return null;
}
var str = "";
for (var i = 0; i < count; i++) {
str += WidgetAPI.retrieveKeyValue(key + i);
}
return str;
}
And of course we need some sample code added to main.js and main.htm to demonstrate this in action:
-----------------
main.htm
----------------- <div id="welcome">Welcome....</div>
<div id="persistenceDemo">Name:
<input id="nameTextbox" type="text" />
<input id="submitButton" type="button" value="Save" onclick="saveName()"/>
</div>
-----------------
main.js
-----------------
function onLoad() {
// Code omitted as same as previous posts
sayWelcome();
}
function sayWelcome() {
var welcome = $get("welcome");
var name = WidgetAPI.retrieveData("Name");
if (!name || name == null) {
name = "...";
}
welcome.innerHTML = "Welcome " + name;
}
function saveName() {
var txt = $get("nameTextbox");
WidgetAPI.persistData("Name", txt.value);
sayWelcome();
}
When you run the widget you can enter a name, which will be persisted across runs of your widget. The following screenshots are from the widget running as a widget, gadget and in the desktop browser. Note that the gadget is unique in that if you close the gadget and open another instance it will not remember your settings. This is because each instance of the gadget has its own unique storage (so you can run multiple instance of the gadget at once). However, if you restart your computer with your gadget running you will notice that it remembers the values. This is because it is the same gadget instance!


Prior posts in this series:
Whilst Windows Mobile widgets are great, they definitely have their shortcomings when compared for true mobile application. One such area is in the ability to interact with device hardware and information. Further, it appears that every OS provider seems to be tackling this differently. If you look at S60 they have expose a wealth of device and user information via their widget API. Unfortunately one of the weaknesses of the current Microsoft implementation of widgets is that there are only a few pieces of device information you can query (out of the box) and no user information (ie contacts, calendar…). If you want to do more, you have to build and deploy ActiveX controls to assist your widget.
Returning to the Windows Mobile widgets and out of the box you get the following pieces of system information. All are exposed via the SystemState object.
CradlePresent
A Boolean value indicating whether the device is cradled.
DisplayRotation
An integer value indicating whether the display is in portrait or landscape mode.
PhoneHomeService
A Boolean value indicating whether the device is presently registered on its home network.
PhoneOperatorName
A string indicating the name of the device’s mobile operator.
PhoneRoaming
A Boolean value indicating whether the device is currently roaming.
PhoneSignalStrength
An integer indicating the phone signal strength, expressed as a percentage of full strength.
PowerBatteryState
An integer indicating the current state of the battery, such as whether the battery level is critically low or if the battery is charging.
PowerBatteryStrength
An integer indicating the current battery strength, expressed as a percentage of full strength.
And here’s an example of how you would access one of these properties. You first need to create an instance of the SystemState object. Next, query the actual property you are interested. Finally, if you want to receive notification when that property changes, you need to add an event handler to the “changed” event, passing in the callback method as the second parameter.
var systemState = widget.createObject("SystemState");
var cradledState = systemState.CradlePresent;
cradledState.addEventListener("changed", cradled);
Note, that the SystemState properties and the callback event are all exposed via the Windows Mobile Notification Broker that has been around since Windows Mobile 5. What I don’t get is why only this limited set of properties?
One of the frustrating things about working with widgets is determining whether your widget has a connection, firstly to a network and secondly to your server. Whilst there is no “IsConnected” property exposed via the SystemState object, you can use a combination of properties to try and deduce if there is a network connection.
Lets start with the widget.js file. You have to be careful when working with the widget API to ensure you don’t break your cross-platform capabilities. Of course if you don’t want your widget to run as a gadget you can eliminate quite a bit of the following code.
-----------------
widget.js
-----------------
var WidgetAPI = function () {
return {
// Code omitted as same as previous post
systemState: null,
stateEvents: null,
createSystemState: function () {
if (WidgetAPI.systemState != null) return;
if (window.widget) {
WidgetAPI.systemState = window.widget.createObject("SystemState");
}
else {
WidgetAPI.systemState = {};
}
},
getCradleState: function () {
WidgetAPI.createSystemState();
if (!WidgetAPI.systemState.CradlePresent) {
WidgetAPI.systemState.CradlePresent = true;
}
return WidgetAPI.systemState.CradlePresent;
},
listenForCradleStateChanged: function (callback) {
WidgetAPI.listenForStateChanged(WidgetAPI.getCradleState(), callback);
},
getPhoneStrengthState: function () {
WidgetAPI.createSystemState();
if (!WidgetAPI.systemState.PhoneSignalStrength) {
WidgetAPI.systemState.PhoneSignalStrength = 100;
}
return WidgetAPI.systemState.PhoneSignalStrength;
},
listenForPhoneStrengthStateChanged: function (callback) {
WidgetAPI.listenForStateChanged(WidgetAPI.getPhoneStrengthState(), callback);
},
listenForStateChanged: function (state, callback) {
if (window.widget) {
state.addEventListener("changed", WidgetAPI.createSafeListenerCallback(callback));
}
},
entered: false,
createSafeListenerCallback: function (callback) {
try {
WidgetAPI.stateEvents = new Date();
WidgetAPI.stateEvents.setTime(WidgetAPI.stateEvents.getTime() - 60 * 1000);
var func = function () {
if (WidgetAPI.entered == true) return;
try {
WidgetAPI.entered = true;
var lastInvoke = WidgetAPI.stateEvents;
lastInvoke.setTime(lastInvoke.getTime() + 1 * 1000);
if (lastInvoke < (new Date())) {
WidgetAPI.stateEvents = new Date();
if (callback && callback != null) {
callback();
}
}
}
finally {
WidgetAPI.entered = false;
}
};
return func;
}
catch (e) {
alert(e);
}
}
};
} ();
The other thing you will notice about this code is that there is a wrapper used for calling the event callback. When certain system events are raised (eg PhoneSignalStrength) a number of events will be raised within a short period of time. This wrapper protects against this. Warning: Some events will be hidden by this wrapper, so only use it if you don’t mind if some events are missed. In our case we are only using the change in state to prompt the application to check if it still has connectivity.
In the utils.js file we’re going to add a simple Ping routine that can be used to detect if a server is reachable. It does so by downloading a specified image within a given timeframe. Note that you should use a small image as you don’t want to waste network bandwidth.
-----------------
Utils.js
-----------------
var Ping= {};
Ping = {
img: null,
imgPreload: null,
timer: null,
success: null,
fail: null,
hasFailed: false,
init: function (imgUrl, pingCallback, failCallback) {
Ping.img = imgUrl;
Ping.success = pingCallback;
Ping.fail = failCallback;
Ping.imgPreload = new Image();
Ping.hasFailed = false;
Ping.imgPreload.onload = function () {
clearTimeout(Ping.timer);
Ping.timer = null;
if (Ping.hasFailed == false && Ping.success != null) {
Ping.success();
}
};
Ping.imgPreload.src = Ping.img;
if (Ping.fail != null) {
Ping.timer = setTimeout(Ping.fail_to_ping, 10000);
}
},
fail_to_ping: function () {
clearTimeout(Ping.timer);
Ping.timer = null;
Ping.imgPreload = null;
Ping.hasFailed = true;
if (Ping.fail != null) {
Ping.fail();
}
}
};
Now, to bring these together we’re going to introduce a new file, network.js, that registers for changes to the cradle and phone signal strength, and then based on those changes calls the Ping function to determine if the server can be reached. Note that as we don’t have any WiFi state information we can’t just assume that because the device is not cradled and there is no phone signal there is no data connection. As such, we just use the change in state to invoke ping the server. Again, there is some time checking around the Ping function to make sure it isn’t called too frequently.
-----------------
Network.js
-----------------
var Network = function () {
return {
isConnected: false,
connectionTestUrl: "http://www.builttoroam.com/ping.gif",
lastPing: null,
minimumPingSeparationInSeconds: 30,
connectionStateChanged: null,
init: function (stateChangedCallback) {
if (stateChangedCallback && stateChangedCallback != null) {
Network.connectionStateChanged = stateChangedCallback;
}
WidgetAPI.listenForCradleStateChanged(Network.cradledStateChange);
WidgetAPI.listenForPhoneStrengthStateChanged(Network.phoneStrengthChange);
Network.testConnection();
},
cradledStateChange: function () {
Network.testConnection();
},
phoneStrengthChange: function () {
Network.testConnection();
},
testConnection: function () {
var pingOk = false;
if (Network.lastPing == null) {
pingOk = true;
}
else {
var pingTime = new Date();
pingTime.setTime(Network.lastPing.getTime() + Network.minimumPingSeparationInSeconds * 1000);
if (pingTime < (new Date())) {
pingOk = true;
}
}
if (WidgetAPI.getCradleState() == false || WidgetAPI.getPhoneStrengthState() <= 0) {
pingOk = true;
}
if (pingOk) {
Network.lastPing = new Date();
Ping.init(Network.connectionTestUrl, Network.connectionTestSuccessful, Network.connectionTestFailed);
}
},
connectionTestSuccessful: function () {
var isConnected = true;
Network.setConnectedState(isConnected);
},
connectionTestFailed: function () {
var isConnected = false;
Network.setConnectedState(isConnected);
Network.lastPing = null;
},
setConnectedState: function (connectedState) {
if (Network.isConnected != connectedState && Network.connectionStateChanged != null) {
Network.connectionStateChanged(connectedState);
}
Network.isConnected = connectedState;
}
};
} ();
Some minor changes to main.htm and main.js in order to display the connected state. Add a div, isConnected, to main.htm, and add a call to Network.init and a callback function to main.js.
-----------------
Main.htm
-----------------
<div id="isConnected">N/A</div>
-----------------
main.js
-----------------
function onLoad() {
// Omitting code from previous post
Network.init(connectionStateChanged);
}
function connectionStateChanged(isConnected) {
var connected = $get("isConnected");
if (isConnected == true) {
connected.innerHTML = "Connected!";
}
else {
connected.innerHTML = "Not connected!";
}
}
After deploying this widget, you should see that the connected status is displayed below the rest of your content. Of course, you may want to use a nicer icon/image to represent the connected state.

Prior posts in this series:
One of the reasons that widgets are an interesting alternative to mobile web sites is their ability to integrate into the Windows Mobile shell similar to native or managed applications. Menus are one of these integration points. When designing your widget you should consider using the menus in additional to placing links within the content on your html page. Menus are a great way of controlling navigation within your application as they are always at the bottom of the screen, regardless of where the user has scrolled to (like mobile websites, widgets tend to be elongated, allowing vertical scrolling but eliminating horizontal scrolling where possible).
For example, the menu may contain items such as Home, Exit, About – items that are will be there regardless of where the user is in the widget. This is not to say you can’t dynamically control what’s displayed in the menu, in fact far from it as you can easily add and remove, enable and disable menu items.
In the previous post you saw how we can display manifest information to the user. Whilst this was useful in demonstrating how to read information from the manifest, it’s not likely that we always want that information to be displayed. Lets add a menu item that will toggle the visibility of this information.
To start with, we need to encapsulate the manifest information in the main.htm file into a single div that we can hide and show. This way we only need to toggle a single div, rather than each of the manifest information divs.
-----------------
Main.htm
-----------------
<div id="about" style="display:none;">
<div id="manifestVersion" class="manifest"></div>
…
</div>
The next thing we need to do is add some helper methods to make working with widget menus that much easier. Note that this code will create menu items when running as a widget but it will also create div elements for menus when running in a standard browser, this aids debugging as you can test the navigation/event handling of your menus from within Visual Studio.
-----------------
widget.js
-----------------
// Creates a menu with specified label and click handler
createMenuItem: function (label, handler) {
var mi = null;
this.LAST_MENU_ID ++;
if (window.widget && window.widget.menu) {
var mi = window.widget.menu.createMenuItem(this.LAST_MENU_ID);
if (mi) {
mi.text = label;
if (handler) {
mi.onSelect = handler;
}
}
}
else if (isGadget != true) {
mi = document.createElement("div");
mi.innerHTML = label;
mi.text = label;
if (handler) {
mi.onclick = handler;
}
mi.id = "menu" + id;
}
return mi;
},
// Returns a menu item whose ID is specified
getMenuItemById: function (id) {
var mi = null;
if (window.widget && window.widget.menu) {
mi = window.widget.menu.getMenuItemById(id);
}
else {
mi = $get("menu" + id);
}
return mi;
},
getMenuText: function (mi) {
if (window.widget && window.widget.menu) {
return mi.text;
}
else {
return mi.innerHTML;
}
},
// Appends the menu item to the main menu at the end. If the id of the menuitem to be added already exists in the menu, an exception will be thrown.
appendMenuItem: function (mi) {
if (mi && window.widget && window.widget.menu) {
window.widget.menu.append(mi);
}
else {
var right = $get("rightSoftKey");
right.appendChild(mi);
right.parentNode.style.display = "block";
}
},
// Appends the menu item to the parent menu at the end. If the id of the menuitem to be added already exists in the menu, an exception will be thrown.
appendSubMenuItem: function (parent, mi) {
if (parent && mi && window.widget && window.widget.menu) {
parent.append(mi);
}
else {
if (parent.childNodes.length == 1) {
var list = document.createElement("div");
list.style.margin = "10px";
parent.appendChild(list);
}
parent.childNodes[1].appendChild(mi);
}
},
// Removes the menu item from the main menu. If the specified id does not correspond to an item in the menu, an exception will be thrown.
removeMenuItem: function (mi) {
if (mi && window.widget && window.widget.menu) {
window.widget.menu.remove(mi);
}
else {
var right = $get("rightSoftKey");
right.removeChild(mi);
}
},
// Removes the menu item from the sub main menu. If the specified id does not correspond to an item in the menu, an exception will be thrown.
removeSubMenuItem: function (parent, mi) {
if (parent && mi && window.widget && window.widget.menu) {
parent.remove(mi);
}
else {
parent.childNodes[1].removeChild(mi);
if (parent.childNodes.length == 1) {
parent.removeChild(parent.childNodes[1]);
}
}
},
// Sets the softkey of the widget. Currently we supprt setting the left softkey and right soft key.
// If there is an error setting the soft key, exception will be thrown. If the softkey index is invalid, exception will be thrown.
setSoftKey: function (mi, softkeyIndex) {
if (mi && window.widget && window.widget.menu) {
window.widget.menu.setSoftKey(mi, softkeyIndex);
}
},
// Sets the left softkey for the widget menu item
setLeftSoftKey: function (mi) {
if (mi && window.widget && window.widget.menu) {
window.widget.menu.setSoftKey(mi, widget.menu.leftSoftKeyIndex);
}
else {
var left = $get("leftSoftKey");
left.appendChild(mi);
left.parentNode.style.display = "block";
}
},
// Sets the right softkey for the widget menu item
setRightSoftKey: function (mi) {
if (mi && window.widget && window.widget.menu) {
window.widget.menu.setSoftKey(mi, widget.menu.rightSoftKeyIndex);
}
else {
var right = $get("rightSoftKey");
right.removeChild(mi);
right.parentNode.style.display = "block";
}
},
// enable/disable a menu item
toggleMenuItem: function (id, on) {
var mi = this.getMenuItemById(id);
if (mi) {
mi.enabled = on;
}
}
And of course we need to add code to main.js in order to actually create the menus:
-----------------
main.js
-----------------
function onLoad() {
// Omitted code as it is the same as previous posts
createMenuItems();
}
// Create the menu items
function createMenuItems() {
// create Refresh as left soft key for the main page
createLeftSoftKey();
// create right soft key and its sub menu items
createRightMenuItems();
}
// create Blog link as left soft key
function createLeftSoftKey() {
// Add the Back menu item and set it to disabled
var mi = WidgetAPI.createMenuItem("Blog", onNavigateToBlog);
if (mi && mi!=null) {
mi.enabled = true;
WidgetAPI.setLeftSoftKey(mi);
}
}
function onNavigateToBlog() {
window.open("http://community.softteq.com/blogs/nick");
}
// Add sub menu items to right soft key "Menu"
function createRightMenuItems() {
// Add the Home menu item and set it to disabled
aboutMenu = WidgetAPI.createMenuItem("About", onAbout);
if (aboutMenu && aboutMenu != null) {
aboutMenu.enabled = true;
WidgetAPI.appendMenuItem(aboutMenu);
}
}
Lastly, returning to the main.htm file we need to add two hidden divs which will be used during testing to display the menu items when the widget is run on the desktop. These divs will remain hidden when the widget is run on the device.
-----------------
Main.htm
-----------------
<!-- Testing on desktop only -->
<div style="display:none;">
LEFT:
<div id="leftSoftKey">
</div>
</div>
<div style="display:none;">
RIGHT:
<div id="rightSoftKey">
<div onclick="window.close()" >Exit</div>
</div>
</div>
</body>
</html>
Here’s the widget in action – you can see that the left menu (which used to read Exit) now reads Blog and that the right menu includes both the standard Exit item and an About item. Clicking the About item displays the hidden manifest information.

If you run this from within Visual Studio, what you will see is that the left and right menus are simulated by divs that are created at the end of the page. In the same way as the widget running on the device, clicking the About will display/hide the manifest information area.
Prior posts in this series:
In this post we’re going to drill a little further into the config.xml file (ie the Manifest file) that is shipped with your widget and how you can access its content from your widget javascript code. In the post Widget Anatomy – The Manifest, Jorge covers a number of points about working with the manifest file. Here I’m going to add code to our on going example which you can use to wrap the widget object, allowing you to use the same code regardless of whether your widget is running in a normal browser, as a gadget or as a widget.
Let’s start with the html page. We’re just going to add some div tags into which the values from the manifest file will be inserted.
-----------------
Main.htm
-----------------
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Hello Widget</title>
<!-- Javascript -->
<script type="text/javascript" src="js/utils.js"></script>
<script type="text/javascript" src="js/widget.js"></script>
<script type="text/javascript" src="js/main.js"></script>
</head>
<body onload="onLoad();">
Hello Widget World!
<hr />
<div id="manifestVersion" class="manifest"></div>
<div id="manifestId" class="manifest"></div>
<div id="manifestName" class="manifest"></div>
<div id="manifestDescription" class="manifest"></div>
<div id="manifestAuthorEmail" class="manifest"></div>
<div id="manifestAuthorName" class="manifest"></div>
<div id="manifestAuthorURL" class="manifest"></div>
<div id="manifestHeight" class="manifest"></div>
<div id="manifestWidth" class="manifest"></div>
<div id="manifestLocale" class="manifest"></div>
<div id="manifestIconSource" class="manifest"></div>
</body>
</html>
Next, let us add code to widget.js to wrap the calls to the widget API:
-----------------
widget.js
----------------- var WidgetAPI = function () {
return {
// gets the widget id
getId: function () {
if (isGadget && isGadget == true) return System.Gadget.path;
return window.widget ? window.widget.identifier : "http://builttoroam.com/invalidid";
},
getVersion: function () {
if (isGadget && isGadget == true) return System.Gadget.version;
return window.widget ? window.widget.version : "0";
},
// gets the widget name
getName: function () {
if (isGadget && isGadget == true) return System.Gadget.name;
return window.widget ? window.widget.name : "Not a Widget nor a Gadget";
},
// gets the widget description
getDescription: function () {
return window.widget ? window.widget.description : "Default description....";
},
// gets the widget author Information
getAuthor: function () {
if (window.widget) {
return { name: window.widget.authorName,
email: window.widget.authorEmail,
url: window.widget.authorURL
};
}
else {
return { name: "Nick Randolph",
email: "nick@builttoroam.com",
url: "http://community.softteq.com/blogs/nick"
};
}
},
// gets the widget height
getHeight: function () {
return window.widget ? window.widget.height : "n/a";
},
// gets the widget width
getWidth: function () {
return window.widget ? window.widget.width : "n/a";
},
// gets the widget locale
getLocale: function () {
return window.widget ? window.widget.locale : "unknown";
},
// gets the current icon information for the widget
getIconInformation: function () {
return window.widget ? window.widget.currentIcon : { height: 0, width: 0, src: "n/a" };
},
// The rest has been omitted as it is the same as in the previous post
Now to update the main.js to iterate through the div tags and set their values:
-----------------
main.js
----------------- function onLoad() {
// Code in this method omitted as it is the same as in the previous post
setupAboutInformation();
}
function setupAboutInformation() {
updateManifestDiv("manifestVersion", WidgetAPI.getVersion());
updateManifestDiv("manifestId", WidgetAPI.getId());
updateManifestDiv("manifestName", WidgetAPI.getName());
updateManifestDiv("manifestDescription", WidgetAPI.getDescription());
var author = WidgetAPI.getAuthor();
updateManifestDiv("manifestAuthorEmail", author.email);
updateManifestDiv("manifestAuthorName", author.name);
updateManifestDiv("manifestAuthorURL", author.url);
updateManifestDiv("manifestHeight", WidgetAPI.getHeight());
updateManifestDiv("manifestWidth", WidgetAPI.getWidth());
updateManifestDiv("manifestLocale", WidgetAPI.getLocale());
var icon = WidgetAPI.getIconInformation();
updateManifestDiv("manifestIconSource", icon.src);
}
function updateManifestDiv(divName, information) {
var div = $get(divName);
if (div != null) {
div.innerHTML = information;
}
}
In the updateManifestDiv method you’ll notice we are using $get. This method is not defined by default so we need to define it in utils.js (the name of this file is not important so long as you include it into your Main.htm file).
-----------------
utils.js
-----------------
// gets the element from the dom
function $get(id) {
return document.getElementById(id);
}
Lastly, don’t forget to define the .manifest class in the css files (both high and low res):
-----------------
highres.css & lowres.css
----------------- .manifest
{
width: 100%;
}
And that’s it, now when you run it you will see information about your widget/gadget:

As indicated by Peter Foot’s post on Expired Development Certificates the certificates that ship with the Windows Mobile 6 SDK have now expired. So you either need to play around with your system clock or, you can now download (yes I know, yet another Windows Mobile development download) the new certificates from the following blog post http://windowsteamblog.com/blogs/wmdev/archive/2010/01/12/new-windows-mobile-developer-certificates.aspx
This morning I was looking for update to the WWOS Cricket widget which NineMSN published late last year. I had already “purchased” (it’s a free app, so it’s not really purchasing) the widget so I was surprised that it was not listed under My Applications within the Marketplace application on the device. Being a little confused by this I thought it may be specific to my device so I loaded up one of the emulators and again, no applications to install.
After a bit of thinking (actually I went off and did other things) it came to me that it may be to do with the region I have my device set to. For whatever reason when I rebuilt my device last I had forgotten to set the region back to Australia. Similarly, the default region for the emulators is also the US, which is why neither the device or emulator was showing my applications. Sure enough, when I reset my region back to Australia, which requires a reboot, I could again see my applications.
In my opinion this is just confusing – if I’ve bought an application/widget and I’ve signed into Marketplace I should see all the applications/widgets I’ve purchased, regardless of which region my device is currently set to.
For those not familiar with the Marketplace application or haven’t seen the WWOS Cricket widget, here’s a few images to get you started.

There’s been quite a bit of talk since the early CTP/Beta release of Visual Studio 2010 regarding the lack of support for Windows Mobile development. However, what most people fail to pick up on is that you can build Windows Mobile Widgets using either Visual Studio 2008 or Visual Studio 2010 (in fact you can probably do it using earlier versions of Visual Studio but I haven’t tried it). Interestingly an update to the Developing Widgets for Windows Mobile 6.5 MSDN article talks about coming support within Visual Studio for doing widget development:
Starting with Windows Mobile 6.5.3, developers can create Windows Mobile widgets using Visual Studio.
Given that you can already do most of the development within Visual Studio this would suggest better IDE support for perhaps debugging or packaging your widget…. This is pure speculation but if you want to get a bit of a heads up on widget development using Visual Studio, try the following posts.
The version of Windows Mobile mentioned in the MSDN article and by Mary Jo in Is Microsoft (slowly) picking up the pace with Windows Mobile? must be a reference to some of the leaked builds that I’ve been piloting on my Touch Pro (see New Windows Mobile build with Zooming for the latest ROM I’m running).
So far in this series I’ve covered Getting Started, generating Start Menu Icons and a Gadget Side Note, all with a single static page that will generally display ok on all devices. However, when you get into building more complex widgets and testing on different devices you will notice that what works on higher resolution devices (Eg the HTC Diamond 2 or the HTC HD2) won’t look good on a smaller device (Eg HTC Snap). Whilst you may be thinking “Oh goodness, please don’t tell me we have to handle all the different resolutions differently,” the good news is that for the most part you only really need to worry about two classifications “high res” and “low res” devices. Devices are typically divided into those with a width >=480 (high res) and those with a width<480 (low res).
The easiest way to change the way your widget displays for different resolutions is to use different css files to determine the style of each element. Our widget doesn’t currently use a css file, so lets add two css files in order to handle high and low resolution displays. Actually, while we’re at it we’ll include a gadget.css file which we will use in order to specify the height/width properties that were manually added to the Main.htm file in the previous post. Put all of these css files into a css folder to keep your project tidy.
In order to dynamically set the correct css file we’ll need to write some javascript. We’ll actually add two javascript files, one called main.js which will do most of the user interaction logic and one called widget.js which will contain most of the widget specific logic (the idea being that this file can be reused amongst your widgets). Again, put these files into a js folder within your project.
The last files we’re going to include are two background images, one for high res and one for low res. In this case the files are background.png (480x328) and background_lowres.png (240x164) in the images folder. With all these files added the build files list should look like:
-----------------
files.txt
-----------------
config.xml
Main.htm
icon.ico
icon.png
js\*.js
css\*.css
images\*.png
-----------------
gadget_files.txt
-----------------
gadget.xml
Main.htm
icon.png
js\*.js
css\*.css
images\*.png
In this case the only difference between the high and low resolution layouts is that it’s going to use a different background image. This makes the css files relatively simple:
-----------------
highres.css
-----------------
body
{
background: transparent url('../images/background.png') no-repeat center top;
}
-----------------
lowres.css
-----------------
body
{
background: transparent url('../images/background_lowres.png') no-repeat center top;
}
-----------------
gadget.css
----------------- body
{
height:200px;
width:200px;
border:1px solid #000000;
}
Note that the gadget.css doesn’t specify the background – instead of having a third layout we are going to combine the highres.css and the gadget.css values. This means that the gadget.css only needs to contain values that are unique to the gadget layout. You could take this approach with the low res display as well but given that most elements/class styles will change between high and low res it's probably easier to manage as two unique layouts.
Ideally we want to specify the style sheet as early as possible in the initial loading/rendering of the widget. This is done by hooking into the onLoad event of the body element in Main.htm. Note that you also need to include references to the javascript files:
-----------------
Main.htm
-----------------
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Hello Widget</title>
<!-- Javascript -->
<script type="text/javascript" src="js/widget.js"></script>
<script type="text/javascript" src="js/main.js"></script>
</head>
<body onload="onLoad();">
Hello Widget World!
</body>
</html>
In the onLoad event we simply need to determine whether the widget is running on a high or low res device and load the appropriate css files:
-----------------
Main.js
-----------------
/****** Constants ******/
var HighResCss = "css\\highres.css";
var LowResCss = "css\\lowres.css";
var GadgetCss = "css\\gadget.css";
/****** Variables ******/
var isGadget = false;
/********************************************************************
This is the entry point to Widget code.
*********************************************************************/
function onLoad() {
// Determine if this is running as a gadget (true if System.Gadget is defined)
if (typeof System != "undefined" && typeof System.Gadget != "undefined") {
isGadget = true;
}
if (WidgetAPI.isHighResolution() == true) {
WidgetAPI.applyCssFile(HighResCss);
}
else {
WidgetAPI.applyCssFile(LowResCss);
}
if (isGadget == true) {
WidgetAPI.applyCssFile(GadgetCss);
}
}
And we of course need to implement the WidgetAPI functions in the widget.js file. Note that to avoid confusion we create a WidgetAPI object rather than the existing window.widget object.
-----------------
Widget.js
-----------------
var WidgetAPI = function () {
return {
// returns true or false to indicate if widget is running on a high resolution device or not
isHighResolution: function () {
return this.getClientWidth() >= 480;
},
// gets the widget's client width
getClientWidth: function () {
return (document.documentElement.clientWidth==0) ? document.body.clientWidth : document.documentElement.clientWidth;
},
// apply css file
applyCssFile: function (cssFileName) {
if (typeof(cssFileName)!="undefined" && cssFileName!=null) {
var cssNode = document.createElement('link');
if (cssNode) {
cssNode.setAttribute('rel', 'stylesheet');
cssNode.setAttribute('type', 'text/css');
cssNode.setAttribute('href', cssFileName);
document.getElementsByTagName('head')[0].appendChild(cssNode);
}
}
}
};
} ();
Running this gives the following displays: Widget (high res), Widget (low res) and Gadget

Note: After you have installed your widget on a device you don’t need to reinstall or upgrade your widget every time you want to see your updates. Instead you can locate where your widget has been extracted to on the device and simply copy across the files that have changed. For example the widget is currently extracted to \Program Files\Widgets\User\17 so when I make changes, say to Main.htm, I just copy that file across to this folder. Then I just need to exit and restart the widget to see the changes take effect.
As I’ve mentioned in a previous post it is quite easy to take your Windows Mobile widget and convert it into a Windows Vista/Windows 7 gadget. In this post I’ll take the Hello World widget I built in the Getting Started and Start Menu Icons posts and walk through converting it into a gadget.
Gadgets are almost identical in structure to widgets, with one exception. Instead of a config.xml manifest file, gadgets use a gadget.xml file. So, the first step in converting your widget is to add a gadget.xml file to your project. Here is a sample file that mirrors the information I used in the config.xml file for the widget.
-----------------
gadget.xml
-----------------
<?xml version="1.0" encoding="utf-8" ?>
<gadget>
<name>Hello Gadget World</name>
<namespace>http://www.builttoroam.com/hellogadgetworld</namespace>
<version>0.1.0.0</version>
<author name="Built to Roam">
<info url="http://www.builttoroam.com" text="Built to Roam" />
<logo src="icon.png" />
</author>
<copyright>Copyright (c) 2009 Built to Roam. All rights reserved.</copyright>
<description>This is a sample gadget that says Hi to the world!</description>
<icons>
<icon width="90" height="90" src="icon.png" />
</icons>
<hosts>
<host name="sidebar">
<base type="HTML" apiVersion="1.0.0" src="Main.htm" />
<permissions>full</permissions>
<platform minPlatformVersion="0.3" />
</host>
</hosts>
</gadget>
Of course, you now need to modify your build to include this file. Now you have two options here, you can either build a single compressed file and simply change the extension between .widget and .gadget depending how you want to use it. Alternatively you can make your build slightly more intelligent:
-----------------
Build.bat
-----------------
cd .\HelloWorld
del ..\helloworld.widget /Q
..\7za.exe a -tzip ..\helloworld.widget -r0 @..\files.txt
copy ..\helloworld.widget ..\helloworld.widget.zip
cd .\HelloWorld
del ..\helloworld.gadget /Q
..\7za.exe a -tzip ..\helloworld.gadget -r0 @..\gadget_files.txt
copy ..\helloworld.gadget ..\helloworld.gadget.zip
pause
This build file now makes use of a file called gadget_files.txt which contains the file specific to building the gadget (ie includes gadget.xml and not config.xml).
-----------------
gadget_files.txt
-----------------
gadget.xml
Main.htm
icon.png
You can now run the build batch and it will generate a .gadget file. Double-click this file under Windows Vista or Windows 7 and it will install and run your gadget. Unfortunately you’re likely to see something like the following:
This happens because the gadget dynamically sizes to fit the content, which means that if you don’t specify a height or width for the gadget you get very minimal space allocated to it. This is simply fixed by adding size information to the body tag of the Main.htm file.
<body style="height:200px;width:200px;border:1px solid #000000">
Now if you build and run (ie double-click on the gadget file) the gadget you will see the following:
And there you have it – your widget is running as a gadget. Now there are some additional features of gadgets that we aren’t using here but I’ll come back to them as we get into adding more functionality to the widget.
In my previous post on Getting Started with widgets I showed how easily you can create a Windows Mobile widget. However, what you would have noticed when you installed the widget is that it uses the default widget icon both during installation and on the start menu (see below). Whilst it’s not a bad icon, it doesn’t advertise your application or company brand. As such it’s recommended that you supply your own icon.
To do this you need to supply an icon file in two formats. For Windows Mobile Professional devices (ie touch screens) you need to supply a 90x90 png image. For Windows Mobile standard you need to supply an ico file that includes images at 44x44, 22x22 at both 32 and 8 bit colour.
Here’s the step by step instructions for creating and including icons for your widget.
- Start with a regular image and use a image editing tool to resize the image to 90x90. I typically use Paint.NET which is a free tool that supports a wide range of image formats. If your image isn’t square you will need to crop/resize the image canvas to make it square.
- With the image resized, simply save it as a png file, icon.png, into the same folder as you widget config.xml file.

(note that the black background indicates that the transparent area of the image – use transparency where possible so that you can see the background of the start menu behind your application icon)
- Next, to build the ico file you will need to scale your icon to the different formats required to be contained within the ico file. For this I use another free tool, IcoFX.
- Open IcoFX
- Insert the original 90x90 image: File > Import Image, select your image, specify the size and resolution to import the image at. I recommend importing the original at the original size (ie 90x90). Doing this will not affect how it renders on the device since ico files can contain images at any resolution.
- Next, add new images for each desired size and bit depth: Icon > New Image, specify size and bit depth.

- Repeat for 44x44 32 bit, 44x44 8 bit, 22x22 32 bit, 22x22 8 bit.
- Save the created ico as icon.ico in the same folder as your config.xml file.
- The last thing to do is to update both the config.xml file and your build files list to include the icon files.
-----------------
config.xml
-----------------
<?xml version="1.0" encoding="utf-8" ?>
<widget xmlns="http://www.w3.org/ns/widgets"
id="http://www.builttoroam.com/hellowidgetworld"
version="0.1">
<name>Hello Widget World</name>
<icon src="icon.png" />
<icon src="icon.ico" />
<description>This is a sample widget that says Hi to the world!</description>
<author href="http://www.builttoroam.com" email="info@builttoroam.com">
Built to Roam Widget Development Team
</author>
<content src="Main.htm" type="text/html"/>
</widget>
-----------------
Files.txt
-----------------
config.xml
Main.htm
icon.ico
icon.png
Now when you run your build batch script and then install the widget on your device you will see your icon displayed both during installation and on the start menu.
Notes:
1) The widget installation screen is not displayed during installation when the widget is downloaded from marketplace. As this is the only sanctioned way to distribute widgets to a Windows Mobile device you don’t need to worry too much about getting the installation screens perfect.
2) If you include both a png and ico file in your widget (and specified in the config.xml file) you will notice that no image is displayed during installation on Windows Mobile standard. This is a known bug but given that this isn’t displayed to the end user (see 1 above) this shouldn’t be an issue.
Over the past month or so I’ve been working on a number of projects involving Windows Mobile Widgets. If you aren’t familiar with widgets they are essentially a mini-application published as a zip file containing html, js, css and images. They are similar to Windows Vista/7 gadgets; in fact so much so that you can use exactly the same code to produce both a widget and desktop gadget. In this post I’ll go through creating a basic widget, including a couple of tricks that can help you build and debug your widgets.
We will of course start off with the canonical Hello World widget and for the most part I’m going to be working in Visual Studio 2010. That’s right, you can build and debug* your widgets from within Visual Studio 2010, which makes it the only form of Windows Mobile development you can currently do with the beta.
Let’s start by building up the necessary project structure for your widget. From the File menu, select New –> Web Site, then select the Empty Web Site project template from under either the C# or VB node. Since you are going to be writing javascript it doesn’t matter what language you select. By default this will create a new project with just a web.config file – this file is not required for your Windows Mobile widget but does enable desktop debugging so leave it in the project. Next, add a new HTML document to your project (Add New Item –> C#/VB –> HTML Page). I typically call this Main.htm as you normally only have a single htm page within your widget that contains all the markup for your widget but the name isn’t important. Modify the html to include a title and some content between the body tags. For example:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Hello Widget</title>
</head>
<body>
Hello Widget World!
</body>
</html>
When you install your widget the installer needs to locate the main html page of your widget, along with other information about your widget such as the author, title and description of the widget. This is located in a config.xml file. Add a new xml file called config.xml to your project (Add New Item –> C#/VB –> XML File) – the name of this file is important. Add, and then modify to suit yourself, the following to the config.xml file.
<?xml version="1.0" encoding="utf-8" ?>
<widget xmlns="http://www.w3.org/ns/widgets"
id="http://www.builttoroam.com/hellowidgetworld"
version="0.1">
<name>Hello Widget World</name>
<description>This is a sample widget that says Hi to the world!</description>
<author href="http://www.builttoroam.com" email="info@builttoroam.com">
Built to Roam Widget Development Team
</author>
<content src="Main.htm" type="text/html"/>
</widget>
You now have the minimum requirements for a Windows Mobile widget. If you press F5 to run this project in Visual Studio you will see the Main.htm web page display (if not, you may have to navigate to this page, or Set [it] as Start Page. To run your widget on a device (or emulator) there are a few more steps involved.
The first thing you need to do is to actually zip up your widget project into a .widget file. This is essentially just a zip file, renamed with the .widget extension. As you don’t want to be doing this manually every time you make a change I created a simple batch file (yeh I know, super old school) that simply calls 7zip (free download) to zip up the relevant files.
-----------------
Build.bat
-----------------
cd .\HelloWorld
del ..\helloworld.widget /Q
..\7za.exe a -tzip ..\helloworld.widget -r0 @..\files.txt
copy ..\helloworld.widget ..\helloworld.widget.zip
pause
Place this batch file in the parent folder of your Hello World widget – you don’t want to mess up your project folder with build files. You need to download and copy the 7zip executable into this folder and you need to create a file called files.txt – this contains a list of files to include in your widget.
-----------------
Files.txt
-----------------
config.xml
Main.htm
Running this batch file will create two output files: helloworld.widget and helloworld.widget.zip. The former is a .widget file that you can copy to your device and click on to install. The latter is created just in case you want to inspect the zip file to ensure all the right files are being packaged – there is nothing worse than trying to track down a javascript issue, only to discover one of the files isn’t being correctly added to the package.
Ok, so down to business, lets get this widget to run on the emulator/device. If you are using an emulator then you can simply cradle the emulator using WMDC, copy the file across to the device using File Explorer and then click on the copied file to run the widget installer. This will automatically run the widget when installation is complete. If you want to run your widget on a real device there are some additional steps. By default the widget installer is not associated with the .widget file extension. In order to get your widget to install by clicking on it, you need to create this association by modifying the registry on the device to include the following values:
[HKEY_CLASSES_ROOT\riapp] "EditFlags"=dword:00010000
[HKEY_CLASSES_ROOT\riapp\Shell\Open\Command] @="wmwidgetinstaller.exe %1"
You can do this using either Remote Registry Editor (external tool that ships with Visual Studio 2008), Pocket Controller PC or another third party registry editing tool. Note that on most devices the HKEY_CLASSES_ROOT\riapp key already exists but the HKEY_CLASSES_ROOT\riapp\Shell\Open\Command key will need to be created. Also note that the @ in the second line corresponds to the “default” value for the key – this means that depending on your editing tool you should either leave the name component empty or use the word Default.
Once you have added these registry keys to your device, clicking on the .widget file should run the installer – if not, it is likely that the registry keys are not correct, or that the wmwidgetinstaller.exe executable can’t be located. Again, once installation is complete your widget should automatically run displaying similar to the following:
Note that the Title in the Main.htm file is used to populate the widget title bar and that the default Exit button and menu has been created.
Creating your first widget is as simple as that. In fact you could submit this widget, in its current form to Windows Mobile Marketplace as it conforms to all the necessary requirements for certification.
*Build and Debug is limited to desktop debugging only. You still need to deploy to an emulator and/or a real device in order to ensure your widget is going to work correctly.
For the last couple of weeks my partner has been complaining about the phone she has been using. Actually, she’s been complaining longer than that but it finally got the better of me last week. What’s interesting is she made it clear that she didn’t want an iphone. So I decided to do the right thing and get her one of the brand spanking new HTC HD2. Now of course, thanks to the mighty fine telcos we have here in Australia, we’re not likely to see this device until early next year. So, I took the liberty of ordering direct from the UK.
No sooner had the device arrived, it was unboxed, setup and called into action. Here’s a couple of photos of the nice packaging. That’s as much as I’m going to see of the device for the next week or so.

Oh, and by the way, the box isn’t lying when it says the phone is “BIG”. The screen is brilliant, camera images are clear and the on-screen keyboard works a treat.
More Posts
Next page »