Click here to Skip to main content
15,895,667 members
Articles / Programming Languages / C++

Faking Multiple Desktops

Rate me:
Please Sign up or sign in to vote.
2.08/5 (7 votes)
26 Jan 2006CPOL3 min read 36.1K   830   26   3
An application that simulates multiple desktops. Including the ability to transfer windows between desktops, which seems to be missing from Microsoft's implementation.

Sample Image - multipledesktops.gif

Introduction

In my mind, by far the coolest feature that a desktop manager can have is proper multiple (virtual) desktops (shallow, I know). So, Windows XP doesn't have this feature; ah well, there's a PowerTool that does it. Except - you can't change the desktop just by mousing off the edge, and more seriously, there doesn't appear to be any mechanism to transfer windows between desktops - which is very annoying, as things never open where you want them to.

Concept

I thought that the easiest way to do this is simply to show and hide windows in such a way as to give the impression of more than one desktop. About halfway through writing this, I discovered SwitchDesktop, which looked quite complicated, so I didn't bother trying it that way.

Technical Details

The program is an MFC Dialog App.

I found out how to list all the windows on the system and show and hide them from the tbarsort article. I ask Windows for handles to every window on the system using EnumWindows, and filter out the irrelevant ones.

C++
bool ValidWindow(HWND hwnd)
{
  if (!IsWindowVisible(hwnd)) return false;
  if (GetWindowTextLength(hwnd) == 0) return false;
  if (GetAsyncKeyState(VK_LBUTTON) && 
           hwnd==GetForegroundWindow()) return false;
  char str[100];
  GetWindowText(hwnd,str,99);
  if(strncmp(str,"Desktop",100)==0) return false;
  if(strncmp(str,"Program Manager",100)==0) return false;
  return true;
}

BOOL CALLBACK AddToList(HWND hwnd,LPARAM ret)
{
  std::vector<HWND>* vecret=(std::vector<HWND>*)ret;
  if(ValidWindow(hwnd)) vecret->push_back(hwnd);
  return TRUE;
}

std::vector<HWND> WindowList()
{
  std::vector<HWND> windows;
  EnumWindows(AddToList,LPARAM(&windows));
  return windows;
}

Desktops can be switched by pressing the relevant button or with a keyboard shortcut, implemented with RegisterHotKey; for example, Win+1 is registered by:

C++
RegisterHotKey(GetSafeHwnd(),1,MOD_WIN,'1');

For some reason, the MFC ClassWizard doesn't know about the WM_HOTKEY message, so it has to be added manually to the message map:

C++
ON_MESSAGE(WM_HOTKEY,OnHotKey)

By far the hardest thing to do was to detect when the mouse touched the edge of the screen (which is when the desktops change). Eventually I found the MouseHookDlg project (although I can't currently find a reference for it), which shows how to install a global mouse hook. All I have to do is package the DLL with my app, and call the simple function API_SetHooks to register a mouse callback, and put a handler in the message map:

C++
ON_REGISTERED_MESSAGE(UWM_MOUSEMOVE, OnHookMouseMove)

having first registered this mesage by:

C++
UWM_MOUSEMOVE = RegisterWindowMessage(UWM_SHELL_HOOK_MSG);

Finally, I wanted it to be possible to drag windows off the side of the screen and have them come with you to the new desktop. I failed to find an actual way of checking if any windows are being dragged (I suspect it can be done with another global hook); instead, if the left mouse button is down as the desktops are switched, then the foreground window is transferred, hence the line:

C++
if (GetAsyncKeyState(VK_LBUTTON) && hwnd==GetForegroundWindow()) return false;

in the ValidWindow above. This works well, but occasionally leads to accidental window transfers.

Conclusion

The program works fine, with one or two minor bugs (not bad for only a few hours' work). Occasionally, windows get transferred when not intended, and much worse, occasionally they get permanently hidden (don't do any absolutely vital work whilst using this program, there is a small chance that this will happen and you will be unable to save). I would be glad of suggestions for bug fixes, especially for improving the dragging detection; extra features are unlikely to get added. Blatant plug: visit my site for various games written using OpenGL with MFC or GLUT.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralThe functionality for multiple desktops is built into Win32 Pin
guttercup7-May-08 10:46
guttercup7-May-08 10:46 
GeneralWell Pin
grin_t22-Feb-07 19:38
grin_t22-Feb-07 19:38 
GeneralHookDll Pin
Justin Yu20-Feb-07 20:49
Justin Yu20-Feb-07 20:49 

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.