A few months ago, one of my colleagues was using a tool that was managing multiple desktops. I was wondering how the tool could manage multiple desktops. I thought it would be just hiding-and-displaying the application windows for different desktops when a user switches between them. As a matter of curiosity, I started studying multiple desktops and ended up with this article.
As I went through the details, I found that I was wrong in thinking that the tool was just hiding-and-displaying the application windows for different desktops. Even the thought that the "Desktop" we see is just a directory was wrong. Let's see how it works.
Window Station and Window Desktop
Actually Windows uses Window Station and Desktop architecture to provide additional security. For the time being, we can refer to "Desktop" as a logical display surface, which contains User Interface Objects (GDI objects) and User Objects. A Window Station is a secure kernel object which contains a clipboard, an atom table, and one or more desktop objects. There exists a default window station "WinSta0", an interactive window station. "WinSta0" is the only interactive window station that can display a user interface or receive user input. All other window stations are non-interactive. By default, there exist three Desktops in an interactive window station : Default, WinLogon and ScreenSaver.
A Desktop is also a secure kernel object. When a new desktop is created, it is associated with the current window station of the calling process. There will always be only one desktop visible (Active) and ready to receive user inputs, provided the desktop is associated with an interactive window station i.e. WinSta0. This active desktop is called the Input Desktop.
As I specified, there exist three desktops in an interactive window station: Default, WinLogon and ScreenSaver. The screen prompting to press ALT + CTL + DEL to login is the WinLogon desktop. Whenever the user logs in, the Default desktop is created and made visible. This "Default" is the default active desktop for any logged in user. When you press ALT + CTL + DEL, you'll be switched back again to the WinLogon desktop. The ScreenSaver desktop will be made visible whenever the screen saver gets activated. As these desktop names are case-insensitive, there could be only one desktop of a specific name in a window station. But a desktop name can be repeated in different window stations. The purpose behind Window Station and Desktop objects is to provide top level isolation between processes.
About the Virtual Desktop (A Sample Application)
The Virtual Desktop Tool helps you to create and switch between different desktops. It even gives you an illusion of switching the application from one desktop to another. But this isn't true as any running application cannot be moved from one desktop to other. As I said, it's just an illusion. The application will be closed in the current desktop and will be launched on the specified desktop. This may cause loss of any unsaved data of the application and may not persist the state as it will be restarted.
The application is using hooks to display "Move To" menu options in the applications Control Panel (System Menu). For more details about the hooks, I would refer this article. I will give you an overview of different APIs used and classes built in the application. Rest of the code in the application is self explanatory and (what I think is) well documented.
Different APIs Used and Classes Built
It retrieves the handle to the current Window Station of the calling process. The retrieved handle is used to enumerate all the desktops of the window station.
It creates a new Desktop with the specified name. This newly created desktop will be associated with the Window Station of the calling process and will be assigned to the calling thread.
It opens the specified Desktop. The handle returned by this function is used to switch between desktops.
It closes an open handle to Desktop.
This makes the specified Desktop visible and ready to receive user inputs (i.e. makes it Active).
It retrieves the handle to the Desktop associated with the specified thread.
It gives information about the Window Station and Desktop Objects.
The application has a class called
CDesktopManager, in which all the desktop related activities are wrapped up. The application solution has a DLL Project, in which all the windows hook functionalities are wrapped up. This Event Hooker DLL is responsible for inserting menu options into the System Menu of the other applications.
Points of Interest
When we create a new desktop and switch to it, it shows nothing. The desktop will be blank(with just a wallpaper visible) -- that's because no process is running on that desktop. So, to avoid that, I launch an Explorer shell whenever I create a new desktop. I think I could add a feature to launch a new process/application on a specified desktop. And so I did in the current update. I have a few more features in mind. I'll keep updating whenever I complete them.
- 17 Nov 2007 : Initial release
- 27 Dec 2007 : The application was exiting once it switches the desktop. It wasn't programmed to stay in memory any longer after desktop switch. But in this release the application launches a new instance of its own after desktop switch and then exits. This makes users feel that the application is always there for them in all desktops. This change has been made after reading one of the comments posted by a reader.
- 1 Jun 2008 : The feature of launching application is been incorporated. Also few bugs I found have been fixed.
- 25 July 2008 : Modified the code to encorporate following features:
- Removed the bug of hooking my own application. :D
- Added featue of shortcut-keys to easily navigate between the desktops.
- Displaying the current desktop name in the application icon tooltip [so you don't get confused on which desktop you are !].
- Tested on Vista also.
If you find a bug in the application or any feature to be embeded, please let me know, so that I can work on it.