Click here to Skip to main content
15,867,308 members
Articles / Programming Languages / C#
Article

Thumbnailgadget: Windows Vista API meets the Sidebar

Rate me:
Please Sign up or sign in to vote.
4.28/5 (23 votes)
23 Jan 20077 min read 72.5K   1.5K   29   10
Most Sidebar Gadgets are simple scripts. The Sidebar, though, the has potential to host any application, even if it uses the native API. This demo gadget allows you to preview any window using the Sidebar.

Sample Image - ThumbnailGadget.jpg

Introduction

It is quite difficult to write an article that uses so many technologies. At first, Windows Vista Sidebar gadgets seem simple sripts, but when you try to create a more complex application you realise that there realy is nothing to stop you, just that you must have the necessary knoledge.

Here is a list of domains in which you should have basic knoledge. If you don't, then don't worry, I will explain everything in detail:

  • creating a Vista Gadget
  • XBAP applications and permissions
  • Vista native API
  • ClickOnce deployment

If you need more info on a subject, just check out the bibliography at the end. About each subject, I left a few details for you to discover on your own, as exercises, they are stated after each paragraph. Or you could just look at the code...

The problem

Vista introduced a feature called live thumbnails. Just pause your mouse over a taskbar application and a small preview of the window will appear. that is not an ordinary preview, it is a live and animated one; if the window is a movie, then you will see the action as it evolves. When I work, I sometimes find myself in a situation of constantly checking the status of a window. Like when I wait for an installation to finish copying files, or when I wait for the movie to reach a certain point. Sometimes I just like to see a smaller image of a window that is on my second monitor, on my first. Doing this with live thumbnails means constantly moving the mouse and pausing over the taskbar, resulting in a loss of productivity. The gadget I created allows you to keep a preview of a chosen window always on top of your desktop.

Access native APIs from .NET

It is clear that, at least until .NET 3.5 is released, offering more managed wrappers to Vista native APIs, we will need to access those APIs directly. This is called Platform Invoke or, shorter, Pinvoke. The API we will use is called the Desktop Window manager and the dll it is located in is called dwmapi.dll. This dll offers some functions for use in your own code. We are interested in the following:

  • the function that tells Windows that I want to see the thumbnail of a window [DwmRegisterThumbnail],
  • the function that configures how and where I want that thumbnail to be [DwmUpdateThumbnailProperties],
  • the function that tells Windows that I am not interested in receiving the thumbnail any more [DwmUnregisterThumbnail].
  • the function that allows to extend the Windows Vista Glass effect on a whole window (check Bibliography and also the Exercises).

To use these function in a managed language, we must declare them first, like this:

C#
DllImport("dwmapi.dll")]
static extern int DwmUpdateThumbnailProperties(IntPtr hThumb, 
                                       ref DWM_THUMBNAIL_PROPERTIES prop);

Notice that we use the DllImport attribute that tells the compiler where exactly is located the function we need. For this to work, we need to include the following line:

C#
using System.Windows.Interop;

Then we can simply call the function we declared as if it were in our project. A note about structure usage, though. In windows, native structures do not share the same layout in memory as .NET structures, so if you ever need to pass a more complex parameter to an API function, the structure declaration should be preceded by an attribute specifying the layout, like this:

C#
[StructLayout(LayoutKind.Sequential)]
internal struct DWM_THUMBNAIL_PROPERTIES
{
public int dwFlags;
public Rect rcDestination;
public Rect rcSource;
public byte opacity;
public bool fVisible;
public bool fSourceClientAreaOnly;
}


Exercise: Try to understand how I created the window on which the thumbnails are displayed. I extended the windows Vista glass over it. What native APIS did I use there?

Creating an XBAP application

.NET 3.0 introduced a new type of application, the WPF browser application, also called XBAP, that is run in the browser. There are several other small differences between stand-alone apps and XBAP, but what we need here is just some info about the security implications.

Being a app hosted by Internet Explorer means that it can be run from a remote computer (the Internet); hence the need for improved security and data protection. Standard XBAP run in partial trust mode ( using a specially designed security sandbox) , denying you access to things like: creating windows, file IO, accessing native APIs. Most of these features we need, so we will increase the trust of our XBAP to full trust or to Custom trust. This is done by right-clicking on the application in Project Explorer, selecting Properties, then Security tab, check ClickOnce security settings and click on Full trust. A best practice in security says that we shouldn't run an application with more privileges than those that are needed, so it would be better to Choose Custom security and check only those features that are used. Note: Without using VS you can edit these properties in the manifest of the application; add the following attribute Unrestricted="true".

Exercise: try running the application without the Full Trust option and see what happens. What kind of error appears?

After setting these permissions we realize that programming an XBAP si identical with stand-alone WPF programming. So we can use classic techniques. This was the purpose of WPF programmers: to unify the stand-alone and internet graphic programming. We create the window on which we want the thumbnail drawn and set its Topmost property to true. Then we extend the glass frame on it and draw the thumbnail using the function specified.

Sidebar Gadget development

The sidebar hosts internet applications; the main page, that is opened when a gadget loads is a simple html file. From then on, the developer is load whatever he wants. This is the main html file from my gadget:

HTML
<html>
<head>
<style>

body {width:120; height:62; margins:5; background:black; }

</style>
<body>
<iframe width="130" height="62" src="ThumbnailGadget.xbap" />
</body>
</html>


Notice how i loaded the xbap application we created earlier? I used the iframe tag.

To describe the exact properties of the gadget a .gadget file must be created in the gadget directory. It will contain things like:

  • the gadget name
  • the gadget description
  • the start-up html file name
  • other useful information
XML
<?xml version="1.0" encoding="utf-8" ?>
<gadget>
    <name>Live Thumbnails</name>
    <namespace>Example.You</namespace>
    <version>1.0</version>
    <author name="Dragos Dumitru Sbirlea">
        <info url="http://<a href="http://www.codeproject.comwww.codeproject.com/">www.codeproject.com</a>/" />
    </author>
    <copyright>2007</copyright>
    <description>Displays window live thumbnails in an always on top 
    window </description>
    <hosts>
        <host name="sidebar">
            <base type="HTML" apiVersion="1.0.0" src="ThumbNails.html" />
            <permissions>full</permissions>
            <platform minPlatformVersion="0.3" />
        </host>
    </hosts>
</gadget>

Exercise: Try to recreate the gadget from the project output. Find the necessary info about gadget development at the bottom of this article,it is really very easy.

The only problem not mentioned in the documentation that I have, is the minimum size of the gadget. The original plan for the gadget included the display of thumbnails directly on the sidebar, but it is not an easy task.

Exercise Check out the documentation of the LiveThumbnail API functions to see what restrictions are imposed to the window that displays the thumbnails.

So, iy you find yourself writing a very small gadget and find that you have black margins and they do not respond to modifying the size from the gadget html file, the gadget might be too small. This minimum size should depend on the screen DPI, what is for sure is when I tried to make the gadget 30px height, it was too small and I had to increase it to a healthy 60px.

ClickOnce deployment

The deployment technology that makes installing the application invisible to the user is called ClickOnce . More info on ClickOnce, here.

Some problems might arise while developing the XBAP application because of deployment errors. The exact source of these problems I did not find but They appear for sure when you add a dependency of the project (a new dll). Then you will be met, when running the XBAP from outside VS, with a deployment error.Try running mage.exe with the cc option like this:

mage -cc 

Mage.exe is the The Manifest Generation and Editing Tool and what the cc parameter really does clear the application cache.

Another useful thing you might do when confronted with a deployment error is changing the test certificate used. Do this by going to Project Properties->Signing->Create test Certificate. Both these options worked for me at a certain point.

Bibliography and further reading

To do

Possible improvements include:

  • graphical improvements
  • finding a way to display the thumbnails on the Sidebar directly
  • setting dialog
  • multiple instances simultaneously

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer
Romania Romania
Dragos is currently a student at the Polytechnic University of Bucharest. He likes keeping up to date with new and amazing technologies and he hopes he will one day master the mechanisms behind modern day programming languages so that he can write the best possible code from a performance and maintainability point of view.

He keeps track of the things he learns on a daily basis on his blog, at http://picobit.wordpress.com/ .

Comments and Discussions

 
QuestionPropunere Pin
morcovescu179-Feb-08 8:35
morcovescu179-Feb-08 8:35 
GeneralGood Idea for a tutorial Pin
rbunn8381529-Dec-07 11:46
rbunn8381529-Dec-07 11:46 
GeneralRe: Good Idea for a tutorial Pin
Dragos Sbirlea29-Dec-07 11:57
Dragos Sbirlea29-Dec-07 11:57 
What happens when you try to load the project in VS 2005 with extensions? You get loading error, compile time error, runtime error?
I have no problem running it...
GeneralRe: Good Idea for a tutorial Pin
rbunn8381529-Dec-07 12:02
rbunn8381529-Dec-07 12:02 
GeneralRe: Good Idea for a tutorial Pin
Dragos Sbirlea29-Dec-07 12:10
Dragos Sbirlea29-Dec-07 12:10 
QuestionType of the project Pin
Andrius8883-Jun-07 22:43
Andrius8883-Jun-07 22:43 
AnswerRe: Type of the project Pin
Dragos Sbirlea3-Jun-07 22:46
Dragos Sbirlea3-Jun-07 22:46 
GeneralGood Article Pin
Warren Stevens22-Mar-07 10:28
Warren Stevens22-Mar-07 10:28 
Generaltanx Pin
Dragos Sbirlea30-Jan-07 1:50
Dragos Sbirlea30-Jan-07 1:50 
GeneralRe: tanx Pin
Raj Lal10-Feb-07 15:09
professionalRaj Lal10-Feb-07 15:09 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.