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.

469 lines
13 KiB

  1. /*
  2. * progman.c
  3. *
  4. * Copyright (c) 1991, Microsoft Corporation
  5. *
  6. * DESCRIPTION
  7. *
  8. * This file is for support of program manager under NT Windows.
  9. * This file is/was ported from progman.c (program manager).
  10. *
  11. * MODIFICATION HISTORY
  12. * Initial Version: x/x/90 Author Unknown, since he didn't feel
  13. * like commenting the code...
  14. *
  15. * NT 32b Version: 1/16/91 Jeff Pack
  16. * Intitial port to begin.
  17. *
  18. *
  19. */
  20. #include "progman.h"
  21. #include "uniconv.h"
  22. BOOL UserIsAdmin = FALSE;
  23. BOOL AccessToCommonGroups= FALSE;
  24. BOOL bLoadIt = FALSE;
  25. BOOL bMinOnRun = FALSE;
  26. BOOL bArranging = FALSE;
  27. BOOL bAutoArrange = FALSE;
  28. BOOL bAutoArranging = FALSE;
  29. BOOL bExitWindows = FALSE;
  30. BOOL bScrolling = FALSE;
  31. BOOL bSaveSettings = TRUE;
  32. BOOL bLoadEvil = FALSE;
  33. BOOL bMove = FALSE;
  34. BOOL bInDDE = FALSE;
  35. BOOL bIconTitleWrap = TRUE;
  36. BOOL fInExec = FALSE;
  37. BOOL fNoRun = FALSE;
  38. BOOL fNoClose = FALSE;
  39. BOOL fNoSave = FALSE;
  40. BOOL fNoFileMenu = FALSE;
  41. BOOL fExiting = FALSE;
  42. BOOL fLowMemErrYet = FALSE;
  43. BOOL fErrorOnExtract = FALSE;
  44. BOOL bFrameSysMenu = FALSE;
  45. TCHAR szNULL[] = TEXT("");
  46. TCHAR szProgman[] = TEXT("progman");
  47. //
  48. // Program Manager's Settings keys
  49. //
  50. TCHAR szWindow[] = TEXT("Window");
  51. TCHAR szOrder[] = TEXT("UNICODE Order");
  52. TCHAR szAnsiOrder[] = TEXT("Order");
  53. TCHAR szStartup[] = TEXT("startup");
  54. TCHAR szAutoArrange[] = TEXT("AutoArrange");
  55. TCHAR szSaveSettings[] = TEXT("SaveSettings");
  56. TCHAR szMinOnRun[] = TEXT("MinOnRun");
  57. TCHAR szFocusOnCommonGroup[] = TEXT("FocusOnCommonGroup");
  58. TCHAR szProgmanHelp[] = TEXT("PROGMAN.HLP");
  59. TCHAR szTitle[MAXTITLELEN+1];
  60. TCHAR szMessage[MAXMESSAGELEN+1];
  61. TCHAR szNameField[MAXITEMPATHLEN+1];
  62. TCHAR szPathField[MAXITEMPATHLEN+1];
  63. TCHAR szDirField[MAXITEMPATHLEN+1];
  64. TCHAR szIconPath[MAXITEMPATHLEN+1];
  65. TCHAR szOriginalDirectory[MAXITEMPATHLEN+1];
  66. TCHAR szWindowsDirectory[MAXITEMPATHLEN+1];
  67. TCHAR szOOMExitMsg[64];
  68. TCHAR szOOMExitTitle[32];
  69. /* for Program Groups in Registry */
  70. HKEY hkeyProgramManager = NULL; // progman.ini key
  71. HKEY hkeyPMSettings = NULL; // keys corresponding to progman.ini sections
  72. HKEY hkeyPMRestrict = NULL;
  73. HKEY hkeyPMGroups = NULL;
  74. HKEY hkeyPMCommonGroups = NULL;
  75. TCHAR szAnsiProgramGroups[] = TEXT("Program Groups"); // registry key for groups
  76. HKEY hkeyProgramGroups = NULL;
  77. HKEY hkeyAnsiProgramGroups = NULL;
  78. HKEY hkeyCommonGroups = NULL;
  79. PSECURITY_ATTRIBUTES pSecurityAttributes = NULL;
  80. PSECURITY_ATTRIBUTES pAdminSecAttr = NULL;
  81. HANDLE hAccel;
  82. HINSTANCE hAppInstance;
  83. HANDLE hCommdlg = NULL;
  84. HICON hDlgIcon = NULL;
  85. HICON hItemIcon = NULL;
  86. HICON hGroupIcon = NULL;
  87. HICON hCommonGrpIcon = NULL;
  88. HICON hProgmanIcon = NULL;
  89. HICON hIconGlobal = NULL;
  90. HFONT hFontTitle = NULL;
  91. HWND hwndProgman = NULL;
  92. HWND hwndMDIClient = NULL;
  93. HBRUSH hbrWorkspace = NULL;
  94. WORD wPendingHotKey = 0;
  95. DWORD dwDDEAppId = 0;
  96. //HANDLE hPendingWindow = 0;
  97. DWORD dwEditLevel = 0;
  98. WORD wLockError = 0;
  99. UINT uiActivateShellWindowMessage = 0;
  100. UINT uiConsoleWindowMessage = 0;
  101. UINT uiSaveSettingsMessage = 0; // for upedit.exe: User Profile Editor
  102. int nGroups = 0;
  103. int dyBorder;
  104. int iDlgIconId;
  105. int iDlgIconIndex;
  106. int cxIconSpace;
  107. int cyIconSpace;
  108. int cxOffset;
  109. int cyOffset;
  110. int cxArrange;
  111. int cyArrange;
  112. int cxIcon;
  113. int cyIcon;
  114. PGROUP pFirstGroup = NULL;
  115. PGROUP pCurrentGroup = NULL;
  116. PGROUP pActiveGroup = NULL;
  117. PGROUP *pLastGroup = &pFirstGroup;
  118. PGROUP pExecingGroup = NULL;
  119. PITEM pExecingItem = NULL;
  120. RECT rcDrag = { 0,0,0,0 };
  121. HWND hwndDrag = 0;
  122. WORD wNewSelection;
  123. UINT uiHelpMessage; // stuff for help
  124. UINT uiBrowseMessage; // stuff for help
  125. WORD wMenuID = 0;
  126. HANDLE hSaveMenuHandle = 0L; /*Save hMenu into one variable*/
  127. WORD wSaveFlags = 0; /*Save flags into another*/
  128. HANDLE hSaveMenuHandleAroundSendMessage; /*Save hMenu into one variable*/
  129. WORD wSaveFlagsAroundSendMessage; /*Save flags into another*/
  130. WORD wSaveMenuIDAroundSendMessage;
  131. DWORD dwContext = 0L;
  132. HHOOK hhkMsgFilter = NULL;
  133. BOOL bUseANSIGroups = FALSE;
  134. extern BOOL bInNtSetup;
  135. extern VOID TMMain(void);
  136. HANDLE hTMThread = NULL;
  137. BOOL FAR PASCAL CheckHotKey(WPARAM wParam, LPARAM lParam);
  138. /*** main -- Program entry point (was WinMain).
  139. *
  140. *
  141. *
  142. * int APIENTRY main(int argc, char *argv[], char *envp[])
  143. *
  144. * ENTRY - int argc - argument count.
  145. * char *argv[] - argument list.
  146. * char *envp[] - environment.
  147. *
  148. * EXIT - TRUE if success, FALSE if not.
  149. * SYNOPSIS -
  150. * WARNINGS -
  151. * EFFECTS -
  152. *
  153. */
  154. int __cdecl main(
  155. int argc,
  156. char *argv[],
  157. char *envp[])
  158. {
  159. MSG msg;
  160. HANDLE hInst;
  161. LPTSTR lpszCmdLine = NULL;
  162. int nCmdShow = SW_SHOWNORMAL;
  163. DWORD dwThreadID;
  164. DWORD dwEvent;
  165. #ifdef DEBUG_PROGMAN_DDE
  166. {
  167. TCHAR szDebug[300];
  168. wsprintf (szDebug, TEXT("%d PROGMAN: Starting\r\n"),
  169. GetTickCount());
  170. OutputDebugString(szDebug);
  171. }
  172. #endif
  173. hInst = GetModuleHandle(NULL);
  174. if (argc > 1) {
  175. //
  176. // Get the command line, sans program name.
  177. //
  178. lpszCmdLine = SkipProgramName(GetCommandLine());
  179. }
  180. /*
  181. * Initialize the window classes and other junk.
  182. */
  183. if (!AppInit(hInst, lpszCmdLine, nCmdShow)) {
  184. return FALSE;
  185. }
  186. //
  187. // Don't start the taskman thread if progman is started from NTSETUP.
  188. //
  189. if (!bInNtSetup) {
  190. HKEY hkeyWinlogon;
  191. DWORD dwType;
  192. TCHAR szBuffer[MAX_PATH];
  193. DWORD cbBuffer;
  194. BOOL bUseDefaultTaskman = TRUE;
  195. //
  196. // Check if a replacement taskman exits. First open the Taskman
  197. // entry in winlogon's settings.
  198. //
  199. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  200. TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"),
  201. 0,
  202. KEY_READ,
  203. &hkeyWinlogon) == ERROR_SUCCESS) {
  204. //
  205. // Query the taskman name.
  206. //
  207. cbBuffer = sizeof(szBuffer);
  208. if (RegQueryValueEx(hkeyWinlogon,
  209. TEXT("Taskman"),
  210. 0,
  211. &dwType,
  212. (LPBYTE)szBuffer,
  213. &cbBuffer) == ERROR_SUCCESS) {
  214. //
  215. // The taskman entry exits. Confirm that it is not NULL.
  216. //
  217. if (szBuffer[0] != TEXT('\0')) {
  218. //
  219. // Try to spawn the taskman replacement. If
  220. // the spawning succeeds, ExecProgram will return 0.
  221. //
  222. if (ExecProgram (szBuffer, NULL, NULL, FALSE,
  223. 0, 0, FALSE) == 0) {
  224. bUseDefaultTaskman = FALSE;
  225. }
  226. }
  227. }
  228. //
  229. // Close the registry key.
  230. //
  231. RegCloseKey (hkeyWinlogon);
  232. }
  233. //
  234. // Check to see if we should spawn the default taskman.
  235. //
  236. if (bUseDefaultTaskman) {
  237. hTMThread = CreateThread(NULL, (DWORD)0,
  238. (LPTHREAD_START_ROUTINE)TMMain,
  239. (LPVOID)NULL, 0, &dwThreadID);
  240. }
  241. }
  242. #ifdef DEBUG_PROGMAN_DDE
  243. {
  244. TCHAR szDebug[300];
  245. wsprintf (szDebug, TEXT("%d PROGMAN: Entering message loop\r\n"),
  246. GetTickCount());
  247. OutputDebugString(szDebug);
  248. }
  249. #endif
  250. //
  251. // Messaging Loop.
  252. //
  253. while (TRUE) {
  254. while (PeekMessage(&msg, (HWND)NULL, 0, 0, PM_REMOVE)) {
  255. if (msg.message == WM_QUIT) {
  256. #ifdef DEBUG_PROGMAN_DDE
  257. {
  258. TCHAR szDebug[300];
  259. wsprintf (szDebug, TEXT("%d PROGMAN: Exiting\r\n"),
  260. GetTickCount());
  261. OutputDebugString(szDebug);
  262. }
  263. #endif
  264. return (int)msg.wParam;
  265. }
  266. /*
  267. * First test if this is a hot key.
  268. *
  269. */
  270. if (msg.message == WM_SYSKEYDOWN || msg.message == WM_KEYDOWN) {
  271. if (CheckHotKey(msg.wParam, msg.lParam))
  272. continue;
  273. }
  274. /*
  275. * Since we use RETURN as an accelerator we have to manually
  276. * restore ourselves when we see VK_RETURN and we are minimized.
  277. */
  278. if (msg.message == WM_SYSKEYDOWN && msg.wParam == VK_RETURN &&
  279. IsIconic(hwndProgman)) {
  280. ShowWindow(hwndProgman, SW_NORMAL);
  281. } else {
  282. if ((hwndMDIClient == NULL ||
  283. !TranslateMDISysAccel(hwndMDIClient, &msg)) &&
  284. (hwndProgman == NULL ||
  285. !TranslateAccelerator(hwndProgman, hAccel, &msg))) {
  286. TranslateMessage(&msg);
  287. DispatchMessage(&msg);
  288. }
  289. }
  290. }
  291. dwEvent = MsgWaitForMultipleObjects(2, gahEvents, FALSE,
  292. INFINITE, QS_ALLINPUT);
  293. if (dwEvent < (WAIT_OBJECT_0 + 2)) {
  294. HandleGroupKeyChange((dwEvent == (WAIT_OBJECT_0 + 1)));
  295. }
  296. }
  297. // return msg.wParam;
  298. }
  299. /*** MyMessageBox --
  300. *
  301. *
  302. * int APIENTRY MyMessageBox(HWND hWnd, WORD idTitle, WORD idMessage, LPSTR lpsz, WORD wStyle)
  303. *
  304. * ENTRY - HWND hWnd
  305. * WORD idTitle
  306. * WORD idMessage
  307. * LPSTR lpsz
  308. * WORD wStyle
  309. *
  310. * EXIT - int xx - Looks like -1 is error, otherwise result.
  311. *
  312. * SYNOPSIS - ???
  313. *
  314. * WARNINGS -
  315. * EFFECTS -
  316. *
  317. */
  318. int APIENTRY MyMessageBox(HWND hWnd, WORD idTitle, WORD idMessage, LPTSTR psz, WORD wStyle)
  319. {
  320. TCHAR szTempField[MAXMESSAGELEN];
  321. int iMsgResult;
  322. if (bInDDE){
  323. return(1);
  324. }
  325. if (!LoadString(hAppInstance, idTitle, szTitle, CharSizeOf(szTitle))){
  326. goto MessageBoxOOM;
  327. }
  328. if (idMessage < 32){
  329. if (!LoadString(hAppInstance, IDS_UNKNOWNMSG, szTempField, CharSizeOf(szTempField))){
  330. goto MessageBoxOOM;
  331. }
  332. wsprintf(szMessage, szTempField, idMessage);
  333. }
  334. else{
  335. if (!LoadString(hAppInstance, idMessage, szTempField, CharSizeOf(szTempField)))
  336. goto MessageBoxOOM;
  337. if (psz)
  338. wsprintf(szMessage, szTempField, (LPTSTR)psz);
  339. else
  340. lstrcpy(szMessage, szTempField);
  341. }
  342. if (hWnd){
  343. hWnd = GetLastActivePopup(hWnd);
  344. }
  345. iMsgResult = MessageBox(hWnd, szMessage, szTitle, wStyle );
  346. if (iMsgResult == -1){
  347. MessageBoxOOM:
  348. MessageBox(GetLastActivePopup(hwndProgman), szOOMExitMsg, szOOMExitTitle, MB_SYSTEMMODAL | MB_ICONHAND | MB_OK);
  349. }
  350. return(iMsgResult);
  351. }
  352. /*** MessageFilter --
  353. *
  354. *
  355. * int APIENTRY MessageFilter(int nCode, WPARAM wParam, LPMSG lpMsg)
  356. *
  357. * ENTRY - int nCode
  358. * WPARAM wParam
  359. * WORD idMessage
  360. * LPMSG lpMsg
  361. *
  362. * EXIT - int xx - Looks like 0 is error, otherwise 1 is success
  363. *
  364. * SYNOPSIS - ???
  365. *
  366. * WARNINGS -
  367. * EFFECTS -
  368. *
  369. */
  370. LRESULT APIENTRY MessageFilter(int nCode, WPARAM wParam, LPARAM lParam)
  371. {
  372. LPMSG lpMsg = (LPMSG)lParam;
  373. if (nCode < 0){
  374. goto DefHook;
  375. }
  376. if (nCode == MSGF_MENU) {
  377. if (lpMsg->message == WM_KEYDOWN && lpMsg->wParam == VK_F1) {
  378. /* Window of menu we want help for is in loword of lParam.*/
  379. PostMessage(hwndProgman, uiHelpMessage, MSGF_MENU, (LPARAM)lpMsg->hwnd);
  380. return(1);
  381. }
  382. } else if (nCode == MSGF_DIALOGBOX) {
  383. if (lpMsg->message == WM_KEYDOWN && lpMsg->wParam == VK_F1) {
  384. /* Dialog box we want help for is in loword of lParam */
  385. PostMessage(hwndProgman, uiHelpMessage, MSGF_DIALOGBOX, (LPARAM)lpMsg->hwnd);
  386. return(1);
  387. }
  388. }
  389. else{
  390. DefHook:
  391. return DefHookProc(nCode, wParam, lParam, &hhkMsgFilter);
  392. }
  393. return(0);
  394. }