/* * progman.c * * Copyright (c) 1991, Microsoft Corporation * * DESCRIPTION * * This file is for support of program manager under NT Windows. * This file is/was ported from progman.c (program manager). * * MODIFICATION HISTORY * Initial Version: x/x/90 Author Unknown, since he didn't feel * like commenting the code... * * NT 32b Version: 1/16/91 Jeff Pack * Intitial port to begin. * * */ #include "progman.h" #include "uniconv.h" BOOL UserIsAdmin = FALSE; BOOL AccessToCommonGroups= FALSE; BOOL bLoadIt = FALSE; BOOL bMinOnRun = FALSE; BOOL bArranging = FALSE; BOOL bAutoArrange = FALSE; BOOL bAutoArranging = FALSE; BOOL bExitWindows = FALSE; BOOL bScrolling = FALSE; BOOL bSaveSettings = TRUE; BOOL bLoadEvil = FALSE; BOOL bMove = FALSE; BOOL bInDDE = FALSE; BOOL bIconTitleWrap = TRUE; BOOL fInExec = FALSE; BOOL fNoRun = FALSE; BOOL fNoClose = FALSE; BOOL fNoSave = FALSE; BOOL fNoFileMenu = FALSE; BOOL fExiting = FALSE; BOOL fLowMemErrYet = FALSE; BOOL fErrorOnExtract = FALSE; BOOL bFrameSysMenu = FALSE; TCHAR szNULL[] = TEXT(""); TCHAR szProgman[] = TEXT("progman"); // // Program Manager's Settings keys // TCHAR szWindow[] = TEXT("Window"); TCHAR szOrder[] = TEXT("UNICODE Order"); TCHAR szAnsiOrder[] = TEXT("Order"); TCHAR szStartup[] = TEXT("startup"); TCHAR szAutoArrange[] = TEXT("AutoArrange"); TCHAR szSaveSettings[] = TEXT("SaveSettings"); TCHAR szMinOnRun[] = TEXT("MinOnRun"); TCHAR szFocusOnCommonGroup[] = TEXT("FocusOnCommonGroup"); TCHAR szProgmanHelp[] = TEXT("PROGMAN.HLP"); TCHAR szTitle[MAXTITLELEN+1]; TCHAR szMessage[MAXMESSAGELEN+1]; TCHAR szNameField[MAXITEMPATHLEN+1]; TCHAR szPathField[MAXITEMPATHLEN+1]; TCHAR szDirField[MAXITEMPATHLEN+1]; TCHAR szIconPath[MAXITEMPATHLEN+1]; TCHAR szOriginalDirectory[MAXITEMPATHLEN+1]; TCHAR szWindowsDirectory[MAXITEMPATHLEN+1]; TCHAR szOOMExitMsg[64]; TCHAR szOOMExitTitle[32]; /* for Program Groups in Registry */ HKEY hkeyProgramManager = NULL; // progman.ini key HKEY hkeyPMSettings = NULL; // keys corresponding to progman.ini sections HKEY hkeyPMRestrict = NULL; HKEY hkeyPMGroups = NULL; HKEY hkeyPMCommonGroups = NULL; TCHAR szAnsiProgramGroups[] = TEXT("Program Groups"); // registry key for groups HKEY hkeyProgramGroups = NULL; HKEY hkeyAnsiProgramGroups = NULL; HKEY hkeyCommonGroups = NULL; PSECURITY_ATTRIBUTES pSecurityAttributes = NULL; PSECURITY_ATTRIBUTES pAdminSecAttr = NULL; HANDLE hAccel; HINSTANCE hAppInstance; HANDLE hCommdlg = NULL; HICON hDlgIcon = NULL; HICON hItemIcon = NULL; HICON hGroupIcon = NULL; HICON hCommonGrpIcon = NULL; HICON hProgmanIcon = NULL; HICON hIconGlobal = NULL; HFONT hFontTitle = NULL; HWND hwndProgman = NULL; HWND hwndMDIClient = NULL; HBRUSH hbrWorkspace = NULL; WORD wPendingHotKey = 0; DWORD dwDDEAppId = 0; //HANDLE hPendingWindow = 0; DWORD dwEditLevel = 0; WORD wLockError = 0; UINT uiActivateShellWindowMessage = 0; UINT uiConsoleWindowMessage = 0; UINT uiSaveSettingsMessage = 0; // for upedit.exe: User Profile Editor int nGroups = 0; int dyBorder; int iDlgIconId; int iDlgIconIndex; int cxIconSpace; int cyIconSpace; int cxOffset; int cyOffset; int cxArrange; int cyArrange; int cxIcon; int cyIcon; PGROUP pFirstGroup = NULL; PGROUP pCurrentGroup = NULL; PGROUP pActiveGroup = NULL; PGROUP *pLastGroup = &pFirstGroup; PGROUP pExecingGroup = NULL; PITEM pExecingItem = NULL; RECT rcDrag = { 0,0,0,0 }; HWND hwndDrag = 0; WORD wNewSelection; UINT uiHelpMessage; // stuff for help UINT uiBrowseMessage; // stuff for help WORD wMenuID = 0; HANDLE hSaveMenuHandle = 0L; /*Save hMenu into one variable*/ WORD wSaveFlags = 0; /*Save flags into another*/ HANDLE hSaveMenuHandleAroundSendMessage; /*Save hMenu into one variable*/ WORD wSaveFlagsAroundSendMessage; /*Save flags into another*/ WORD wSaveMenuIDAroundSendMessage; DWORD dwContext = 0L; HHOOK hhkMsgFilter = NULL; BOOL bUseANSIGroups = FALSE; extern BOOL bInNtSetup; extern VOID TMMain(void); HANDLE hTMThread = NULL; BOOL FAR PASCAL CheckHotKey(WPARAM wParam, LPARAM lParam); /*** main -- Program entry point (was WinMain). * * * * int APIENTRY main(int argc, char *argv[], char *envp[]) * * ENTRY - int argc - argument count. * char *argv[] - argument list. * char *envp[] - environment. * * EXIT - TRUE if success, FALSE if not. * SYNOPSIS - * WARNINGS - * EFFECTS - * */ int __cdecl main( int argc, char *argv[], char *envp[]) { MSG msg; HANDLE hInst; LPTSTR lpszCmdLine = NULL; int nCmdShow = SW_SHOWNORMAL; DWORD dwThreadID; DWORD dwEvent; #ifdef DEBUG_PROGMAN_DDE { TCHAR szDebug[300]; wsprintf (szDebug, TEXT("%d PROGMAN: Starting\r\n"), GetTickCount()); OutputDebugString(szDebug); } #endif hInst = GetModuleHandle(NULL); if (argc > 1) { // // Get the command line, sans program name. // lpszCmdLine = SkipProgramName(GetCommandLine()); } /* * Initialize the window classes and other junk. */ if (!AppInit(hInst, lpszCmdLine, nCmdShow)) { return FALSE; } // // Don't start the taskman thread if progman is started from NTSETUP. // if (!bInNtSetup) { HKEY hkeyWinlogon; DWORD dwType; TCHAR szBuffer[MAX_PATH]; DWORD cbBuffer; BOOL bUseDefaultTaskman = TRUE; // // Check if a replacement taskman exits. First open the Taskman // entry in winlogon's settings. // if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), 0, KEY_READ, &hkeyWinlogon) == ERROR_SUCCESS) { // // Query the taskman name. // cbBuffer = sizeof(szBuffer); if (RegQueryValueEx(hkeyWinlogon, TEXT("Taskman"), 0, &dwType, (LPBYTE)szBuffer, &cbBuffer) == ERROR_SUCCESS) { // // The taskman entry exits. Confirm that it is not NULL. // if (szBuffer[0] != TEXT('\0')) { // // Try to spawn the taskman replacement. If // the spawning succeeds, ExecProgram will return 0. // if (ExecProgram (szBuffer, NULL, NULL, FALSE, 0, 0, FALSE) == 0) { bUseDefaultTaskman = FALSE; } } } // // Close the registry key. // RegCloseKey (hkeyWinlogon); } // // Check to see if we should spawn the default taskman. // if (bUseDefaultTaskman) { hTMThread = CreateThread(NULL, (DWORD)0, (LPTHREAD_START_ROUTINE)TMMain, (LPVOID)NULL, 0, &dwThreadID); } } #ifdef DEBUG_PROGMAN_DDE { TCHAR szDebug[300]; wsprintf (szDebug, TEXT("%d PROGMAN: Entering message loop\r\n"), GetTickCount()); OutputDebugString(szDebug); } #endif // // Messaging Loop. // while (TRUE) { while (PeekMessage(&msg, (HWND)NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) { #ifdef DEBUG_PROGMAN_DDE { TCHAR szDebug[300]; wsprintf (szDebug, TEXT("%d PROGMAN: Exiting\r\n"), GetTickCount()); OutputDebugString(szDebug); } #endif return (int)msg.wParam; } /* * First test if this is a hot key. * */ if (msg.message == WM_SYSKEYDOWN || msg.message == WM_KEYDOWN) { if (CheckHotKey(msg.wParam, msg.lParam)) continue; } /* * Since we use RETURN as an accelerator we have to manually * restore ourselves when we see VK_RETURN and we are minimized. */ if (msg.message == WM_SYSKEYDOWN && msg.wParam == VK_RETURN && IsIconic(hwndProgman)) { ShowWindow(hwndProgman, SW_NORMAL); } else { if ((hwndMDIClient == NULL || !TranslateMDISysAccel(hwndMDIClient, &msg)) && (hwndProgman == NULL || !TranslateAccelerator(hwndProgman, hAccel, &msg))) { TranslateMessage(&msg); DispatchMessage(&msg); } } } dwEvent = MsgWaitForMultipleObjects(2, gahEvents, FALSE, INFINITE, QS_ALLINPUT); if (dwEvent < (WAIT_OBJECT_0 + 2)) { HandleGroupKeyChange((dwEvent == (WAIT_OBJECT_0 + 1))); } } // return msg.wParam; } /*** MyMessageBox -- * * * int APIENTRY MyMessageBox(HWND hWnd, WORD idTitle, WORD idMessage, LPSTR lpsz, WORD wStyle) * * ENTRY - HWND hWnd * WORD idTitle * WORD idMessage * LPSTR lpsz * WORD wStyle * * EXIT - int xx - Looks like -1 is error, otherwise result. * * SYNOPSIS - ??? * * WARNINGS - * EFFECTS - * */ int APIENTRY MyMessageBox(HWND hWnd, WORD idTitle, WORD idMessage, LPTSTR psz, WORD wStyle) { TCHAR szTempField[MAXMESSAGELEN]; int iMsgResult; if (bInDDE){ return(1); } if (!LoadString(hAppInstance, idTitle, szTitle, CharSizeOf(szTitle))){ goto MessageBoxOOM; } if (idMessage < 32){ if (!LoadString(hAppInstance, IDS_UNKNOWNMSG, szTempField, CharSizeOf(szTempField))){ goto MessageBoxOOM; } wsprintf(szMessage, szTempField, idMessage); } else{ if (!LoadString(hAppInstance, idMessage, szTempField, CharSizeOf(szTempField))) goto MessageBoxOOM; if (psz) wsprintf(szMessage, szTempField, (LPTSTR)psz); else lstrcpy(szMessage, szTempField); } if (hWnd){ hWnd = GetLastActivePopup(hWnd); } iMsgResult = MessageBox(hWnd, szMessage, szTitle, wStyle ); if (iMsgResult == -1){ MessageBoxOOM: MessageBox(GetLastActivePopup(hwndProgman), szOOMExitMsg, szOOMExitTitle, MB_SYSTEMMODAL | MB_ICONHAND | MB_OK); } return(iMsgResult); } /*** MessageFilter -- * * * int APIENTRY MessageFilter(int nCode, WPARAM wParam, LPMSG lpMsg) * * ENTRY - int nCode * WPARAM wParam * WORD idMessage * LPMSG lpMsg * * EXIT - int xx - Looks like 0 is error, otherwise 1 is success * * SYNOPSIS - ??? * * WARNINGS - * EFFECTS - * */ LRESULT APIENTRY MessageFilter(int nCode, WPARAM wParam, LPARAM lParam) { LPMSG lpMsg = (LPMSG)lParam; if (nCode < 0){ goto DefHook; } if (nCode == MSGF_MENU) { if (lpMsg->message == WM_KEYDOWN && lpMsg->wParam == VK_F1) { /* Window of menu we want help for is in loword of lParam.*/ PostMessage(hwndProgman, uiHelpMessage, MSGF_MENU, (LPARAM)lpMsg->hwnd); return(1); } } else if (nCode == MSGF_DIALOGBOX) { if (lpMsg->message == WM_KEYDOWN && lpMsg->wParam == VK_F1) { /* Dialog box we want help for is in loword of lParam */ PostMessage(hwndProgman, uiHelpMessage, MSGF_DIALOGBOX, (LPARAM)lpMsg->hwnd); return(1); } } else{ DefHook: return DefHookProc(nCode, wParam, lParam, &hhkMsgFilter); } return(0); }