Flush current work
[desktopswitcher.git] / desktop.cpp
blob67d4f4e8715719f535ff37a017e8ba52f43dd075
1 // $Id: desktop.cpp,v 1.1 2002/05/29 22:06:50 nedko Exp $
2 //
3 // Desktop Switcher
4 // Copyright (C) 2000,2001,2002 Nedko Arnaudov <nedko@users.sourceforge.net>
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include "ph.h"
21 #include "Desktop.h"
22 #include "switcher.h"
23 #include "SwitcherWindow.h"
25 CDesktop::CDesktop(CDesktopSwitcher *pDesktopSwitcher, const char *pszDesktopName, const char *pszDesktopShowName, HRESULT& rhrError)
27 rhrError = E_UNEXPECTED;
28 m_hDesktop = NULL;
29 m_pWnd = NULL;
30 m_pDesktopSwitcher = NULL;
31 m_pszDesktopShowName = NULL;
32 m_pszDesktopName = NULL;
34 m_pszDesktopName = new char [strlen(pszDesktopName)+1];
35 if (!m_pszDesktopName)
37 rhrError = E_OUTOFMEMORY;
38 return;
41 strcpy(m_pszDesktopName,pszDesktopName);
43 m_pszDesktopShowName = new char [strlen(pszDesktopShowName)+1];
44 if (!m_pszDesktopShowName)
46 rhrError = E_OUTOFMEMORY;
47 return;
50 strcpy(m_pszDesktopShowName,pszDesktopShowName);
52 // First, try to open an existing desktop
53 m_hDesktop = OpenDesktop(m_pszDesktopName, 0, FALSE, GENERIC_ALL);
54 if (!m_hDesktop)
56 // Failing an open, create it
57 m_hDesktop = CreateDesktop(m_pszDesktopName,
58 NULL,
59 NULL,
61 MAXIMUM_ALLOWED,
62 NULL);
64 if (!m_hDesktop)
66 rhrError = HRESULT_FROM_WIN32(GetLastError());
67 return;
71 m_pDesktopSwitcher = pDesktopSwitcher;
73 DWORD tID;
74 HANDLE hThread = CreateThread(NULL,
76 ThreadProc,
77 this,
79 &tID);
81 if (!hThread)
83 rhrError = HRESULT_FROM_WIN32(GetLastError());
84 return;
87 VERIFY(CloseHandle(hThread));
89 rhrError = S_OK;
92 CDesktop::~CDesktop()
94 ASSERT(!m_hDesktop);
95 if (m_hDesktop)
96 VERIFY(CloseDesktop(m_hDesktop));
98 if (m_pszDesktopName)
99 delete m_pszDesktopName;
101 if (m_pszDesktopShowName)
102 delete m_pszDesktopShowName;
104 if (m_pWnd)
105 delete m_pWnd;
108 DWORD WINAPI CDesktop::ThreadProc(LPVOID lpParameter)
110 return ((CDesktop *)lpParameter)->ThreadProc();
113 DWORD CDesktop::ThreadProc()
115 DWORD dwRet = -1;
117 USEROBJECTFLAGS uof; // To set Desktop attributes
119 uof.fInherit = FALSE; // If an app inherits multiple desktop handles,
120 // it could run on any one of those desktops
121 uof.fReserved = FALSE;
122 // Let other account processes hook this desktop
123 uof.dwFlags = DF_ALLOWOTHERACCOUNTHOOK;
124 SetUserObjectInformation(m_hDesktop,
125 UOI_FLAGS,
126 (LPVOID)&uof,
127 sizeof(uof));
129 // Assign new desktop to this thread
130 SetThreadDesktop (m_hDesktop);
132 m_pWnd = new CSwitcherWindow(m_pDesktopSwitcher,this);
133 if (!m_pWnd)
135 dwRet = ERROR_OUTOFMEMORY;
136 goto Exit;
139 if (!m_pWnd->Create())
141 dwRet = GetLastError();
142 goto Exit;
145 // The message loop
146 MSG msg;
147 while (((dwRet = GetMessage(&msg, NULL, 0, 0)) != 0) && (dwRet != -1))
149 TranslateMessage(&msg);
150 DispatchMessage(&msg);
153 m_pWnd->Destroy();
155 Exit:
156 if (m_pWnd)
157 delete m_pWnd;
158 VERIFY(CloseDesktop(m_hDesktop));
160 delete this;
161 return dwRet;
164 // Called by CDesktopSwitcher only !!!
165 void CDesktop::Exit()
167 PostQuitMessage(0); // we don't use the parameter
170 HRESULT CDesktop::SwitchTo()
172 if (!SwitchDesktop(m_hDesktop))
174 DWORD dwError = GetLastError();
175 return HRESULT_FROM_WIN32(dwError);
178 return S_OK;
181 void CDesktop::WindowToggleVisible()
183 if (m_pWnd)
184 m_pWnd->ToggleVisible();
187 void CDesktop::Run(const char *pszCommand)
189 STARTUPINFO sui; // Process startup info
190 PROCESS_INFORMATION pi; // info returned from CreateProcess
192 // Most sui members will be 0
194 ZeroMemory ((PVOID)&sui, sizeof(sui));
196 sui.cb = sizeof (sui);
198 TCHAR *pszCommandBuffer = new char [strlen(pszCommand)+1];
199 if (!pszCommandBuffer)
201 ::MessageBox(NULL,"Out of memory", "Error", MB_OK|MB_ICONSTOP);
202 return;
205 strcpy(pszCommandBuffer,pszCommand);
207 TCHAR *pszDesktopName = new char [strlen(m_pszDesktopName)+1];
208 if (!pszDesktopName)
210 ::MessageBox(NULL,"Out of memory", "Error", MB_OK|MB_ICONSTOP);
211 delete pszCommandBuffer;
212 return;
215 strcpy(pszDesktopName,m_pszDesktopName);
217 sui.lpDesktop = pszDesktopName;
218 if (!CreateProcess( NULL, // image name
219 pszCommandBuffer, // command line
220 NULL, // process security attributes
221 NULL, // thread security attributes
222 TRUE, // inherit handles
223 CREATE_DEFAULT_ERROR_MODE|CREATE_SEPARATE_WOW_VDM,
224 NULL, // environment block
225 NULL, // current directory
226 &sui, // STARTUPINFO
227 &pi)) // PROCESS_INFORMATION
229 char Buffer[1024];
230 sprintf(Buffer,"CreateProcess failed. GetLastError() returns 0x%X",GetLastError());
231 ::MessageBox(NULL, Buffer, "Error", MB_OK|MB_ICONSTOP);
234 delete pszCommandBuffer;
235 delete pszDesktopName;
238 const char *CDesktop::GetDesktopName()
240 return m_pszDesktopShowName;
243 void CDesktop::RunPrompt()
245 if (m_pWnd)
246 m_pWnd->OnRun();