SCF intellisense

Wed, October 31, 2007, 02:59 AM under SideShow
It has been a while since I blogged anything about SideShow but it occurred to me recently that when I was throwing together the SCF XML for my SideShow screencast, I never used the schema to get intellisense for it because I was using the managed API. However, just because you can use the managed API to generate the SCF for you doesn't mean you cannot use the SCF schema to get intellisense and create the SCF that way (and then use the managed API to send it down). All you need is the XSD file and then to use Visual Studio's schema support.

Step 1: Get SCF schema from here. Plug it in as per usual and notice how you get compiler errors.
Step 2: Fix the error you get by changing this <xsd:complexType name="ItemType" mixed="true"> to this <xsd:complexType mixed="true">.
Step 3: At this point you notice that intellisense works great but it allows you to start with any element, and not just with the only legal SCF option which is body. Not being an XSD person I kindly asked the XSD Jedi to refactor the schema so it can only start with the body element – luckily he obliged.
Step 4: So intellisense worked fine at previous step (thanks Dave), but I still wanted to have comments. So I manually populated the schema with comments and now I have a really cool SCF XSD schema with rich intellisense:



Download the xsd here.

Sidebar + SideShow = Love

Fri, June 22, 2007, 01:35 AM under Windows | Vista | SideShow
In the past I have introduced Sidebar gadgets and have made a quite few blog posts on SideShow. What I've not done here is talk about the integration between these two. In this blog entry I'll assume you are familiar with both of them independently.

HOW:
The integration is about being able to send content from your Sidebar gadget to SideShow-enabled devices. Effectively, the SideShow gadget(s) running on Windows *is* the Sidebar process. So how do you SideShow-enable your Sidebar gadget? You add a bit to your manifest and the remainder modifications are all in javascript calling the SideShow methods of the Sidebar API:

1. Add an icon for SideShow to your Sidebar gadget manifest. In your gadget.xml file you already have an icon element under an icons element which is under the gadget element. You need to add another element named ico that points to your SideShow icon i.e.
   <icons>
<icon height="48" width="48" src="daniel.PNG" />
<ico src="SSnotification1.ico"/>
</icons>

2. Set a friendly name. Somewhere in your javascript make the following method call:
var friendName = "danielmoth.com"; //your data
System.Gadget.SideShow.setFriendlyName(friendName);
3. Add glance content. Whenever you want to update the glance data, make this call:
var glance = "Hello from Sidebar"; //your data
System.Gadget.SideShow.addText(0, glance);
At this point on your SideShow device you have something like this:

4. If you want to send SCF pages, use the same method as above, this time changing the id (first argument) as appropriate and making the 2nd argument hold the XML, e.g.
var scfXmlcontent = "<body><menu id='1' title='My menu'><item target='2'>I am a menu</item></menu></body>";
System.Gadget.SideShow.addText(1, scfXmlcontent);
So, on your previous screenshot if you now click on the SideShow's OK button you'll get the following:

Clearly, if you select the menu item then you'll get a "Page not found" message because we haven't send any other page with an id=2. I leave that as an exercise to you.

NOTES:
Of course, it would be great if whatever you render on your Sidebar gadget automatically got sent to the SideShow device but as you see above, that is not the case. However, the crucial part of building gadgets in general is getting the content that you want to show: you only need fetch that once and then you just need to package it twice (html for Sidebar and SCF for SideShow).

Note that if you want to send images that you reference by id in your SCF pages, then you must use the addImage API. When you visit the APIs, ignore their advice to check for the enabled method because it apparently always returns true. Also note that when you want to update the same content id, it is best that you call the remove method first and the send down the new content corresponding to the id. You should also not bother with notifications or events for combined gadgets, since the applicationEvent is non-functioning.

DOWNLOAD:
Should you wish to play with the simple sample I described here and you are too lazy to type it yourself, download this ZIP on your Vista machine and then execute the daniel.gadget inside it. To see a fully fledged proper gadget and not the Hello World demo I created, download the StocksPlus combined gadget (it is the Stocks gadget you have in your box, enhanced to support SideShow). Whichever gadget your download, first make sure the SideShow Simulator is running already! Enjoy :)

More SideShow devices

Sat, May 19, 2007, 03:40 AM under SideShow | Links
It looks like Dan's pit of cool toys is truly bottomless! If you thought the video from CES had a cool collection of SideShow devices, then check out this video from WinHEC.

VirtualSideShow

Wed, April 25, 2007, 11:06 AM under Windows | Vista | SideShow
At some point I must find time to continue my series of blog posts on the Windows SideShow technology that ships with Vista. But until then, if you've wanted to play with this stuff but couldn't be bothered to download the Windows SDK (shame on you btw!), now you have the option of downloading the Device Simulator as standalone (and it is a newer version too!). Go get it.

i-mate SideShow Debugger

Mon, March 19, 2007, 05:26 AM under SideShow
I haven't played with this yet but it looks promising for anyone with SideShow interest.

See announcement in SideShow forums and also the download site.

SideShow designer: ISV opportunity

Thu, January 18, 2007, 04:20 AM under Windows | Vista | SideShow
I am really pleased that Scott is jumping on the SideShow train :-)

Windows SideShow provides an opportunity for every manufacturer that has a device with a screen on it to SideShow-enable it. It also provides an opportunity for all application developers to extend the reach of their application by either directly calling the SideShow API from their existing app to send content to SideShow-compatible displays, or to write a new non-UI process (a SideShow gadget) that sends the content.

There is another opportunity here for ISVs. Provide a graphical designer for generating SCF, which application developers can then easily send down to the devices. Crafting SCF by hand or using the managed API’s Scf class is trivial but still not as smooth as using a graphical designer (a bit like designing Windows Forms without the designer or even closer a bit like crafting XAML by hand without "Sparkle"/"Cider").

So what are you waiting for? The schema is there, the elements (think controls) have only a few attributes (think properties) and there can only be a single element/control per row/line... show me what you can do!

UPDATE: The Microsoft.SideShow.dll (written by Jeffrey Richter) that I have been using in all my posts is now publicly available. Details here :-)

SideShow devices

Mon, January 8, 2007, 10:14 AM under Windows | Vista | SideShow
Just before leaving for CES, Dan Polivy recorded a short video for on10 showing off 8 SideShow-compatible devices: Asus laptop, LG Z1-p laptop, credit card companion device, remote controls from 3 different manufacturers and Logitech keyboard & speakers!

As always with cool gadgets words are not enough so check out the video and drool :-)

I wonder if the guy behind SideShowDevices will be posting pictures of all these soon...

UPDATE: Also spotted at CES, wearable SideShow device (thanks Keeron Modi for the heads up).

SideShow notifications and events

Fri, December 29, 2006, 08:44 PM under Windows | Vista | SideShow
When I introduced the SideShow gadget fundamentals, I listed 3 types of communication between the gadget running on the PC and the SideShow-compatible device. You know how to design your SCF content and then download it via the managed API. Here I will introduce notifications and events.

Notification
Sending a notification down to the device takes one line of code, given that you already have a ScfSideShowGadget reference as described before:
Icon ico = new Icon(@"C:\Users\Public\Pictures\SideShow\SSnotification.ico");
g.ShowNotification(
100, // unique content id
"some caption", // caption
"some message", // body
ico, // icon to appear on the far right of the body
TimeSpan.FromSecondss(30)); // timeout interval
Executing the above will result in the behaviour captured below on the SideShow simulator:

The notification will time out after the timeout period specified or the user can manually dismiss it with the ENTER button or, finally, you can programmatically dismiss a notification by its id e.g. g.RevokeNotification(100); or a more brutal approach g.RevokeAllNotifications;

Events
There are 9 events that you can handle programmatically on the PC-side while the user performs actions. The following code shows hooking up to them
g.AllDevicesRemoved += new EventHandler(g_AllDevicesRemoved);
g.ContentMissing += new EventHandler <ContentMissingEventArgs> (g_ContentMissing);
g.ContentNavigate += new EventHandler <ContentNavigateEventArgs> (g_ContentNavigate);
g.ContextMenuSelect += new EventHandler <ContextMenuSelectEventArgs> (g_ContextMenuSelect);
g.DeviceAdded += new EventHandler <DeviceCapabilityEventArgs> (g_DeviceAdded);
g.DeviceRemoved += new EventHandler <DeviceCapabilityEventArgs> (g_DeviceRemoved);
g.GadgetEnter += new EventHandler(g_GadgetEnter);
g.GadgetExit += new EventHandler(g_GadgetExit);
g.MenuSelect += new EventHandler <MenuSelectEventArgs>(g_MenuSelect);
- GadgetEnter, GadgetExit when the user navigates from the glance data page (id=0) to the SCF pages and back.
- DeviceAdded, DeviceRemoved, AllDevicesRemoved when SideShow-compatible device connect or disconnect from this gadget.
- MenuSelect, ContextMenuSelect when the user selects one of your menus or opens your contextmenus.
- ContentNavigate every time the user traverses from one SCF page to another.
- ContentMissing if a user action results in a request for a content id that is not on the device.

The event handler method signatures for these follow the standard .NET pattern of having two parameters. The first being the sender object and the second being a type that inherits from EventArgs. The following class diagram shows the EventArgs classes with their members so you can get an idea of the information you receive with each event mentioned above:


Stay tuned on this blog for more on SideShow gadget development in the new year ;-)

Gadget in C#

Tue, December 5, 2006, 02:53 PM under Windows | Vista | SideShow
Goal
Walk through all the code required to write the SideShow gadget that we designed and showed screenshots of here.

Prerequisites
1. SideShow
2. Gadget Fundamentals
3. Designing with SCF
4. Microsoft.SideShow.dll

Installation/registration revisited
When talking about the basics of SideShow gadgets you saw how we need to create the appropriate registry keys and run a command for the Gadget manager to notify the user. You can actually achieve all of those actions in managed code and specifically with one line of code (I’ve separated the parameters into their own variable to make the line of code self-explanatory):
bool registerForAllUsers = false;
Guid gadgetId = new Guid("{65EA3E9A-8F83-4139-8139-94DE7E4149B0}");
string startCmd = String.Empty;
string iconPathNameAndResourceId;
bool onlineOnly = false;
Guid? propertyPage = null;

GadgetRegistration.Register(registerForAllUsers,
gadgetId, ScfSideShowGadget.ScfEndpointId, "The Moth", startCmd,
iconPathNameAndResourceId, onlineOnly, GadgetCachePolicies.KeepOldest, propertyPage);
To uninstall/unregister the gadget we need another line of code
GadgetRegistration.Unregister(registerForAllUsers, gadgetId);

ScfSideShowGadget class
Writing a gadget in managed code begins by creating a ScfSideShowGadget object (that you must remember to Dispose when your gadget exits). The way the gadget is associated with the registration/installation metadata is via the use of the same gadget GUID, of course. The following code snippet demonstrates that:
  ScfSideShowGadget gadget = new ScfSideShowGadget(new Guid("{65EA3E9A-8F83-4139-8139-94DE7E4149B0}"));
// send content to device
Sending glance data
Sending glance data is simply one line of code:
gadget.AddGlanceContent("some short summary \r\n" + DateTime.Now.ToLongTimeString() + "\r\n http://www.danielmoth.com/Blog \r\n Even more text all the way to the \r\n bottom");

Sending Images
Any images rendered on the SideShow-compatible device must be sent there of course and their content ids can then be referenced from the SCF XML snippets. The following code shows sending of the images:
string path = @"C:\Users\Public\Pictures\SideShow\";
string b = path + "SSForest.jpg";
string d = path + "SSgarden.jpg";
string m = path + "SSmenu.jpg";
string r = path + "SSdive.jpg";
gadget.AddContent(MothImages.Background, ImageContentTransforms.None, new Bitmap(b));
gadget.AddContent(MothImages.DialogIcon, ImageContentTransforms.KeepAspectRatio ImageContentTransforms.StretchToFit, new Bitmap(d));
gadget.AddContent(MothImages.MenuIcon, ImageContentTransforms.ReduceColorDepth, new Bitmap(m));
gadget.AddContent(MothImages.RandomImage, ImageContentTransforms.None, new Bitmap(r));
In the code above, MothImages is a simple class for holding the integer image content ids (as opposed to hard coding them in the body of the code).

Sending SCF content
As you’ll recall from the introduction to SCF, each page is its own SCF body tag. When sending pages to the device, we make a single method call per page that we want to send: a different overload of the AddContent method we already saw above for sending images. The code that follows is what was used to create *all* the screenshots of my previous SideShow blog post:
gadget.AddContent(MainMenuPage); //MainMenuPage is a property that returns a string
gadget.AddContent(ContextMenuPage); // ContextMenuPage is a property that returns a string
gadget.AddContent(ContentPageA); // ContentPageA is a property that returns a string
gadget.AddContent(ContentPageB); // ContentPageB is a property that returns a string
gadget.AddContent(ContentPageC); // ContentPageC is a property that returns a string
gadget.AddContent(DialogPage); // DialogPage is a property that returns a string
The above piece of code assumes that the properties we pass into the AddContent method calls return the XML as we designed it last time. This could look something like this:
public static string MainMenuPage
{
get
{
string content;
content = File.ReadAllText("page1.xml");
return content;
}
}
In the code above, page1.xml would hold the XML of this SideShow screenshot.

SCF creation revisited
So the above few lines of C# code register our gadget, create it and send both glance data and content data! The only thing it assumes is that we have created the SCF XML in a file already (i.e. in page1.xml).

However, Microsoft.SideShow.dll offers a class (Scf) with static methods (Body, Br, Btn, Clr, Content, Dialog, Div, Em, Img, Item, Menu, Txt) each with appropriate overloads that accept as parameters the attributes you would set on an SCF XML element and returns the equivalent XML. So, if you don’t want to hand craft the XML, you can get some intellisense help doing so programmatically (still no graphical way though).
For example, recall the screenshot of this XML and page? Here is the code that can generate that:
    content =
Scf.Body(
Scf.Menu(MothPages.MainMenu, "Main Menu Moth", ScfSelectAction.Target,
Scf.Item(MothPages.SomeText, "Points to 1st content page"), // 1st overload
Scf.Item(MothImages.MenuIcon, null, MothPages.WithImage, "Click for 2d one"), //2nd overload
Scf.Item(null, MothPages.ContextMenu, MothPages.MixedText, "This adds to the context menu"), // 2nd overload with context menu
Scf.Div(),
Scf.Item(MothMenuIds.Open, MothImages.MenuIcon, null, MothPages.DialogExample, "Shows dialog"), //3rd overload
Scf.Item(null, MothImages.MenuIcon, true, true, null, MothPages.MixedText, "IsDefault and points to 3rd content page"), // 4th overload
Scf.Item(null, MothImages.MenuIcon, false, false, null, MothPages.DialogExample, "I am !enabled"), // 4th overload, default & enabled
Scf.Btn(DeviceButton.Right, "Won't show up", MothPages.ContextMenu)
)
);
In the code above, any class starting with Moth is a simple class for holding the integer content ids. As a further example, the following screenshot shows some SCF XML and the c# code required to generate it (for the two pages that look like this and like that):

What’s left
Tons of stuff :-D
There are many more developer capabilities that we haven’t talked about on the SideShow platform and, instead of introducing them generically, I’ll introduce them as part of the managed API over subsequent posts... or maybe I should wait until we make Microsoft.SideShow.dll publicly available before doing so... let me know if you’d like to learn about it beforehand regardless...

Designing SideShow gadgets with SCF

Thu, November 30, 2006, 02:35 PM under Windows | Vista | SideShow
Please read the intro to SideShow and the SideShow gadget fundamentals posts as they provide essential background to this post.

Glance data
Your gadget may send to the SideShow device a complex UI and various navigation structures between pages of your UI. Regardless of whether it does that, it must first send what we call glance data. This is just plain text, and it is the text that appears next to your gadget icon when the user browses the gadgets on the device. Examples of glance data for the Windows Media Player, Picture Viewer, Windows Mail and our gadget, you can see in the following screenshot:


Simple Content Format (SCF)
Simple Content Format (SCF) is a simple XML format. It is used to describe pages and the elements on a page (except of course the very first glance data page which we established is plain text) including how everything maps to the buttons on the device. For an overview of SCF, click here.

When we look at the API later, we'll see that we send XML fragments to the device and each XML fragment represents a page.

Pages
A page is what is displayed on the SideShow device. For Windows Forms developers, think of this as the equivalent to a Form, except there is no designer and the way we describe what the page contains is via the SCF (which as I said is just XML, in this case an XML element that can contain other XML elements). All pages have a unique content id. Page types can be: content, menu, dialog.

For more, see SDK for body, content, menu and dialog.

Page Items
Elements on a page are the things that end users see on a page on the display (and the things that sometimes the hardware button actions apply to). For Windows Forms developers, think of this as the equivalent to WinForms Controls, except we don't drag and drop them on the page and the way we add them is via the SCF (they are just XML elements). Each element must have a unique content id. There can only be one element per (imaginary) row on the display, a bit like the guidelines for Smartphone development. These elements can be: menu item, button, image, text and blank lines.

For more, see SDK for item (including div), btn, img, txt (including clr and em), br.

Buttons
SCF-compatible SideShow devices must have at least 5 physical buttons: UP, DOWN, ENTER, BACK and MENU.
- UP and DOWN have a fixed function of navigating up and down a menu page (or a context menu) and scrolling up and down a page that shows a vertical scrollbar.
- MENU shows a fixed built-in context menu [Back, Home] but you can also add your own menu items above the 2 built-in ones.
- BACK returns to the previous page. The BACK button can also be overridden if you desire to do something specific to your page.
- ENTER (aka SELECT aka OK) takes whatever action you have assigned to a menu item. The ENTER button can also be overridden if you desire to do something specific to your page. Also, the ENTER button is what navigates from the glance data page to your first real (SCF) page.

The other two buttons that may be present on an SCF device are LEFT and RIGHT. If they are present, you can also assign to them custom actions relevant to your page (but also provide those on the context menu of the page in case they are missing).

Just FYI, for non-SCF devices you can also have buttons for PLAY, PAUSE, STOP, REW, FF.

Images
Note that in addition to the glance data and in addition to XML representing each page, we can also send images (with their own content id of course) that can be referenced from pages and elements.

Mapping SCF to screenshots
If you followed the links to the SDK that I provided previously, you can read all about what SCF element combinations are allowed, what attributes each element accepts for configuring its appearance/behaviour etc. Let's see how easy the SCF is by mapping the XML to the screens they result in.

1. In the screenshot below you can see a menu page with 6 menu items and a divider line after the 3rd menu item. The content id of this page is 1.

Notice how the XML elements map to the screen elements?
- Most menu items have their imgid set to a content id that represents an image that we have also sent to the device (along with the XML) - the 1st and 3rd menu items do not have this attribute and hence there is no icon next to the text for them.
- Looking at the XML you can tell that the 5th menu item is the default one that would be preselected when this page was loaded.
- The last menu item is disabled (its appearance doesn't show that, but if you hit ENTER after selecting it, nothing happens!).
- The 3rd menu item has an attribute that the others don't: menuid. This means that if we press the MENU button after selecting this menu item, the context menu will include menu items that we specified on another page with a content id of 6. If we press the MENU button on any other menu item, just the default built-in context menu will appear.
- Pressing the UP and DOWN buttons navigates up and down the menu structure.
- Pressing the ENTER button will navigate to the page that has a content id equal to the target of the menu item (see the XML in the screenshot).
- Finally, notice how there is a btn element in the XML. This does not show on the content page, but if we hit the RIGHT button it will navigate to whatever has a content id of 6 e.g. another page.

2. In the screenshot below you can see a content page with 3 text elements and an image element after the 2nd text element. The content id of this page is 2 (so this will appear when on the previous menu page we select the 1st menu item and we hit ENTER).

Notice in the XML how the text attributes align and rgb control the alignment and colour of the text. Notice how the image element references an image with id 21 that we must have also sent down to the device.

3. In the screenshot below you can see another content page with just one text element. The content id of this page is 3.

- This shows wrapping in action for the text element (wrap="1"). If that was not set then the text would have been chopped off. In the XML we also see a button element.
- This is not shown on the screen but if we hit the ENTER button then we would navigate away from this page and on to the page with a content id of 4. If this button element was not in the XML, then hitting the ENTER button would not do anything.
- Observe how the content element also specified the bg attribute pointing to content id 31. Clearly content id 31 must be another image that we sent to the device and it is now set as a background to this page.
- Also notice the menuid attribute of this content page: 6. So we must have defined a menu page with a content id of 6 that will be merged with the default context menu when we press the MENU button.

4. In the screenshot below you can see the final content page of this gadget, with two text elements separated by two blank lines. The content id of this page is 4.

This page demonstrates that text elements can have two other nested elements that allow the same line of text to have mixed colouring and emphasis.

5. In the screenshot below you can see our first (and only) dialog page with two text elements and 3 buttons. The content id of this page is 5.

What we see here is that for dialog pages, the buttons can appear on the screen (except if the button element is assigned to the BACK button). Also, the dialog element has an attribute for an image that it will insert before any other element (something like a banner).

6. In the screenshot below you see a menu page with a single menu item. The content id of this page is 6.

Do you recall above, that content page with id of 3 had specified as its menuid the content id 6? If you press the MENU button on that page, it is the screenshot above that will appear. Our menu item is merged with the default context menu. Note that if you hit the RIGHT button on the first menu page we described, then a full screen menu page will appear with just the single menu item we define here.

Tool support
I encourage you to study the built-in gadgets with the knowledge you gained above and mentally map the elements you see on the screen to the SCF elements. Note that the two games in the simulator are not gadgets (hence they don’t appear in the control panel), instead they are built-in NETMF applications.

There is no tool for designing the UI of the content that your gadget will send down to the device. This is a great opportunity for some smart individual to create one! How hard would it be to have a GUI designer tool that spits out valid SCF? ;-)

Regardless of how the SCF gets created, each page (i.e. each complete body element) has to be sent down to the device. Once sent, you can update it from your gadget periodically or when your data on the PC has changed. As an example, the Media Player gadget sends every 1 second a page with the same content id to the device. The only thing that changes on that page is the progress duration of the song. So how do we send SCF to a SideShow-compatible display?

Native API
There is a native COM API for those still living in that world :-)

If you do want to mess with the ISideShowSession, ISideShowContentManager, ISideShowContent and their friends then here is my top tip: There are 4 different sample SideShow gadgets in the SDK. They all use the COM API so you can explore them. In fact, the Picture Viewer gadget I linked to earlier is pretty much the same as the one in the SDK.

Managed API
That will be shown next time - honest!

SideShow gadget fundamentals

Wed, November 29, 2006, 08:14 AM under Windows | Vista | SideShow
In a previous post I described the new Windows Vista feature: SideShow. Please read that as I will assume that you have done so since it helps if you perceive the terminology and concepts in the same way that I do :-)

Gadget and SideShow device interaction
Remember that gadgets are just applications running on your laptop/PC that send data to a SideShow-compatible device. The gadget does not run on your actual auxiliary display. If you ever read "browse different gadgets on your SideShow display" you can interpret that as "browse the contents that the various gadgets from your laptop send to your SideShow display".

At a high level think of the gadget communications being one of the following (I cover these later):
- Gadget sends a message with content to the device.
- Device may optionally send event back to the gadget (e.g. at a click of a hardware button).
- Gadget may optionally send a notification to the device.

SideShow target
Before you write a SideShow gadget it helps if you have a target to test it on. If you have a real device great, otherwise your best friend is the SideShow simulator, which comes with the Windows SDK. Different SideShow devices will have different capabilities. At the most basic think about a 2-line monochrome text display with no hardware buttons. For this device you can only update it with text. At the other end of the spectrum, devices may understand the iCalendar format so you can send calendar data to it (e.g. the simulator and any full NETMF implementation) and it will interpret it in a rich manner. You can even plug custom content formats for your own SideShow-compatible device. Having said that, most devices will understand the Simple Content Format (SCF) , a device-independent XML format which is core to SideShow (I cover this later). There are APIs for querying at runtime the capabilities of the SideShow target(s) that the user has connected. In everything I write/do, I am going to assume that the target supports the SCF (e.g. the simulator does).

Gadget installation
Usually installation is left as the last thing you learn in any application development, but in this case it is important to understand this first as you will have to install the gadget even on your own dev machine before you do anything (and by "anything" I mean run it, debug it etc).

Gadget installation is simply a collection of registry entries in the right place (think of these as 'gadget metadata'). For example, for the built-in gadgets you can browse their registry entries by navigating to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SideShow\Gadgets. Under there you will find keys that are basically GUIDs. Every gadget has its own application GUID that the developer must generate (I buy mine from uuidgen or guidgen). Under each GUID, there are various values that describe the gadget. The following screenshot shows the registry entries for one of the Outlook 2007 gadgets:

This one shows the Picture Viewer gadget (available from the online gallery):

I also have registry screenshots of the 2 built-in gadgets if you are away from your Vista box right now: Windows Media Player and Windows Mail.

When you deploy your gadget to other computers, you'll have a setup program of some sort to do this for you but for now let's add the registry entries for our gadget manually. Of course, we will install it for the current user only, here: HKEY_CURRENT_USER\Software\Microsoft\SideShow\Gadgets (i.e. same path as above but instead of HKLM we go to HKCU).

First create a key under the Gadgets key with your own guid for your gadget (TIP: at the end of all this, if you want to remove the gadget simply delete this key!).

Under that key, we need to specify the following:
1. Endpoints that we support. I will only support the SCF endpoint: {A9A5353F-2D4B-47ce-93EE-759F3A7DDA4F}
2. FriendlyName. Mine will be "The Moth"
3. OnlineOnly (i.e. content is not cached on device, and computer must be on). Mine will be only online: 1
4. Icon. Nothing for me, so it will get the default.
This is what your registry should look like after doing the above:

If you were doing all of the above in an installation program, you should also run at the command line the following to invoke the Gadget Manager for a better user experience:
Schtasks.exe /run /tn Microsoft\Windows\SideShow\GadgetManager

Try it manually! You’ll see the following screenshot:

If you click on that notification (which is what your users would have seen) it will take you straight to the SideShow control panel. To be honest, you can go straight to control panel after you made the registry modifications and refresh. Your control panel should now look something like the following screenshot:

(my additional device column is irrelevant for now, I’ll talk about that later).

Hopefully you are running your simulator. Check the box next to the gadget under your simulator and notice how the gadget is available to use. See following screenshot of what it should look like on the simulator:


What is left?
So now all we need is a windows process for our gadget. That is easily found: Either create a brand new GUI exe or a console EXE or a blind exe or use an existing exe.

Once we have an EXE, then all we need is to write some code in there that calls the relevant APIs to send content down to the device. Before we do that though let’s think what that content should depict. In other words, what should the UI of our application look like?

NOTE: Where it now says "(No information availalbe)", we should have our first text content. When the user clicks on OK, we should show a full page of more content etc.

This blog post is getting long already so in my next SideShow blog entry we'll design in SCF a few pages with elements, and also see how to send that down to the device using the SideShow API.

Vista: SideShow

Mon, November 20, 2006, 09:14 AM under Windows | Vista | SideShow
I've very briefly mentioned SideShow recently here. My first intro was at MEDC and you can watch that session (APP322) for free (note that Viji is no longer with the team).

"Side what?"
SideShow is a new Windows Vista platform. It enables a variety of auxiliary display devices to be connected to Vista so they can display information from applications running on Vista. In some cases from the display you may control applications running on Windows.

For the information to be exchanged between the display and Windows, developers must write a SideShow gadget (note that this actually runs on the OS, not the display!). The gadget can gather the data from anywhere it wishes and then using the SideShow APIs can send it to the display (more on this later).

"What display(s)?"
So what display are we talking about here? The example that has become synonymous with SideShow (to the extent where most people miss the point and think it is the only SideShow implementation!) is the in-lid attached laptop display. This implements SideShow fully, is connected to Windows via USB (even though it is embedded in the display) and the driver for it ships with Vista. For those that are curious, it is actually running the .NET MicroFramework.

Other display examples would be a phone, a remote control with built-in screen, a keyboard with built-in screen, wearable display devices, music players, digital picture frames, insert your own hardware/display here etc. Photos of examples of these you can see in various articles by searching the web. Remember, these can be connected to Vista with any protocol they want (e.g. bluetooth, IR, proprietary etc).

"Why?"
So, previously, to connect a display to Windows you would have to choose a transport, implement the display-side of things, implement some custom protocol for exchanging data between OS and display, and then finally, implement a custom Windows-side application/driver for gathering and sending the data. SideShow, standardises all of this. In particular, as developers, you just need to learn the SideShow API and call it from your gadget and then whatever other hardware becomes available that supports the SideShow infrastructure will automatically work with your gadget!

It’s a bit like those dual display phones. You don't have to flip the phone open to see what you want; you can just glance at the smaller outer display and get the information you quickly need. Your imagination is the only limit to writing great on-line gadgets. SideShow devices can also work when your computer is off (using cached data)! You can even schedule Windows to wake up periodically so the cached data gets refreshed if that is applicable in your scenario. You could control a powerpoint presentation from your mobile phone (and that can be any phone not just Windows Mobile, as long as there is a SideShow driver for it). You could have small displays on the PC towers in a server room, glance at data on the box there rather than having to remote connect. For other ideas, again just search.

Personally, I can see a lot of killer ideas manifesting themselves on the SideShow platform once more devices become widely available. Be one of the first to get there by extending what your application can do, with a companion SideShow gadget.

"Not quite sure I get it, tell me more"
- A short blurb for SideShow from a consumer perspective can be seen here.
- If you have the time, watch this channel9 video (featuring Dan Polivy) that explains all of the above much better.
- Subscribe to the SideShow blog for more info as it becomes available.

"OK, I am hooked. How do I write gadgets?"
First, you can browse the gadgets and SideShow devices you already have on your Vista machine. Simply go to the "Control Panel", select "Hardware and Sound" and then "Windows SideShow": it should look something like this. Then install the simulator which will make your panel looks something like this.

You can very easily write gadgets (essentially just an exe on your Vista machine). Remember, they are separated from the communication protocol and from the actual target display so you only have to do two things:
1. "Design" your screens (they will be represented in XML)
2. From your gadget, call the API that sends the XML to the device

All you need to know is in the SideShow SDK. Soon I'll show you how to build a simple gadget in C#. Stay tuned :-)