Introduction
The feature, multi desktops (workspace), is supported by KDE/GNOME on Linux, and it can also be found on Mac OSX.
This tiny tool can impersonate this feature on Windows platform.
Desktop Functions
There is a series of APIs to maintain desktops.
Function | Description |
CloseDesktop | Closes an open handle to a desktop object. |
CreateDesktop | Creates a new desktop, associates it with the current window station of the calling process, and assigns it to the calling thread. |
CreateDesktopEx | Creates a new desktop, associates it with the current window station of the calling process, and assigns it to the calling thread. |
EnumDesktops | Enumerates all desktops associated with the current window station of the calling process. |
EnumDesktopWindows | Enumerates all top-level windows associated with the specified desktop. |
GetThreadDesktop | Retrieves a handle to the desktop assigned to the specified thread. |
GetUserObjectInformation | Gets information about a window station or desktop object. |
GetUserObjectSecurity | Gets security information for a window station or desktop object. |
OpenDesktop | Opens the specified desktop object. |
OpenInputDesktop | Opens the desktop that receives user input. |
SetThreadDesktop | Assigns the specified desktop to the calling thread. |
SetUserObjectInformation | Sets information about a window station or desktop object. |
SetUserObjectSecurity | Sets security information for a window station or desktop object. |
SwitchDesktop | Makes a desktop visible and activates it. This enables the desktop to receive input from the user. |
How To Create a New Desktop
The simple code below demonstrates how to create a new desktop.
SECURITY_ATTRIBUTES stSecurityAttr = {sizeof(SECURITY_ATTRIBUTES), 0, TRUE};
stSecurityAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
stSecurityAttr.bInheritHandle = TRUE;
HDESK hDesktop = ::CreateDesktop( lpszDesktopName
, NULL
, NULL
, 0
, GENERIC_ALL
, &stSecurityAttr
);
if( hDesktop == NULL )
{
::MessageBox( m_hWnd, _T("Failed to create new desktop."),
_T("Error"), MB_ICONERROR | MB_OK);
return;
}
STARTUPINFO stStartInfo = {0};
stStartInfo.cb = sizeof(STARTUPINFO);
stStartInfo.lpDesktop = (LPTSTR)lpszDesktopName;
PROCESS_INFORMATION stProcInfo = {0};
CString strCmdLine = _T("explorer.exe");
BOOL bRet = ::CreateProcess( NULL
, strCmdLine.GetBuffer()
, NULL
, NULL
, TRUE
, 0
, NULL
, NULL
, &stStartInfo
, &stProcInfo
);
strCmdLine.ReleaseBuffer();
if( !bRet )
{
::CloseDesktop(hDesktop);
::MessageBox( m_hWnd, _T("Failed to launch the explorer.exe
in the new desktop."), _T("Error"), MB_ICONERROR | MB_OK);
return;
}
::SwitchDesktop(hDesktop);
Sleep(3000);
TCHAR tszBuffer[MAX_PATH] = {0};
GetModuleFileName( m_hInstance, tszBuffer, MAX_PATH);
bRet = ::CreateProcess( NULL
, tszBuffer
, NULL
, NULL
, TRUE
, 0
, NULL
, NULL
, &stStartInfo
, &stProcInfo
);
::CloseDesktop(hDesktop);
History
- 5th March, 2009: Initial post