Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

283 lines
7.1 KiB

  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // File: MultiDesk.cpp
  4. // Created: Jan 1996
  5. // By: Martin Holladay (a-martih) and Ryan D. Marshall (a-ryanm)
  6. //
  7. // Project: Desktop Switcher
  8. //
  9. // Main Functions:
  10. // InitApplication - Initialize an instance of the Application
  11. // WinMain()
  12. // StartThreadDisplay() - Starts a UI thread
  13. //
  14. // Misc. Functions (helpers)
  15. //
  16. //
  17. // Revision History:
  18. //
  19. // March 1997 - Add external icon capability
  20. //
  21. //
  22. #include <windows.h>
  23. #include <assert.h>
  24. #include <stdio.h>
  25. #include <shellapi.h>
  26. #include <commctrl.h>
  27. #include "Resource.h"
  28. #include "DeskSpc.h"
  29. #include "Desktop.h"
  30. #include "Registry.h"
  31. #include "User.h"
  32. #include "CmdHand.h"
  33. #include "Splash.h"
  34. //
  35. // Global structure to hold application wide variables
  36. //
  37. APPVARS AppMember;
  38. //
  39. // Dispatch function for creating displays
  40. //
  41. DispatchFnType CreateDisplayFn = StartThreadDisplay;
  42. /*------------------------------------------------------------------------------*/
  43. /*------------------------------------------------------------------------------*/
  44. BOOL InitApplication(HINSTANCE hInstance)
  45. {
  46. WNDCLASSEX wc;
  47. INITCOMMONCONTROLSEX iccex;
  48. // Initialize the common controls.
  49. ZeroMemory(&iccex, sizeof(INITCOMMONCONTROLSEX));
  50. iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
  51. iccex.dwICC = ICC_LISTVIEW_CLASSES;
  52. InitCommonControlsEx(&iccex);
  53. // Load the application name and description strings.
  54. LoadString(hInstance, IDS_MULTIDESK, AppMember.szAppName, MAX_APPNAME);
  55. LoadString(hInstance, IDS_MULTIDESK, AppMember.szAppTitle, MAX_TITLELEN);
  56. AppMember.hApplicationIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MULTIDESK_ICON));
  57. AppMember.hApplicationSmallIcon = (HICON)LoadImage(hInstance,
  58. MAKEINTRESOURCE(IDI_MULTIDESK_ICON),
  59. IMAGE_ICON,
  60. 16,
  61. 16,
  62. LR_DEFAULTCOLOR);
  63. AppMember.hTaskbarIcon = (HICON) LoadImage(hInstance,
  64. MAKEINTRESOURCE(IDI_TASKBAR_ICON),
  65. IMAGE_ICON,
  66. 16,
  67. 16,
  68. LR_DEFAULTCOLOR);
  69. // Fill in window class structure
  70. wc.cbSize = sizeof(WNDCLASSEX);
  71. wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW; // Class style(s).
  72. wc.hIconSm = AppMember.hApplicationSmallIcon;
  73. wc.lpfnWndProc = (WNDPROC)MainMessageProc; // Window Procedure
  74. wc.cbClsExtra = 0; // No per-class extra data.
  75. wc.cbWndExtra = 0; // No per-window extra data.
  76. wc.hInstance = hInstance; // Owner of this class
  77. wc.hIcon = AppMember.hApplicationIcon; // Icon name from .RC
  78. wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Cursor
  79. wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); // CreateSolidBrush(RGB(192,192,192));
  80. wc.lpszMenuName = NULL;
  81. wc.lpszClassName = AppMember.szAppName; // Name to register as
  82. // Register the window class and return FALSE if unsuccesful.
  83. if (!RegisterClassEx(&wc))
  84. {
  85. if (!RegisterClass((LPWNDCLASS)&wc.style)) return FALSE;
  86. }
  87. // Modify the things for the second class structure.
  88. wc.lpfnWndProc = (WNDPROC) TransparentMessageProc;
  89. wc.lpszClassName = TRANSPARENT_CLASSNAME;
  90. wc.hbrBackground = NULL;
  91. // Register the window class and return FALSE if unsuccesful.
  92. if (!RegisterClassEx(&wc))
  93. {
  94. if (!RegisterClass((LPWNDCLASS)&wc.style)) return FALSE;
  95. }
  96. // App inits
  97. AppMember.hInstance = hInstance;
  98. AppMember.bTrayed = FALSE;
  99. AppMember.nWidth = 100;
  100. AppMember.nHeight = 200;
  101. return TRUE;
  102. }
  103. /*------------------------------------------------------------------------------*/
  104. /* the thread loop that is started in a separate thread for each desktop
  105. /*------------------------------------------------------------------------------*/
  106. void StartThreadDisplay(void)
  107. {
  108. MSG msg;
  109. BOOL Finished;
  110. //
  111. // Perform initializations that apply to a specific instance
  112. //
  113. if (!CreateMainWindow())
  114. {
  115. Message("Failed to create main window.");
  116. return;
  117. }
  118. if (!CreateTransparentLabelWindow())
  119. {
  120. Message("Failed to create transparent window.");
  121. }
  122. //
  123. // Message Pump
  124. //
  125. Finished = FALSE;
  126. while ((!Finished) && GetMessage(&msg, NULL, 0, 0))
  127. {
  128. TranslateMessage(&msg);
  129. DispatchMessage(&msg);
  130. switch (msg.message)
  131. {
  132. case WM_PUMP_TERMINATE:
  133. Finished = TRUE;
  134. break;
  135. case WM_THREAD_SCHEME_UPDATE:
  136. AppMember.pDesktopControl->FindSchemeAndSet();
  137. break;
  138. case WM_KILL_APPS:
  139. AppMember.pDesktopControl->KillAppsOnDesktop((HDESK) msg.wParam, (HWND) msg.lParam);
  140. break;
  141. }
  142. }
  143. }
  144. /*------------------------------------------------------------------------------*/
  145. /*------------------------------------------------------------------------------*/
  146. int WINAPI WinMain(HINSTANCE hInstance,
  147. HINSTANCE hPrevInstance,
  148. LPSTR lpCmdLine,
  149. int nCmdShow)
  150. {
  151. HWND hWnd;
  152. HANDLE hMultideskMutex;
  153. CHAR szName[MAX_PATH];
  154. SPLASH_DATA SplashData;
  155. HANDLE hThread;
  156. DWORD dwThreadId;
  157. OSVERSIONINFO versioninfo;
  158. //
  159. // We require Windows NT 5 minimum now (for Saifer,
  160. // Explorer as shell, local instance mutex, etc).
  161. //
  162. ZeroMemory(&versioninfo, sizeof(OSVERSIONINFO));
  163. versioninfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  164. if (!GetVersionEx(&versioninfo) ||
  165. versioninfo.dwPlatformId != VER_PLATFORM_WIN32_NT ||
  166. versioninfo.dwMajorVersion < 5)
  167. {
  168. Message("This application require Windows 2000 or later.");
  169. return FALSE;
  170. }
  171. //
  172. // Are there other instance of app running?
  173. //
  174. hMultideskMutex = CreateMutex(NULL, TRUE, "Local\\Multi Desk Mutex");
  175. if (!hMultideskMutex || GetLastError() == ERROR_ALREADY_EXISTS)
  176. {
  177. // Another instance found? switch to it, if possible.
  178. LoadString(hInstance, IDS_MULTIDESK, szName, MAX_APPNAME);
  179. hWnd = FindWindow(szName, szName);
  180. if (hWnd)
  181. SetForegroundWindow(hWnd);
  182. return FALSE;
  183. }
  184. //
  185. // Start Splash Screen
  186. //
  187. SplashData.hInstance = hInstance;
  188. if (hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) DoSplashWindow, (LPVOID) &SplashData, CREATE_SUSPENDED, &dwThreadId))
  189. {
  190. ResumeThread(hThread);
  191. WaitForSingleObject(hThread, INFINITE);
  192. CloseHandle(hThread);
  193. }
  194. //
  195. // Initialize UI shared things
  196. //
  197. if (!InitApplication(hInstance))
  198. {
  199. return FALSE;
  200. }
  201. //
  202. // Initilize desktop switching code
  203. //
  204. AppMember.pDesktopControl = (CDesktop*) new CDesktop;
  205. AppMember.pDesktopControl->InitializeDesktops(CreateDisplayFn, hInstance);
  206. //
  207. // Start the display for context zero
  208. //
  209. CreateDisplayFn();
  210. //
  211. // Tidy up
  212. //
  213. Sleep(500);
  214. delete AppMember.pDesktopControl;
  215. //
  216. // Returns the value from PostQuitMessage
  217. //
  218. return 1;
  219. }
  220. //////////////////////////////////////////////////////////////////////////////////
  221. //
  222. // Helper functions follow
  223. //
  224. //
  225. // Display a messagebox with a meaningful title.
  226. //
  227. void Message(LPCTSTR szMsg)
  228. {
  229. if (AppMember.hInstance != NULL)
  230. MessageBox((HWND)AppMember.hInstance, szMsg, AppMember.szAppTitle,
  231. MB_OK | MB_APPLMODAL);
  232. else
  233. MessageBox(NULL, szMsg, TEXT("DeskTops..."), MB_OK);
  234. }