home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- Module name: PMRest.C
- Programmer : Jeffrey M. Richter.
- *****************************************************************************/
-
- #include "..\nowindws.h"
- #undef NOCTLMGR
- #undef NOKERNEL
- #undef NOMB
- #undef NOMENUS
- #undef NOMSG
- #undef NOSHOWWINDOW
- #undef NOSYSCOMMANDS
- #undef NOUSER
- #undef NOWINOFFSETS
- #undef NOWINMESSAGES
- #include <windows.h>
-
- #include "pmrest.h"
-
- // Menu IDs from Program Manager's menu.
- #define IDM_AUTO_ARRANGE (0xC9)
- #define IDM_PMRESTOREABOUT (4444)
- #define IDM_PMRESTOREREMOVE (4445)
-
- char _szAppName[] = "Program Manager Restore";
-
- // Class name of the Program Manager window.
- char _szPMClass[] = "PROGMAN";
-
- // Address for original window procedure.
- FARPROC _fpOrigPMProc = NULL;
-
- // Window handle of Program Manager.
- HWND _hWndPM = NULL;
-
- // Our instance handle.
- HANDLE _hInstance = NULL;
-
- // Our task handle.
- HANDLE _PMRestoreTask = NULL;
-
- // Forward reference to subclass function.
- LONG FAR PASCAL PMSubClass (HWND, WORD, WORD, LONG);
-
-
- int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdLine, int cmdShow) {
- MSG msg;
- DWORD dwWinFlags;
- HMENU hMenu, hMenuPopup;
- int nTopLevelMenuNum;
-
- dwWinFlags = GetWinFlags();
- if ((dwWinFlags & WF_LARGEFRAME) || (dwWinFlags & WF_SMALLFRAME)) {
- MessageBox(GetFocus(), "PM Restore cannot run with EMS memory.",
- _szAppName, MB_OK | MB_SYSTEMMODAL);
- return(FALSE);
- }
-
- // Don't allow second instance of "PMRest" to run.
- if (hPrevInstance != NULL) {
- MessageBox(GetFocus(), "Application already running.",
- _szAppName, MB_OK | MB_SYSTEMMODAL);
- return(FALSE);
- }
-
- // Get our data-instance handle and store it in a global variable.
- _hInstance = hInstance;
-
- // Get our task-instance handle and store it in a global variable.
- _PMRestoreTask = GetCurrentTask();
-
-
- // Find window handle of Program Manager.
- // Do not specify a caption because the Program Manager's caption
- // changes depending whether a group is maximized or not.
- _hWndPM = FindWindow(_szPMClass, NULL);
-
- if (_hWndPM == NULL) {
-
- // If the Program Manager's window couldn't be found, try to
- // execute the Program Manager application.
- // This happens if PMREST.EXE is in the LOAD= line of the WIN.INI file.
- WinExec("ProgMan", SW_SHOW);
- _hWndPM = FindWindow(_szPMClass, NULL);
-
-
- // If still can't find Program Manager, we can't subclass it and
- // must terminate.
- if (_hWndPM == NULL) {
- MessageBox(GetFocus(), "Cannot find Program Manager.",
- _szAppName, MB_OK);
- return(FALSE);
- }
- }
-
-
- // Get Menu handle to Program Manager's "Options" menu
- hMenu = GetMenu(_hWndPM);
-
- // Get number of top level menu items
- nTopLevelMenuNum = GetMenuItemCount(hMenu) - 1;
- while (nTopLevelMenuNum) {
-
- // Get handle to popup menu.
- hMenuPopup = GetSubMenu(hMenu, nTopLevelMenuNum);
-
-
- // Is the first option in the popup menu IDM_AUTO_ARRANGE?
- if (IDM_AUTO_ARRANGE == GetMenuItemID(hMenuPopup, 0)) {
-
- // Add a separator bar & "About PM Restore..." option to this menu
- AppendMenu(hMenuPopup, MF_SEPARATOR, 0, 0);
- AppendMenu(hMenuPopup, MF_ENABLED | MF_STRING,
- IDM_PMRESTOREABOUT, "A&bout PM Restore...");
- AppendMenu(hMenuPopup, MF_ENABLED | MF_STRING,
- IDM_PMRESTOREREMOVE, "&Remove PM Restore");
-
- break; // Stop check menus
- }
- nTopLevelMenuNum--; // Try next menu
- }
-
- DrawMenuBar(_hWndPM); // Update the new menu bar
-
-
- // Save present window function for the Program Manager in global variable
- _fpOrigPMProc = (FARPROC) GetWindowLong(_hWndPM, GWL_WNDPROC);
-
-
- // Set new window function for the Program Manager
- SetWindowLong(_hWndPM, GWL_WNDPROC,
- (LONG) MakeProcInstance((FARPROC) PMSubClass, hInstance));
-
-
- // Running PMRest.EXE will minimize the Program Manager if
- // "Minimize on Use" is selected in the Program Manager's Options menu.
- // Since there will not be an application switch, our subclassing will
- // not restore the Program Manager automatically, so we must do it.
- PostMessage(_hWndPM, WM_SYSCOMMAND, SC_RESTORE, 0);
-
-
- // Begin message loop. This is so that our application doesn't terminate.
- // If we terminated, our subclass function would be removed from memory.
- // When Windows tried to call it, it would jump to garbage.
- while (GetMessage(&msg, NULL, 0, 0)) DispatchMessage(&msg);
-
- return(0);
- }
-
-
-
-
- // Function to process About Box.
- BOOL FAR PASCAL AboutProc (HWND hDlg, WORD wMsg, WORD wParam, LONG lParam) {
- char szBuffer[100];
- BOOL fProcessed = TRUE;
-
- switch (wMsg) {
-
- case WM_INITDIALOG:
- // Set version static window to have date and time of compilation.
- wsprintf(szBuffer, "%s at %s", (LPSTR) __DATE__, (LPSTR) __TIME__);
- SetWindowText(GetDlgItem(hDlg, ID_VERSION), szBuffer);
- break;
-
- case WM_COMMAND:
- switch (wParam) {
- case IDOK: case IDCANCEL:
- if (HIWORD(lParam) == BN_CLICKED)
- EndDialog(hDlg, wParam);
- break;
-
- default:
- break;
- }
- break;
-
- default:
- fProcessed = FALSE; break;
- }
- return(fProcessed);
- }
-
-
-
-
- // Forward reference to function called by EnumWindows.
- BOOL FAR PASCAL AnyAppsRunning (HWND, LONG);
-
-
- // Subclass function for the Program Manager. Any messages for the
- // Program Manager window come here before reaching the original
- // window function.
- LONG FAR PASCAL PMSubClass (HWND hWnd, WORD wMsg, WORD wParam, LONG lParam) {
- FARPROC fpProc;
- BOOL fAnyWindowsUp, fCallOrigProc = TRUE;
- LONG lResult = 0L;
- HMENU hMenu, hMenuPopup;
- int nTopLevelMenuNum;
-
- switch (wMsg) {
-
- case WM_ACTIVATEAPP:
- // Program Manager is either being activated or deactivated.
-
- if (wParam == 0) break; // Program Manager is being deactivated.
- if (!IsIconic(hWnd)) break; // Program Manager isn't an icon.
-
- // Program Manager is being made active & is an icon.
- // We have to check to see if any other applications are running.
- fpProc = MakeProcInstance(AnyAppsRunning, _hInstance);
- fAnyWindowsUp = (EnumWindows(fpProc, 0l) == 0);
- FreeProcInstance(fpProc);
-
- // If the enumeration was stopped prematurely, there must be
- // at least one other application running.
- if (fAnyWindowsUp) break;
-
- // No other applications are running, restore the Program Manager
- // to "open" state.
- ShowWindow(hWnd, SW_RESTORE);
- break;
-
- case WM_COMMAND:
- switch (wParam) {
-
- case IDM_PMRESTOREABOUT:
- // Our added menu option to display
- // "About PM Restore..." was chosen.
- fpProc = MakeProcInstance(AboutProc, _hInstance);
- DialogBox(_hInstance, "About", hWnd, fpProc);
- FreeProcInstance(fpProc);
-
- // Don't pass this message to Original Program Manager
- // window procedure because it wouldn't know what
- // to do with it.
- fCallOrigProc = FALSE;
- break;
-
- case IDM_PMRESTOREREMOVE:
- // Stop window sub-classing by putting back the address of
- // the original window procedure.
- SetWindowLong(hWnd, GWL_WNDPROC, (LONG) _fpOrigPMProc);
-
-
- // Get Menu handle to Program Manager's "Options" menu
- hMenu = GetMenu(hWnd);
- RemoveMenu(hMenu, IDM_PMRESTOREABOUT, MF_BYCOMMAND);
- RemoveMenu(hMenu, IDM_PMRESTOREREMOVE, MF_BYCOMMAND);
-
- // Get number of top level menu items
- nTopLevelMenuNum = GetMenuItemCount(hMenu) - 1;
- while (nTopLevelMenuNum) {
-
- // Get handle to popup menu.
- hMenuPopup = GetSubMenu(hMenu, nTopLevelMenuNum);
-
- // Is the first option in the popup menu IDM_AUTO_ARRANGE?
- if (IDM_AUTO_ARRANGE == GetMenuItemID(hMenuPopup, 0)) {
-
- // Remove separator bar.
- RemoveMenu(hMenuPopup, GetMenuItemCount(hMenuPopup) - 1,
- MF_BYPOSITION);
-
- break; // Stop check menus
- }
- nTopLevelMenuNum--; // Try next menu
- }
-
- DrawMenuBar(hWnd); // Update the new menu bar
-
-
- // Post a WM_QUIT message to our application to remove it from
- // memory.
- PostAppMessage(_PMRestoreTask, WM_QUIT, 0, 0);
- break;
-
- default: // Pass other WM_COMMAND's to original procedure
- break;
- }
- break;
-
- default: // Pass other messages to original procedure
- break;
-
- }
-
- if (fCallOrigProc) {
- // Call original window procedure and return the result to whoever
- // sent this message to the Program Manager.
- lResult = CallWindowProc(_fpOrigPMProc, hWnd, wMsg, wParam, lParam);
- }
-
- return(lResult);
- }
-
-
-
-
- // Window's callback function to determine if any windows exist
- // that should stop us from restoring the Program Manager
- BOOL FAR PASCAL AnyAppsRunning (HWND hWnd, LONG lParam) {
- GetCurrentTask();
-
- // If window is the Window's desktop, continue enumeration
- if (hWnd == GetDesktopWindow())
- return(1);
-
- // If the window is invisible (hidden), continue enumeration
- if (!IsWindowVisible(hWnd))
- return(1);
-
- // If window is associated with the Program Manager, continue enumeration
- if (GetWindowTask(_hWndPM) == GetWindowTask(hWnd))
- return(1);
-
- // Any other type of window, stop enumeration
- return(0);
- }
-