Last Thursday I held a presentation at NNUG (Norwegian .NET User Group) in Trondheim. I talked about application development on the Windows Vista Platform.

Seen from a developer perspective, the platform is huge! There are lots of new API’s in this release of Windows. I picked out three features that I think will lift desktop applications running on Windows Vista to a new level; Sidebar, Desktop Search and RSS Platform.

Content from the presentation

Monday, May 14, 2007 3:35:27 PM (W. Europe Standard Time, UTC+01:00) 
  Permalink  |  Comments [2]  |  View blog reactions  | 

I just released an update for the VGNett Live Sidebar Gadget. The update has a very important feature; automatic update. The Gadget will now notify the users when a new update/version of the Gadget is available and give them the option to download the update.

Jonas tipped my about this yesterday at NNUG, thanks a lot! Automatic update is sweet :)

Download the new version by clicking on the link below.

Friday, May 11, 2007 4:24:32 PM (W. Europe Standard Time, UTC+01:00) 
  Permalink  |  Comments [0]  |  View blog reactions  | 

There is always a first time for something. I spent a couple of hours today developing my first Windows Vista Sidebar Gadget.

I love sports, especially European soccer. My favorite soccer club is Manchester United. Manchester is playing in Premier League, the top division in England. I try to follow them as often as I can. The problem is that not every match is sent on TV and I don’t have time to see all the matches on TV anyway.

There are several news papers in Norway that offer Live Stats from European soccer matches on their website, for instance VG and Dagbladet. All of them have nice AJAX enabled web apps that spits out live stats for me in the browser. I never need to refresh the website to get the updated content. They “magically” refresh themselves and when a team scores a goal a sound is played (ping) to notify the users. The problem with this is that I have to open the browser every time I hear this sound. By Live Stats I mean current events that happened during the matches. For instance when a team scores a goal, change formation, a player get a yellow card etc.

Wouldn’t it be really nice if you could glance at the live soccer stats in the Windows Vista Sidebar while working? – I think! Therefore I’ve developed a Windows Vista Sidebar Gadget with these features.

My Gadget gets the live match data from a Norwegian news papers (VG) website. The data is downloaded every 10 seconds. I haven’t had the chance to test my Gadget during soccer matches, because the first game is this evening. Manchester United is going to play against Chelsea. This is a huge match, and it’s my first opportunity to test this Gadget with live stats.

You are welcome to test my Gadget during this match. You can download it from the link below. Please give me some feedback if you are testing the Gadget this evening.


Creating of the Gadget

I developed my Gadget using Visual Studio 2005. I followed these steps during the development phase.

Step 1: Creating a directory

The installed Windows Sidebar Gadgets are localized in the “%userprofile%\AppData\Local\Microsoft\Windows Sidebar\Gadgets\” folder. I started the developed by creating a new folder “VGLive.gadget” in this folder. Note the .gadget “extension” in the folder name. Your folder must contain this “extension” in order to be visible for the Gadget Explorer.


Windows Sidebar Gadget Explorer 

Step 2: Create the content (HTML file)

The content of a Gadget html files, images and java scripts. I created new HTML file called docked.html. This file contains the content for the Gadget. 

<html xmlns="http://www.w3.org/1999/xhtml" >
    <head>
        <title>VGLive!</title>
        <link rel="stylesheet" 
              type="text/css" 
              href="stylesheets/docked.css" />
        <script type="text/javascript" 
                src="scripts/vglive.js"></script>
        <script type="text/javascript" 
                src="scripts/gadget.js"></script>
    </head>
    <body onload="startTimer(), init()">
        <div id="content">
        </div>
    </body>
</html>

 

Note that I have to JavaScript resources (vglive.js and gadget.js). The gadget.js script contains gadget specific functions. Here I specify which HTML to load for the settings screen.

The vglive.js JavaScript contains scripting logic for gathering Live Stats data from http://sport.vg.no/live website.

Step 3: Creating manifest

Then I created a XML file for the Gadget manifest. This file describes the Gadget package. Some of the properties are Name, version, description, icon, which file to start with etc. I specify that the Gadgets shall load the docked.html file when it starts.

<?xml version="1.0" encoding="utf-8" ?>
<gadget>
  <name>VG Nett Live!</name>
  <namespace>GOEran.Gadgets.VGLive</namespace>
  <version>1.0</version>
  <author name="Gøran Hansen">
    <logo src="images\goeran.jpg" />
    <info url="http://blog.goeran.no" />
  </author>
  <copyright>Last ned flere Gadgets på:</copyright>
  <description>
    Live oppdateringer fra VG!
  </description>
  <icons>
    <icon height="64" 
          width="64" 
          src="images\gadget-logo.png"/>
  </icons>
  <hosts>
    <host name="sidebar">
      <base type="HTML" 
            apiVersion="1.0.0" 
            src="docked.html" />
      <permissions>full</permissions>
      <platform minPlatformVersion="0.3" />
    </host>
  </hosts>
</gadget>


Step 4: Develop and test

It’s not efficient to test the Gadget implementation in the Sidebar. Because then you need to add the Gadget to the Sidebar in order to get it to reload itself. When you are finished testing you have to remove it. Then you must add it again the next time you have med some new changes – you get the picture.

I think the best way is to load Gadget HTML file into the browser and test the implementation there. When the functionality works properly you can start to add it to the Sidebar for environment testing.


Live Match data

My Gadget gets the data from the Norwegian news papers VG website: http://sport.vg.no/live/. This web pages show live stats from the currently playing matches that they cover. They usually cover most of the European soccer matches. Especially Norwegian and English premier league matches.

This is an AJAX enabled web page, which means that they use JavaScript to update the content of the page instead of refreshing the whole page. This made it pretty trivial for me to download the live stats data to the Gadget. Luckily for me I didn’t have to screen scrape the page and parse the HTML in order to get the data.

By using Fiddler to monitor HTTP traffic from my computer I could find the location from where the JavaScript on webpage download the data. The location is http://sport.vg.no/live/fun/xmlhttp.php?live2op=getDiff&postfix=1.

As you can is if you try to access this URL you get lots of JavaScript code in return. The type of the content in the response is “text/plain”.

currentEvents = new Array(10);
currentEvents[0] = new Array(6);
currentEvents[0][0] = '14866';
currentEvents[0][1] = 'Charlton';
currentEvents[0][2] = 'Spurs';
currentEvents[0][3] = new Array(12);
currentEvents[0][3][0] = '79';
currentEvents[0][3][1] = '0';
currentEvents[0][3][2] = '';
currentEvents[0][3][3] = "Charlton har ballen mye";
currentEvents[0][3][4] = "14866_tell_470";
currentEvents[0][3][5] = "0";
currentEvents[0][3][6] = "1";
currentEvents[0][3][7] = "1";
currentEvents[0][3][8] = "";
currentEvents[0][3][9] = "0";
currentEvents[0][3][10] = new Array(2);
currentEvents[0][3][10][0] = "";
currentEvents[0][3][10][1] = "";
currentEvents[0][3][11] = "14866_tell_460";
currentEvents[0][4] = "0";
currentEvents[0][5] = "2";


If you are a developer you probably notice that the returned JavaScript creates a multi dimensional array. My challenge was to figure out how to take advantage of that the content of the HTTP response was actually JavaScript – could I somehow load the downloaded JavaScript into the JavaScript runtime of the browser (Gadget) in order to traverse the array? Of course! This is the lovely part about dynamic languages!

If you look up the Function object in the JavaScript documentation you find out that JavaScript threats all functions as a data type that has a value. You can either return something or execute some code. This is not as efficient as the alternative method of declaring a function using the function statement where the code is compiled.

//Dynamically loaded hello code
var hello2 = new Function("window.alert('hello2');");
//Call compiled hello
hello();
//Call dynamic loaded hello (evualuted for every call)
hello2();
 
/* Compiled hello code */
function hello()
{
    window.alert("hello");
}


So what I did was to create a new instance of a Function object. Into the object is passed the JavaScript downloaded from http://sport.vg.no/live/fun/xmlhttp.php?live2op=getDiff&postfix=1 as an argument. And voila, I could traverse the array as it was an array I declared an instantiated myself.

/*
    Download live match data from VG Nett Live
*/
function getData()
{
    //Create a new instance of the XmlHttpRequest obj. 
    //This is used to download the data from the webside
    xmlHttp = new XMLHttpRequest();
    //The callback method to be called when state 
    //of the xmlHttp object is changed.
    xmlHttp.onreadystatechange = dataCallback;
    //The random number in the end of the url is used
    //to prevent the XMLHttpRequest from caching data.
    xmlHttp.open("GET",
        "http://sport.vg.no/live/fun/xmlhttp.php?" +
        "live2op=getDiff&postfix=1&" + 
        Math.random());
 
    //Send the request    
    xmlHttp.send();
}
 
/* 
    This method is called by the xmlHttp 
    object when executin web request
*/
function dataCallback()
{
    //Data downloaded
    if (xmlHttp.readyState == 4)
    {
        var data = xmlHttp.responseText;
 
        //Create a new Function object and pass 
        //the downloaded JavaScript into it
        var currentEvents = new Function(
            "var " + xmlHttp.responseText + 
            "return currentEvents;")();
 
        //Reverse the array 
        //(To get the newest events first)
        currentEvents.reverse();
        
        //Renders the output
        renderOutput(currentEvents, 4);
    }
}

You can get all the JavaScript code if you download the Gadget.


Tips for Gadget development

  1. Take a look at the Sidebar API http://msdn2.microsoft.com/en-us/library/aa965853.aspx.
  2. Separate the structure from layout. By this I mean use div tags in the Gadget content file (The HTML file). Use the ID and CLASS property of the tags so you can refer to them in the style sheets (CSS files)
  3. Separate JavaScript from the content. Add the JavaScript resources in the header of the Gadget content file (HTML file). I usually create on dedicated script for Gadget specific functions (gadget.js). By Gadget specific function I mean Sidebar API calls 
  4. Create a background image of type PNG for the Gadget to get transparency 
  5. Test the implementation in a web browser during the development phase 
  6. When you have reached code complete, test the Gadget in the Sidebar Environment.

Do you have any other tips for Gadget development; feel free to drop me a comment on this :)

Resources

 

Happy coding!

Wednesday, May 09, 2007 11:41:02 AM (W. Europe Standard Time, UTC+01:00) 
  Permalink  |  Comments [9]  |  View blog reactions  | 

Finally! I have updated my blog with a new layout. I’ve been working on this for the last couple of days, and it has been lots of fun. It’s a really long time since I’ve had the chance to challenge my esthetic senses and creativity.

I use DasBlog as blog engine. It runs on ASP.NET 1.1/2.0 and it’s developed in C#. DasBlog is an evolution of the BlogX blog engine originally written by Chris Anderson. The initial conversion from BlogX was created by Clemens Vasters when he was working at Newtelligence. It’s free BSD-licensed, easy to use and have support for the MetaWeblog API.

Design and implementation workflow

I started to design the new layout in Adobe Photoshop. When I had a design I was satisfied with I started to port the design to HTML.


I used Microsoft Expression Web to implement the layout in HTML. I had never used it before I started the work with the new layout and it really gave me a good first impression. Most of the work was in the CSS editor. The intellisense (code complete) in this editor was excellent. For instance when I had to specify the URL for a background image one of the choices for the value given by the instellisense was “Pick URL...”. When I selected this choice I got a File dialog to pick the image. Neat features like this gave me an impression that this is a piece of high quality software. Then I started the DasBlog implementation phase.

First I downloaded the latest DasBlog bits and set it up to run on my local computer. Then I started to port the HTML layout over to DasBlog “format”. This might sounds like a job for a monkey since I repeat the previous task, and it is. To use the DasBlog terminology I started to implement a theme.

The built-in themes are found in the “themes” folder in DasBlog. I just started to copy one of this and renamed it to “goeran”. Then I started to xcopy over the style sheets, javascripts and images from the implementation I did in Microsoft Expression Web.

DasBlog engine use templates to render the content. This templates have “.blogtemplate” as extension name. You should pay attention to homeTemplate.blogtemplate, itemTemplate.blogtemplate and dayTemplate.blogtemplate. The hometemplate renders the skeleton of the HTML page and the itemTemplate renders the post content. The relation between this templates are homeTemplate 1-1 dayTemplate 1-* itemTemplate.

The first job of creating a theme package was to copy the HTML from the previous implementation to the blogtemplates. This was a bit time consuming because of the cache options in the DasBlog engine. But after many hours of hacking I managed to create a DasBlog theme package from the HTML layout is designed with Microsoft Expression Blend.

This was a really nice workflow and I suggest the same for others that going to implement a new design for their DasBlog based blogs.

I’m wondering though if there is any packaging tool for DasBlog themes? I would be really neat if I could take the HTML implementation and convert it to a DasBlog theme. The tool could work like a code generator to generate DasBlog theme specific files based in the HTML implementation. The HTML implementation could consist of tokens to notify the packaging tool about it contents. For instance [BlogTitleLink] token in the HTML implementation notify the tool to create a <%SiteNameLink%> macro in the DasBlog template.

The new layout

This is the first version of the layout. During the summer I’m going to give it some few small upgrades.

I tried to design the layout using usability blog guidelines from Jacob Nielsen. One of the things I would like to point out is the photo of me in the upper right corner. This is the author photo. According to Nielsen this is suppose to give the readers a more personal impression of the author (me). This is illustrated in the picture below.

 
Blog header 

I’ve chosen to remove the Calendar as a navigation tool. Personally I never use this, and I think the “months archive” and the Tag cloud are way better for navigation. And I doesn’t post that frequently anyway that there need to be a timeline browsing for my posts.

I’ve bought a new domain, goeran.no. And added my blog is published under the sub domain name blog.goeran.no. I have a very common sure name (Hansen). It was impossible to get this domain name.

I’m still working on the author biography. According to Nielsen this is a simple matter of trust. Anonymous writings have less credence that something that’s signed. I also think this give a more personal touch over the blog. As well as information about the author, credentials and experience. The first thing I do when I read a new blog that’s interesting is wondering who the author is. Do you?

Mashups

I also mashed up with some online services. You have probably noticed 
(I hope) that there is a speech bubble over my author photo in the upper right corner. The text in the speech bubble is received from my Twitter account. Twitter is a social networking and micro-blogging service that allows users to send “updates” via SMS, instant messaging, twitter website or 3rd party applications. These updates are displayed on the user’s profile page and also instantly delivered to other users that have signed up to receive them. If you someday create a Twitter account my username is goeran (http://www.twitter.com/goeran). When I have short messages to my friends or some notice I would like on my blog I just post a new message on Twitter. I use a Windows Vista Sidebar Gadget to post new Twitter messages as well as monitoring my friends messages.

 

I’ve been a Flickr user for about a year now. Flickr is a photo sharing  service that allows users to share photos. I have of course mashed up with Flickr as well. My blog renders my 8 last photos on Flickr.

I also created a Technorati account. Technorati is an internet search engine that search blogs. What’s cool about Technorati is that it enables me to check if there have been some reactions on some of my blog posts. Since is a “Web 2.0” application is also have some nice API’s that can be use to integrate with. This enable me to show “blog reactions stats” in the bottom of the posts on my page. This is illustrated in the picture below.

 
Technorati blog reaction in the footer of my blog posts

 

I use Google Reader as RSS aggregator. There is to reasons why I  started to use it. It is accessible from mobile phones using WAP and it is easy to share blog posts items in feeds that I subscribe to. Other people can subscribe to these collated feed of shared items. I’ve inserted a snippet of JavaScript code into my blog that display my 5 last shared items. All my shared items are accessible from here.

The reason I think the sharing feature in Google Reader is neat is because it enable people with same interests to share subscribed blog items. I subscribe to Robert Scobles shared items, because we have lots of common interests and it seems like he spend a lot of time browsing feed items in the aggregator. He is kind of filtering out the good stuff and shares with other people. You can find his shared items here.

Tuesday, May 08, 2007 1:37:08 PM (W. Europe Standard Time, UTC+01:00) 
  Permalink  |  Comments [3]  |  View blog reactions  |