Go to the CodePlex Project Site for the latest releases and source code.
Introduction
Most developers often have many Windows open at once, and so often will use a virtual desktop program to help organize their Windows. However, most virtual desktop software is ugly and lacks many useful features. While I don't put every feature you may want in this program, I do give a powerful base implementation of a Vista thumbnail-enhanced virtual desktop program.
How to Use the Program
Obviously, you need Windows Vista to use this program. It was tested on RC1, and some older versions have differing thumbnail API functions that may fail. When you first start the program, a Window flashes open and then closes. A new icon is now in the system tray. It installs hotkeys as follows:
- Windows Key + Z - Open switcher
- Windows Key + Numpad 1...4 (with numlock on) - Switch to desktop x
When you hit Windows Key + Z, everything starts to fade to black and any Windows you have open will appear as thumbnails in the first desktop in the upper lefthand corner. You can drag Windows around and they will move in real time. If you drag them to a different desktop, they will disappear. To move between desktops, either double-click a Window on a desktop, or use the arrow keys to select a desktop and then press enter to switch to it. You can also press Escape to hide the switcher.
Every time you switch desktops, the switcher Window gives a visual representation of the switch.
If you right-click on the tray icon, you are presented with standard options and a menu for switching between desktops.
How it Works
I'll go over the internals of the program by class. A lot of tricks are needed in order to get everything working. I not only have classes that will be useful in other projects, but a library I'll do another article on named PPAB Forms.dll. This library contains many useful graphical functions and most importantly, it offers a class called Form
that inherits from System.Windows.Forms.Form
that displays a "layered Window". If you don't know what a layered Window is, it's a special kind of Window that is composited and can have per-pixel alpha information (PPAB stands for per-pixel alpha blending). That's right, before Vista and DWM, there were layered Windows. You can use them for all kinds of graphical things. If you've ever used Object Desktop, Konfabulator, ObjectDock, etc, or seen the old Adobe Reader alpha-blended splash screen, you've seen layered Windows in action.
Thumbnail Class
This class mainly wraps the Vista thumbnail API. You give it source and destination Windows. Then, you set some properties and call UpdateRendering
. This starts the rendering. It is disposable, so you can stop the rendering completely by calling dispose.
WindowInfo Class
This is the biggest class in the project. It wraps more than 30 Windows API functions into a fully featured Window controller. Just pass it the handle to a Window when you create it, and it gives you access to tons of useful properties. You can set almost all of the properties as well. I don't use everything in this class for virtual desktops. In fact, I only use a few functions and properties. There are some shared (static
) functions that wrap FindWindow
and EnumWindows
as well. I can see much use for this class in many programs. I may continue expanding it and publish another article about it.
HotKey Class
This class provides an event based hotkey manager. Call RegisterHotKey
with an id for the hotkey and the keys themselves. Then, listen for the HotKeyPressed
event and check the id given to the event to handle hotkeys.
NativeWindowEx Class
This class is used by the HotKey
class. It simply inherits the NativeWindow
class and adds an event that is called from WndProc
. It allows you to handle NativeWindow
messages without inheriting from NativeWindow
every time.
VirtualDesktop and VirtualDesktopManager Classes
These classes are in the same file because they use one another. They compose the base virtual desktop "engine". I've found this implementation to be pretty reliable, but remember that when debugging a virtual desktop program you must end the program normally rather than hit "Stop" if you have Windows on other desktops. Otherwise, the Windows will stay hidden until you log off (that is not fun). When the program starts up, it calls InitVirtualDesktops
with the number 4
as the parameter for how many desktops to make. That's right, this virtual desktop engine supports as many desktops as you want. However, the thumbnail based preview Window supports only 4 at this time.
ThumbnailWindow and ThumbnailManager Classes
These classes actually control the preview Window. Actually that's preview Windows. Many people complained about the thumbnail API to Microsoft. The API's aren't very powerful by themselves and give you only a few options about how to draw them. You can't create a program like Flip3D with only these API's. Flip3D is built into the DWM program and works by simply applying matrix transformations to the Windows.
I don't need any 3D stuff for this program, but I did need fast 2D animation. The Windows needed to move when dragged and to fade in rather quickly. Most other thumbnail programs use the thumbnail API's to move, scale, and alpha-blend their thumbnails. The API's aren't usually fast enough to provide fluid animation (especially on slower computers), so I came up with a trick. Firstly, each thumbnail is on its own Window. Now, if you use regular Windows for this, the translucent glass areas won't be translucent. Instead, I found that Windows will allow you to use layered Windows for this. Basically, you create the layered Window and tell it to render on it like on a normal Window. Then in order to make the Window touch-sensitive, you have to color the pixels in something other than 0,0,0,0. So I just fill a rectangle with 1,0,0,0 (1/255 alpha, black) the same size as the thumbnail. You end up with a perfect translucent floating thumbnail.
Once I figured out how to display the thumbnails like that, I wrote the ThumbnailWindow
and ThumbnailManager
classes. The TumbnailWindow
class inherits from the layered window class (PerPixelAlpha.Form
). They access one another to control the animations and the windows represented by the thumbnails. Using an altered version of the ThumbnailWindow
class, you could display highly animated thumbnails floating over the desktop any time you want!
DoubleBufferedForm Class
This simply inherits from System.Windows.Form
and sets the DoubleBuffered
property to true
in the constructor.
MainForm Class
This class simply provides the startup code and sets up everything including the system tray icon. It also handles the hot key presses and calls the needed functions.
SwitchForm Class
This form is a click-throughable layered Window that is shown whenever the user switches desktops. The draw code that matters is the RenderDesktops
method.
OptionsForm Class
This form contains some useful options, including the ability to have more than 4 desktops (although the preview Windows don't show more than 4).
In Conclusion
This program provides a great example of using Vista thumbnails for functional purposes. You can easily use the ThumbnailWindow
class for other thumbnail animations as well. For example, you could make an alternate version of Alt-Tab that has the Window thumbnails fade in and fall down from the top of the screen. It also gives you a very reliable virtual desktop engine. Lastly, it gives you a few very handy Win32 API wrappers for use in just about anything.
History