<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://community.softteq.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>The SoftTeq Community Site</title><link>http://community.softteq.com/blogs/</link><description>SoftTeq blogs</description><dc:language>en-US</dc:language><generator>CommunityServer 2007 (Build: 20416.853)</generator><item><title>Windows Phone 7 series Developer Preview…. Virtual Machine Fail</title><link>http://community.softteq.com/blogs/nick/archive/2010/03/15/windows-phone-7-series-developer-preview-virtual-machine-fail.aspx</link><pubDate>Mon, 15 Mar 2010 18:37:26 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1650</guid><dc:creator>nick</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Having sat through the MIX keynote I was excited to see the announcement of the Windows Phone 7 series development tools.&amp;#160; These can all be downloaded from &lt;a href="http://developer.windowsphone.com"&gt;http://developer.windowsphone.com&lt;/a&gt;.&amp;#160; The downloads are only compatible with VS2010 RC and so installing these on my main machine (which I haven’t had a chance to upgrade from the beta) is going to be a major effort.&amp;#160; I thought I’d go an install them on one of my many virtual machines I have running on my Hyper-V server – FAIL… According to the &lt;a href="http://download.microsoft.com/download/D/9/2/D926FB38-BB43-4D87-AE5A-1A3391279FAC/ReleaseNotes.htm"&gt;release notes&lt;/a&gt; this is not a supported option. I also noticed that round-tripping between VS and Blend is not supported – doesn’t that defeat the whole purpose?&lt;/p&gt;  &lt;blockquote&gt;   &lt;h3&gt;Scenarios Not Supported&lt;/h3&gt;    &lt;ul&gt;     &lt;li&gt;Opening Windows Phone projects in Expression Blend® is not supported, except for Expression Blend 4 Beta with “MICROSOFT EXPRESSION BLEND ADD-IN PREVIEW FOR WINDOWS PHONE.” &lt;/li&gt;      &lt;li&gt;&lt;strong&gt;Round-trip editing of the Windows Phone projects between Expression Blend and Visual Studio is not supported.&lt;/strong&gt; &lt;/li&gt;      &lt;li&gt;Windows XP and Windows Server® are not supported. &lt;/li&gt;      &lt;li&gt;&lt;strong&gt;Virtual PC and Hyper-V™ are not supported.&lt;/strong&gt; &lt;/li&gt;   &lt;/ul&gt; &lt;/blockquote&gt;  &lt;p&gt;I’m actually guessing the issue with Virtual PC/Hyper-V is to do with the emulator, rather than the actual developer experience. This is something that we saw with very old versions of the Windows Mobile emulator where they couldn’t be run in a virtual machine – this was fixed when the emulator was moved to true ARM emulation.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Update: &lt;/strong&gt;I’ve just finished installing the tools on a VM and the emulator, whilst slow to load the first time did in fact load and run my hello world application. Big kudos to Microsoft – the tooling looks great so far. &lt;/p&gt;  &lt;p&gt;Also, don’t forget to check out the following discussion documents on the platform and designing for Windows Phone 7 series.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://go.microsoft.com/?linkid=9713249"&gt;Application Platform Overview for Windows Phone&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://go.microsoft.com/?linkid=9713252"&gt;Windows Phone UI Design and Interaction Guide&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://go.microsoft.com/?linkid=9713253"&gt;Designing Web Sites for Phone Browsers&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;&lt;img src="http://community.softteq.com/aggbug.aspx?PostID=1650" width="1" height="1"&gt;</description></item><item><title>Jamie Oliver live in Centennial Park with food from Sydney Picnics</title><link>http://community.softteq.com/blogs/nick/archive/2010/03/14/jamie-oliver-live-in-centennial-park-with-food-from-sydney-picnics.aspx</link><pubDate>Sun, 14 Mar 2010 12:49:31 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1648</guid><dc:creator>nick</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;We just got back from a fantastic evening watching &lt;a href="http://www.jamieoliver.com/"&gt;Jamie Oliver&lt;/a&gt; prepare some gourmet delights on the stage in Centennial Park. He’s got such a great stage presence. Between him, the audience and his good mate, &lt;a href="http://www.benodonoghue.com/"&gt;Ben O’Donoghue&lt;/a&gt;, Jamie brought the full song-and-dance production to Sydney, delivering an evening that will be remembered for a while to come.&lt;/p&gt;  &lt;p&gt;&lt;img style="display:inline;margin-left:0px;margin-right:0px;" title="Next image &amp;gt;&amp;gt;" align="left" src="http://www.sydneypicnic.com.au/images/gallery/P1010154.jpg" width="239" height="180" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Normally at these event you’re left drooling as all the best food ends up being created and eaten on stage by those fortunate enough to make themselves noticed at the front of the event. Not to be left feeling hungry we came prepared and had our own picnic courtesy of the &lt;a href="http://www.sydneypicnic.com.au"&gt;Sydney Picnic Co&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;After looking around at a number of different picnic providers I settled on the Sydney Picnic Co because they seemed to have the same idea about food as I do – it’s there to be enjoyed rather than to just fill you up. The selection of cold meats, wild onions, risoni and of course the Valrhona chocolate pots made for an amazing feast from which none of us went hungry. In fact we got a picnic sized for 4 and walked away with enough food for lunch tomorrow (and yes, there’s going to be some arguing over who gets what….).&lt;/p&gt;  &lt;p&gt;Anyhow, a big thanks to the Sydney Picnic Co for making a great event and unforgettable experience. If you’re looking to do a picnic in the park or at the beach I can’t recommend them enough!&lt;/p&gt;&lt;img src="http://community.softteq.com/aggbug.aspx?PostID=1648" width="1" height="1"&gt;</description></item><item><title>Windows Phone 7 – Will it be everything Microsoft wants it to be?</title><link>http://community.softteq.com/blogs/nick/archive/2010/03/11/windows-phone-7-will-it-be-everything-microsoft-wants-it-to-be.aspx</link><pubDate>Fri, 12 Mar 2010 06:35:29 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1646</guid><dc:creator>nick</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Charlie Kindel’s &lt;a href="http://feedproxy.google.com/~r/ckindel/~3/U4QgL6t6TYA/looking-into-the-future-last-year.aspx"&gt;posted about some internal planning&lt;/a&gt; that the team did as part of building Windows Phone 7 series. I’m assuming that this isn’t an ordered list but I’m also guessing that this was the order the points were on some list somewhere (perhaps as they were written on a whiteboard during a brainstorming session). If this is the case, it’s concerning that “&lt;em&gt;It’s easy to build beautiful applications users just love&amp;quot; &lt;/em&gt;falls at the bottom of the list.&lt;/p&gt;  &lt;p&gt;For those that are familiar with Windows Mobile development you’ll have gone through the list and gone yep, yep, yep to most of the points. Most of these points we could achieve on the current Windows Mobile platform (perhaps with the exception of protecting the developers IP and until recently a single marketplace). Where Windows Mobile sucks is the ability to generate awesome applications that users really want to use – it’s not impossible by the way, just hard to do. Actually, it’s hard to do this full stop. I’d almost stake my life on it that despite Microsoft’s attempt at making it easy to build “beautiful” applications, beauty is definitely in the eye of the beholder and we are going to get some hideous creations appearing on the marketplace.&lt;/p&gt;  &lt;p&gt;I’m looking forward to MIX next week when we’ll hear just how great we can my Windows Phone 7 series applications.&lt;/p&gt;&lt;img src="http://community.softteq.com/aggbug.aspx?PostID=1646" width="1" height="1"&gt;</description></item><item><title>OpenGL: More on Transforms</title><link>http://community.softteq.com/blogs/nick/archive/2010/03/09/opengl-more-on-transforms.aspx</link><pubDate>Tue, 09 Mar 2010 13:58:19 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1645</guid><dc:creator>nick</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;In &lt;a title="OpenGL- Rotate, Scale and Translate" href="http://community.softteq.com/blogs/nick/archive/2010/03/08/opengl-rotate-scale-and-translate.aspx"&gt;OpenGL- Rotate, Scale and Translate&lt;/a&gt; I took a very simple example of transforming some text but what happens if you want to do something more complex. For example you want to have a pair of strings that you can transform around the screen together (ie not have to worry about transforming individually. To do this we can use a form of layering in our rendering where each layer can contain any number of items that will be rendered together. Each layer can be transformed with the resulting transform being applied to each item in the layer.&lt;/p&gt;  &lt;p&gt;We’re going to start off by defining an abstract class called ScreenWidget. I’ve used widget because I couldn’t think of a more “correct” name to call items that are going to be displayed on the screen. If there is a better name, do tell me as I’m keen to stick with a vocabulary that is well understood.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;abstract class ScreenWidget       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public Vector3f Position { get; set; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public Vector3f Anchor { get; set; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public Vector3f Scale { get; set; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public float Angle { get; set; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public Vector3f RotationAxis { get; set; } &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public ScreenWidget()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Scale = new Vector3f(1, 1, 1);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; RotationAxis = new Vector3f(0,0,1);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public unsafe void Draw()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; gl.PushMatrix();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; gl.Translatef(Position.X, Position.Y, Position.Z);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; gl.Scalef(Scale.X, Scale.Y, Scale.Z);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; gl.Rotatef(Angle, RotationAxis.X, RotationAxis.Y, RotationAxis.Z);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; gl.Translatef(-Anchor.X, -Anchor.Y, -Anchor.Z); &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; DrawComponents();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; gl.PopMatrix();        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; protected abstract void DrawComponents(); &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public virtual void Setup() {} &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public virtual void Update(float secondsSinceLastUpdate){}       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;In the ScreenWidget class we can see that it tracks values for position, anchor, scale, angle and rotation axis. It’s worth noting that the position is actually the position of the anchor point within the containing widget. If the widget isn’t nested within another widget then the position will be the position of the anchor point on the screen. &lt;/p&gt;  &lt;p&gt;The Draw method on the ScreenWidget is called in order to render all items contained within the widget to the screen. Before doing so it applies a sequence of transforms to scale, rotate and position the widget correctly with respect to its containing widget (and thus subsequently the screen). &lt;/p&gt;  &lt;p&gt;What’s interesting is that all these transforms and the call to DrawComponents (which by the way is what an overriding class has to implement in order to actually render items to the screen) are wrapped in a pair of PushMatrix and PopMatrix method calls.&amp;#160; Essentially this ensures that the OpenGL model matrix (ie the matrix that is used to transform items being rendered) is the same when the method ends as when the method started – failure to do this may lead to unexpected results with items being incorrectly positioned, scaled or rotated further on during rendering. PushMatrix pushes the current matrix onto a temporary stack, whilst PopMatrix pops the top matrix on the stack off and makes it the current matrix.&lt;/p&gt;  &lt;p&gt;We’ll start by creating the simplest of widgets, the TextWidget:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;class TextWidget:ScreenWidget       &lt;br /&gt;{        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; OpenGLFont font;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; GlyphRun title;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public override void Setup()        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; font = new OpenGLFont(new Font(FontFamily.GenericSerif, 12, FontStyle.Regular));        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; title = new GlyphRun(font, &amp;quot;Hello World!&amp;quot;, new Size(int.MaxValue, int.MaxValue), OpenGLTextAlignment.Left, true);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; this.Anchor = new Vector3f(title.Size.Width / 2, title.Size.Height / 2, 0);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; protected override void DrawComponents()        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; title.Draw();        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;}&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;As you can see the TextWidget simply creates a GlyphRun object that can be draw during the DrawComponents method. Also note that the Anchor property has been set based on the size of the title. This will ensure that if this widget is rotated or scaled it will be done based on the centre of the text, rather than a corner.&lt;/p&gt;  &lt;p&gt;Next is a simple container widget, funnily enough called ContainerWidget:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;class ContainerWidget : ScreenWidget       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; { &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TextWidget text;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TextWidget text2;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public override void Setup()        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; text = new TextWidget();        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; text.Position = new Vector3f(10,10, 0);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; text.Angle = 30;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; text.Setup(); &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; text2 = new TextWidget();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; text2.Position = new Vector3f(20, 20, 0);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; text2.Angle = 50;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; text2.Setup();        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; protected override void DrawComponents()        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; text.Draw();        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; text2.Draw();        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;You can see that the two TextWidget instances have been position and rotated by different amounts. Before we can see this we’ll need to go back to our MainForm and create an instance of the ContainerWidget.&amp;#160; The Draw method will then be called on this instance in order to draw the two nested GlyphRuns.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;public partial class MainForm : ApplicationForm       &lt;br /&gt;{ &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160; public MainForm()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; InitializeComponent();&amp;#160; &lt;br /&gt;&lt;/em&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160; ContainerWidget widget;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; protected override void SetupScene()        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; base.SetupScene(); &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; widget = new ContainerWidget();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; widget.Position = new Vector3f(0, 0, 0);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; widget.Setup();        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160; protected override void DrawScene()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; base.DrawScene(); &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; widget.Draw(); &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/em&gt;&lt;em&gt;} &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160; protected override void UpdateScene(float secondsSinceLastUpdate)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; base.UpdateScene(secondsSinceLastUpdate); &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; widget.Update(secondsSinceLastUpdate);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;}&lt;/em&gt;&lt;/p&gt;   &lt;em&gt;&lt;/em&gt;&lt;/blockquote&gt;  &lt;p&gt;As you can see this keeps both the MainForm and the ContainerWidget very clean in terms of the code than needs to be written to display elements. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_6CA76584.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_5BFF44C9.png" width="184" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This image isn’t particularly great as the two pieces of text are mostly off screen. So lets modify just the position of the ContainerWidget in the DrawScene method of the MainForm:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;gl.PushMatrix();       &lt;br /&gt;gl.Translatef(100.0f, 100.0f, 0);        &lt;br /&gt;widget.Draw();        &lt;br /&gt;gl.PopMatrix();&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This gives a much clearer picture of the two pieces of text but note that we only needed to translate the container widget.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_688CF1E5.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_27123F8C.png" width="184" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://community.softteq.com/aggbug.aspx?PostID=1645" width="1" height="1"&gt;</description></item><item><title>OpenGL: Rotate, Scale and Translate</title><link>http://community.softteq.com/blogs/nick/archive/2010/03/08/opengl-rotate-scale-and-translate.aspx</link><pubDate>Tue, 09 Mar 2010 04:28:49 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1642</guid><dc:creator>nick</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;In my previous post, &lt;a title="OpenGL ES Wrapper- Your First Application" href="http://community.softteq.com/blogs/nick/archive/2010/03/08/opengl-es-wrapper-your-first-application.aspx"&gt;OpenGL ES Wrapper- Your First Application&lt;/a&gt;, you would have seen that we were creating a GlyphRun that we then draw. This is actually a wrapper class that handles all the processing required to draw the text on the screen. However, it doesn’t handle the positioning of the text on the screen – by default it is located at the origin ie (0,0,0).&lt;/p&gt;  &lt;p&gt;To move this text around the screen we can specify an amount to translate, scale or even rotate the text by using the appropriate OpenGL commands. One thing to note here is that the order in which you do these operations may change the result you see. For example in the following images the original text (first image) is translated by (50,50,0) and then rotate around the z axis by 40 degrees. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_66A728CA.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_46E82935.png" width="184" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Now apply translation and rotation – note the order of the gl.Translate and gl.Rotate method calls.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;gl.Translatef(50.0f,50.0f,0);        &lt;br /&gt;gl.Rotatef(40.0f,0,0,1.0f);         &lt;br /&gt;title.Draw(); &lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;a href="http://community.softteq.com/blogs/nick/image_37651766.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_2E950F1A.png" width="184" height="244" /&gt;&lt;/a&gt;&amp;#160; &lt;/p&gt;  &lt;p&gt;Now apply translation and rotation in the other order.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;gl.Rotatef(40.0f,0,0,1.0f);      &lt;br /&gt;&lt;em&gt;&lt;em&gt;gl.Translatef(50.0f,50.0f,0);          &lt;br /&gt;&lt;/em&gt;&lt;/em&gt;&lt;em&gt;title.Draw(); &lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_28D9F574.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_6B6990EC.png" width="184" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;You can see that the order that rotate and translate are applied makes a difference. Interestingly they almost appear in the wrong order. In the second image the original image has been translated by (50,50,0) then rotated to get the text to where it appears, whilst in the previous image the text has been rotated by 40 and then translated. This is a result of the way OpenGL uses matrix multiplication to apply transforms to what you are drawing. Each time you issue a transform the corresponding matrix is multiplied against the current matrix to calculate the position of the items you drawing.&lt;/p&gt;  &lt;p&gt;The other thing you’ll notice is that the text appears to be rotating around the top left corner of the text. To get it to rotate around the centre of the text, you need to apply a translate function to position the text with its centre at the origin, prior to rotating it and then translating it back into it’s final position. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_57DC314B.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_444ED1AA.png" width="184" height="244" /&gt;&lt;/a&gt; &lt;a href="http://community.softteq.com/blogs/nick/image_6DE29CDD.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_44F787D4.png" width="184" height="244" /&gt;&lt;/a&gt; &lt;a href="http://community.softteq.com/blogs/nick/image_09577914.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_5B1D7D59.png" width="184" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Update &lt;/strong&gt;– here’s the code for doing this additional translation (again, note the order that they’re done in)&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;gl.Translatef(50.0f, 50.0f, 0);        &lt;br /&gt;gl.Rotatef(40.0f, 0, 0, 1.0f);        &lt;br /&gt;gl.Translatef(-title.Size.Width/2, -title.Size.Height/2, 0);        &lt;br /&gt;title.Draw();&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;img src="http://community.softteq.com/aggbug.aspx?PostID=1642" width="1" height="1"&gt;</description></item><item><title>OpenGL ES Wrapper: Your First Application</title><link>http://community.softteq.com/blogs/nick/archive/2010/03/08/opengl-es-wrapper-your-first-application.aspx</link><pubDate>Mon, 08 Mar 2010 13:12:42 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1640</guid><dc:creator>nick</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;In my previous post on &lt;a href="http://community.softteq.com/blogs/nick/archive/2010/03/06/getting-started-with-opengl-on-windows-mobile.aspx"&gt;Getting Started with OpenGL on Windows Mobile&lt;/a&gt; I talked about taking the existing OpenGL ES wrapper by &lt;a href="http://www.koushikdutta.com/2008/08/net-compact-framework-wrapper-for.html"&gt;Koushik Dutta&lt;/a&gt; and extending it to make it easier to work with.&amp;#160; In this, and subsequent posts, I’ll show you how you can take this wrapper and start building out an application.&lt;/p&gt;  &lt;p&gt;To get started create a new Smart Device project in Visual Studio 2008.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_65ADA81C.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_430969A1.png" width="265" height="169" /&gt;&lt;/a&gt; &lt;a href="http://community.softteq.com/blogs/nick/image_12FF1820.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_443DDCB3.png" width="299" height="163" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Note that I’ve created this against the Windows Mobile 5 SDK – if you can find a legacy device still running WM5 which supports OpenGL then this application will still run. I only bother building against the later SDKs if I particularly need one of the few features that were added since WM5.&lt;/p&gt;  &lt;p&gt;Next, copy the two OpenGL projects from the &lt;a href="http://community.softteq.com/blogs/nick/OpenGLESWrapper_1CAE450A.zip"&gt;this link&lt;/a&gt; into your solution folder and add them to your solution within Visual Studio. Also, go ahead and add a project reference from your application to both OpenGL projects.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_5B1CAE2F.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_4B2D696B.png" width="179" height="304" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;You won’t be needing the designer support for your form but you do need some of the initialization values set in the Form1.designer.cs file. It’s up to you whether you move the InitializeComponent method from your Form1.designer.cs file into your Form1.cs, and then delete Form1.designer.cs, or just leave the designer.cs file there and ignore it. &lt;/p&gt;  &lt;p&gt;At this stage I’d recommend renaming Form1 to something more descriptive. In this case my application is only going to have a single form so I have used MainForm. In the MainForm.cs file I’ve modified the class to inherit from ApplicationForm, rather than just Form – this gives me all the OpenGL initialization I talked about previously, as well as some virtual methods that can be implemented to setup, draw and update the current scene:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;public partial class MainForm : ApplicationForm       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public MainForm()        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; InitializeComponent();        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; protected override void SetupScene()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; base.SetupScene();        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; protected override void DrawScene()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; base.DrawScene();        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; protected override void UpdateScene(float secondsSinceLastUpdate)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; base.UpdateScene(secondsSinceLastUpdate);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;In this case we’re going to simply implement Hello World by creating a Font and GlyphRun in the SetupScene method:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;OpenGLFont font;       &lt;br /&gt;GlyphRun title;        &lt;br /&gt;protected override void SetupScene()        &lt;br /&gt;{        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; base.SetupScene(); &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160; font = new OpenGLFont(new Font(FontFamily.GenericSerif, 12, FontStyle.Regular));       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; title = new GlyphRun(font, &amp;quot;Hello World!&amp;quot;, new Size(int.MaxValue, int.MaxValue), OpenGLTextAlignment.Left, true);        &lt;br /&gt;}&lt;/em&gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Then to draw the text on the screen, simply update the Draw method:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;protected override void DrawScene()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; base.DrawScene(); &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; title.Draw();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_28F55DE5.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_6E99E803.png" width="184" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Not the worlds greatest demo, but surprisingly simple for an OpenGL application. In the next post we’ll start to investigate what you can really do with OpenGL that you can’t do easily with traditional Windows Forms application.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Note: &lt;/strong&gt;In the InitializeOpenGL function within ApplicationForm you need to include the following call otherwise your text will appear as a solid white rectangle:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;gl.BlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA);&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;img src="http://community.softteq.com/aggbug.aspx?PostID=1640" width="1" height="1"&gt;</description></item><item><title>Getting Started with OpenGL on Windows Mobile</title><link>http://community.softteq.com/blogs/nick/archive/2010/03/06/getting-started-with-opengl-on-windows-mobile.aspx</link><pubDate>Sun, 07 Mar 2010 00:52:54 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1638</guid><dc:creator>nick</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;There are a number of good posts on working with OpenGL on Windows Mobile via the .NET Compact Framework but one thing I’ve noticed is that they don’t really try to wrap the OpenGL functionality in a way that makes it reusable as an application/game framework. Mostly the logic for rendering was intermingled with windows forms logic, such as OnPaint, which was intermingled with logic for updating the current scene. If you look at say XNA you notice that the model is very simple – essentially they have a single run loop consisting of Update and Draw. I set out to update the OpenGL ES wrapper initially provided by &lt;a href="http://www.koushikdutta.com/2008/08/net-compact-framework-wrapper-for.html"&gt;Koushik Dutta&lt;/a&gt; and since extended with some great examples across at &lt;a href="http://forum.xda-developers.com/showthread.php?t=511363"&gt;XDA Developers&lt;/a&gt;. Here’s what I came up with to start with.&lt;/p&gt;  &lt;p&gt;If you grab the &lt;a href="http://www.koushikdutta.com/2008/08/net-compact-framework-wrapper-for.html"&gt;OpenGL ES wrapper&lt;/a&gt; you will notice that at its core is essentially a single Windows Form that handles the OnPaint method in order to draw using OpenGL primitives. Nearly all the computation and rendering is done in this method. In the constructor and subsequent initialization methods there are a number of OpenGL ES calls in order to setup the display, surface and context required in order for OpenGL to draw to the screen. In order to create a reusable framework that would be a starting point for any project undertaken in OpenGL all this code would have to be wrapped in a way that it doesn’t need to be duplicated for each project.&lt;/p&gt;  &lt;p&gt;I decided to go down the path of creating an abstract form which I called the ApplicationForm. This form has three virtual methods that the overriding form needs to implement:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;protected virtual void SetupScene(){} &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;protected virtual void UpdateScene(float secondsSinceLastUpdate){} &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;protected virtual void DrawScene(){}&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;As you can imagine these form the basis of the Draw-Update rendering loop. Of course SetupScene is called prior to the first iteration of this loop to ensure the scene is correctly setup before the first call to Draw. Unlike some implementations which rely on a For/While loop and DoEvents (to allow windows events to be processed) I went with the approach that works in conjunction with the existing windows message pump. When the form needs to be painted the OnPaint method is invoked:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;protected override void OnPaint(PaintEventArgs e)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; base.OnPaint(e); &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // Draw the current scene       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; RunDrawScene(); &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; egl.SwapBuffers(_display, _surface);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; gl.Clear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT); &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // Update the current scene       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; RunUpdateScene();        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;As you can see this does a single pass of the rendering loop.&amp;#160; What’s interesting is the implementation of the RunUpdateScene method:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;private void RunUpdateScene()       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // Check for running instance - exit if already running        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (Interlocked.CompareExchange(ref isUpdating, 1, 0) == 1)        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // Only instance running, so create the thread in which to       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // invoke the UpdateScene method        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ThreadPool.QueueUserWorkItem((async) =&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; try        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // Calculate the time in seconds since last update        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var seconds = (float)Environment.TickCount/1000.0f;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var diff = 0.0f;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (this.lastUpdate &amp;gt; 0)        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; diff = seconds - this.lastUpdate;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; this.lastUpdate = seconds; &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // Invoke the virtual UpdateScene method       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; UpdateScene(diff);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; finally        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // Make sure this method can be re-entered        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Interlocked.Decrement(ref isUpdating); &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // Invoke &amp;quot;Invalidate&amp;quot; on the control which will cause       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // the control to be refreshed (ie OnPaint called) leading        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // to another iteration of Draw and Update        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; this.BeginInvoke((Action)(() =&amp;gt; { Invalidate(); }));        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; });        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Essentially this method wraps the actual call to UpdateScene for three reasons:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;To ensure only one instance of UpdateScene is being invoked at any time&lt;/li&gt;    &lt;li&gt;To push the call to UpdateScene onto a separate thread. This prevents the UI from blocking whilst it’s in running.&lt;/li&gt;    &lt;li&gt;To invoke Invalidate once UpdateScene has completed. This ensures that OnPaint will be invoked again and that the draw-update loop will be invoked again.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;In the next post I’ll show you how to get started with this wrapper by overriding the ApplicationForm.&amp;#160; In the meantime, try it yourself….&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:8eb9d37f-1541-4f29-b6f4-1eea890d4876:58f79f73-3bd0-460a-9d93-f199b6d76fdb" class="wlWriterEditableSmartContent"&gt;&lt;p&gt;&lt;div&gt;&lt;a href="http://community.softteq.com/blogs/nick/OpenGLESWrapper_1CAE450A.zip" target="_self"&gt;OpenGLESWrapper.zip&lt;/a&gt;&lt;/div&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://community.softteq.com/aggbug.aspx?PostID=1638" width="1" height="1"&gt;</description></item><item><title>Breaking Changes: Windows Phone 7 series Development Story</title><link>http://community.softteq.com/blogs/nick/archive/2010/03/05/breaking-changes-windows-phone-7-series-development-story.aspx</link><pubDate>Fri, 05 Mar 2010 21:47:39 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1637</guid><dc:creator>nick</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Well the cat’s out of the bag… actually no all that’s happened is that Microsoft has confirmed that one of the cats that was in the bag is now dead: The rumour that legacy applications will run on Windows Phone 7 series is officially dead with Charlie Kindel confirming the lack of backwards compatibility in a post entitled &lt;a title="http://blogs.msdn.com/ckindel/archive/2010/03/04/different-means-better-with-the-new-windows-phone-developer-experience.aspx" href="http://blogs.msdn.com/ckindel/archive/2010/03/04/different-means-better-with-the-new-windows-phone-developer-experience.aspx"&gt;Different Means Better with the new Windows Phone Developer Experience&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;What’s interesting is just how well the whole Windows Phone 7 series announcements have been. If you look at other blogs from Microsoft, they all have similar posts talking about the decisions that were made in order to give developers an awesome platform to start building applications on. For example the following blogs all have posts coinciding with Charlie’s post:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Andre Vrignaud: &lt;a href="http://www.ozymandias.com"&gt;www.ozymandias.com&lt;/a&gt; &lt;/p&gt;    &lt;p&gt;&lt;a&gt;Break with the Past, Bright New Future: Windows Phone Application Development Platform built on XNA and Silverlight&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;Christian Schormann: &lt;u&gt;&lt;a href="http://electricbeach.org/?page_id=2"&gt;electricbeach.org&lt;/a&gt;&lt;/u&gt; &lt;/p&gt;    &lt;p&gt;&lt;a&gt;Windows Phone 7 Series for Designers and Developers&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;Shawn Hargreaves: &lt;a href="http://blogs.msdn.com/shawnhar"&gt;blogs.msdn.com/shawnhar&lt;/a&gt; &lt;/p&gt;    &lt;p&gt;&lt;a&gt;Backward compatibility&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;Anand Iyer: &lt;a href="http://www.artificialignorance.net/blog"&gt;www.artificialignorance.net/blog&lt;/a&gt; &lt;/p&gt;    &lt;p&gt;&lt;a&gt;Windows Phone 7 Series – Developers, Developers, Developers&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;Michael Klucher: &lt;a href="http://klucher.com"&gt;klucher.com&lt;/a&gt; &lt;/p&gt;    &lt;p&gt;&lt;a&gt;Gaming Development for the Go!&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Also confirmed in a twitter Q&amp;amp;A at &lt;a href="http://twitter.com/wp7dev"&gt;@WP7dev&lt;/a&gt; was support for both Silverlight and XNA development for Windows Phone 7 series. Hopefully this will provide a much more consistent rapid development environment for building phone applications whilst still making them perform. &lt;/p&gt;  &lt;p&gt;Currently on Windows Mobile we have a number of technologies to choose from, none of which provide a great experience to both developer and consumer without a lot of cycles invested in making your application look good. The worst part about this is not the cycles spent working out what the application should look like (eg working with a designer to make it look awesome), it’s the wasted cycles having to code it from the ground up each time.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;Native C++&lt;/strong&gt;: Sure you can do nearly anything you want but you take a major productivity hit. Not to mention building a team of top notch c++ developers is becoming very difficult.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;WinForms&lt;/strong&gt;: This just sux for anything other than a mundane LOB application. Sure you can use some of the transparency tools out there to get stylish buttons, or override OnPaint to DIY it to make it look reasonable but you aren’t really going to be doing much in the way of animations, rotating elements etc.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;Direct3D&lt;/strong&gt;: Well this is a technology flop in so far as there is little hardware rendering support out there on a lot of devices. Best to ignore this one….&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;OpenGL&lt;/strong&gt;: This is an interesting beast. You can write all your code in C#, yet you have the power of doing nearly any sort of animation, rotation, translation, in fact there is a lot you can do with vectors, triangles and quads. Documentation on getting started and troubleshooting is a little light on but once you get things up and running the results are quite good. You do of course have to think in matrices, projections etc which for those not familiar with these constructs can pose a bit of a learning barrier.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;So, if you were going to build a mobile application today, what would you do….. Well contrary to Charlie’s post in which he suggests that developers will continue to build for Windows Mobile, I suspect the reality is that nearly every mobile developer out there will start building Windows Phone 7 series applications as soon as the tooling arrives.&lt;/p&gt;&lt;img src="http://community.softteq.com/aggbug.aspx?PostID=1637" width="1" height="1"&gt;</description></item><item><title>OData SyncClient for MIX</title><link>http://community.softteq.com/blogs/nick/archive/2010/03/02/odata-syncclient-for-mix.aspx</link><pubDate>Tue, 02 Mar 2010 22:14:19 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1636</guid><dc:creator>nick</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Yesterday &lt;a href="http://twitter.com/ckindel"&gt;Charlie Kindel&lt;/a&gt; tweeted about this &lt;a href="http://live.visitmix.com/SyncClient"&gt;session planner&lt;/a&gt; that can be used for MIX. What’s really interesting about this Silverlight application is that it has the ability to synchronise data and work offline.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_1C33A450.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_5E0A63D1.png" width="350" height="281" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Having noticed this (which you can hardly miss given the “Sync” icon in the top right corner) I wondered if there was a session on Sync.&amp;#160; Sure enough there is a session called “Building Offline Web Apps Using Microsoft Sync Framework” with the following abstract:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Come learn about offline web applications and how they can provide a better experience to your users.&amp;#160; Windows Azure, Microsoft SQL Azure, and Sync Framework are the core technologies that enable web developers to create offlien applications. See how to use these three technologies to produce great applications.&amp;#160; We also introduce our upcoming support for offline Microsoft Silverlight clients and show you how you will have the flexibility to use any platform for your offline applications, device or desktop.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Coming from “mobile-land” where we take doing synchronisation (whether it be DIY webservices, RDA, Merge, Sync Services) for granted the idea that finally web developers might get the concept of offline applications is quite laughable. But, leaving that aside what interested me is what this “upcoming support for Silverlight” is going to be – well they kind of let the cat out of the bag with the session builder. Whilst there is a pseudo attempt at hiding what’s going on in the sync (I’m guessing more out of privacy concerns rather than hiding the sync technology) this is easily broken using Fiddler (you’ll have to enable https tracing in Fiddler and add the Fiddler certificate to your trusted cert list – see &lt;a title="http://www.fiddler2.com/Fiddler/help/httpsdecryption.asp" href="http://www.fiddler2.com/Fiddler/help/httpsdecryption.asp"&gt;http://www.fiddler2.com/Fiddler/help/httpsdecryption.asp&lt;/a&gt; for instructions).&lt;/p&gt;  &lt;p&gt;A typical sync session looks like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_42192ED9.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_38DCF398.png" width="409" height="310" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Notice that each request to either GetChanges or UploadChanges has the same suffix:&lt;/p&gt;  &lt;p&gt;/ODataSync.svc/GetChanges/377d1869-e69a-4b67-9ddd-392169e9b06e?userToken=d39ea0f0e5104c4aad457b897a7b4b62&lt;/p&gt;  &lt;p&gt;/ODataSync.svc/UploadChanges/377d1869-e69a-4b67-9ddd-392169e9b06e?userToken=d39ea0f0e5104c4aad457b897a7b4b62&lt;/p&gt;  &lt;p&gt;The response to the first GetChanges call (which doesn’t contain any data) looks something like:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_7BF84BF8.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_40C4702D.png" width="376" height="251" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;In this we can see that there is an anchor and then there are a list of entries.&amp;#160; Each entry, under the content node, contains a series of properties.&amp;#160; As you can see sync is using odata to transport entity information.&lt;/p&gt;  &lt;p&gt;Each successive GetChanges call sends the anchor back to the server – I’m guessing this anchor value is used to track the synchronization state of the client with the server.&lt;/p&gt;  &lt;p&gt;“eyJLbm93bGVkZ2VCbG9iIjoiQUFBQUJRQUFBQUFBQUFBQkFBQUFBQUFBQUFVQUFCQUFBQUFDTjMwWWFlYWFTMmVkM1RraGFlbXdidGxzQU1rZkowNyt1MHNWYXE1YVBDNEFBQUFZQUFBUUFTZ0NBQUFCQUFBQUZRQUFBQUVBQUFBQkFBQUFBQUFBQUJjQUFBQUJBQUFBRmdBQUFBRUFBd0FBQUFBQUFBQUFBQUFBQUJrQkFBQUFBQT09IiwiVGFibGVXYXRlcm1hcmtzIjpbeyJLZXkiOiJTY2hlZHVsZUl0ZW0iLCJWYWx1ZSI6MTcwNTZ9XX0=”&lt;/p&gt;  &lt;p&gt;Of course, the session planner must be storing data in Silverlight’s isolated storage.&amp;#160; After a little poking I managed to find some of the data being stored:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;{&amp;quot;Anchor&amp;quot;:&amp;quot;eyJLbm93bGVkZ2VCbG9iIjoiQUFBQUJRQUFBQUFBQUFBQkFBQUFBQUFBQUFVQUFCQUFBQUFDTjMwWWFlYWFTMmVkM1RraGFlbXdidGxzQU1rZkowNyt1MHNWYXE1YVBDNEFBQUFZQUFBUUFTZ0NBQUFCQUFBQUZRQUFBQUlBQUFBQkFBQUFBQUFBQUFFQUFBQUNBQUFBQUFBQUFBQUFBRWswQUFBQUFRQUFBQUFBQUVrekFBQUFGd0FBQUFFQUFBQVdBQUFBQVFBREFBQUFBQUVBQUFBQUFBQUFHUUVBQUFBQSIsIlRhYmxlV2F0ZXJtYXJrcyI6W119&amp;quot;,&amp;quot;Data&amp;quot;:[{&amp;quot;Key&amp;quot;:&amp;quot;speaker&amp;quot;,&amp;quot;Value&amp;quot;:[{&amp;quot;__type&amp;quot;:&amp;quot;ItemChangeOfDbSpeakerzgKIiSuC:#Microsoft.Synchronization.Offline&amp;quot;,&amp;quot;IsCreate&amp;quot;:false,&amp;quot;IsDirty&amp;quot;:false,&amp;quot;IsTombstone&amp;quot;:false,&amp;quot;Item&amp;quot;:{&amp;quot;Bio&amp;quot;:&amp;quot;Beginning life as an art student, then after a stint in the military joining the world of technology, Adam Kinney feels right at home in that sweet spot between Designer and Developer. Always at least a part-time evangelist, Adam has traveled the trail of UI technologies. First HTML\/CSS, then Flash, WPF and now Silverlight, the one client technology to rule them all, he has enjoyed learning, experimenting and teaching them all.\r\nAdam’s current focus is Expression Blend, the first interactive design tool that’s really made him happy as a designer and developer.&amp;quot;,&amp;quot;SpeakerDisplayName&amp;quot;:&amp;quot;Adam Kinney&amp;quot;,&amp;quot;SpeakerFirstName&amp;quot;:&amp;quot;Adam&amp;quot;,&amp;quot;SpeakerID&amp;quot;:&amp;quot;b5056969-1f9f-4268-8cbd-64a2fcb7080f&amp;quot;,&amp;quot;SpeakerLastName&amp;quot;:&amp;quot;Kinney&amp;quot;,&amp;quot;SpeakerName&amp;quot;:&amp;quot;Adam-Kinney&amp;quot;}},{&amp;quot;__type&amp;quot;:&amp;quot;ItemChangeOfDbSpeakerzgKIiSuC:#Microsoft.Synchronization.Offline&amp;quot;,&amp;quot;IsCreate&amp;quot;:false,&amp;quot;IsDirty&amp;quot;:false,&amp;quot;IsTombstone&amp;quot;:false,&amp;quot;Item&amp;quot;:{&amp;quot;Bio&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;SpeakerDisplayName&amp;quot;:&amp;quot;Akash Patel&amp;quot;,&amp;quot;SpeakerFirstName&amp;quot;:&amp;quot;Akash&amp;quot;,&amp;quot;SpeakerID&amp;quot;:&amp;quot;cd381f2f-cdca-469a-a937-dae1ad6f72d6&amp;quot;,&amp;quot;SpeakerLastName&amp;quot;:&amp;quot;Patel&amp;quot;,&amp;quot;SpeakerName&amp;quot;:&amp;quot;Akash-Patel&amp;quot;}},&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Sure enough as you can see the anchor is being persisted, along with a series of entities. There are typical fields that you’d expect with synchronization such as IsCreate, IsDirty, IsTombstone but very little in the way of date time or versioning stamps. This again points towards the server doing the bulk of the synchronization logic.&lt;/p&gt;  &lt;p&gt;Well that’s enough poking around with the session builder for one day – I can’t wait to see this session at MIX and see what the sync team have been working on.&lt;/p&gt;&lt;img src="http://community.softteq.com/aggbug.aspx?PostID=1636" width="1" height="1"&gt;</description></item><item><title>LINQ to SQL generator fails due to custom code</title><link>http://community.softteq.com/blogs/nick/archive/2010/02/28/linq-to-sql-generator-fails-due-to-custom-code.aspx</link><pubDate>Mon, 01 Mar 2010 04:21:12 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1634</guid><dc:creator>nick</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;Today I decided to do something quite innocuous, or so I thought, on an existing application that happened to use LINQ to SQL. I needed to add an additional field to an existing table which I did quite easily via SSMS. However, when I came to update the LINQ to SQL model file I ran into all sorts of issues. The easiest way I’ve found in the past to update the LINQ to SQL model is to simply delete the table that you need to update and drag it onto the design surface from Server Explorer. Normally this updates the model and doesn’t usually break anything (unless you say delete a field that is in use in your code in which case the compile error is an artefact you want). &lt;/p&gt;  &lt;p&gt;Today this process seemed to go completely haywire for no reason. I was getting 10-15 compile errors – since I was just adding a field I shouldn’t have seen any. Thinking that I’d broken something accidentally I reverted back to the version in subversion and tried again. Same result. Looking in Solution Explorer it was clear why these errors were being generated – there was no .designer.cs file to go alongside the .dbml LINQ to SQL model file.&lt;/p&gt;  &lt;p&gt;I right-click on the dbml file in Solution Explorer and selected “Run Custom Tool” (for those unfamiliar with the Visual Studio custom tool model this is essentially an external executable that is called to automatically create or modify files in your solution – in this case create the .designer.cs file). This time I at least got an error message:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_6BAF4438.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_10605BB0.png" width="310" height="123" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Error: &lt;strong&gt;The custom tool ‘MSLinqToSQLGenerator’ failed. Unsepecifed error&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Interestingly it also opened up a file in which I had added some custom properties for my LINQ to SQL entities. I found that if I excluded this file from my solution I was again able to run the custom tool to generate the .designer.cs file. So, in order to make schema changes from now on I need to:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;-Exclude my custom properties file&lt;/p&gt;    &lt;p&gt;-Make changes to my LINQ to SQL model&lt;/p&gt;    &lt;p&gt;-Run the Custom tool to generate the .designer.cs file – this is automatically run if you save or close the model designer&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;Update: &lt;/strong&gt;Actually, you need to do a build of the project that contains the LINQ to SQL model prior to adding the custom properties file back into the project. Otherwise Visual Studio decides to nuke the .designer.cs file again.&lt;/p&gt;    &lt;p&gt;-Include my custom properties files&lt;/p&gt;    &lt;p&gt;-Rebuild my solution.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Hope this helps anyone else seeing the same issue&lt;/p&gt;&lt;img src="http://community.softteq.com/aggbug.aspx?PostID=1634" width="1" height="1"&gt;</description></item><item><title>Does Windows Mobile 6 Smell (part II)?</title><link>http://community.softteq.com/blogs/nick/archive/2010/02/26/does-windows-mobile-6-smell-part-ii.aspx</link><pubDate>Sat, 27 Feb 2010 06:49:41 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1632</guid><dc:creator>nick</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;In my &lt;a href="http://community.softteq.com/blogs/nick/archive/2010/02/25/does-windows-mobile-6-smell.aspx"&gt;previous post&lt;/a&gt; I talked about Microsoft and the enterprise and how it had help shape Windows Mobile 6.x. Now I want to look at some of the implications of this strategy, specifically looking at how the attitude towards touch input has changed over time.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Touch v’s Non-Touch v’s Multi-Touch&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;One of the things that really differentiated Windows Mobile was it’s ability to work on multiple different form factors, from your non-touch txt friendly devices with keyboards through to your candy bar devices through to your pda-style devices with on-screen keyboards. Track back a few years and you would have seen the names Pocket PC and Smartphone being used to describe devices with and without a touch interface. With a move to align the two operating systems these came to be known as Windows Mobile Professional and Windows Mobile Standard – personally I think this did more than confuse the market who were already confused by the double use of the word Smartphone.&lt;/p&gt;  &lt;p&gt;But this post wasn’t supposed to be a Windows Mobile history lesson, instead it was to look at our opinions on touch have evolved. If you recall back to the Pocket PC days there were very few people who actually used “touch” to interact with their device. Most uses whipped out their stylus and used that to push and poke at the screen. They would tap at the on-screen keyboard or even learn how to use the quirky text recognition capabilities of the device. This process was quite painful, particularly if you were responding to a text message or email. This is in part why both hardware keyboards and the Smartphone increased in popularity – both these addressed the problem of how to quickly navigate and type on the device.&lt;/p&gt;  &lt;p&gt;The challenge with a physical keyboard is that no matter how to position it you end up with a tiny keyboard that simply adds weight and size to the device. Text entry, whilst quickest using a full qwerty keyboard was still a far shy from entering it on the desktop and often the extra hassle of sliding out a keyboard, waiting for the screen to reorientate and then entering text was enough to put off a lot of users.&lt;/p&gt;  &lt;p&gt;The challenge with Smartphone is that it just sux – ok, you have me, I’m not a Smartphone advocate. Whilst I find that the interface is quick to navigate nearly all the applications are somewhat lacking or clumsy to use.&amp;#160; Take internet explorer for example – you either have a little arrow cursor that you drag around the screen using a dpad or you jump from link to link, often making the text of the website very difficult to read. Personally I’ve never liked this style of device and it was scary a couple of years ago because it seemed that 90% of all new devices being released by OEMs were a Smartphone, rather than having a touch screen.&lt;/p&gt;  &lt;p&gt;From a development perspective we saw the convergence of Smartphone and Pocket PC into Windows Mobile as a good thing. It meant we could build a single application that would work on both styles of devices. Unfortunately, this is a bit like building a desktop application and running it on the device – great idea, but results in an aweful user experience as either the desktop application is limited to display what’s available on the device (ie small screen real estate) or the application has to scale down to fit to the device (resulting in small controls that are hard to use). Guidance from Microsoft even suggested that developers should build to target Smartphone so it will work on both devices.&lt;/p&gt;  &lt;p&gt;This whole topic became even more interesting when Apple released the iPhone and multi-touch came into the mainstream. Unfortunately the Windows Mobile team failed to get it and released 6, 6.1 and 6.5 without any support for multi-touch.&amp;#160; In fact it’s only been with the release of the HTC HD2 that we’ve even seen capacitive screens for Windows Mobile which would effectively allow multi-touch. I believe this was because there was a misunderstanding on how users wanted to use their device. Too much research focussed on looking at ways to improve what users were currently doing (eg using a stylus), rather than exploring more innovative ways for the users to do things (eg making all controls larger so that the user can use touch instead of a stylus).&lt;/p&gt;  &lt;p&gt;Now, finally Microsoft has awoken and we are seeing a new era of devices and operating systems heavily geared towards making touch (and I’m sure in the future multi-touch). Windows Mobile 6.5.3 has restyled controls, repositioned Start menu and Ok buttons, specifically geared to making it easy to navigate with touch and gestures. Windows Phone 7 series is all about touch, swipe, gesture and motion in general. It’s clear to see that this is the way forward and that the old Blackberry style non-touch devices are a thing of the past.&lt;/p&gt;&lt;img src="http://community.softteq.com/aggbug.aspx?PostID=1632" width="1" height="1"&gt;</description></item><item><title>Does Windows Mobile 6 Smell?</title><link>http://community.softteq.com/blogs/nick/archive/2010/02/25/does-windows-mobile-6-smell.aspx</link><pubDate>Thu, 25 Feb 2010 22:12:25 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1630</guid><dc:creator>nick</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;If you ask most users what they think of Windows Mobile they either don’t know what it is (most non-techie consumers) or they shudder saying that slow, overly complex phone that I never use now I have…. Anyone would think that Windows Mobile smells. I’d like to put forward some points that at least explains why it looks and smells the way it is. You may even decide to give the current generation of Windows Mobile 6.5.3 devices a go.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Microsoft and the Enterprise&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I think the first point I’d like to make is that I doubt at any stage Microsoft decided that the end user wasn’t the highest priority when designing and building Windows Mobile. The whole “end-user-first” message that’s coming from Microsoft is just another re-hash of the “Age of User Experience” message that we saw a couple of years ago. What I do buy is that Microsoft has changed focus on which end user they’re putting first, or at least, what end user activities should come first. &lt;/p&gt;  &lt;p&gt;In the past the design of Windows Mobile was geared towards an end user who worked for an enterprise, was connected to Exchange server and the reason for having a device was to make phone calls, send sms, triage email, work with contacts, calendar and tasks to get their work done. Now we’re seeing a new era where Windows Phone 7 is about supporting end users in every facet of their lives – helping them stay in contact, entertain them, help them relax, get work done, oh and of course make a phone call. Actually the latter seems to have been almost an after thoughts as there is not even a hardware call and/or hang up button according to the specs released by Microsoft last week.&lt;/p&gt;  &lt;p&gt;So I guess the question has to be asked as to why the focus was on the enterprise user? Microsoft’s entry into the mobile phone market came as an extension of their embedded operating system. In fact Windows Mobile is essentially Windows CE in a specified configuration, with additional modules, such as Office Mobile and of course a phone stack. As such it seemed logical for them to enter this space in order to support enterprise users. &lt;/p&gt;  &lt;p&gt;Once in this space it appears that Microsoft saw RIM as one of the main competitors with their Blackberry devices. Those familiar with Microsoft codenames will know that &lt;a href="http://en.wikipedia.org/wiki/List_of_Microsoft_codenames"&gt;Crossbow&lt;/a&gt; was one of the code names used internally for one of the previous versions of Windows Mobile – this happens (probably coincidentally) to be the &lt;a href="http://www.dowagro.com/au/prod/crossbow.htm"&gt;name of a pesticide&lt;/a&gt; that can be used to get ride of the blackberry plant (ref Website). The Blackberry OS has traditionally been menu centric, so as long as Windows Mobile only had as single “Start” menu it was considered to be a safe bet. Also, since Blackberries didn’t have touch screens, supporting touch (rather than stylus, and definitely not multi-touch) input wasn’t really considered a core use case. Again the result was that Windows Mobile continued to evolve towards a dpad/keyboard driven interface – in the enterprise this resulted in some very effective office worker devices that could be used to rapidly triage email but they weren’t the nicest consumer devices.&lt;/p&gt;  &lt;p&gt;More on this discussion in future posts….&lt;/p&gt;&lt;img src="http://community.softteq.com/aggbug.aspx?PostID=1630" width="1" height="1"&gt;</description></item><item><title>Windows Phone 7 Series Development – What Do You Want?</title><link>http://community.softteq.com/blogs/nick/archive/2010/02/25/windows-phone-7-series-development-what-do-you-want.aspx</link><pubDate>Thu, 25 Feb 2010 12:35:09 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1628</guid><dc:creator>nick</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;Since it’s announcement over a week ago the question on all our lips is “what’s the development story going to be?” Whilst there has been countless rumours regarding support for Silverlight (perhaps third time’s like for this can of worms….) and XNA it won’t be until &lt;a href="http://live.visitmix.com/"&gt;MIX&lt;/a&gt; that we’re going get a good look at what Microsoft has in store for us mobile developers going forward.&lt;/p&gt;  &lt;p&gt;In the meantime, I took a little bit of time out to think about the current generation of development tools. Now, I’m going to overlook the obvious failing around stylish controls for building Windows Mobile applications (which in my opinion is one of the fundamental reasons the iPhone is trumping Windows Mobile applications at the moment, after all it sure as hell isn’t the development language!). What I’m interested in is the development/debugging/testing/deployment story, so here’s a list of the tools/frameworks etc that we have at the moment. I’ll start this list but I suspect it may have to be continued as I remember things that I’ve omitted. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Microsoft&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;IDE - Visual Studio&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;- Support for Native, C# and VB.NET development      &lt;br /&gt;- Visual Designer for Forms and Controls, including designer skin       &lt;br /&gt;- Intellisense, Code completion       &lt;br /&gt;- Debuggin support       &lt;br /&gt;&amp;gt;&amp;gt; Breakpoints       &lt;br /&gt;&amp;gt;&amp;gt; Watches and variable inspection       &lt;br /&gt;&amp;gt;&amp;gt; Datatips       &lt;br /&gt;&amp;gt;&amp;gt; Step through/over&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Managed Frameworks&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;- .NET Compact Framework      &lt;br /&gt;- Windows Mobile managed libraries       &lt;br /&gt;&amp;gt;&amp;gt; POOM (contacts, calendar, email, tasks)       &lt;br /&gt;&amp;gt;&amp;gt; Camera       &lt;br /&gt;&amp;gt;&amp;gt; Contact picker       &lt;br /&gt;&amp;gt;&amp;gt; State and Notification Broker       &lt;br /&gt;[missing APIs could be p/invoked to native APIs]       &lt;br /&gt;- Rich networking stack (sockets &amp;amp; httprequest)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Data Story&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;- SQL Server Compact      &lt;br /&gt;- Multiple Synchronization Frameworks (RDA, Merge Replication, Sync Services)       &lt;br /&gt;- Designer support for connecting to web services&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Support Tools&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;- Device Emulator      &lt;br /&gt;&amp;gt;&amp;gt; Able to change configuration       &lt;br /&gt;&amp;gt;&amp;gt; Able to adjust system state       &lt;br /&gt;&amp;gt;&amp;gt; Able to connect to ActiveSync/WMDC to simulate docking real device       &lt;br /&gt;- Cellular Emulator       &lt;br /&gt;- Hopper&amp;#160; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;strong&gt;3rd Party&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;- &lt;a href="http://www.opennetcf.com/cf/products/sdf.ocf"&gt;Smart Devices Framework&lt;/a&gt; (OpenNETCF)&lt;/p&gt;  &lt;p&gt;- &lt;a href="http://inthehand.com/content/Products.aspx"&gt;Mobile In The Hand&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;- &lt;a href="http://mobile.codeplex.com/"&gt;Mobile Client Software Factory&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;- &lt;a href="http://www1.orientationaware.net/home.html"&gt;Orientation Aware Control&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;- &lt;a href="http://nlog-project.org/download.html"&gt;NLog&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;With this list in mind, what do you feel is missing? If your answer is nothing, then think harder – after all there must be a reason why Windows Mobile 6.x was failing to attract users and developers alike.&lt;/p&gt;&lt;img src="http://community.softteq.com/aggbug.aspx?PostID=1628" width="1" height="1"&gt;</description></item><item><title>Motorola Devour is yet another average Android device</title><link>http://community.softteq.com/blogs/nick/archive/2010/02/24/motorola-devour-is-yet-another-average-android-device.aspx</link><pubDate>Wed, 24 Feb 2010 22:59:11 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1626</guid><dc:creator>nick</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;On the way from the airport into the Melbourne CBD I read the &lt;a href="http://blogs.zdnet.com/gadgetreviews/?p=12500%20"&gt;ZDNet Review of the Motorola Devour&lt;/a&gt; and I think it confirms my view that Android, whilst perhaps a great operating system for OEMs to build on, lacks anything at all that would draw me to the platform. The Devour seems an overly unimpressive device both in terms of the hardware spec and the software. &lt;/p&gt;  &lt;p&gt;From looking at the hardware I can’t get away from the feeling that Android devices, pretty much across the board, have been designed with your average “google-loving-geek-boy” in mind. The ZDNet review comments that the design of the Devour could be considered “retro” (from &lt;a href="http://www.wired.com/gadgetlab/2010/02/hands-on-motorola-devour/"&gt;&lt;em&gt;Wired’s Priya Ganapati&lt;/em&gt;&lt;/a&gt;) and that it’s the “next chapter of Motorola’s signature industrial design” but I think the hardware appears chunky and uncomfortable, and lacks any sense of true style.&lt;/p&gt;  &lt;p&gt;From the software perspective it of course features the standard Android home screen featuring icons (urgh, so last year – get with the program, it’s all about square updating tiles now…. we’ll probably come back to that to determine whether Microsoft’s gamble pays off there). What’s interesting is that like other Android devices it supports the latest version of Google Maps. With Google increasingly leaning towards providing the latest features (such as navigation) only on the version of Google Maps for Android, it will be interesting to see what other players like Microsoft bring to the table.&lt;/p&gt;  &lt;p&gt;[As an aside – the recently released &lt;a title="Download details- Windows Mobile 6.5.3 DTK" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=c0213f68-2e01-4e5c-a8b2-35e081dcf1ca&amp;amp;displaylang=en"&gt;Windows Mobile 6.5.3 DTK&lt;/a&gt; includes a mapping framework sample.&amp;#160; The sample is written in native code but has a managed wrapper so can be used in either a native or .NET Compact Framework application. This sample is a great starting point for anyone wanting to build an application making use of mapping on the Windows Mobile platform. No information yet as to whether there will be a similar control/framework for Windows Phone 7 series development. More to come on this topic…]&lt;/p&gt;&lt;img src="http://community.softteq.com/aggbug.aspx?PostID=1626" width="1" height="1"&gt;</description></item><item><title>Is Windows Phone 7 series going to be great for developers?</title><link>http://community.softteq.com/blogs/nick/archive/2010/02/23/is-windows-phone-7-series-going-to-be-great-for-developers.aspx</link><pubDate>Tue, 23 Feb 2010 22:16:42 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1625</guid><dc:creator>nick</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;As you’ve no doubt seen Microsoft announced Windows Phone 7 series last week at Mobile World Congress in Barcelona. I guess I’ll start off with the mandatory “here’s what it looks like” piece: Here’s a couple of screenshots for you to go “oh-ah” over – if you want more you can head over to &lt;a href="http://robtiffany.com/"&gt;Rob’s blog&lt;/a&gt; where he’s got some more images, as well as the official &lt;a href="http://www.windowsphone7series.com"&gt;Windows Phone 7 Series&lt;/a&gt; website.&lt;/p&gt;  &lt;p&gt;&lt;img title="startscreen_web" alt="startscreen web 158x300 Windows Phone 7 Series debuts at Barcelona!" src="http://robtiffany.com/wp-content/uploads/2010/02/startscreen_web-158x300.jpg" width="124" height="210" /&gt;&lt;img title="officescreen_web" alt="officescreen web 300x181 Windows Phone 7 Series debuts at Barcelona!" src="http://robtiffany.com/wp-content/uploads/2010/02/officescreen_web-300x181.jpg" width="329" height="210" /&gt;&lt;/p&gt;  &lt;p&gt;Now the reason for this post is a way of providing commentary following the &lt;a href="http://blogs.msdn.com/ckindel/archive/2010/02/22/focus-focus-focus.aspx"&gt;Focus, Focus, Focus&lt;/a&gt; post by Charlie Kindel. Firstly, I want to say that I love the fact that there appears to be such a high level of “focus” from the Windows Phone team. It would appear that despite severely dropping the ball with Windows Mobile 6.x I think the departure from this platform to Windows Phone 7 series will definitely be a positive move and will position Microsoft in a strong position in the mobile market. &lt;/p&gt;  &lt;p&gt;Yes, I know everyone’s (well at least a large proportion of the techie crowd) going on about Android this and Android that but they’re seeing the same issues Microsoft saw 5 years ago with market fragmentation and a UI that is already very dated. Unless Google does something remarkable prior to Windows Phone 7 hitting the stores I suspect we’ll see an un-remarkable end to Android phones being the alternative to buying an iPhone.&lt;/p&gt;  &lt;p&gt;Coming back to Charlie’s post – What I found particularly interesting is the priority list regarding the developer audience, which essentially puts us enterprise developers close to the bottom of the heap. Initially you might look at that and say “but enterprise has been Microsoft’s staple when it comes to WM” but you have to remember this is NOT Windows Mobile, it’s Windows Phone 7, it’s a new era of devices and with that comes all the issues you’d expect to see with a v1 product.&amp;#160; Actually as an aside I’m surprised they went with 7 – this is so radically different they could have just gone with Windows Phone and be done with it. Alternatively they could have just picked a single manufacturer and released the Microsoft Phone but that’s a completely different topic altogether.&lt;/p&gt;  &lt;p&gt;So, where does that leave us enterprise developers? Well the first thing you should do is realise that Charlie’s list is only a priority list, it doesn’t imply that you can’t do enterprise development. In fact, I’m guessing that in order to support the Pro and non-Pro developer audience in their ability to create awesome applications for consumers, a large proportion of the enterprise capabilities will be there. &lt;/p&gt;  &lt;p&gt;So what may be missing for enterprise developers? If you consider enterprise as including line of business applications such as stock management, then it is highly likely that when Windows Phone 7 ships there won’t be hardware out there to support barcode scanning etc. This isn’t actually a new problem as hardware manufacturers for LOB devices typically take 6-12 months (or more in some cases) to update their devices with new operating system versions. &lt;/p&gt;  &lt;p&gt;Microsoft also hasn’t talked about what the deployment story will be for applications and the extent of the programming apis that will be available for application developers to interact not only with other services on the device (eg camera or the phone), storage, other applications, PIM data (eg contacts, calendar) and whether there will be developer libraries for connecting to Windows Azure, Live Id and other hosted services. My guess is that like previous versions of Windows Mobile there will be apis for accessing some of these – how this affects enterprise development is really dependent on what apis are there and which are missing. For anyone interested in this story, you should be heading to &lt;a href="http://live.visitmix.com/"&gt;MIX&lt;/a&gt; where they’ll be disclosing the developer story.&lt;/p&gt;&lt;img src="http://community.softteq.com/aggbug.aspx?PostID=1625" width="1" height="1"&gt;</description></item><item><title>Windows Mobile 6.5.3 DTK (not SDK or 6.6) download available</title><link>http://community.softteq.com/blogs/nick/archive/2010/02/16/windows-mobile-6-5-3-dtk-not-sdk-or-6-6-download-available.aspx</link><pubDate>Wed, 17 Feb 2010 00:24:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1620</guid><dc:creator>nick</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;Get it while it&amp;#39;s hot from the &lt;a title="Download Center" href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=c0213f68-2e01-4e5c-a8b2-35e081dcf1ca&amp;amp;utm_source=feedburner&amp;amp;utm_medium=feed&amp;amp;utm_campaign=Feed%3A+MicrosoftDownloadCenter+%28Microsoft+Download+Center%29#tm"&gt;download center&lt;/a&gt;. The content in my &lt;a href="http://community.softteq.com/blogs/nick/archive/2010/01/22/windows-mobile-6-5-sdk-overview.aspx"&gt;original overview of the Windows Mobile 6.5.3 SDK&lt;/a&gt;&amp;nbsp;is still accurate. However the installation issues have been resolved and there is a bunch of things (like the help files and the Map Framework sample) are now installed correctly.&amp;nbsp; The installation of the DTK should not affect any of the existing emulator images you have installed.&amp;nbsp; Stay tuned for more information on what&amp;#39;s in the DTK.&lt;/p&gt;&lt;img src="http://community.softteq.com/aggbug.aspx?PostID=1620" width="1" height="1"&gt;</description><category domain="http://community.softteq.com/blogs/nick/archive/tags/DTK/default.aspx">DTK</category><category domain="http://community.softteq.com/blogs/nick/archive/tags/SDK/default.aspx">SDK</category><category domain="http://community.softteq.com/blogs/nick/archive/tags/Widget/default.aspx">Widget</category><category domain="http://community.softteq.com/blogs/nick/archive/tags/windows+mobile+6.5.3/default.aspx">windows mobile 6.5.3</category></item><item><title>Windows Mobile 6.5.3 DTK - Ready, Set….. Oh wait, hang on….. Go!</title><link>http://community.softteq.com/blogs/nick/archive/2010/02/16/windows-mobile-6-5-3-dtk-ready-set-oh-wait-hang-on-go.aspx</link><pubDate>Tue, 16 Feb 2010 18:35:19 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1617</guid><dc:creator>nick</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;As some of you will be aware there was a &lt;a href="http://community.softteq.com/blogs/nick/archive/2010/01/22/windows-mobile-6-5-sdk-overview.aspx"&gt;first attempt at releasing&lt;/a&gt; the Windows Mobile 6.5.3 DTK (&lt;a href="http://community.softteq.com/blogs/nick/archive/2010/01/25/windows-mobile-6-5-sdk-is-now-missing-in-action.aspx"&gt;now missing&lt;/a&gt;) earlier this month. Despite a number of bits being missing or not installed correctly there are definitely some good bits coming in the DTK (take for example the Widget development story within VS2008).&amp;#160; According to Todd in his &lt;a href="http://windowsteamblog.com/blogs/wmdev/archive/2010/02/16/marketplace-momentum.aspx"&gt;Marketplace Momentum&lt;/a&gt; post we should see the real version of the DTK later this week. Check back with &lt;a href="http://windowsteamblog.com/blogs/windowsphone"&gt;this blog&lt;/a&gt; to find out more about the actual release when it happens.&lt;/p&gt;&lt;img src="http://community.softteq.com/aggbug.aspx?PostID=1617" width="1" height="1"&gt;</description></item><item><title>Windows Mobile 6.5 SDK is now Missing In Action</title><link>http://community.softteq.com/blogs/nick/archive/2010/01/25/windows-mobile-6-5-sdk-is-now-missing-in-action.aspx</link><pubDate>Mon, 25 Jan 2010 22:04:24 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1615</guid><dc:creator>nick</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;According to Twitter, which Microsoft clearly believes as the best way to communicate to its developer community, the &lt;a href="http://community.softteq.com/blogs/nick/archive/2010/01/22/windows-mobile-6-5-sdk-overview.aspx"&gt;Windows Mobile 6.5 SDK&lt;/a&gt; has been pulled. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_2BEEFE0C.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_510C4878.png" width="364" height="191" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;&lt;img src="http://community.softteq.com/aggbug.aspx?PostID=1615" width="1" height="1"&gt;</description><category domain="http://community.softteq.com/blogs/nick/archive/tags/Microsoft/default.aspx">Microsoft</category><category domain="http://community.softteq.com/blogs/nick/archive/tags/SDK/default.aspx">SDK</category><category domain="http://community.softteq.com/blogs/nick/archive/tags/Windows+Mobile+6.5/default.aspx">Windows Mobile 6.5</category></item><item><title>Windows Mobile 6.5 SDK Overview</title><link>http://community.softteq.com/blogs/nick/archive/2010/01/22/windows-mobile-6-5-sdk-overview.aspx</link><pubDate>Sat, 23 Jan 2010 00:44:14 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1604</guid><dc:creator>nick</dc:creator><slash:comments>12</slash:comments><description>&lt;p&gt;The first thing to note about the newly released &lt;a href="http://community.softteq.com/blogs/nick/archive/2010/01/22/windows-mobile-6-5-sdk-available-for-download.aspx"&gt;Windows Mobile 6.5 SDK&lt;/a&gt; is that it effectively comes in two parts.&amp;#160; 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.&lt;/p&gt;  &lt;p&gt;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.&amp;#160; 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.&lt;/p&gt;  &lt;p&gt;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 “&lt;a name="Introduction"&gt;Windows Mobile 6 SDK Refresh&lt;/a&gt;”.&amp;#160; 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. &lt;/p&gt;  &lt;p&gt;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”.&amp;#160; Given my recent set of blog posts on building Windows Mobile widgets I was really eager to see what this would entail.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_46F18ABB.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_3ABFEAC7.png" width="346" height="264" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;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. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_31177C91.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_44583330.png" width="244" height="203" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;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. &lt;/p&gt;  &lt;p&gt;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:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_2D49B1F4.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_3E0136D5.png" width="394" height="291" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;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.&amp;#160; The simple work around to this issue is to not stop the debugger.&amp;#160; 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.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_5407A267.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_1E423740.png" width="373" height="324" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;What’s cool is that you can do the following:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Set breakpoints and then walk through your code inspecting variables.&lt;/li&gt; &lt;/ul&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_7F5B9D94.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_4EE5191E.png" width="244" height="95" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;ul&gt;   &lt;li&gt;Use the “hide” (which changes to “show” when clicked) button to mimic the widget going into the background.&amp;#160; The onshow and onhide events get invoked.&lt;/li&gt;    &lt;li&gt;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.&lt;/li&gt;    &lt;li&gt;You can change most of the System State properties to see what effect it has on your device. See my post on &lt;a title="System State (aka Notification Broker) and Device Information" href="http://community.softteq.com/blogs/nick/archive/2010/01/15/windows-mobile-widget-101-system-state-aka-notification-broker-and-device-information.aspx"&gt;System State (aka Notification Broker) and Device Information&lt;/a&gt; for more information on working with this information.&lt;/li&gt;    &lt;li&gt;Even the menus are simulated:&lt;/li&gt; &lt;/ul&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_7AB56D0D.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_195C312C.png" width="244" height="235" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Of course, whilst this is convenient for development, you must and I repeat must test your widgets on real devices.&lt;/p&gt;  &lt;p&gt;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:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_05CED18B.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_38227F3D.png" width="407" height="248" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_7CEEA371.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_28BEF761.png" width="399" height="140" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_1FEEEF15.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_37A6267B.png" width="342" height="68" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_5CC370E7.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_740E7558.png" width="291" height="293" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;My only criticism here is that the team haven’t really thought this through.&amp;#160; 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.&lt;/p&gt;  &lt;p&gt;That’s enough about widgets. Let’s take a quick look at the emulator.&amp;#160; Notice that this isn’t the 6.5 we’re used to see in the emulator.&amp;#160; 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.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_2B085392.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_2257D539.png" width="162" height="244" /&gt;&lt;/a&gt; &lt;a href="http://community.softteq.com/blogs/nick/image_58E5807D.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_47B1A2DA.png" width="164" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;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.&amp;#160; 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.&lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;&lt;img src="http://community.softteq.com/aggbug.aspx?PostID=1604" width="1" height="1"&gt;</description></item><item><title>Windows Mobile 6.5 SDK Available for Download</title><link>http://community.softteq.com/blogs/nick/archive/2010/01/22/windows-mobile-6-5-sdk-available-for-download.aspx</link><pubDate>Fri, 22 Jan 2010 22:51:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1603</guid><dc:creator>nick</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;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 &lt;a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=c5241738-0fe6-4396-a4e5-5a516deb1bc5"&gt;Windows Mobile 6.5 SDK Download page&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://community.softteq.com/aggbug.aspx?PostID=1603" width="1" height="1"&gt;</description><category domain="http://community.softteq.com/blogs/nick/archive/tags/SDK/default.aspx">SDK</category><category domain="http://community.softteq.com/blogs/nick/archive/tags/Windows+Mobile+6.5/default.aspx">Windows Mobile 6.5</category></item><item><title>Windows Mobile Widget 101 - Persistence</title><link>http://community.softteq.com/blogs/nick/archive/2010/01/17/windows-mobile-widget-101-persistence.aspx</link><pubDate>Sun, 17 Jan 2010 22:00:25 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1594</guid><dc:creator>nick</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Prior posts in this series:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://community.softteq.com/blogs/nick/archive/2009/12/20/windows-mobile-widget-101-getting-started.aspx"&gt;Getting Started&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://community.softteq.com/blogs/nick/archive/2009/12/21/windows-mobile-widget-101-start-menu-icons.aspx"&gt;Start Menu Icons&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://community.softteq.com/blogs/nick/archive/2009/12/22/windows-mobile-widget-101-a-gadget-side-note.aspx"&gt;A Gadget Side Note&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://community.softteq.com/blogs/nick/archive/2009/12/22/windows-mobile-widget-101-handling-form-factors.aspx"&gt;Handling Form Factors&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://community.softteq.com/blogs/nick/archive/2010/01/13/windows-mobile-widget-101-the-manifest-file.aspx"&gt;The Manifest File&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://community.softteq.com/blogs/nick/archive/2010/01/14/windows-mobile-widget-101-menus.aspx"&gt;Menus&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://community.softteq.com/blogs/nick/archive/2010/01/15/windows-mobile-widget-101-system-state-aka-notification-broker-and-device-information.aspx"&gt;System State (aka Notification Broker) and Device Information&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Out of the box the Windows Mobile widget API provides only basic support for saving and retrieving data. The &lt;a href="http://msdn.microsoft.com/en-us/library/dd721906.aspx#UsingWidgetPersistence"&gt;documentation on MSDN&lt;/a&gt; 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. &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;-----------------        &lt;br /&gt;widget.js         &lt;br /&gt;-----------------&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;//-----------------------------------------------------------------------       &lt;br /&gt;// Storage        &lt;br /&gt;//----------------------------------------------------------------------- &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // saves key-value pair (length restricted, use persistData for long string values)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; saveKeyValue: function (key, value) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (window.widget) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; window.widget.setPreferenceForKey(value, key);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else if (isGadget &amp;amp;&amp;amp; isGadget == true){        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return System.Gadget.Settings.writeString(key,value);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return Cookie.set(key,value,365);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }, &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // retrieves key-value pair       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; retrieveKeyValue: function (key) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (window.widget) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return window.widget.preferenceForKey(key);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else if (isGadget &amp;amp;&amp;amp; isGadget == true){        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return System.Gadget.Settings.readString(key);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return Cookie.get(key);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // Persists Data (any length)        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; persistData: function (key, value) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (!value || value == null) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WidgetAPI.saveKeyValue(key, 0);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var str = value;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var i = 0;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var j = 0; &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; while (j &amp;lt; str.length) {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var inc = 2000;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (j + inc &amp;gt; str.length) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; inc = str.length - j;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var tmp = str.substring(j, j + inc);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; j += inc;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WidgetAPI.saveKeyValue(key + i, tmp);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; i += 1;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WidgetAPI.saveKeyValue(key, i);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // Checks to see if data exists        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; dataExists: function (key) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var count = WidgetAPI.retrieveKeyValue(key);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (typeof(count)==&amp;quot;undefined&amp;quot; || count == null || count &amp;lt;= 0) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return false;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return true;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }, &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // Retrive data (any length)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; retrieveData: function (key) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var count = WidgetAPI.retrieveKeyValue(key);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (!count || count == null || count &amp;lt;= 0) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return null;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var str = &amp;quot;&amp;quot;;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; for (var i = 0; i &amp;lt; count; i++) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; str += WidgetAPI.retrieveKeyValue(key + i);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return str;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;And of course we need some sample code added to main.js and main.htm to demonstrate this in action:&lt;/p&gt;  &lt;blockquote&gt;&lt;em&gt;-----------------&amp;#160; &lt;br /&gt;main.htm       &lt;br /&gt;-----------------&lt;/em&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div id=&amp;quot;welcome&amp;quot;&amp;gt;Welcome....&amp;lt;/div&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div id=&amp;quot;persistenceDemo&amp;quot;&amp;gt;Name:         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;input id=&amp;quot;nameTextbox&amp;quot; type=&amp;quot;text&amp;quot; /&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;input id=&amp;quot;submitButton&amp;quot; type=&amp;quot;button&amp;quot; value=&amp;quot;Save&amp;quot; onclick=&amp;quot;saveName()&amp;quot;/&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/div&amp;gt;&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;-----------------&amp;#160; &lt;br /&gt;main.js       &lt;br /&gt;-----------------&lt;/p&gt;    &lt;p&gt;function onLoad() {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; // Code omitted as same as previous posts&lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; sayWelcome();     &lt;br /&gt;} &lt;/p&gt;    &lt;p&gt;function sayWelcome() {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; var welcome = $get(&amp;quot;welcome&amp;quot;);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; var name = WidgetAPI.retrieveData(&amp;quot;Name&amp;quot;);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (!name || name == null) {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; name = &amp;quot;...&amp;quot;;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; welcome.innerHTML = &amp;quot;Welcome &amp;quot; + name;      &lt;br /&gt;} &lt;/p&gt;    &lt;p&gt;function saveName() {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; var txt = $get(&amp;quot;nameTextbox&amp;quot;);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; WidgetAPI.persistData(&amp;quot;Name&amp;quot;, txt.value);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; sayWelcome();      &lt;br /&gt;}&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;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.&amp;#160; 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!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_4BBE4986.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_192AC647.png" width="184" height="244" /&gt;&lt;/a&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_7E11F738.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_434A4E62.png" width="239" height="221" /&gt;&lt;/a&gt;&amp;#160;&lt;a href="http://community.softteq.com/blogs/nick/image_01636914.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_30D1D7E0.png" width="237" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://community.softteq.com/aggbug.aspx?PostID=1594" width="1" height="1"&gt;</description></item><item><title>Windows Mobile Widget 101 – System State (aka Notification Broker) and Device Information</title><link>http://community.softteq.com/blogs/nick/archive/2010/01/15/windows-mobile-widget-101-system-state-aka-notification-broker-and-device-information.aspx</link><pubDate>Sat, 16 Jan 2010 05:31:49 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1593</guid><dc:creator>nick</dc:creator><slash:comments>2</slash:comments><description>&lt;p&gt;Prior posts in this series:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://community.softteq.com/blogs/nick/archive/2009/12/20/windows-mobile-widget-101-getting-started.aspx"&gt;Getting Started&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://community.softteq.com/blogs/nick/archive/2009/12/21/windows-mobile-widget-101-start-menu-icons.aspx"&gt;Start Menu Icons&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://community.softteq.com/blogs/nick/archive/2009/12/22/windows-mobile-widget-101-a-gadget-side-note.aspx"&gt;A Gadget Side Note&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://community.softteq.com/blogs/nick/archive/2009/12/22/windows-mobile-widget-101-handling-form-factors.aspx"&gt;Handling Form Factors&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://community.softteq.com/blogs/nick/archive/2010/01/13/windows-mobile-widget-101-the-manifest-file.aspx"&gt;The Manifest File&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a title="Windows Mobile Widget 101 - Menus" href="http://community.softteq.com/blogs/nick/archive/2010/01/14/windows-mobile-widget-101-menus.aspx"&gt;Menus&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;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.&amp;#160; 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.&lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;code&gt;&lt;strong&gt;CradlePresent&lt;/strong&gt;&lt;/code&gt;&lt;/p&gt;    &lt;p&gt;A Boolean value indicating whether the device is cradled.&lt;/p&gt;    &lt;p&gt;&lt;code&gt;&lt;strong&gt;DisplayRotation&lt;/strong&gt;&lt;/code&gt;&lt;/p&gt;    &lt;p&gt;An integer value indicating whether the display is in portrait or landscape mode.&lt;/p&gt;    &lt;p&gt;&lt;code&gt;&lt;strong&gt;PhoneHomeService&lt;/strong&gt;&lt;/code&gt;&lt;/p&gt;    &lt;p&gt;A Boolean value indicating whether the device is presently registered on its home network.&lt;/p&gt;    &lt;p&gt;&lt;code&gt;&lt;strong&gt;PhoneOperatorName&lt;/strong&gt;&lt;/code&gt;&lt;/p&gt;    &lt;p&gt;A string indicating the name of the device’s mobile operator.&lt;/p&gt;    &lt;p&gt;&lt;code&gt;&lt;strong&gt;PhoneRoaming&lt;/strong&gt;&lt;/code&gt;&lt;/p&gt;    &lt;p&gt;A Boolean value indicating whether the device is currently roaming.&lt;/p&gt;    &lt;p&gt;&lt;code&gt;&lt;strong&gt;PhoneSignalStrength&lt;/strong&gt;&lt;/code&gt;&lt;/p&gt;    &lt;p&gt;An integer indicating the phone signal strength, expressed as a percentage of full strength.&lt;/p&gt;    &lt;p&gt;&lt;code&gt;&lt;strong&gt;PowerBatteryState&lt;/strong&gt;&lt;/code&gt;&lt;/p&gt;    &lt;p&gt;An integer indicating the current state of the battery, such as whether the battery level is critically low or if the battery is charging. &lt;/p&gt;    &lt;p&gt;&lt;code&gt;&lt;strong&gt;PowerBatteryStrength&lt;/strong&gt;&lt;/code&gt;&lt;/p&gt;    &lt;p&gt;An integer indicating the current battery strength, expressed as a percentage of full strength.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;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. &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;var systemState = widget.createObject(&amp;quot;SystemState&amp;quot;);      &lt;br /&gt;var cradledState = systemState.CradlePresent;       &lt;br /&gt;cradledState.addEventListener(&amp;quot;changed&amp;quot;, cradled);&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;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?&lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;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.&amp;#160; Of course if you don’t want your widget to run as a gadget you can eliminate quite a bit of the following code.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;-----------------        &lt;br /&gt;widget.js        &lt;br /&gt;-----------------&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;var WidgetAPI = function () {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // Code omitted as same as previous post        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; systemState: null,        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; stateEvents: null,        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; createSystemState: function () {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (WidgetAPI.systemState != null) return; &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (window.widget) {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WidgetAPI.systemState = window.widget.createObject(&amp;quot;SystemState&amp;quot;);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WidgetAPI.systemState = {};        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; getCradleState: function () {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WidgetAPI.createSystemState(); &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (!WidgetAPI.systemState.CradlePresent) {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WidgetAPI.systemState.CradlePresent = true;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return WidgetAPI.systemState.CradlePresent;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }, &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; listenForCradleStateChanged: function (callback) {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WidgetAPI.listenForStateChanged(WidgetAPI.getCradleState(), callback);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }, &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; getPhoneStrengthState: function () {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WidgetAPI.createSystemState(); &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (!WidgetAPI.systemState.PhoneSignalStrength) {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WidgetAPI.systemState.PhoneSignalStrength = 100;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return WidgetAPI.systemState.PhoneSignalStrength;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }, &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; listenForPhoneStrengthStateChanged: function (callback) {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WidgetAPI.listenForStateChanged(WidgetAPI.getPhoneStrengthState(), callback);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }, &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; listenForStateChanged: function (state, callback) {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (window.widget) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; state.addEventListener(&amp;quot;changed&amp;quot;, WidgetAPI.createSafeListenerCallback(callback));        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; entered: false,        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; createSafeListenerCallback: function (callback) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; try {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WidgetAPI.stateEvents = new Date();        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WidgetAPI.stateEvents.setTime(WidgetAPI.stateEvents.getTime() - 60 * 1000);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var func = function () {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (WidgetAPI.entered == true) return;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; try {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WidgetAPI.entered = true;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var lastInvoke = WidgetAPI.stateEvents;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lastInvoke.setTime(lastInvoke.getTime() + 1 * 1000);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (lastInvoke &amp;lt; (new Date())) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WidgetAPI.stateEvents = new Date();        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (callback &amp;amp;&amp;amp; callback != null) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; callback();        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; finally {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WidgetAPI.entered = false;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; };        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return func;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; catch (e) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; alert(e);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160; };       &lt;br /&gt;} ();&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;-----------------        &lt;br /&gt;Utils.js        &lt;br /&gt;-----------------&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;var Ping= {};       &lt;br /&gt;Ping = {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; img: null,        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; imgPreload: null,        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; timer: null,        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; success: null,        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; fail: null,        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; hasFailed: false,        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; init: function (imgUrl, pingCallback, failCallback) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Ping.img = imgUrl;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Ping.success = pingCallback;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Ping.fail = failCallback; &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Ping.imgPreload = new Image();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Ping.hasFailed = false;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Ping.imgPreload.onload = function () {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; clearTimeout(Ping.timer);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Ping.timer = null;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (Ping.hasFailed == false &amp;amp;&amp;amp; Ping.success != null) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Ping.success();        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }; &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Ping.imgPreload.src = Ping.img;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (Ping.fail != null) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Ping.timer = setTimeout(Ping.fail_to_ping, 10000);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }, &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160; fail_to_ping: function () {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; clearTimeout(Ping.timer);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Ping.timer = null;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Ping.imgPreload = null;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Ping.hasFailed = true;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (Ping.fail != null) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Ping.fail();        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;};&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;-----------------&amp;#160; &lt;br /&gt;Network.js         &lt;br /&gt;-----------------&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;var Network = function () {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; isConnected: false,        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; connectionTestUrl: &amp;quot;&lt;/em&gt;&lt;a href="http://www.builttoroam.com/ping.gif&amp;quot;"&gt;&lt;em&gt;http://www.builttoroam.com/ping.gif&amp;quot;&lt;/em&gt;&lt;/a&gt;&lt;em&gt;,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; lastPing: null,        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; minimumPingSeparationInSeconds: 30,        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; connectionStateChanged: null,        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; init: function (stateChangedCallback) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (stateChangedCallback &amp;amp;&amp;amp; stateChangedCallback != null) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Network.connectionStateChanged = stateChangedCallback;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WidgetAPI.listenForCradleStateChanged(Network.cradledStateChange);       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WidgetAPI.listenForPhoneStrengthStateChanged(Network.phoneStrengthChange); &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Network.testConnection();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }, &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cradledStateChange: function () {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Network.testConnection();        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; phoneStrengthChange: function () {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Network.testConnection();        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }, &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; testConnection: function () {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var pingOk = false;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (Network.lastPing == null) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pingOk = true;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var pingTime = new Date();        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pingTime.setTime(Network.lastPing.getTime() + Network.minimumPingSeparationInSeconds * 1000);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (pingTime &amp;lt; (new Date())) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pingOk = true;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (WidgetAPI.getCradleState() == false || WidgetAPI.getPhoneStrengthState() &amp;lt;= 0) {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; pingOk = true;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (pingOk) {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Network.lastPing = new Date();        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Ping.init(Network.connectionTestUrl, Network.connectionTestSuccessful, Network.connectionTestFailed);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }, &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; connectionTestSuccessful: function () {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var isConnected = true;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Network.setConnectedState(isConnected);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }, &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; connectionTestFailed: function () {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var isConnected = false;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Network.setConnectedState(isConnected);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Network.lastPing = null;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }, &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; setConnectedState: function (connectedState) {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (Network.isConnected != connectedState &amp;amp;&amp;amp; Network.connectionStateChanged != null) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Network.connectionStateChanged(connectedState);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Network.isConnected = connectedState;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; };        &lt;br /&gt;} ();&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;-----------------        &lt;br /&gt;Main.htm         &lt;br /&gt;-----------------&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;lt;div id=&amp;quot;isConnected&amp;quot;&amp;gt;N/A&amp;lt;/div&amp;gt;&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;-----------------        &lt;br /&gt;main.js        &lt;br /&gt;-----------------&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;function onLoad() {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; // Omitting code from previous post        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Network.init(connectionStateChanged);        &lt;br /&gt;} &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;function connectionStateChanged(isConnected) {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; var connected = $get(&amp;quot;isConnected&amp;quot;);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (isConnected == true) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; connected.innerHTML = &amp;quot;Connected!&amp;quot;;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; else {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; connected.innerHTML = &amp;quot;Not connected!&amp;quot;;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;}&lt;/em&gt;&amp;#160;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_7A060598.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_6FF1646D.png" width="184" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://community.softteq.com/aggbug.aspx?PostID=1593" width="1" height="1"&gt;</description></item><item><title>Windows Mobile Widget 101 - Menus</title><link>http://community.softteq.com/blogs/nick/archive/2010/01/14/windows-mobile-widget-101-menus.aspx</link><pubDate>Thu, 14 Jan 2010 21:43:13 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1591</guid><dc:creator>nick</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;Prior posts in this series:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://community.softteq.com/blogs/nick/archive/2009/12/20/windows-mobile-widget-101-getting-started.aspx"&gt;Getting Started&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://community.softteq.com/blogs/nick/archive/2009/12/21/windows-mobile-widget-101-start-menu-icons.aspx"&gt;Start Menu Icons&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://community.softteq.com/blogs/nick/archive/2009/12/22/windows-mobile-widget-101-a-gadget-side-note.aspx"&gt;A Gadget Side Note&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://community.softteq.com/blogs/nick/archive/2009/12/22/windows-mobile-widget-101-handling-form-factors.aspx"&gt;Handling Form Factors&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a title="Windows Mobile Widget 101 – The Manifest File" href="http://community.softteq.com/blogs/nick/archive/2010/01/13/windows-mobile-widget-101-the-manifest-file.aspx"&gt;The Manifest File&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;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). &lt;/p&gt;  &lt;p&gt;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.&amp;#160; 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.&lt;/p&gt;  &lt;p&gt;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.&amp;#160; Lets add a menu item that will toggle the visibility of this information.&lt;/p&gt;  &lt;p&gt;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.&amp;#160; This way we only need to toggle a single div, rather than each of the manifest information divs.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;-----------------        &lt;br /&gt;Main.htm         &lt;br /&gt;-----------------&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;lt;div id=&amp;quot;about&amp;quot; style=&amp;quot;display:none;&amp;quot;&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div id=&amp;quot;manifestVersion&amp;quot; class=&amp;quot;manifest&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; …         &lt;br /&gt;&amp;lt;/div&amp;gt;&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;-----------------        &lt;br /&gt;widget.js         &lt;br /&gt;-----------------&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // Creates a menu with specified label and click handler        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; createMenuItem: function (label, handler) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var mi = null;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; this.LAST_MENU_ID ++;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (window.widget &amp;amp;&amp;amp; window.widget.menu) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var mi = window.widget.menu.createMenuItem(this.LAST_MENU_ID);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (mi) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mi.text = label;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (handler) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mi.onSelect = handler;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else if (isGadget != true) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mi = document.createElement(&amp;quot;div&amp;quot;);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mi.innerHTML = label;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mi.text = label;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (handler) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mi.onclick = handler;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mi.id = &amp;quot;menu&amp;quot; + id;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return mi;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; //&amp;#160; Returns a menu item whose ID is specified         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; getMenuItemById: function (id) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var mi = null;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (window.widget &amp;amp;&amp;amp; window.widget.menu) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mi = window.widget.menu.getMenuItemById(id);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mi = $get(&amp;quot;menu&amp;quot; + id);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return mi;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; getMenuText: function (mi) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (window.widget &amp;amp;&amp;amp; window.widget.menu) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return mi.text;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return mi.innerHTML;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; //&amp;#160; 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.         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; appendMenuItem: function (mi) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (mi &amp;amp;&amp;amp; window.widget &amp;amp;&amp;amp; window.widget.menu) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; window.widget.menu.append(mi);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var right = $get(&amp;quot;rightSoftKey&amp;quot;);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; right.appendChild(mi);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; right.parentNode.style.display = &amp;quot;block&amp;quot;;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; //&amp;#160; 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.         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; appendSubMenuItem: function (parent, mi) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (parent &amp;amp;&amp;amp; mi &amp;amp;&amp;amp; window.widget &amp;amp;&amp;amp; window.widget.menu) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; parent.append(mi);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (parent.childNodes.length == 1) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var list = document.createElement(&amp;quot;div&amp;quot;);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; list.style.margin = &amp;quot;10px&amp;quot;;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; parent.appendChild(list);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; parent.childNodes[1].appendChild(mi);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // 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.         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; removeMenuItem: function (mi) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (mi &amp;amp;&amp;amp; window.widget &amp;amp;&amp;amp; window.widget.menu) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; window.widget.menu.remove(mi);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var right = $get(&amp;quot;rightSoftKey&amp;quot;);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; right.removeChild(mi);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // 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.         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; removeSubMenuItem: function (parent, mi) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (parent &amp;amp;&amp;amp; mi &amp;amp;&amp;amp; window.widget &amp;amp;&amp;amp; window.widget.menu) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; parent.remove(mi);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; parent.childNodes[1].removeChild(mi);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (parent.childNodes.length == 1) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; parent.removeChild(parent.childNodes[1]);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }, &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // Sets the softkey of the widget. Currently we supprt setting the left softkey and right soft key.        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // If there is an error setting the soft key, exception will be thrown. If the softkey index is invalid, exception will be thrown.         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; setSoftKey: function (mi, softkeyIndex) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (mi &amp;amp;&amp;amp; window.widget &amp;amp;&amp;amp; window.widget.menu) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; window.widget.menu.setSoftKey(mi, softkeyIndex);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // Sets the left softkey for the widget menu item         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; setLeftSoftKey: function (mi) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (mi &amp;amp;&amp;amp; window.widget &amp;amp;&amp;amp; window.widget.menu) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; window.widget.menu.setSoftKey(mi, widget.menu.leftSoftKeyIndex);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else {         &lt;br /&gt;&lt;/em&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var left = $get(&amp;quot;leftSoftKey&amp;quot;);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; left.appendChild(mi);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; left.parentNode.style.display = &amp;quot;block&amp;quot;;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // Sets the right softkey for the widget menu item         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; setRightSoftKey: function (mi) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (mi &amp;amp;&amp;amp; window.widget &amp;amp;&amp;amp; window.widget.menu) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; window.widget.menu.setSoftKey(mi, widget.menu.rightSoftKeyIndex);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var right = $get(&amp;quot;rightSoftKey&amp;quot;);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; right.removeChild(mi);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; right.parentNode.style.display = &amp;quot;block&amp;quot;;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // enable/disable a menu item         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; toggleMenuItem: function (id, on) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; var mi = this.getMenuItemById(id);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (mi) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mi.enabled = on;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;And of course we need to add code to main.js in order to actually create the menus:&lt;/p&gt;    &lt;p&gt;&lt;em&gt;-----------------        &lt;br /&gt;main.js         &lt;br /&gt;-----------------&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;function onLoad() {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; // Omitted code as it is the same as previous posts        &lt;br /&gt;&lt;/em&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160; createMenuItems();       &lt;br /&gt;} &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;// Create the&amp;#160; menu items       &lt;br /&gt;function createMenuItems() { &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160; // create Refresh as left soft key for the main page       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; createLeftSoftKey(); &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160; // create right soft key and its sub menu items       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; createRightMenuItems();        &lt;br /&gt;} &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;// create Blog link as left soft key       &lt;br /&gt;function createLeftSoftKey() {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; // Add the Back menu item and set it to disabled        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; var mi = WidgetAPI.createMenuItem(&amp;quot;Blog&amp;quot;, onNavigateToBlog);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (mi &amp;amp;&amp;amp; mi!=null) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mi.enabled = true;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WidgetAPI.setLeftSoftKey(mi);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }        &lt;br /&gt;} &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;function onNavigateToBlog() {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; window.open(&amp;quot;&lt;/em&gt;&lt;a href="http://community.softteq.com/blogs/nick&amp;quot;);"&gt;&lt;em&gt;http://community.softteq.com/blogs/nick&amp;quot;);&lt;/em&gt;&lt;/a&gt;      &lt;br /&gt;&lt;em&gt;} &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;// Add sub menu items to right soft key &amp;quot;Menu&amp;quot;       &lt;br /&gt;function createRightMenuItems() {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; // Add the Home menu item and set it to disabled        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; aboutMenu = WidgetAPI.createMenuItem(&amp;quot;About&amp;quot;, onAbout);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (aboutMenu &amp;amp;&amp;amp; aboutMenu != null) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; aboutMenu.enabled = true;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WidgetAPI.appendMenuItem(aboutMenu);        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;}&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;-----------------        &lt;br /&gt;Main.htm         &lt;br /&gt;-----------------&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;!-- Testing on desktop only --&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div style=&amp;quot;display:none;&amp;quot;&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; LEFT:        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div id=&amp;quot;leftSoftKey&amp;quot;&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/div&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/div&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div style=&amp;quot;display:none;&amp;quot;&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; RIGHT:        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div id=&amp;quot;rightSoftKey&amp;quot;&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div onclick=&amp;quot;window.close()&amp;quot; &amp;gt;Exit&amp;lt;/div&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/div&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/div&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/body&amp;gt;        &lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_225BD773.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_58E982B7.png" width="184" height="244" /&gt;&lt;/a&gt; &lt;a href="http://community.softteq.com/blogs/nick/image_3D6480B4.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_34284573.png" width="184" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_7168FA3A.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_49B25843.png" width="244" height="239" /&gt;&lt;/a&gt; &lt;a href="http://community.softteq.com/blogs/nick/image_54FB6C80.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_2267E941.png" width="244" height="239" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:8eb9d37f-1541-4f29-b6f4-1eea890d4876:f0c09bd1-33de-4af4-8691-4a8fd64dab4d" class="wlWriterEditableSmartContent"&gt;&lt;p&gt;&lt;div&gt;&lt;a href="http://community.softteq.com/blogs/nick/HelloWorldWidget2_456834E4.zip" target="_self"&gt;HelloWorldWidget2.zip&lt;/a&gt;&lt;/div&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://community.softteq.com/aggbug.aspx?PostID=1591" width="1" height="1"&gt;</description><category domain="http://community.softteq.com/blogs/nick/archive/tags/Css/default.aspx">Css</category><category domain="http://community.softteq.com/blogs/nick/archive/tags/Javascript/default.aspx">Javascript</category><category domain="http://community.softteq.com/blogs/nick/archive/tags/Menu/default.aspx">Menu</category><category domain="http://community.softteq.com/blogs/nick/archive/tags/Widget/default.aspx">Widget</category><category domain="http://community.softteq.com/blogs/nick/archive/tags/Windows+Mobile+6.5/default.aspx">Windows Mobile 6.5</category></item><item><title>Windows Mobile Widget 101 – The Manifest File</title><link>http://community.softteq.com/blogs/nick/archive/2010/01/13/windows-mobile-widget-101-the-manifest-file.aspx</link><pubDate>Thu, 14 Jan 2010 06:11:40 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1590</guid><dc:creator>nick</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;Prior posts in this series:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://community.softteq.com/blogs/nick/archive/2009/12/20/windows-mobile-widget-101-getting-started.aspx"&gt;Getting Started&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://community.softteq.com/blogs/nick/archive/2009/12/21/windows-mobile-widget-101-start-menu-icons.aspx"&gt;Start Menu Icons&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://community.softteq.com/blogs/nick/archive/2009/12/22/windows-mobile-widget-101-a-gadget-side-note.aspx"&gt;A Gadget Side Note&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://community.softteq.com/blogs/nick/archive/2009/12/22/windows-mobile-widget-101-handling-form-factors.aspx"&gt;Handling Form Factors&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;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 &lt;a href="http://windowsteamblog.com/blogs/windowsphone/archive/2009/08/12/widget-anatomy-the-manifest.aspx"&gt;Widget Anatomy – The Manifest&lt;/a&gt;, 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.&lt;/p&gt;  &lt;p&gt;Let’s start with the html page.&amp;#160; We’re just going to add some div tags into which the values from the manifest file will be inserted.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;-----------------        &lt;br /&gt;Main.htm         &lt;br /&gt;-----------------&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;&amp;lt;html xmlns=&amp;quot;&lt;/em&gt;&lt;a href="http://www.w3.org/1999/xhtml&amp;quot;"&gt;&lt;em&gt;http://www.w3.org/1999/xhtml&amp;quot;&lt;/em&gt;&lt;/a&gt;&lt;em&gt;&amp;gt;        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;head&amp;gt;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;title&amp;gt;Hello Widget&amp;lt;/title&amp;gt;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;!-- Javascript --&amp;gt;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;js/utils.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;js/widget.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;js/main.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/head&amp;gt;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;body onload=&amp;quot;onLoad();&amp;quot;&amp;gt;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Hello Widget World!         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;hr /&amp;gt;         &lt;br /&gt;&lt;/em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div id=&amp;quot;manifestVersion&amp;quot; class=&amp;quot;manifest&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div id=&amp;quot;manifestId&amp;quot; class=&amp;quot;manifest&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div id=&amp;quot;manifestName&amp;quot; class=&amp;quot;manifest&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div id=&amp;quot;manifestDescription&amp;quot; class=&amp;quot;manifest&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div id=&amp;quot;manifestAuthorEmail&amp;quot; class=&amp;quot;manifest&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div id=&amp;quot;manifestAuthorName&amp;quot; class=&amp;quot;manifest&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div id=&amp;quot;manifestAuthorURL&amp;quot; class=&amp;quot;manifest&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div id=&amp;quot;manifestHeight&amp;quot; class=&amp;quot;manifest&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div id=&amp;quot;manifestWidth&amp;quot; class=&amp;quot;manifest&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div id=&amp;quot;manifestLocale&amp;quot; class=&amp;quot;manifest&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;div id=&amp;quot;manifestIconSource&amp;quot; class=&amp;quot;manifest&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;       &lt;br /&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/body&amp;gt;        &lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Next, let us add code to widget.js to wrap the calls to the widget API:&lt;/p&gt;  &lt;blockquote&gt;&lt;em&gt;-----------------      &lt;br /&gt;widget.js       &lt;br /&gt;-----------------&lt;/em&gt;     &lt;p&gt;&lt;em&gt;var WidgetAPI = function () {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // gets the widget id&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; getId: function () {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (isGadget &amp;amp;&amp;amp; isGadget == true) return System.Gadget.path;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return window.widget ? window.widget.identifier : &amp;quot;&lt;/em&gt;&lt;a href="http://builttoroam.com/invalidid&amp;quot;;"&gt;&lt;em&gt;http://builttoroam.com/invalidid&amp;quot;;&lt;/em&gt;&lt;/a&gt;       &lt;br /&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; getVersion: function () {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (isGadget &amp;amp;&amp;amp; isGadget == true) return System.Gadget.version;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return window.widget ? window.widget.version : &amp;quot;0&amp;quot;;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // gets the widget name         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; getName: function () {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (isGadget &amp;amp;&amp;amp; isGadget == true) return System.Gadget.name;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return window.widget ? window.widget.name : &amp;quot;Not a Widget nor a Gadget&amp;quot;;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // gets the widget description         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; getDescription: function () {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return window.widget ? window.widget.description : &amp;quot;Default description....&amp;quot;;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // gets the widget author Information         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; getAuthor: function () {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (window.widget) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return { name: window.widget.authorName,         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; email: window.widget.authorEmail,         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; url: window.widget.authorURL         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; };         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return { name: &amp;quot;Nick Randolph&amp;quot;,         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; email: &amp;quot;nick@builttoroam.com&amp;quot;,         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; url: &amp;quot;&lt;/em&gt;&lt;a href="http://community.softteq.com/blogs/nick&amp;quot;"&gt;&lt;em&gt;http://community.softteq.com/blogs/nick&amp;quot;&lt;/em&gt;&lt;/a&gt;       &lt;br /&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; };        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // gets the widget height         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; getHeight: function () {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return window.widget ? window.widget.height : &amp;quot;n/a&amp;quot;;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // gets the widget width         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; getWidth: function () {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return window.widget ? window.widget.width : &amp;quot;n/a&amp;quot;;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // gets the widget locale         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; getLocale: function () {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return window.widget ? window.widget.locale : &amp;quot;unknown&amp;quot;;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // gets the current icon information for the widget         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; getIconInformation: function () {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return window.widget ? window.widget.currentIcon : { height: 0, width: 0, src: &amp;quot;n/a&amp;quot; };         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; },&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // The rest has been omitted as it is the same as in the previous post&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Now to update the main.js to iterate through the div tags and set their values:&lt;/p&gt;  &lt;blockquote&gt;&lt;em&gt;-----------------      &lt;br /&gt;main.js       &lt;br /&gt;-----------------&lt;/em&gt;     &lt;p&gt;&lt;em&gt;function onLoad() {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; // Code in this method omitted as it is the same as in the previous post         &lt;br /&gt;&lt;/em&gt;&lt;em&gt;&amp;#160;&amp;#160;&amp;#160; setupAboutInformation();        &lt;br /&gt;}&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;function setupAboutInformation() {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; updateManifestDiv(&amp;quot;manifestVersion&amp;quot;, WidgetAPI.getVersion());         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; updateManifestDiv(&amp;quot;manifestId&amp;quot;, WidgetAPI.getId());         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; updateManifestDiv(&amp;quot;manifestName&amp;quot;, WidgetAPI.getName());         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; updateManifestDiv(&amp;quot;manifestDescription&amp;quot;, WidgetAPI.getDescription());         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; var author = WidgetAPI.getAuthor();         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; updateManifestDiv(&amp;quot;manifestAuthorEmail&amp;quot;, author.email);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; updateManifestDiv(&amp;quot;manifestAuthorName&amp;quot;, author.name);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; updateManifestDiv(&amp;quot;manifestAuthorURL&amp;quot;, author.url);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; updateManifestDiv(&amp;quot;manifestHeight&amp;quot;, WidgetAPI.getHeight());         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; updateManifestDiv(&amp;quot;manifestWidth&amp;quot;, WidgetAPI.getWidth());         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; updateManifestDiv(&amp;quot;manifestLocale&amp;quot;, WidgetAPI.getLocale());         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; var icon =&amp;#160; WidgetAPI.getIconInformation();         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; updateManifestDiv(&amp;quot;manifestIconSource&amp;quot;, icon.src);         &lt;br /&gt;} &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;function updateManifestDiv(divName, information) {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; var div = $get(divName);         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (div != null) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; div.innerHTML = information;         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }         &lt;br /&gt;}&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;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).&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;-----------------        &lt;br /&gt;utils.js         &lt;br /&gt;-----------------&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;// gets the element from the dom        &lt;br /&gt;function $get(id) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return document.getElementById(id);         &lt;br /&gt;}&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Lastly, don’t forget to define the .manifest class in the css files (both high and low res):&lt;/p&gt;  &lt;blockquote&gt;&lt;em&gt;-----------------      &lt;br /&gt;highres.css &amp;amp; lowres.css       &lt;br /&gt;-----------------&lt;/em&gt;     &lt;p&gt;&lt;em&gt;.manifest        &lt;br /&gt;{         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; width: 100%;         &lt;br /&gt;}&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;And that’s it, now when you run it you will see information about your widget/gadget:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://community.softteq.com/blogs/nick/image_61D7F2BF.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_2A4231D1.png" width="184" height="244" /&gt;&lt;/a&gt; &lt;a href="http://community.softteq.com/blogs/nick/image_7CE09C00.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://community.softteq.com/blogs/nick/image_thumb_7ECDEB09.png" width="241" height="224" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:8eb9d37f-1541-4f29-b6f4-1eea890d4876:a9017998-a51d-4b87-b74e-9775235daa45" class="wlWriterEditableSmartContent"&gt;&lt;p&gt;&lt;div&gt;&lt;a href="http://community.softteq.com/blogs/nick/HelloWorldWidget_75F4C54C.zip" target="_self"&gt;HelloWorldWidget.zip&lt;/a&gt;&lt;/div&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://community.softteq.com/aggbug.aspx?PostID=1590" width="1" height="1"&gt;</description><category domain="http://community.softteq.com/blogs/nick/archive/tags/Css/default.aspx">Css</category><category domain="http://community.softteq.com/blogs/nick/archive/tags/Javascript/default.aspx">Javascript</category><category domain="http://community.softteq.com/blogs/nick/archive/tags/Manifest/default.aspx">Manifest</category><category domain="http://community.softteq.com/blogs/nick/archive/tags/Widget/default.aspx">Widget</category><category domain="http://community.softteq.com/blogs/nick/archive/tags/Windows+Mobile+6.5/default.aspx">Windows Mobile 6.5</category></item><item><title>New Development Certificates for Windows Mobile</title><link>http://community.softteq.com/blogs/nick/archive/2010/01/13/new-development-certificates-for-windows-mobile.aspx</link><pubDate>Thu, 14 Jan 2010 02:24:48 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1589</guid><dc:creator>nick</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;As indicated by Peter Foot’s post on &lt;a href="http://peterfoot.net/ExpiredDevelopmentCertificates.aspx"&gt;Expired Development Certificates&lt;/a&gt; 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 &lt;a href="http://windowsteamblog.com/blogs/wmdev/archive/2010/01/12/new-windows-mobile-developer-certificates.aspx"&gt;http://windowsteamblog.com/blogs/wmdev/archive/2010/01/12/new-windows-mobile-developer-certificates.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://community.softteq.com/aggbug.aspx?PostID=1589" width="1" height="1"&gt;</description><category domain="http://community.softteq.com/blogs/nick/archive/tags/Certificates/default.aspx">Certificates</category><category domain="http://community.softteq.com/blogs/nick/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://community.softteq.com/blogs/nick/archive/tags/Windows+Mobile/default.aspx">Windows Mobile</category></item></channel></rss>