windows-nt/Source/XPSP1/NT/shell/osshell/progman/progman.c
2020-09-26 16:20:57 +08:00

470 lines
13 KiB
C

/*
* 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);
}