The QuickMailr Gadget
The example gadget described in this article is called QuickMailr
, which lets you email yourself or someone you know a link or a short text messagewithout having to open your email application. It has two text boxes: an address field into which users enter the "To" address, and a message field into which users paste a link or a short text message (see Figure 1
|Figure 1. QuickMailr Gadget: The figure shows the QuickMailr gadget running in the Windows Sidebar.|
You can download the full source code
for this gadget to follow along with the rest of this article.
Technically, you could paste an entire novel into the message fieldI didn't limit the input sizebut as written, it would be a bit painstaking to try to proofread before sending, because the display area is so small. Microsoft recommends that gadgets should be no larger than 130 x 200 pixels. This helps keep them handy, while still allowing room for other gadgets. The gadget API doesn't expose any innate ability to send email, so I had to write an ActiveX control to take care of that part.
When I say ActiveX, you might think I mean ATL and C++. Fortunately for those who have been spoiled by the straightforward, garbage-collected, managed code environment of the Common Language Runtime, you can do this in plain old C# by taking advantage of COM Interop to leverage a .NET component as a COM-visible entity. Rather than trying to explain the gory details (though that's not to say they aren't important to understand), I'll just present an example that all but eliminates the need to consider exactly how the Interop process works.
A Consistent Platform
A key point is that the Sidebar provides a consistent platform host for DHTML applets. Unlike web-delivered applets, you won't have to write different versions or test for different conditions to support a variety of platforms. The Sidebar treats script and HTML exactly as Internet Explorer (IE) would; in other words, all the features available to IE, including ActiveX, are available to gadgets. I'm going to defer showing the ActiveX control implementation for the moment, but I'll come back to it later.
After the manifest, the next most prominent feature of a gadget is the HTML file itself. It bears the file name that is specified in the manifest, (gadget.html
tags, but you can import it in the usual HTML fashion as well.
Flyouts and Settings
|Figure 2. QuickMailr Flyout: The flyout appears when users click the "About" link next to the Send button.|
Gadgets bring to the table several idioms that are truly new. Every gadget can have a settings document. The settings document is another HTML page that allows users to configure the gadget. In my example, the settings.html
file holds the settings for the SMTP server information used by the mailer. Gadgets also introduce the concept of "Flyouts," which are panels that "fly out" from the main gadget upon some user action. A flyout panel is simply another HTML template file, and there are no limits on their size or shape; however, Microsoft recommends that you not make flyouts a necessary feature of gadget operation. So, a flyout can be an "About" box or a "detail view" but should not be something that users must see or manipulated for the normal gadget operation. The simple flyout example shown in Figure 2
link triggers it) is nothing but a shameful promotion of myself.
You specify flyouts by setting the System.Gadget.Flyout.file
property to the path of the HTML file, and make them visible by setting the System.Gadget.Flyout.show
property to true
System.Gadget.Flyout.file = "about.html";
System.Gadget.Flyout.show = true;
The Sidebar host automatically provides a way to show and hide the settings panel; all you have to do to set it up is tell the System.Gadget object where to find your settings HTML file. Here's an example:
System.Gadget.settingsUI = "settings.html";
The last fully new feature, which you've just seen a peek of, is the System.Gadget and other related API enhancements available from the Sidebar environment. You don't have to do anything out of the ordinary to use the API; the host makes it directly available to your scripts without you having to specify any include files or link any external libraries. The Gadget API has methods that allow you to work with CardSpace contacts, hardware statistics, and performance data as well as a way to persist your gadget's particular settings to an INI file.
The other interesting bit of the example gadget is the persistent settings. The System.Gadget.Settings class has four methods that allow you to store your gadget specifics. That's not quite as great as it sounds, because the data disappears as soon as you remove your particular instance of the gadget from the host (when you close it). At one level, that makes sense, because theoretically you could have multiple instances of the same type gadget, and you wouldn't want them fighting with each other over settings storage. But when you make only one instance of your gadget available, having persistent settings makes sense.
Here's a snippet that will store settings read from a form field using the API:
// From settings.html in the <a href='#codeitemarea'>downloadable</a> code.
Here you can spot another "feature" of the native Microsoft version of scripting. I can refer to defined HTML form fields using standard (X)HTML as if they were objects. There is no need to repeatedly use document.getElementByID
in this environment. If you write your script in Visual Studio or Visual Web Developer, you'll notice that Intellisense kicks in when you enter the name of an element on the page, and auto-completes as if you had declared the elements as actual objects. Reading the values back into the form is also a snap, as shown below.
// From settings.html
SMTPServer.value = System.Gadget.Settings.readString("SMTPServer");
SMTPPort.value = System.Gadget.Settings.readString("SMTPPort");
SMTPUser.value = System.Gadget.Settings.readString("SMTPUser");
SMTPPass.value = System.Gadget.Settings.readString("SMTPPassword");
FromAddy.value = System.Gadget.Settings.readString("FromAddy");
So you've had a quick glance at the underpinnings of gadgets and the Sidebar; now it's time for you to see one in action. You can accomplish many things with only normal script and HTML, especially when you add in the gadget API; however, you can do even more by writing an ActiveX control and using that to do any additional heavy (and possibly privileged) lifting that you can't accomplish with simple script.