home *** CD-ROM | disk | FTP | other *** search
- // Includes
- // --------
- #define INCL_WIN
- #define INCL_DOS
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <os2.h>
-
- #include "MDI.H"
- #include "MDI.RH"
-
- #include "AllocMem.H"
- #include "TellUser.H"
-
-
- // Constants
- // ---------
- #define MAX_STRING 256 // Maximum string size
- #define INSERT_TITLE 1 // Insert title command code
- #define REMOVE_TITLE 2 // Remove title command code
- #define AWP_TILED 1 // Arrange tiled flag
- #define AWP_CASCADED 2 // Arrange cascaded flag
- #define CASC_EDGE_NUM 2 // Cascaded arrange edge
- #define CASC_EDGE_DENOM 3 // Cascaded arrange edge
- #define ICON_PARK_NUM 5 // Icon park
- #define ICON_PARK_DENOM 3 // Icon park
-
- const USHORT cbExtraData // Extra window storage
- = (2 * sizeof (PVOID));
-
-
- // Desktop Creation Parameters
- // ---------------------------
- typedef struct _DESKTOPCREATEPARMS
- {USHORT cbDeskData; // Size of user desktop data
- PCHAR pszExit; // Exit menu item text
- PCHAR pszWindow; // Window menu item text
- } DESKTOPCREATEPARMS;
-
- typedef DESKTOPCREATEPARMS *PDESKTOPCREATEPARMS;
-
-
- // Document Creation Parameters
- // ----------------------------
- typedef struct _DOCUMENTCREATEPARMS
- {USHORT cbDocData; // Size of user document data
- USHORT cbInstData; // Size of user instance data
- ULONG flCreateFlags; // Copy of frame creation flags
- HMODULE hmodResources; // Copy of frame resources
- USHORT idResources; // Copy of frame resources id
- PFNWP pfnUser; // User window procedure
- } DOCUMENTCREATEPARMS;
-
- typedef DOCUMENTCREATEPARMS *PDOCUMENTCREATEPARMS;
-
-
- // Desktop Intra-instance Data
- // ---------------------------
- typedef struct _INSTDESKTOP
- {HWND hwndDocument; // Active document window
- HWND hwndDesktop; // Desktop window
- HWND hwndParent; // Its frame's parent
- HWND hwndFrame; // Its frame
- HWND hwndMenu; // Its menu
- HACCEL haccel; // Its accelerator table
- CHAR szTitle[MAX_STRING]; // Its title
- SWP swp; // Its position
- MENUITEM miWindow; // Window menu
- MENUITEM miSysMenu; // Maximized child system menu
- PVOID pvDeskData; // -->user desktop data
- BOOL fTileAlways; // TRUE == Tile always
- BOOL fCascadeAlways; // TRUE == Cascade always
- PCHAR pszExit; // Exit menu item text
- PCHAR pszWindow; // Window menu item text
- USHORT idDesktop; // Desktop id
- } INSTDESKTOP;
-
- typedef INSTDESKTOP *PINSTDESKTOP;
-
-
- // Document Intra-instance Data
- // ----------------------------
- typedef struct _INSTDOCUMENT
- {HWND hwndDocument; // Document window
- HWND hwndDesktop; // Desktop window
- HWND hwndFrame; // Its frame
- HWND hwndSysMenu; // Its system menu
- HWND hwndTitleBar; // Its title bar
- HWND hwndMinMax; // Its min/max buttons
- HWND hwndVScroll; // Its vertical scroll bar
- HWND hwndHScroll; // Its horizontal scroll bar
- USHORT idFrame; // Its frame id
- HACCEL haccel; // Its accelerator table
- CHAR szTitle[MAX_STRING]; // Its title
- SHORT iTitle; // Its title index
- SWP swp; // Its position
- USHORT usState; // Its state
- USHORT cbDocData; // Size of user document data
- USHORT cbInstData; // Size of user instance data
- PFNWP pfnUser; // User window procedure
- ULONG flCreateFlags; // Frame creation flags
- HMODULE hmodResources; // Frame resources
- USHORT idResources; // Frame resources id
- USHORT idDesktop; // Desktop id
- PVOID pvDocData; // -->user document data
- PVOID pvInstData; // -->user instance data
- } INSTDOCUMENT;
-
- typedef INSTDOCUMENT *PINSTDOCUMENT;
-
-
- // Function Declarations (see also MDI.H)
- // --------------------------------------
- MRESULT FAR MDIDesktopClose (PINSTDESKTOP);
- MRESULT FAR MDIDesktopCommand (PINSTDESKTOP, USHORT);
- MRESULT FAR MDIDesktopCreate (HWND, PDESKTOPCREATEPARMS);
- MRESULT FAR MDIDesktopDestroy (PINSTDESKTOP);
- MRESULT FAR MDIDesktopPaint (PINSTDESKTOP);
- MRESULT FAR MDIDocumentActivate (PINSTDOCUMENT, BOOL);
- VOID FAR MDIDocumentArrange (HWND, USHORT);
- VOID FAR MDIDocumentArrangeCascaded (PRECTL, SHORT, PSWP);
- VOID FAR MDIDocumentArrangeTiled (PRECTL, SHORT, PSWP);
- VOID FAR MDIDocumentClone (PINSTDOCUMENT);
- MRESULT FAR MDIDocumentClose (PINSTDOCUMENT);
- MRESULT FAR MDIDocumentCommand (PINSTDOCUMENT, USHORT);
- MRESULT FAR MDIDocumentCreate (HWND, PDOCUMENTCREATEPARMS);
- MRESULT FAR MDIDocumentDestroy (PINSTDOCUMENT);
- VOID FAR MDIDocumentHide (PINSTDOCUMENT);
- MRESULT FAR MDIDocumentMinMax (PINSTDOCUMENT, PSWP);
- MRESULT FAR MDIDocumentPaint (PINSTDOCUMENT);
- PINSTDOCUMENT FAR MDIDocumentTitlesRebuild (PINSTDOCUMENT, USHORT);
- MRESULT EXPENTRY MDIDocumentUnhideDlgProc (HWND, USHORT, MPARAM, MPARAM);
- VOID EXPENTRY MDIInitialize (HAB);
- HACCEL FAR MDILoadAccelTable (USHORT);
- HWND FAR MDILoadDialog (HWND, PFNWP, USHORT, PVOID);
- HWND FAR MDILoadMenu (HWND, USHORT);
-
-
- // Function: MDICreateDesktop - Create MDI Desktop
- // -----------------------------------------------
- HWND FAR MDICreateDesktop (pfnUser, flFrameFlags, pszTitle, hmodResources,
- idResources, phwndClient, cbDeskData, idDesktop, pszExit, pszWindow)
-
- PFNWP pfnUser; // User window procedure
- ULONG flFrameFlags; // Frame creation flags
- PCHAR pszTitle; // Desktop title
- HMODULE hmodResources; // Module that contains resources
- USHORT idResources; // Resources identifier
- PHWND phwndClient; // -->area to receive desktop handle
- USHORT cbDeskData; // Size of user desktop data
- USHORT idDesktop; // ID of desktop
- PCHAR pszExit; // "Exit" menu text
- PCHAR pszWindow; // Desired "Window" menu text
-
- // Define function data
-
- {HWND hwndFrame; // Frame window
- FRAMECDATA fcdata; // Frame creation parameters
- DESKTOPCREATEPARMS deskcp; // Desktop creation parameters
- PINSTDESKTOP pinst; // -->desktop instance data
-
- // Initialize frame creation parameters
-
- fcdata.cb = sizeof (fcdata);
- fcdata.flCreateFlags = flFrameFlags;
- fcdata.hmodResources = hmodResources;
- fcdata.idResources = idResources;
-
- // Initialize desktop creation parameters
-
- deskcp.cbDeskData = cbDeskData;
- deskcp.pszExit = pszExit;
- deskcp.pszWindow = pszWindow;
-
- // Create desktop frame and client windows
-
- hwndFrame = WinCreateWindow (HWND_DESKTOP, WC_FRAME, pszTitle,
- WS_VISIBLE, 0, 0, 0, 0, NULL, HWND_TOP, idDesktop, &fcdata, NULL);
- if (hwndFrame == NULL) return NULL;
- *phwndClient = WinCreateWindow (hwndFrame, MDI_DESKTOPCLASS, NULL,
- WS_VISIBLE, 0, 0, 0, 0, hwndFrame, HWND_BOTTOM, FID_CLIENT, &deskcp, NULL);
- if (*phwndClient == NULL) return NULL;
-
- // Subclass desktop window procedure
-
- if (pfnUser != NULL)
- WinSubclassWindow (*phwndClient, pfnUser);
-
- // Tell user that desktop has been created
-
- pinst = (PINSTDESKTOP) WinQueryWindowULong (*phwndClient, QWL_USER + sizeof (PVOID));
- WinSendMsg (*phwndClient, WM_CONTROL,
- MPFROM2SHORT (pinst->idDesktop, MDI_NOTIFY_CREATE_DESKTOP),
- (MPARAM) pinst->pvDeskData);
-
- // Return
-
- return hwndFrame;
-
- }
-
-
- // Function: MDICreateDocument - Create MDI Document
- // -------------------------------------------------
- HWND FAR MDICreateDocument (pfnUser, hwndParent, flFrameFlags, pszTitle,
- hmodResources, idResources, phwndClient, cbDocData, cbInstData)
-
- PFNWP pfnUser; // User window procedure
- HWND hwndParent; // Document parent
- ULONG flFrameFlags; // Frame creation flags
- PCHAR pszTitle; // Document title
- HMODULE hmodResources; // Module that contains resources
- USHORT idResources; // Resources identifier
- PHWND phwndClient; // -->area to receive document handle
- USHORT cbDocData; // Size of user document data
- USHORT cbInstData; // Size of user document data
-
- // Define function data
-
- {HWND hwndFrame; // Frame window
- FRAMECDATA fcdata; // Frame creation parameters
- DOCUMENTCREATEPARMS doccp; // Document creation parameters
- PINSTDOCUMENT pinst; // -->document instance data
-
- // Initialize frame creation parameters
-
- fcdata.cb = sizeof (fcdata);
- fcdata.flCreateFlags = flFrameFlags;
- fcdata.hmodResources = hmodResources;
- fcdata.idResources = idResources;
-
- // Initialize document creation parameters
-
- doccp.cbDocData = cbDocData;
- doccp.cbInstData = cbInstData;
- doccp.pfnUser = pfnUser;
- doccp.flCreateFlags = flFrameFlags;
- doccp.hmodResources = hmodResources;
- doccp.idResources = idResources;
-
- // Create document frame and client windows
-
- hwndFrame = WinCreateWindow (hwndParent, WC_FRAME, pszTitle,
- WS_VISIBLE, 0, 0, 0, 0, NULL, HWND_TOP, 1, &fcdata, NULL);
- if (hwndFrame == NULL) return NULL;
- *phwndClient = WinCreateWindow (hwndFrame, MDI_DOCUMENTCLASS, NULL,
- WS_VISIBLE, 0, 0, 0, 0, hwndFrame, HWND_BOTTOM, FID_CLIENT, &doccp, NULL);
- if (*phwndClient == NULL) return NULL;
-
- // Subclass document window procedure
-
- if (pfnUser != NULL)
- WinSubclassWindow (*phwndClient, pfnUser);
-
- // Tell user that document has been created
-
- pinst = (PINSTDOCUMENT) WinQueryWindowULong (*phwndClient, QWL_USER + sizeof (PVOID));
- WinSendMsg (*phwndClient, WM_CONTROL,
- MPFROM2SHORT (pinst->idDesktop, MDI_NOTIFY_CREATE_DOCUMENT),
- (MPARAM) pinst->pvInstData);
-
- // Return
-
- return hwndFrame;
-
- }
-
-
- // Function: MDIDesktopClose - Close MDI Desktop
- // ---------------------------------------------
- MRESULT FAR MDIDesktopClose (pinst)
-
- PINSTDESKTOP pinst; // -->desktop instance data
-
- // Post "quit"
-
- {WinPostMsg (NULL, WM_QUIT, NULL, NULL);
-
- // Destroy MDI desktop window
-
- WinDestroyWindow (pinst->hwndFrame);
-
- // Indicate close handled
-
- return (MRESULT) NULL;
-
- }
-
-
- // Function: MDIDesktopCommand - Handle MDI Desktop Command
- // --------------------------------------------------------
- MRESULT FAR MDIDesktopCommand (pinst, usCommand)
-
- PINSTDESKTOP pinst; // -->desktop instance data
- USHORT usCommand; // WM_COMMAND code
-
- // Define function data
-
- {PINSTDOCUMENT pinstDocument; // -->document instance data
- HWND hdlg; // Unhide dialog box
-
- // Act upon command code
-
- switch (usCommand)
-
- // Handle Desktop system menu command by passing the system equivalent
- // to the desktop frame
-
- {case CMD_DESKTOP_SIZE:
- case CMD_DESKTOP_MOVE:
- case CMD_DESKTOP_MINIMIZE:
- case CMD_DESKTOP_MAXIMIZE:
- case CMD_DESKTOP_CLOSE:
- case CMD_DESKTOP_NEXT:
- case CMD_DESKTOP_APPMENU:
- case CMD_DESKTOP_SYSMENU:
- case CMD_DESKTOP_RESTORE:
- WinSendMsg (pinst->hwndFrame, WM_SYSCOMMAND,
- MPFROMSHORT ((usCommand - CMD_DESKTOP_BASE) | SC_SIZE),
- MPFROM2SHORT (CMDSRC_ACCELERATOR, FALSE));
- break;
-
- // Handle Maximized Document system menu command by applying
- // the command to the active document
-
- case CMD_DOCUMENT_SIZE:
- case CMD_DOCUMENT_MOVE:
- case CMD_DOCUMENT_MINIMIZE:
- case CMD_DOCUMENT_MAXIMIZE:
- case CMD_DOCUMENT_CLOSE:
- case CMD_DOCUMENT_NEXT:
- case CMD_DOCUMENT_APPMENU:
- case CMD_DOCUMENT_SYSMENU:
- case CMD_DOCUMENT_RESTORE:
- if (pinst->hwndDocument != NULL)
- {pinstDocument = (PINSTDOCUMENT) WinQueryWindowULong (pinst->hwndDocument,
- QWL_USER + sizeof (PVOID));
- if (pinstDocument->usState == SWP_MAXIMIZE)
- {if (usCommand == CMD_DOCUMENT_RESTORE)
- {WinSetParent (pinstDocument->hwndMinMax, pinstDocument->hwndFrame, FALSE);
- WinSetWindowPos (pinstDocument->hwndFrame, NULL, 0, 0, 0, 0, SWP_RESTORE);
- }
- else if (usCommand == CMD_DOCUMENT_NEXT)
- WinSendMsg (pinstDocument->hwndFrame, WM_SYSCOMMAND,
- MPFROMSHORT (SC_NEXT), MPFROM2SHORT (CMDSRC_MENU, FALSE));
- else if (usCommand == CMD_DOCUMENT_CLOSE)
- WinDestroyWindow (pinstDocument->hwndFrame);
- }
- }
- else WinAlarm (HWND_DESKTOP, WA_WARNING);
- break;
-
- // Handle arrange tiled request
-
- case CMD_ARRANGE_TILED:
- MDIDocumentArrange (pinst->hwndDesktop, AWP_TILED);
- break;
-
- // Handle arrange cascaded request
-
- case CMD_ARRANGE_CASCADED:
- MDIDocumentArrange (pinst->hwndDesktop, AWP_CASCADED);
- break;
-
- // Handle tile always request by reseting flags and checking menu items;
- // then we perform actual tile
-
- case CMD_TILE_ALWAYS:
- pinst->fTileAlways = ! pinst->fTileAlways;
- pinst->fCascadeAlways = FALSE;
- WinSendMsg (pinst->miWindow.hwndSubMenu, MM_SETITEMATTR,
- MPFROM2SHORT (CMD_TILE_ALWAYS, FALSE),
- MPFROM2SHORT (MIA_CHECKED, (pinst->fTileAlways)? MIA_CHECKED : FALSE));
- WinSendMsg (pinst->miWindow.hwndSubMenu, MM_SETITEMATTR,
- MPFROM2SHORT (CMD_CASCADE_ALWAYS, FALSE), MPFROM2SHORT (MIA_CHECKED, FALSE));
- if (pinst->fTileAlways)
- MDIDocumentArrange (pinst->hwndDesktop, AWP_TILED);
- break;
-
- // Handle cascade always request by reseting flags and checking menu items;
- // then we perform actual cascade
-
- case CMD_CASCADE_ALWAYS:
- pinst->fCascadeAlways = ! pinst->fCascadeAlways;
- pinst->fTileAlways = FALSE;
- WinSendMsg (pinst->miWindow.hwndSubMenu, MM_SETITEMATTR,
- MPFROM2SHORT (CMD_CASCADE_ALWAYS, FALSE),
- MPFROM2SHORT (MIA_CHECKED, (pinst->fCascadeAlways)? MIA_CHECKED : FALSE));
- WinSendMsg (pinst->miWindow.hwndSubMenu, MM_SETITEMATTR,
- MPFROM2SHORT (CMD_TILE_ALWAYS, FALSE), MPFROM2SHORT (MIA_CHECKED, FALSE));
- if (pinst->fCascadeAlways)
- MDIDocumentArrange (pinst->hwndDesktop, AWP_CASCADED);
- break;
-
- // Handle request to hide document by removing its entry from the
- // window submenu, activating the next entry in the submenu (if any)
- // and hiding the document
-
- case CMD_HIDE:
- if (pinst->hwndDocument != NULL)
- {pinstDocument = (PINSTDOCUMENT) WinQueryWindowULong (pinst->hwndDocument,
- QWL_USER + sizeof (PVOID));
- MDIDocumentHide (pinstDocument);
- }
- break;
-
- // Handle request to unhide document using the unhide dialog procedure
-
- case CMD_UNHIDE:
- hdlg = MDILoadDialog (pinst->hwndDesktop, MDIDocumentUnhideDlgProc,
- DIALOG_UNHIDE, (PVOID) pinst);
- WinProcessDlg (hdlg);
- WinDestroyWindow (hdlg);
- break;
-
- // Handle request for a new document by creating the document
- // based on the currently active document
-
- case CMD_NEW_DOCUMENT:
- if (pinst->hwndDocument != NULL)
- {pinstDocument = (PINSTDOCUMENT) WinQueryWindowULong (pinst->hwndDocument,
- QWL_USER + sizeof (PVOID));
- MDIDocumentClone (pinstDocument);
- }
- break;
-
- // Handle request to activate document
-
- default:
- if (usCommand >= CMD_SELECT_DOCUMENT)
- WinSetWindowPos (WinWindowFromID (pinst->hwndDesktop, usCommand),
- HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE | SWP_ZORDER);
- break;
-
- // Complete handling of command code
-
- }
-
- // Indicate command handled
-
- return (MRESULT) NULL;
-
- }
-
-
- // Function: MDIDesktopCreate - Create MDI Desktop
- // -----------------------------------------------
- MRESULT FAR MDIDesktopCreate (hwndDesktop, pdeskcp)
-
- HWND hwndDesktop; // Desktop window
- PDESKTOPCREATEPARMS pdeskcp; // -->desktop creation parameters
-
- // Define function data
-
- {PINSTDESKTOP pinst; // -->instance data
- BOOL fIniDatFound; // TRUE == OS2.INI data found
- USHORT cbBuf; // Length of OS2.INI data
- SHORT xLeft, xRight; // X indentation factors
- SHORT yBottom, yTop; // Y indentation factors
- CHAR szText[MAX_STRING]; // Menu item text
-
- // Acquire instance data and save in MDI desktop window
-
- pinst = AllocMemAlloc ((LONG) (sizeof (*pinst)));
- WinSetWindowULong (hwndDesktop, QWL_USER + sizeof (PVOID), (ULONG) pinst);
-
- // Copy desktop creation parameters if available
-
- if (pdeskcp != NULL)
- {pinst->pszExit = pdeskcp->pszExit;
- pinst->pszWindow = pdeskcp->pszWindow;
- }
-
- // Initialize inter-window relationships
-
- pinst->hwndDesktop = hwndDesktop;
- pinst->hwndFrame = WinQueryWindow (pinst->hwndDesktop, QW_PARENT, FALSE);
- pinst->hwndParent = WinQueryWindow (pinst->hwndFrame, QW_PARENT, FALSE);
- pinst->hwndMenu = WinWindowFromID (pinst->hwndFrame, FID_MENU);
- pinst->idDesktop = WinQueryWindowUShort (pinst->hwndFrame, QWS_ID);
-
- // Verify inter-window relationships
-
- while (pinst->hwndMenu == NULL)
- TellUser (ERROR_DESKTOP_NO_MENU, MDI_MODNAME, MB_ABORTRETRYIGNORE | MB_ICONHAND);
-
- // Find location in desktop menu at which to insert the window sub-menu
-
- pinst->miWindow.iPosition = 0;
- while ((pinst->miWindow.id = (USHORT) WinSendMsg (pinst->hwndMenu, MM_ITEMIDFROMPOSITION,
- MPFROMSHORT (pinst->miWindow.iPosition), NULL)) != MID_ERROR)
- {WinSendMsg (pinst->hwndMenu, MM_QUERYITEMTEXT, MPFROM2SHORT (pinst->miWindow.id,
- sizeof (szText)), (MPARAM) szText);
- if (strcmpi (szText, pinst->pszExit) == 0) break;
- pinst->miWindow.iPosition++;
- }
-
- // Verify that a location for the window sub-menu was found
-
- while (pinst->miWindow.id == MID_ERROR)
- TellUser (ERROR_DESKTOP_NO_EXIT, MDI_MODNAME, MB_ABORTRETRYIGNORE | MB_ICONHAND, pinst->pszExit);
-
- // Initialize the window menu
-
- pinst->miWindow.afStyle = MIS_TEXT | MIS_SUBMENU;
- pinst->miWindow.afAttribute = 0;
- pinst->miWindow.id = MENU_WINDOW;
- pinst->miWindow.hwndSubMenu = MDILoadMenu (pinst->hwndMenu, MENU_WINDOW);
- pinst->miWindow.hItem = NULL;
-
- // Initialize the maximized child system menu
-
- pinst->miSysMenu.iPosition = 0;
- pinst->miSysMenu.afStyle = MIS_BITMAP | MIS_SUBMENU;
- pinst->miSysMenu.afAttribute = 0;
- pinst->miSysMenu.id = MENU_MAXCHILD_SYSMENU;
- pinst->miSysMenu.hwndSubMenu = MDILoadMenu (pinst->hwndMenu, MENU_MAXCHILD_SYSMENU);
- pinst->miSysMenu.hItem = (ULONG) WinGetSysBitmap (HWND_DESKTOP, SBMP_CHILDSYSMENU);
-
- // Load accelerator table
-
- pinst->haccel = MDILoadAccelTable (ACCEL_DESKTOP);
- WinSetAccelTable (NULL, pinst->haccel, pinst->hwndFrame);
-
- // Determine initial title
-
- WinQueryWindowText (pinst->hwndFrame, sizeof (pinst->szTitle), pinst->szTitle);
-
- // Create user desktop data if applicable
-
- if (pdeskcp && (pdeskcp->cbDeskData > 0))
- pinst->pvDeskData = AllocMemAlloc ((LONG) (pdeskcp->cbDeskData));
-
- // Recall window position from OS2.INI file, if available
-
- cbBuf = sizeof (pinst->swp);
- pinst->swp.fs = 0;
- fIniDatFound = WinQueryProfileData (NULL, MDI_DESKTOPCLASS, pinst->szTitle,
- &(pinst->swp), &cbBuf);
-
- // If no prior position was stored, or if the window was maximized,
- // minimized or hidden, find a default position
-
- if (! fIniDatFound || (pinst->swp.fs & (SWP_MINIMIZE | SWP_MAXIMIZE | SWP_HIDE)))
- {xLeft = (SHORT) WinQuerySysValue (HWND_DESKTOP, SV_CXSIZEBORDER);
- xRight = (SHORT) WinQuerySysValue (HWND_DESKTOP, SV_CXSIZEBORDER);
- yTop = (SHORT) WinQuerySysValue (HWND_DESKTOP, SV_CYSIZEBORDER);
- yBottom = 2 * (SHORT) WinQuerySysValue (HWND_DESKTOP, SV_CYICON);
- pinst->swp.x = xLeft;
- pinst->swp.y = yBottom;
- pinst->swp.cx = (SHORT) WinQuerySysValue (HWND_DESKTOP, SV_CXSCREEN) - xLeft - xRight;
- pinst->swp.cy = (SHORT) WinQuerySysValue (HWND_DESKTOP, SV_CYSCREEN) - yBottom - yTop;
- pinst->swp.fs &= ~SWP_HIDE;
- }
-
- // Display and position the desktop window
-
- pinst->swp.fs |= SWP_ACTIVATE | SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_ZORDER;
- pinst->swp.hwndInsertBehind = HWND_TOP;
- pinst->swp.hwnd = pinst->hwndFrame;
- WinSetMultWindowPos (NULL, &(pinst->swp), 1);
-
- // Indicate create handled
-
- return (MRESULT) NULL;
-
- }
-
-
- // Function: MDIDesktopDestroy - Destroy MDI Desktop
- // -------------------------------------------------
- MRESULT FAR MDIDesktopDestroy (pinst)
-
- PINSTDESKTOP pinst; // -->desktop instance data
-
- // Save window position onto OS2.INI file
-
- {WinWriteProfileData (NULL, MDI_DESKTOPCLASS, pinst->szTitle,
- &(pinst->swp), sizeof (pinst->swp));
-
- // Free accelerator table
-
- WinDestroyAccelTable (pinst->haccel);
-
- // Tell user desktop will be destroyed
-
- WinSendMsg (pinst->hwndDesktop, WM_CONTROL,
- MPFROM2SHORT (pinst->idDesktop, MDI_NOTIFY_DESTROY_DESKTOP),
- (MPARAM) pinst->pvDeskData);
-
- // Free user desktop data if applicable
-
- if (pinst->pvDeskData)
- AllocMemFree (pinst->pvDeskData);
-
- // Free instance data
-
- AllocMemFree (pinst);
-
- // Indicate destroy handled
-
- return (MRESULT) NULL;
-
- }
-
-
- // Function: MDIDesktopPaint - Paint MDI Desktop
- // ---------------------------------------------
- MRESULT FAR MDIDesktopPaint (pinst)
-
- PINSTDESKTOP pinst; // -->desktop instance data
-
- // Define function data
-
- {HPS hps; // Presentation space
- RECTL rcl; // Update rectangle
-
- // Paint a white background
-
- hps = WinBeginPaint (pinst->hwndDesktop, NULL, &rcl);
- WinFillRect (hps, &rcl, CLR_WHITE);
- WinEndPaint (hps);
-
- // Indicate paint handled
-
- return (MRESULT) NULL;
-
- }
-
-
- // Function: MDIDesktopWndProc - MDI Desktop window procedure
- // ----------------------------------------------------------
- MRESULT EXPENTRY MDIDesktopWndProc (hwndDesktop, msg, mp1, mp2)
-
- HWND hwndDesktop; // Desktop window
- USHORT msg; // PM message
- MPARAM mp1; // Mesage parameter 1
- MPARAM mp2; // Mesage parameter 2
-
- // Define function data
-
- {PINSTDESKTOP pinst; // -->instance data
-
- // Locate instance data
-
- pinst = (PINSTDESKTOP) WinQueryWindowULong (hwndDesktop, QWL_USER + sizeof (PVOID));
-
- // Analyze and process message
-
- switch (msg)
-
- {case WM_CLOSE:
- return MDIDesktopClose (pinst);
-
- case WM_COMMAND:
- return MDIDesktopCommand (pinst, LOUSHORT (mp1));
-
- case WM_CREATE:
- return MDIDesktopCreate (hwndDesktop, (PDESKTOPCREATEPARMS) mp1);
-
- case WM_DESTROY:
- return MDIDesktopDestroy (pinst);
-
- case WM_MOVE:
- return (MRESULT) !WinQueryWindowPos (pinst->hwndFrame, &(pinst->swp));
-
- case WM_PAINT:
- return MDIDesktopPaint (pinst);
-
- case WM_SIZE:
- return (MRESULT) !WinQueryWindowPos (pinst->hwndFrame, &(pinst->swp));
-
- case MDI_MSG_LOCATE_DESKTOP_DATA:
- return (MRESULT) pinst->pvDeskData;
-
- }
-
- // Return to PM
-
- return WinDefWindowProc (hwndDesktop, msg, mp1, mp2);
-
- }
-
-
- // Function: MDIDocumentActivate - Activate MDI Document
- // -----------------------------------------------------
- MRESULT FAR MDIDocumentActivate (pinst, fActivate)
-
- PINSTDOCUMENT pinst; // -->document instance data
- BOOL fActivate; // TRUE == document is being activated
-
- // Define function data
-
- {PINSTDESKTOP pinstDesktop; // -->desktop instance data
- CHAR szTitle[MAX_STRING]; // Desktop title
- MENUITEM mi; // Menu item
-
- // Show/hide all frame controls if document is not maximized or minimized
-
- if ((pinst->usState != SWP_MAXIMIZE) && (pinst->usState != SWP_MINIMIZE))
- {WinSetParent (pinst->hwndSysMenu, (fActivate)? pinst->hwndFrame : HWND_OBJECT, FALSE);
- WinSetParent (pinst->hwndMinMax, (fActivate)? pinst->hwndFrame : HWND_OBJECT, FALSE);
- WinSetParent (pinst->hwndVScroll, (fActivate)? pinst->hwndFrame : HWND_OBJECT, FALSE);
- WinSetParent (pinst->hwndHScroll, (fActivate)? pinst->hwndFrame : HWND_OBJECT, FALSE);
- WinSetParent (pinst->hwndTitleBar, pinst->hwndFrame, FALSE);
- WinSendMsg (pinst->hwndFrame, WM_UPDATEFRAME, NULL, NULL);
- }
-
- // Locate the desktop instance data
-
- pinstDesktop = (PINSTDESKTOP) WinQueryWindowULong (pinst->hwndDesktop, QWL_USER + sizeof (PVOID));
-
- // Set the handle of the active document window in the desktop
-
- pinstDesktop->hwndDocument = (fActivate)? pinst->hwndDocument : NULL;
-
- // Check/uncheck the document title in the window menu
-
- WinSendMsg (pinstDesktop->miWindow.hwndSubMenu, MM_SETITEMATTR,
- MPFROM2SHORT (pinst->idFrame, FALSE),
- MPFROM2SHORT (MIA_CHECKED, (fActivate)? MIA_CHECKED : FALSE));
-
- // For maximized documents, insert/remove the maximized child system
- // menu from the desktop and set/reset the desktop title
-
- if (pinst->usState == SWP_MAXIMIZE)
- {if (fActivate)
- {if (! (BOOL) WinSendMsg (pinstDesktop->hwndMenu, MM_QUERYITEM,
- MPFROM2SHORT (MENU_MAXCHILD_SYSMENU, FALSE), (MPARAM) &mi))
- WinSendMsg (pinstDesktop->hwndMenu, MM_INSERTITEM, (MPARAM) &(pinstDesktop->miSysMenu), NULL);
- if (pinst->iTitle == 0)
- sprintf (szTitle, "%s - %s", pinstDesktop->szTitle, pinst->szTitle);
- else sprintf (szTitle, "%s - %s:%d", pinstDesktop->szTitle, pinst->szTitle, pinst->iTitle);
- WinSetWindowText (pinstDesktop->hwndFrame, szTitle);
- }
- else
- {WinSendMsg (pinstDesktop->hwndMenu, MM_REMOVEITEM,
- MPFROM2SHORT (MENU_MAXCHILD_SYSMENU, FALSE), NULL);
- WinSetWindowText (pinstDesktop->hwndFrame, pinstDesktop->szTitle);
- }
- }
-
- // Indicate activate handled
-
- return (MRESULT) NULL;
-
- }
-
-
- // Function: MDIDocumentArrange - Arrange all documents in the desktop
- // -------------------------------------------------------------------
- VOID FAR MDIDocumentArrange (hwndDesktop, fStyle)
-
- HWND hwndDesktop; // Desktop window
- USHORT fStyle; // AWP_TILED or AWP_CASCADED
-
- // Define function data
-
- {USHORT cswpWnd, cswpIcon; // Window, Icon count
- PSWP pswpWnd, pswpIcon; // Window, Icon positions
- ULONG ulStyle; // Style flags
- RECTL rcl; // Rectangle work area
- HWND hwnd; // Window work area
- SHORT cDocs; // Document count
- USHORT yIcon; // Icon height
- SHORT cxBorderInset; // Border inset width
- USHORT i; // Counter
- PINSTDOCUMENT pinstDocument; // -->document instance data
-
- SHORT cxBorder = // Border width
- (SHORT) WinQuerySysValue (HWND_DESKTOP, SV_CXSIZEBORDER);
-
- SHORT cyBorder = // Border height
- (SHORT) WinQuerySysValue (HWND_DESKTOP, SV_CYSIZEBORDER);
-
- // Count the number of document windows
-
- for (cDocs = 0, hwnd = WinQueryWindow (hwndDesktop, QW_TOP, FALSE);
- hwnd; hwnd = WinQueryWindow (hwnd, QW_NEXT, FALSE)) cDocs++;
-
- // Allocate space for document and icon positions
-
- pswpWnd = (PSWP) AllocMemAlloc ((LONG) (sizeof(SWP) * cDocs));
- pswpIcon = (PSWP) AllocMemAlloc ((LONG) (sizeof(SWP) * cDocs));
-
- // Enumerate windows and selectively add them to the arrange lists
-
- for (cswpWnd = cswpIcon = 0, hwnd = WinQueryWindow (hwndDesktop, QW_TOP, FALSE);
- hwnd; hwnd = WinQueryWindow (hwnd, QW_NEXT, FALSE))
-
- // Make sure the window is visible and owned by the desktop
-
- {ulStyle = WinQueryWindowULong (hwnd, QWL_STYLE);
- if (WinQueryWindow (hwnd, QW_OWNER, FALSE)
- || !(ulStyle & WS_VISIBLE)) continue;
-
- // Count icons
-
- if (ulStyle & WS_MINIMIZED)
- pswpIcon[cswpIcon++].hwnd = hwnd;
-
- // Count windows (restore any that are maximized)
-
- else
- {if (ulStyle & WS_MAXIMIZED)
- {pinstDocument = (PINSTDOCUMENT) WinQueryWindowULong
- (WinWindowFromID (hwnd, FID_CLIENT), QWL_USER + sizeof (PVOID));
- WinSetParent (pinstDocument->hwndMinMax, pinstDocument->hwndFrame, FALSE);
- WinSetWindowPos (hwnd, NULL, 0, 0, 0, 0, SWP_ACTIVATE | SWP_RESTORE);
- }
- pswpWnd[cswpWnd++].hwnd = hwnd;
- }
-
- // Loop until all windows accounted for
-
- }
-
- // Get dimensions of desktop window
-
- WinQueryWindowRect (hwndDesktop, &rcl);
- cxBorderInset = (SHORT) (WinQuerySysValue (HWND_DESKTOP, SV_CXBYTEALIGN)
- - WinQuerySysValue (HWND_DESKTOP, SV_CXSIZEBORDER));
- WinInflateRect (NULL, &rcl, -cxBorderInset, -cxBorderInset * (cyBorder / cxBorder));
-
- // Make room for a single row of icons
-
- if (cswpIcon > 0)
- {yIcon = LOUSHORT (WinQuerySysValue(HWND_DESKTOP, SV_CYICON));
- rcl.yBottom += (yIcon * ICON_PARK_NUM) / ICON_PARK_DENOM;
- }
-
- // Set window positions
-
- if (fStyle == AWP_CASCADED)
- MDIDocumentArrangeCascaded (&rcl, cswpWnd, pswpWnd);
- else if (fStyle == AWP_TILED)
- MDIDocumentArrangeTiled (&rcl, cswpWnd, pswpWnd);
-
- // Set icon positions
-
- for (i = 0; i < cswpIcon; i++)
- {pswpIcon[i].x = 0;
- pswpIcon[i].y = 0;
- pswpIcon[i].fs = SWP_MOVE;
- }
-
- // Reposition all windows and icons
-
- WinSetMultWindowPos (NULL, pswpWnd, cswpWnd);
- WinSetMultWindowPos (NULL, pswpIcon, cswpIcon);
-
- // Free space used for document and icon positions
-
- AllocMemFree (pswpWnd);
- AllocMemFree (pswpIcon);
-
- }
-
-
- // Function: MDIDocumentArrangeCascaded - Arrange all documents cascaded
- // ---------------------------------------------------------------------
- VOID FAR MDIDocumentArrangeCascaded (prc, cWnd, aswp)
-
- PRECTL prc; // -->area in which arrange will occur
- SHORT cWnd; // Count of windows
- PSWP aswp; // Array of window positions
-
- // Define function data
-
- {SHORT xEdge, yEdge;
- SHORT xDelta, yDelta;
- SHORT cMaxWnd;
- SHORT x, y, i, j;
- RECTL rc;
-
- SHORT cxBorder =
- (SHORT) WinQuerySysValue (HWND_DESKTOP, SV_CXSIZEBORDER);
-
- SHORT cyBorder =
- (SHORT) WinQuerySysValue (HWND_DESKTOP, SV_CYSIZEBORDER);
-
- // Set cascade parameters
-
- rc.xLeft = prc->xLeft - cxBorder;
- rc.xRight = prc->xRight + cyBorder;
- rc.yBottom = prc->yBottom - cyBorder;
- rc.yTop = prc->yTop + cyBorder;
-
- // Get x and y deltas from system values
-
- xDelta = LOUSHORT(WinQuerySysValue(HWND_DESKTOP, SV_CXSIZEBORDER))
- + LOUSHORT(WinQuerySysValue(HWND_DESKTOP, SV_CXMINMAXBUTTON)) / 2 + 2;
- yDelta = LOUSHORT(WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR));
-
- // Get initial cut at yEdge using fraction
-
- yEdge = (((SHORT)(rc.yTop - rc.yBottom)) * CASC_EDGE_NUM) / CASC_EDGE_DENOM;
-
- // Determine maximum number of deltas used per run
-
- cMaxWnd = (((SHORT)(rc.yTop - rc.yBottom)) - yEdge) / yDelta;
-
- // Set x and y edges so full cascade will fill rectangle completely
-
- xEdge = ((SHORT)(rc.xRight - rc.xLeft)) - xDelta/2 - cMaxWnd * xDelta;
- yEdge = ((SHORT)(rc.yTop - rc.yBottom)) - cMaxWnd * yDelta;
- cMaxWnd++;
-
- // Arrange if only one run is needed
-
- if (cWnd <= cMaxWnd)
- {x = (SHORT)rc. xLeft;
- y = (SHORT)rc. yTop - yEdge;
- for (i = cWnd - 1; i >= 0; i--)
- {aswp[i].x = x;
- aswp[i].y = y;
- aswp[i].cx = xEdge;
- aswp[i].cy = yEdge;
- aswp[i].fs = SWP_SIZE | SWP_MOVE;
- x += xDelta;
- y -= yDelta;
- }
- }
-
- // Arrange if multiple runs are necessary; start at bottom
- // right, iterate up to top left
-
- else
- {i = 0;
- while (i < cWnd)
- {x = ((SHORT)rc. xLeft) + (cMaxWnd-1) * xDelta;
- y = ((SHORT)rc. yTop) - yEdge - (cMaxWnd-1) * yDelta;
- for (j = 0; j < cMaxWnd; j++)
- {aswp[i].x = x;
- aswp[i].y = y;
- aswp[i].cx = xEdge;
- aswp[i].cy = yEdge;
- aswp[i].fs = SWP_SIZE | SWP_MOVE;
- x -= xDelta;
- y += yDelta;
- if (++i >= cWnd) break;
- }
- if (i >= cWnd) break;
- x = ((SHORT)rc. xLeft) + (cMaxWnd-1) * xDelta + xDelta/2;
- y = ((SHORT)rc. yTop) - yEdge - (cMaxWnd-1) * yDelta + yDelta/2;
- for (j = 0; j < cMaxWnd - 1; j++)
- {aswp[i].x = x;
- aswp[i].y = y;
- aswp[i].cx = xEdge;
- aswp[i].cy = yEdge;
- aswp[i].fs = SWP_SIZE | SWP_MOVE;
- x -= xDelta;
- y += yDelta;
- if (++i >= cWnd) break;
- }
- }
- }
- }
-
-
- // Function: MDIDocumentArrangeTiled - Arrange all documents tiled
- // ---------------------------------------------------------------
- VOID FAR MDIDocumentArrangeTiled (prc, cWnd, aswp)
-
- PRECTL prc; // -->area in which arrange will occur
- SHORT cWnd; // Count of windows
- PSWP aswp; // Array of window positions
-
- // Define function data
-
- {USHORT usRoot;
- SHORT cExtras;
- SHORT iChange;
- SHORT cDiff;
- SHORT x, y, cx, cy;
- SHORT iRow, iCol;
-
- SHORT cxBorder =
- (SHORT) WinQuerySysValue (HWND_DESKTOP, SV_CXSIZEBORDER);
-
- SHORT cyBorder =
- (SHORT) WinQuerySysValue (HWND_DESKTOP, SV_CYSIZEBORDER);
-
- // Get grid dimensions
-
- if ((USHORT) cWnd > (0xFE * 0xFE))
- usRoot = 0x00FF;
- else for (usRoot = 0; (usRoot * usRoot) < cWnd; usRoot++);
- cExtras = usRoot * usRoot - cWnd;
-
- // Find column where number of rows increases and find initial
- // difference of rows versus columns
-
- if (cExtras >= usRoot)
- {iChange = cExtras - usRoot;
- cDiff = 2;
- }
- else
- {iChange = cExtras;
- cDiff = 1;
- }
-
- // Assign x coordinates
-
- x = (SHORT)prc->xLeft;
- cx = 0;
- for (iCol = 0; iCol < usRoot; iCol++)
- {x += cx - cxBorder;
- cx = ((SHORT)prc->xLeft) + (((SHORT)(prc->xRight - prc->xLeft))
- * (iCol + 1)) / usRoot - x + cxBorder;
- for (iRow = 0; iRow < usRoot - cDiff; iRow++)
- {aswp[iRow * usRoot + iCol].x = x;
- aswp[iRow * usRoot + iCol].cx = cx;
- aswp[iRow * usRoot + iCol].fs = SWP_SIZE | SWP_MOVE;
- }
- if (iCol >= iChange)
- {aswp[iRow * usRoot + iCol - iChange].x = x;
- aswp[iRow * usRoot + iCol - iChange].cx = cx;
- aswp[iRow * usRoot + iCol - iChange].fs = SWP_SIZE | SWP_MOVE;
- }
- }
-
- // Assign y coordinates, for columns without extra row
-
- y = (SHORT)prc->yBottom;
- cy = 0;
- for (iRow = usRoot - cDiff - 1; iRow >= 0; iRow--)
- {y += cy - cyBorder;
- cy = ((SHORT)prc->yBottom) + (((SHORT)(prc->yTop - prc->yBottom))
- * (usRoot - cDiff - iRow)) / (usRoot - cDiff) - y + cyBorder;
- for (iCol = 0; iCol < iChange; iCol++)
- {aswp[iRow * usRoot + iCol].y = y;
- aswp[iRow * usRoot + iCol].cy = cy;
- }
- }
-
- // Assign y coordinates, for columns with extra row
- // do last row first (different offsets)
-
- y = (SHORT)prc->yBottom - cyBorder;
- cy = ((SHORT)(prc->yTop - prc->yBottom)) / (usRoot - cDiff + 1) + (2 * cyBorder);
- for (iCol = iChange; iCol < usRoot; iCol++)
- {aswp[usRoot * (usRoot - cDiff) + iCol - iChange].y = y;
- aswp[usRoot * (usRoot - cDiff) + iCol - iChange].cy = cy;
- }
- for (iRow = usRoot - cDiff - 1; iRow >= 0; iRow--)
- {y += cy - cyBorder;
- cy = ((SHORT)(prc->yBottom)) + (((SHORT)(prc->yTop - prc->yBottom))
- * (usRoot - cDiff - iRow + 1)) / (usRoot - cDiff + 1) - y + cyBorder;
- for (iCol = iChange; iCol < usRoot; iCol++)
- {aswp[iRow * usRoot + iCol].y = y;
- aswp[iRow * usRoot + iCol].cy = cy;
- }
- }
- }
-
-
- // Function: MDIDocumentClone - Clone MDI Document
- // -----------------------------------------------
- VOID FAR MDIDocumentClone (pinst)
-
- PINSTDOCUMENT pinst; // -->document instance data
-
- // Define function data
-
- {PINSTDESKTOP pinstDesktop; // -->desktop instance data
- HWND hwndDocument; // New document window
- HWND hwndFrame; // New document frame
- HPOINTER hptrIcon; // New document icon
- ULONG flFrameFlags; // Frame flags
-
- // Locate the desktop instance data
-
- pinstDesktop = (PINSTDESKTOP) WinQueryWindowULong (pinst->hwndDesktop,
- QWL_USER + sizeof (PVOID));
-
- // Copy creation flags from base document; set defaults if missing
-
- if (pinst->flCreateFlags != NULL)
- flFrameFlags = pinst->flCreateFlags;
- else flFrameFlags = FCF_TITLEBAR | FCF_SYSMENU | FCF_SIZEBORDER | FCF_MINMAX
- | FCF_SHELLPOSITION | FCF_NOBYTEALIGN;
-
- // Create new document
-
- hwndFrame = MDICreateDocument (pinst->pfnUser, pinstDesktop->hwndDesktop,
- flFrameFlags, pinst->szTitle, pinst->hmodResources, pinst->idResources,
- &hwndDocument, pinst->cbDocData, pinst->cbInstData);
-
- // Copy QWL_USER from base document
-
- WinSetWindowULong (hwndDocument, QWL_USER, WinQueryWindowULong
- (pinst->hwndDocument, QWL_USER));
-
- // If applicable, copy icon from base document
-
- if ((hptrIcon = (HPOINTER) WinSendMsg (pinst->hwndFrame,
- WM_QUERYICON, NULL, NULL)) != NULL)
- WinSendMsg (hwndFrame, WM_SETICON, (MPARAM) hptrIcon, NULL);
-
- }
-
-
- // Function: MDIDocumentClose - Close MDI Document
- // -----------------------------------------------
- MRESULT FAR MDIDocumentClose (pinst)
-
- PINSTDOCUMENT pinst; // -->document instance data
-
- // Destroy document window
-
- {WinDestroyWindow (pinst->hwndFrame);
-
- // Indicate close handled
-
- return (MRESULT) NULL;
-
- }
-
-
- // Function: MDIDocumentCommand - Handle MDI Document Command
- // ----------------------------------------------------------
- MRESULT FAR MDIDocumentCommand (pinst, usCommand)
-
- PINSTDOCUMENT pinst; // -->document instance data
- USHORT usCommand; // WM_COMMAND code
-
- // Act upon command code
-
- {switch (usCommand)
-
- // Handle Desktop system menu command by passing it to the desktop frame
-
- {case CMD_DESKTOP_SIZE:
- case CMD_DESKTOP_MOVE:
- case CMD_DESKTOP_MINIMIZE:
- case CMD_DESKTOP_MAXIMIZE:
- case CMD_DESKTOP_CLOSE:
- case CMD_DESKTOP_NEXT:
- case CMD_DESKTOP_APPMENU:
- case CMD_DESKTOP_SYSMENU:
- case CMD_DESKTOP_RESTORE:
- WinSendMsg (pinst->hwndDesktop, WM_COMMAND,
- MPFROMSHORT (usCommand), MPFROM2SHORT (CMDSRC_ACCELERATOR, FALSE));
- break;
-
- // Handle Document system menu command by passing the system equivalent
- // to the document's frame. However, if the document is maximized,
- // the command is passed to the desktop for processing
-
- case CMD_DOCUMENT_SIZE:
- case CMD_DOCUMENT_MOVE:
- case CMD_DOCUMENT_MINIMIZE:
- case CMD_DOCUMENT_MAXIMIZE:
- case CMD_DOCUMENT_CLOSE:
- case CMD_DOCUMENT_NEXT:
- case CMD_DOCUMENT_APPMENU:
- case CMD_DOCUMENT_SYSMENU:
- case CMD_DOCUMENT_RESTORE:
- if (pinst->usState == SWP_MAXIMIZE)
- WinSendMsg (pinst->hwndDesktop, WM_COMMAND,
- MPFROMSHORT (usCommand), MPFROM2SHORT (CMDSRC_ACCELERATOR, FALSE));
- else
- WinSendMsg (pinst->hwndFrame, WM_SYSCOMMAND,
- MPFROMSHORT ((usCommand - CMD_DOCUMENT_BASE) | SC_SIZE),
- MPFROM2SHORT (CMDSRC_ACCELERATOR, FALSE));
- break;
-
- // Terminate command processing
-
- }
-
- // Indicate command handled
-
- return (MRESULT) NULL;
-
- }
-
-
- // Function: MDIDocumentCreate - Create MDI Document
- // -------------------------------------------------
- MRESULT FAR MDIDocumentCreate (hwndDocument, pdoccp)
-
- HWND hwndDocument; // Document window
- PDOCUMENTCREATEPARMS pdoccp; // -->document creation parameters
-
- // Define function data
-
- {PINSTDOCUMENT pinst; // -->instance data
- PINSTDOCUMENT pinstFirst; // -->first document instance data
- PINSTDESKTOP pinstDesktop; // -->desktop instance data
- MENUITEM mi; // Menu structure
- CHAR szClassName[MAX_STRING]; // Class name
- BOOL fIniDatFound; // TRUE == OS2.INI data found
- USHORT cbBuf; // Length of OS2.INI data
- HWND hwndSibling; // Sibling window handle
- SWP swp; // Sibling position
-
- // Acquire instance data and save in MDI document window
-
- pinst = AllocMemAlloc ((LONG) (sizeof (*pinst)));
- WinSetWindowULong (hwndDocument, QWL_USER + sizeof (PVOID), (ULONG) pinst);
-
- // Copy document creation parameters if available
-
- if (pdoccp != NULL)
- {pinst->cbDocData = pdoccp->cbDocData;
- pinst->cbInstData = pdoccp->cbInstData;
- pinst->pfnUser = pdoccp->pfnUser;
- pinst->flCreateFlags = pdoccp->flCreateFlags;
- pinst->hmodResources = pdoccp->hmodResources;
- pinst->idResources = pdoccp->idResources;
- }
-
- // Initialize inter-window relationships
-
- pinst->hwndDocument = hwndDocument;
- pinst->hwndFrame = WinQueryWindow (pinst->hwndDocument, QW_PARENT, FALSE);
- pinst->hwndDesktop = WinQueryWindow (pinst->hwndFrame, QW_PARENT, FALSE);
- pinst->hwndSysMenu = WinWindowFromID (pinst->hwndFrame, FID_SYSMENU);
- pinst->hwndTitleBar = WinWindowFromID (pinst->hwndFrame, FID_TITLEBAR);
- pinst->hwndMinMax = WinWindowFromID (pinst->hwndFrame, FID_MINMAX);
- pinst->hwndVScroll = WinWindowFromID (pinst->hwndFrame, FID_VERTSCROLL);
- pinst->hwndHScroll = WinWindowFromID (pinst->hwndFrame, FID_HORZSCROLL);
- pinst->idDesktop = WinQueryWindowUShort (WinQueryWindow (pinst->hwndDesktop, QW_PARENT, FALSE), QWS_ID);
-
- // Verify inter-window relationships
-
- WinQueryClassName (pinst->hwndDesktop, sizeof (szClassName), szClassName);
- while (stricmp (szClassName, MDI_DESKTOPCLASS) != 0)
- TellUser (ERROR_DOCUMENT_PARENT_INVALID, MDI_MODNAME, MB_ABORTRETRYIGNORE | MB_ICONHAND);
-
- while (pinst->hwndSysMenu == NULL)
- TellUser (ERROR_DOCUMENT_NO_SYSMENU, MDI_MODNAME, MB_ABORTRETRYIGNORE | MB_ICONHAND);
-
- // Find the desktop instance data
-
- pinstDesktop = (PINSTDESKTOP) WinQueryWindowULong (pinst->hwndDesktop, QWL_USER + sizeof (PVOID));
-
- // Load accelerator table
-
- pinst->haccel = MDILoadAccelTable (ACCEL_DOCUMENT);
- WinSetAccelTable (NULL, pinst->haccel, pinst->hwndFrame);
-
- // Alter the appearance of the child system menu to the MDI standard
-
- WinSendMsg (pinst->hwndSysMenu, MM_QUERYITEM, MPFROM2SHORT (SC_SYSMENU, FALSE), (MPARAM) &mi);
- WinSendMsg (pinst->hwndSysMenu, MM_REMOVEITEM, MPFROM2SHORT (SC_SYSMENU, FALSE), NULL);
- mi.hItem = (ULONG) WinGetSysBitmap (HWND_DESKTOP, SBMP_CHILDSYSMENU);
- mi.hwndSubMenu = MDILoadMenu (pinst->hwndSysMenu, MENU_CHILD_SYSMENU);
- WinSendMsg (pinst->hwndSysMenu, MM_INSERTITEM, (MPARAM) &mi, NULL);
-
- // Determine initial title
-
- WinQueryWindowText (pinst->hwndFrame, sizeof (pinst->szTitle), pinst->szTitle);
-
- // Rebuild the titles of all document windows inserting the current title
-
- pinstFirst = MDIDocumentTitlesRebuild (pinst, INSERT_TITLE);
-
- // If applicable, allocate user document and instance data
-
- if (pdoccp && (pdoccp->cbInstData > 0))
- pinst->pvInstData = AllocMemAlloc ((LONG) (pdoccp->cbInstData));
- if (pdoccp && (pdoccp->cbDocData > 0))
- {if (pinst == pinstFirst)
- pinst->pvDocData = AllocMemAlloc ((LONG) (pdoccp->cbDocData));
- else if (pinstFirst != NULL)
- pinst->pvDocData = pinstFirst->pvDocData;
- }
-
- // Recall window information from OS2.INI file, if available
-
- cbBuf = sizeof (pinst->swp);
- pinst->swp.fs = 0;
- fIniDatFound = WinQueryProfileData (NULL, MDI_DOCUMENTCLASS,
- pinst->szTitle, &(pinst->swp), &cbBuf);
-
- // If no prior position was stored, or if the window was maximized,
- // minimized or hidden, find a default position inside the desktop
- // window. If there is a sibling that is a frame, and is itself not
- // maximized, minimized or hidden, offset the new window from it
-
- if (! fIniDatFound || (pinst->swp.fs & (SWP_MINIMIZE | SWP_MAXIMIZE | SWP_HIDE)))
- {WinQueryWindowPos (pinst->hwndDesktop, &swp);
- pinst->swp.cx = swp.cx / 2;
- pinst->swp.cy = swp.cy / 2;
- pinst->swp.x = swp.x + ((SHORT) WinQuerySysValue (HWND_DESKTOP, SV_CXVSCROLL) / 2);
- pinst->swp.y = swp.y + pinst->swp.cy - ((SHORT) WinQuerySysValue
- (HWND_DESKTOP, SV_CYTITLEBAR) / 2);
- if ((hwndSibling = WinQueryWindow (pinst->hwndFrame, QW_NEXT, FALSE)) != NULL)
- {WinQueryClassName (hwndSibling, sizeof (szClassName), szClassName);
- if (strcmpi (szClassName, "#1") == 0)
- {WinQueryWindowPos (hwndSibling, &swp);
- if (! (swp.fs & (SWP_MINIMIZE | SWP_MAXIMIZE | SWP_HIDE)))
- {pinst->swp.x = swp.x + ((SHORT) WinQuerySysValue (HWND_DESKTOP, SV_CXVSCROLL) / 2);
- pinst->swp.y = swp.y - (SHORT) WinQuerySysValue (HWND_DESKTOP, SV_CYTITLEBAR);
- pinst->swp.cx = swp.cx;
- pinst->swp.cy = swp.cy;
- }
- }
- }
- pinst->swp.fs &= ~SWP_HIDE;
- }
-
- // Display, position and activate the document window
-
- if (pinstDesktop->fTileAlways || pinstDesktop->fCascadeAlways)
- pinst->swp.fs = SWP_ACTIVATE | SWP_SHOW | SWP_ZORDER;
- else pinst->swp.fs |= SWP_ACTIVATE | SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_ZORDER;
- pinst->swp.hwndInsertBehind = HWND_TOP;
- pinst->swp.hwnd = pinst->hwndFrame;
- WinSetMultWindowPos (NULL, &(pinst->swp), 1);
-
- // Re-tile or re-cascade all windows if necessary
-
- if (pinstDesktop->fTileAlways)
- MDIDocumentArrange (pinst->hwndDesktop, AWP_TILED);
- else if (pinstDesktop->fCascadeAlways)
- MDIDocumentArrange (pinst->hwndDesktop, AWP_CASCADED);
-
- // Force the current window to be activated
-
- MDIDocumentActivate (pinst, TRUE);
-
- // Indicate create handled
-
- return (MRESULT) NULL;
-
- }
-
-
- // Function: MDIDocumentDestroy - Destroy MDI Document
- // ---------------------------------------------------
- MRESULT FAR MDIDocumentDestroy (pinst)
-
- PINSTDOCUMENT pinst; // -->document instance data
-
- // Define function data
-
- {PINSTDESKTOP pinstDesktop; // -->desktop instance data
- PINSTDOCUMENT pinstFirst; // -->first document instance data
- PINSTDOCUMENT pinstDocument; // -->next active document instance data
- HWND hwndFrame; // Next active document frame
- MENUITEM mi; // Menu item
-
- // Find the desktop instance data
-
- pinstDesktop = (PINSTDESKTOP) WinQueryWindowULong (pinst->hwndDesktop, QWL_USER + sizeof (PVOID));
-
- // Save window position onto OS2.INI file
-
- WinWriteProfileData (NULL, MDI_DOCUMENTCLASS, pinst->szTitle,
- &(pinst->swp), sizeof (pinst->swp));
-
- // Rebuild the titles of all document windows removing the current title
-
- pinstFirst = MDIDocumentTitlesRebuild (pinst, REMOVE_TITLE);
-
- // Free accelerator table
-
- WinDestroyAccelTable (pinst->haccel);
-
- // Re-tile or re-cascade all remaining windows if necessary
-
- if (pinstDesktop->fTileAlways)
- MDIDocumentArrange (pinst->hwndDesktop, AWP_TILED);
- else if (pinstDesktop->fCascadeAlways)
- MDIDocumentArrange (pinst->hwndDesktop, AWP_CASCADED);
-
- // If there is a next entry in the window submenu, activate it
-
- if ((mi.id = (SHORT) WinSendMsg (pinstDesktop->miWindow.hwndSubMenu, MM_ITEMIDFROMPOSITION,
- MPFROMSHORT (CMD_WINDOW_MAX - CMD_WINDOW), NULL)) != MID_ERROR)
- {hwndFrame = WinWindowFromID (pinstDesktop->hwndDesktop, mi.id);
- WinSetWindowPos (hwndFrame, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE | SWP_ZORDER);
- pinstDocument = (PINSTDOCUMENT) WinQueryWindowULong (WinWindowFromID (hwndFrame, FID_CLIENT),
- QWL_USER + sizeof (PVOID));
- if (pinstDocument)
- MDIDocumentActivate (pinstDocument, TRUE);
- }
-
- // Tell user instance and maybe document will be destroyed
-
- WinSendMsg (pinst->hwndDocument, WM_CONTROL,
- MPFROM2SHORT (pinst->idDesktop, MDI_NOTIFY_DESTROY_INSTANCE),
- (MPARAM) pinst->pvInstData);
- if (pinstFirst == NULL)
- WinSendMsg (pinst->hwndDocument, WM_CONTROL,
- MPFROM2SHORT (pinst->idDesktop, MDI_NOTIFY_DESTROY_DOCUMENT), (MPARAM) pinst->pvDocData);
-
- // If applicable, free the user document and instance data
-
- if (pinst->pvInstData)
- AllocMemFree (pinst->pvInstData);
- if (pinst->pvDocData && (pinstFirst == NULL))
- AllocMemFree (pinst->pvDocData);
-
- // Free instance data
-
- AllocMemFree (pinst);
-
- // Indicate destroy handled
-
- return (MRESULT) NULL;
-
- }
-
-
- // Function: MDIDocumentHide - Hide MDI Document
- // ---------------------------------------------
- VOID FAR MDIDocumentHide (pinst)
-
- PINSTDOCUMENT pinst; // -->document instance data
-
- // Define function data
-
- {PINSTDESKTOP pinstDesktop; // -->desktop instance data
- PINSTDOCUMENT pinstDocument; // -->next active document instance data
- HWND hwndFrame; // Next active document frame
- MENUITEM mi; // Menu item
-
- // Locate the desktop instance data
-
- pinstDesktop = (PINSTDESKTOP) WinQueryWindowULong (pinst->hwndDesktop, QWL_USER + sizeof (PVOID));
-
- // Delete document entry from window submenu
-
- WinSendMsg (pinstDesktop->miWindow.hwndSubMenu, MM_DELETEITEM,
- MPFROM2SHORT (pinst->idFrame, FALSE), NULL);
-
- // If there is a next entry in the window submenu, activate it
-
- if ((mi.id = (SHORT) WinSendMsg (pinstDesktop->miWindow.hwndSubMenu, MM_ITEMIDFROMPOSITION,
- MPFROMSHORT (CMD_WINDOW_MAX - CMD_WINDOW), NULL)) != MID_ERROR)
- {hwndFrame = WinWindowFromID (pinstDesktop->hwndDesktop, mi.id);
- WinSetWindowPos (hwndFrame, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE | SWP_ZORDER);
- pinstDocument = (PINSTDOCUMENT) WinQueryWindowULong (WinWindowFromID (hwndFrame, FID_CLIENT),
- QWL_USER + sizeof (PVOID));
- if (pinstDocument)
- MDIDocumentActivate (pinstDocument, TRUE);
- }
-
- // Otherwise, remove any maximized child system menu and reset the desktop
- // In addition, we disable the HIDE and NEW window menu options
-
- else
- {WinSendMsg (pinstDesktop->hwndMenu, MM_REMOVEITEM,
- MPFROM2SHORT (MENU_MAXCHILD_SYSMENU, FALSE), NULL);
- WinSetWindowText (pinstDesktop->hwndFrame, pinstDesktop->szTitle);
- pinstDesktop->hwndDocument = NULL;
- WinSendMsg (pinstDesktop->miWindow.hwndSubMenu, MM_SETITEMATTR,
- MPFROM2SHORT (CMD_HIDE, FALSE), MPFROM2SHORT (MIA_DISABLED, MIA_DISABLED));
- WinSendMsg (pinstDesktop->miWindow.hwndSubMenu, MM_SETITEMATTR,
- MPFROM2SHORT (CMD_NEW_DOCUMENT, FALSE), MPFROM2SHORT (MIA_DISABLED, MIA_DISABLED));
- }
-
- // Hide document
-
- WinShowWindow (pinst->hwndFrame, FALSE);
- pinst->usState |= SWP_HIDE;
-
- // Enable the UNHIDE window submenu option
-
- WinSendMsg (pinstDesktop->miWindow.hwndSubMenu, MM_SETITEMATTR,
- MPFROM2SHORT (CMD_UNHIDE, FALSE), MPFROM2SHORT (MIA_DISABLED, FALSE));
-
- // Re-tile or re-cascade if necessary
-
- if (pinstDesktop->fTileAlways)
- MDIDocumentArrange (pinstDesktop->hwndDesktop, AWP_TILED);
- else if (pinstDesktop->fCascadeAlways)
- MDIDocumentArrange (pinstDesktop->hwndDesktop, AWP_CASCADED);
-
- }
-
-
- // Function: MDIDocumentMinMax - Minimize/Maximize MDI Document
- // ------------------------------------------------------------
- MRESULT FAR MDIDocumentMinMax (pinst, pswp)
-
- PINSTDOCUMENT pinst; // -->document instance data
- PSWP pswp; // -->document position information
-
- // Define function data
-
- {PINSTDESKTOP pinstDesktop; // -->desktop instance data
- CHAR szTitle[MAX_STRING]; // Desktop title
- MENUITEM mi; // Menu item
-
- // Update document state flags
-
- pinst->usState = pswp->fs & (SWP_MAXIMIZE | SWP_MINIMIZE);
-
- // Show/hide all frame controls
-
- WinSetParent (pinst->hwndSysMenu, (pinst->usState == SWP_MAXIMIZE)?
- HWND_OBJECT : pinst->hwndFrame, FALSE);
- WinSetParent (pinst->hwndMinMax, (pinst->usState == SWP_MAXIMIZE)?
- HWND_OBJECT : pinst->hwndFrame, FALSE);
- WinSetParent (pinst->hwndTitleBar, (pinst->usState == SWP_MAXIMIZE)?
- HWND_OBJECT : pinst->hwndFrame, FALSE);
- WinSendMsg (pinst->hwndFrame, WM_UPDATEFRAME, NULL, NULL);
-
- // Locate the desktop instance data
-
- pinstDesktop = (PINSTDESKTOP) WinQueryWindowULong (pinst->hwndDesktop, QWL_USER + sizeof (PVOID));
-
- // For maximized documents, insert the maximized child system
- // menu to the desktop if it does not already exist, and update
- // the desktop title
-
- if (pinst->usState == SWP_MAXIMIZE)
- {if (! (BOOL) WinSendMsg (pinstDesktop->hwndMenu, MM_QUERYITEM,
- MPFROM2SHORT (MENU_MAXCHILD_SYSMENU, FALSE), (MPARAM) &mi))
- WinSendMsg (pinstDesktop->hwndMenu, MM_INSERTITEM,
- (MPARAM) &(pinstDesktop->miSysMenu), NULL);
- if (pinst->iTitle == 0)
- sprintf (szTitle, "%s - %s", pinstDesktop->szTitle, pinst->szTitle);
- else sprintf (szTitle, "%s - %s:%d", pinstDesktop->szTitle, pinst->szTitle, pinst->iTitle);
- WinSetWindowText (pinstDesktop->hwndFrame, szTitle);
- }
-
- // Otherwise, remove the maximized child system menu from the desktop
- // and reset the desktop title
-
- else
- {WinSendMsg (pinstDesktop->hwndMenu, MM_REMOVEITEM,
- MPFROM2SHORT (MENU_MAXCHILD_SYSMENU, FALSE), NULL);
- WinSetWindowText (pinstDesktop->hwndFrame, pinstDesktop->szTitle);
- }
-
- // Indicate min/max handled
-
- return (MRESULT) NULL;
-
- }
-
-
- // Function: MDIDocumentPaint - Paint MDI Document
- // -----------------------------------------------
- MRESULT FAR MDIDocumentPaint (pinst)
-
- PINSTDOCUMENT pinst; // -->document instance data
-
- // Define function data
-
- {HPS hps; // Presentation space
- RECTL rcl; // Update rectangle
-
- // Paint a white background
-
- hps = WinBeginPaint (pinst->hwndDocument, NULL, &rcl);
- WinFillRect (hps, &rcl, CLR_WHITE);
- WinEndPaint (hps);
-
- // Indicate paint handled
-
- return (MRESULT) NULL;
-
- }
-
-
- // Function: MDIDocumentTitlesRebuild - Rebuild the titles of all Documents
- // ------------------------------------------------------------------------
- PINSTDOCUMENT FAR MDIDocumentTitlesRebuild (pinst, usCommand)
-
- PINSTDOCUMENT pinst; // -->document instance data
- USHORT usCommand; // INSERT_TITLE or REMOVE_TITLE
-
- // Define function data
-
- {HWND hwndDocument; // Document window
- HWND hwndFrame; // Its frame
- CHAR szClassName[MAX_STRING]; // Class/Title name
- PINSTDOCUMENT pinstFirst; // -->first document instance data
- PINSTDOCUMENT pinstDocument; // -->document instance data
- PINSTDESKTOP pinstDesktop; // -->desktop instance data
- MENUITEM mi; // Menu item
- SHORT cmd; // Which window to retrieve
- SHORT nSameName; // Number of documents with the same name
- SHORT nDocuments; // Number of documents
- SHORT iDocument; // Document index
- BOOL fListed; // TRUE == at least one document listed
-
- // Find the desktop instance data
-
- pinstDesktop = (PINSTDESKTOP) WinQueryWindowULong (pinst->hwndDesktop, QWL_USER + sizeof (PVOID));
-
- // Count the number of documents that already exist with the same name
- // as the current document and the total number of documents
-
- cmd = QW_TOP;
- hwndFrame = pinst->hwndDesktop;
- nDocuments = nSameName = 0;
- while ((hwndFrame = WinQueryWindow (hwndFrame, cmd, FALSE)) != NULL)
- {cmd = QW_NEXT;
- WinQueryClassName (hwndFrame, sizeof (szClassName), szClassName);
- if (strcmpi (szClassName, "#1") != 0) continue;
- hwndDocument = WinWindowFromID (hwndFrame, FID_CLIENT);
- WinQueryClassName (hwndDocument, sizeof (szClassName), szClassName);
- if (strcmpi (szClassName, MDI_DOCUMENTCLASS) != 0) continue;
- pinstDocument = (PINSTDOCUMENT) WinQueryWindowULong (hwndDocument, QWL_USER + sizeof (PVOID));
- nDocuments++;
- if (pinst == pinstDocument) continue;
- if (strcmp (pinst->szTitle, pinstDocument->szTitle) == 0)
- nSameName++;
- }
- if (usCommand == REMOVE_TITLE) nDocuments--;
-
- // If there is exactly one document, insert the window submenu
-
- if ((nDocuments == 1) && (usCommand == INSERT_TITLE))
- WinSendMsg (pinstDesktop->hwndMenu, MM_INSERTITEM, (MPARAM) &(pinstDesktop->miWindow),
- (MPARAM) pinstDesktop->pszWindow);
-
- // If there are no documents left, remove the window submenu
-
- else if ((nDocuments == 0) && (usCommand == REMOVE_TITLE))
- WinSendMsg (pinstDesktop->hwndMenu, MM_REMOVEITEM, MPFROM2SHORT (MENU_WINDOW, FALSE), NULL);
-
- // Remove all the document entries in the window submenu
-
- for (iDocument = 0; iDocument <= nDocuments; iDocument++)
- {WinSendMsg (pinstDesktop->miWindow.hwndSubMenu, MM_DELETEITEM,
- MPFROM2SHORT (CMD_SELECT_DOCUMENT + iDocument, FALSE), NULL);
- }
-
- // Scan each document window in the desktop
-
- cmd = QW_TOP;
- hwndFrame = pinst->hwndDesktop;
- iDocument = -1;
- pinstFirst = NULL;
- fListed = FALSE;
- while ((hwndFrame = WinQueryWindow (hwndFrame, cmd, FALSE)) != NULL)
- {cmd = QW_NEXT;
- WinQueryClassName (hwndFrame, sizeof (szClassName), szClassName);
- if (strcmpi (szClassName, "#1") != 0) continue;
- hwndDocument = WinWindowFromID (hwndFrame, FID_CLIENT);
- WinQueryClassName (hwndDocument, sizeof (szClassName), szClassName);
- if (strcmpi (szClassName, MDI_DOCUMENTCLASS) != 0) continue;
- pinstDocument = (PINSTDOCUMENT) WinQueryWindowULong (hwndDocument, QWL_USER + sizeof (PVOID));
-
- // Reset the id of this document
-
- if ((pinst == pinstDocument) && (usCommand == REMOVE_TITLE))
- {WinSetWindowUShort (pinstDocument->hwndFrame, QWS_ID, CMD_SELECT_DOCUMENT - 1);
- continue;
- }
- iDocument++;
- pinstDocument->idFrame = CMD_SELECT_DOCUMENT + iDocument;
- WinSetWindowUShort (pinstDocument->hwndFrame, QWS_ID, pinstDocument->idFrame);
-
- // If document titles match, re-number title
-
- if (strcmp (pinst->szTitle, pinstDocument->szTitle) == 0)
-
- // If we are inserting the current title, re-number apropriately
-
- {if (usCommand == INSERT_TITLE)
- {if (nSameName == 0)
- pinstDocument->iTitle = 0;
- else if (nSameName == 1)
- {pinstDocument->iTitle = (pinst == pinstDocument)? 2 : 1;
- sprintf (szClassName, "%s:%d", pinstDocument->szTitle, pinstDocument->iTitle);
- WinSetWindowText (pinstDocument->hwndFrame, szClassName);
- }
- else if (pinst == pinstDocument)
- {pinstDocument->iTitle = nSameName + 1;
- sprintf (szClassName, "%s:%d", pinstDocument->szTitle, pinstDocument->iTitle);
- WinSetWindowText (pinstDocument->hwndFrame, szClassName);
- }
- }
-
- // If we are removing the current title, re-number apropriately
-
- else if (usCommand == REMOVE_TITLE)
- {if (nSameName == 1)
- {pinstDocument->iTitle = 0;
- sprintf (szClassName, "%s", pinstDocument->szTitle);
- WinSetWindowText (pinstDocument->hwndFrame, szClassName);
- }
- else if ((nSameName > 1) && (pinstDocument->iTitle > pinst->iTitle))
- {pinstDocument->iTitle--;
- sprintf (szClassName, "%s:%d", pinstDocument->szTitle, pinstDocument->iTitle);
- WinSetWindowText (pinstDocument->hwndFrame, szClassName);
- }
- }
-
- // Save a pointer to the instance data of the first document
- // with the same name
-
- if (pinstDocument->iTitle <= 1)
- pinstFirst = pinstDocument;
- }
-
- // Put document title into the window submenu if it is not hidden
-
- if (! (pinstDocument->usState & SWP_HIDE))
- {mi.id = CMD_SELECT_DOCUMENT + iDocument;
- mi.iPosition = MIT_END;
- mi.afAttribute = 0;
- mi.hwndSubMenu = NULL;
- mi.hItem = NULL;
- mi.afStyle = MIS_TEXT;
- if (pinstDocument->iTitle == 0)
- sprintf (szClassName, "%s", pinstDocument->szTitle);
- else sprintf (szClassName, "%s:%d", pinstDocument->szTitle, pinstDocument->iTitle);
- WinSendMsg (pinstDesktop->miWindow.hwndSubMenu, MM_INSERTITEM, (MPARAM) &mi, (MPARAM) szClassName);
- fListed = TRUE;
- }
-
- // Loop until all windows processed
-
- }
-
- // If at least one document is listed in the window submenu, enable
- // the HIDE and NEW window submenu options
-
- WinSendMsg (pinstDesktop->miWindow.hwndSubMenu, MM_SETITEMATTR,
- MPFROM2SHORT (CMD_HIDE, FALSE), MPFROM2SHORT (MIA_DISABLED, FALSE));
- WinSendMsg (pinstDesktop->miWindow.hwndSubMenu, MM_SETITEMATTR,
- MPFROM2SHORT (CMD_NEW_DOCUMENT, FALSE), MPFROM2SHORT (MIA_DISABLED, FALSE));
-
- // Return pointer to instance data of first document with the same name
-
- return pinstFirst;
-
- }
-
-
- // Function: MDIDocumentUnhideDlgProc - MDI Document Unhide dialog procedure
- // -------------------------------------------------------------------------
- MRESULT EXPENTRY MDIDocumentUnhideDlgProc (hwndUnhide, msg, mp1, mp2)
-
- HWND hwndUnhide; // Unhide dialog box
- USHORT msg; // PM message
- MPARAM mp1; // Message parameter 1
- MPARAM mp2; // Message parameter 2
-
- // Define function data
-
- {HWND hwndDocument; // Document window
- HWND hwndFrame; // Its frame
- HWND hwndFirst; // First document unhidden
- CHAR szClassName[MAX_STRING]; // Class/Title name
- CHAR szTitle[MAX_STRING]; // Window title
- PINSTDESKTOP pinstDesktop; // -->desktop instance data
- PINSTDOCUMENT pinstDocument; // -->document instance data
- MENUITEM mi; // Menu item
- SHORT cmd; // Which window to retrieve
- SHORT nItems, nUnhidden; // Number of items, number unhidden
- SHORT i; // Temporary counter
-
- // Analyze and process message
-
- switch (msg)
-
- // Initially, load list box with all hidden window titles
-
- {case WM_INITDLG:
- pinstDesktop = (PINSTDESKTOP) mp2;
- WinSetWindowULong (hwndUnhide, QWL_USER, (ULONG) pinstDesktop);
-
- // Scan each document window in the desktop
-
- cmd = QW_TOP;
- hwndFrame = pinstDesktop->hwndDesktop;
- while ((hwndFrame = WinQueryWindow (hwndFrame, cmd, FALSE)) != NULL)
- {cmd = QW_NEXT;
- WinQueryClassName (hwndFrame, sizeof (szClassName), szClassName);
- if (strcmpi (szClassName, "#1") != 0) continue;
- hwndDocument = WinWindowFromID (hwndFrame, FID_CLIENT);
- WinQueryClassName (hwndDocument, sizeof (szClassName), szClassName);
- if (strcmpi (szClassName, MDI_DOCUMENTCLASS) != 0) continue;
- pinstDocument = (PINSTDOCUMENT) WinQueryWindowULong (hwndDocument, QWL_USER + sizeof (PVOID));
-
- // If the document is hidden, add its title to the list box
-
- if (pinstDocument->usState & SWP_HIDE)
- {if (pinstDocument->iTitle == 0)
- sprintf (szClassName, "%s", pinstDocument->szTitle);
- else sprintf (szClassName, "%s:%d", pinstDocument->szTitle, pinstDocument->iTitle);
- WinSendMsg (WinWindowFromID (hwndUnhide, DIALOG_UNHIDE_LISTBOX),
- LM_INSERTITEM, MPFROMSHORT (LIT_SORTASCENDING), (MPARAM) szClassName);
- }
-
- // Loop until all documents processed
-
- }
-
- // Indicate initialize handled
-
- return (MRESULT) NULL;
-
- // When OK hit, unhide all selected entries
-
- case WM_COMMAND:
- if (SHORT1FROMMP (mp1) == DID_OK)
-
- // Scan each selected entry in the list box
-
- {i = (SHORT) WinSendDlgItemMsg (hwndUnhide, DIALOG_UNHIDE_LISTBOX,
- LM_QUERYSELECTION, MPFROMSHORT (LIT_FIRST), NULL);
- nItems = (SHORT) WinSendDlgItemMsg (hwndUnhide, DIALOG_UNHIDE_LISTBOX,
- LM_QUERYITEMCOUNT, NULL, NULL);
- nUnhidden = 0;
- hwndFirst = NULL;
- pinstDesktop = (PINSTDESKTOP) WinQueryWindowULong (hwndUnhide, QWL_USER);
- while (i != LIT_NONE)
- {WinSendDlgItemMsg (hwndUnhide, DIALOG_UNHIDE_LISTBOX,
- LM_QUERYITEMTEXT, MPFROM2SHORT (i, sizeof (szClassName)), (MPARAM) szTitle);
-
- // Scan each document window in the desktop
-
- cmd = QW_TOP;
- hwndFrame = pinstDesktop->hwndDesktop;
- while ((hwndFrame = WinQueryWindow (hwndFrame, cmd, FALSE)) != NULL)
- {cmd = QW_NEXT;
- WinQueryClassName (hwndFrame, sizeof (szClassName), szClassName);
- if (strcmpi (szClassName, "#1") != 0) continue;
- hwndDocument = WinWindowFromID (hwndFrame, FID_CLIENT);
- WinQueryClassName (hwndDocument, sizeof (szClassName), szClassName);
- if (strcmpi (szClassName, MDI_DOCUMENTCLASS) != 0) continue;
- pinstDocument = (PINSTDOCUMENT) WinQueryWindowULong (hwndDocument, QWL_USER + sizeof (PVOID));
-
- // If the document is hidden, extract its title
-
- if (pinstDocument->usState & SWP_HIDE)
- {if (pinstDocument->iTitle == 0)
- sprintf (szClassName, "%s", pinstDocument->szTitle);
- else sprintf (szClassName, "%s:%d", pinstDocument->szTitle, pinstDocument->iTitle);
-
- // If title matches select list box entry, unhide document
- // and put its entry back in the window menu
-
- if (strcmp (szClassName, szTitle) == 0)
- {pinstDocument->usState &= ~SWP_HIDE;
- mi.id = pinstDocument->idFrame;
- mi.iPosition = MIT_END;
- mi.afAttribute = 0;
- mi.hwndSubMenu = NULL;
- mi.hItem = NULL;
- mi.afStyle = MIS_TEXT;
- WinSendMsg (pinstDesktop->miWindow.hwndSubMenu,
- MM_INSERTITEM, (MPARAM) &mi, (MPARAM) szClassName);
- WinShowWindow (pinstDocument->hwndFrame, TRUE);
- if (hwndFirst == NULL)
- hwndFirst = pinstDocument->hwndFrame;
- nUnhidden++;
- break;
- }
- }
-
- // Loop until all documents scanned
-
- }
-
- // Loop until all list box entries processed
-
- i = (SHORT) WinSendDlgItemMsg (hwndUnhide, DIALOG_UNHIDE_LISTBOX,
- LM_QUERYSELECTION, MPFROMSHORT (i), NULL);
- }
-
- // If all entries have been unhidden, disable the
- // UNHIDE window submenu option
-
- if (nItems == nUnhidden)
- WinSendMsg (pinstDesktop->miWindow.hwndSubMenu, MM_SETITEMATTR,
- MPFROM2SHORT (CMD_UNHIDE, FALSE), MPFROM2SHORT (MIA_DISABLED, MIA_DISABLED));
-
- // If any entries at all have been unhidden, enable the
- // HIDE and NEW window submenu options
-
- WinSendMsg (pinstDesktop->miWindow.hwndSubMenu, MM_SETITEMATTR,
- MPFROM2SHORT (CMD_HIDE, FALSE), MPFROM2SHORT (MIA_DISABLED, FALSE));
- WinSendMsg (pinstDesktop->miWindow.hwndSubMenu, MM_SETITEMATTR,
- MPFROM2SHORT (CMD_NEW_DOCUMENT, FALSE), MPFROM2SHORT (MIA_DISABLED, FALSE));
-
- // Re-tile or re-cascade if necessary
-
- if (pinstDesktop->fTileAlways)
- MDIDocumentArrange (pinstDesktop->hwndDesktop, AWP_TILED);
- else if (pinstDesktop->fCascadeAlways)
- MDIDocumentArrange (pinstDesktop->hwndDesktop, AWP_CASCADED);
-
- // Activate the first document unhidden
-
- if (hwndFirst != NULL)
- WinSetWindowPos (hwndFirst, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE | SWP_ZORDER);
-
- }
-
- // Indicate dialog box terminated
-
- WinDismissDlg (hwndUnhide, SHORT1FROMMP (mp1));
- return (MRESULT) NULL;
-
- }
-
- // Return to PM
-
- return WinDefDlgProc (hwndUnhide, msg, mp1, mp2);
-
- }
-
-
- // Function: MDIDocumentWndProc - MDI Document window procedure
- // ------------------------------------------------------------
- MRESULT EXPENTRY MDIDocumentWndProc (hwndDocument, msg, mp1, mp2)
-
- HWND hwndDocument; // Document window
- USHORT msg; // PM message
- MPARAM mp1; // Message parameter 1
- MPARAM mp2; // Message parameter 2
-
- // Define function data
-
- {PINSTDOCUMENT pinst; // -->instance data
- PINSTDESKTOP pinstDesktop; // -->desktop instance data
-
- // Locate instance data
-
- pinst = (PINSTDOCUMENT) WinQueryWindowULong (hwndDocument, QWL_USER + sizeof (PVOID));
-
- // Analyze and process message
-
- switch (msg)
-
- {case WM_CLOSE:
- return MDIDocumentClose (pinst);
-
- case WM_COMMAND:
- return MDIDocumentCommand (pinst, LOUSHORT (mp1));
-
- case WM_CREATE:
- return MDIDocumentCreate (hwndDocument, (PDOCUMENTCREATEPARMS) mp1);
-
- case WM_DESTROY:
- return MDIDocumentDestroy (pinst);
-
- case WM_MINMAXFRAME:
- return MDIDocumentMinMax (pinst, (PSWP) mp1);
-
- case WM_MOVE:
- return (MRESULT) !WinQueryWindowPos (pinst->hwndFrame, &(pinst->swp));
-
- case WM_PAINT:
- return MDIDocumentPaint (pinst);
-
- case WM_SETFOCUS:
- pinstDesktop = (PINSTDESKTOP) WinQueryWindowULong (pinst->hwndDesktop, QWL_USER + sizeof (PVOID));
- if ((WinIsChild ((HWND) mp1, pinst->hwndFrame)
- || ((HWND) mp1 == pinstDesktop->hwndMenu)) && ! (BOOL) mp2)
- return (MRESULT) NULL;
- return MDIDocumentActivate (pinst, (BOOL) mp2);
-
- case WM_SIZE:
- return (MRESULT) !WinQueryWindowPos (pinst->hwndFrame, &(pinst->swp));
-
- case MDI_MSG_LOCATE_DOCUMENT_DATA:
- return (MRESULT) pinst->pvDocData;
-
- case MDI_MSG_LOCATE_INSTANCE_DATA:
- return (MRESULT) pinst->pvInstData;
-
- }
-
- // Return to PM
-
- return WinDefWindowProc (hwndDocument, msg, mp1, mp2);
-
- }
-
-
- // Function: MDIInitialize - Initialize MDI processing
- // ---------------------------------------------------
- VOID EXPENTRY MDIInitialize (hab)
-
- HAB hab; // Application anchor block
-
- // Define function data
-
- {static DOSFSRSEM dosfsrs; // Semaphore to block registration
- static BOOL fRegistered = FALSE; // TRUE if already registered
-
- // Block the actions that follow such that only one process at a
- // time executes them.
-
- DosFSRamSemRequest (&dosfsrs, SEM_INDEFINITE_WAIT);
-
- // Once only, perform initialization.
-
- if (! fRegistered)
-
- // Register MDI Desktop window class
-
- {WinRegisterClass (hab, MDI_DESKTOPCLASS, MDIDesktopWndProc,
- /*CS_PUBLIC |*/ CS_SIZEREDRAW | CS_MOVENOTIFY, cbExtraData);
-
- // Register MDI Document window class
-
- WinRegisterClass (hab, MDI_DOCUMENTCLASS, MDIDocumentWndProc,
- /*CS_PUBLIC |*/ CS_SIZEREDRAW | CS_MOVENOTIFY, cbExtraData);
-
- // Indicate initialization complete
-
- /*fRegistered = TRUE;*/
- }
-
- // Release the block and return
-
- DosFSRamSemClear (&dosfsrs);
- }
-
-
- // Function: MDILoadAccelTable - Load an MDI Accelerator Table
- // -----------------------------------------------------------
- HACCEL FAR MDILoadAccelTable (idAccelTable)
-
- USHORT idAccelTable; // Accelerator table id
-
- // Define function data
-
- {HACCEL haccel; // Accelerator table
- HMODULE hmod; // DLL module handle
- CHAR szDLL[MAX_STRING]; // DLL name
- PCHAR pszDot; // Temporary pointer
-
- // Extract the DLL name from our name
-
- strcpy (szDLL, MDI_MODNAME);
- if ((pszDot = strrchr (szDLL, '.')) != NULL)
- *pszDot = 0;
-
- // Load accelerator table
-
- DosLoadModule (szDLL, sizeof (szDLL), szDLL, &hmod);
- haccel = WinLoadAccelTable (NULL, hmod, idAccelTable);
- DosFreeModule (hmod);
-
- // Return handle
-
- return haccel;
-
- }
-
-
- // Function: MDILoadDialog - Load an MDI Dialog Box
- // ------------------------------------------------
- HWND FAR MDILoadDialog (hwndParent, pfnDlgProc, idDialog, pCreateParms)
-
- HWND hwndParent; // Dialog box parent
- PFNWP pfnDlgProc; // Dialog box procedure
- USHORT idDialog; // Dialog box id
- PVOID pCreateParms; // Creation parameters
-
- // Define function data
-
- {HWND hdlg; // Dialog box
- HMODULE hmod; // DLL module handle
- CHAR szDLL[MAX_STRING]; // DLL name
- PCHAR pszDot; // Temporary pointer
-
- // Extract the DLL name from our name
-
- strcpy (szDLL, MDI_MODNAME);
- if ((pszDot = strrchr (szDLL, '.')) != NULL)
- *pszDot = 0;
-
- // Load dialog box
-
- DosLoadModule (szDLL, sizeof (szDLL), szDLL, &hmod);
- hdlg = WinLoadDlg (HWND_DESKTOP, hwndParent, pfnDlgProc, hmod, idDialog, pCreateParms);
- DosFreeModule (hmod);
-
- // Return handle
-
- return hdlg;
-
- }
-
-
- // Function: MDILoadMenu - Load an MDI Menu
- // ----------------------------------------
- HWND FAR MDILoadMenu (hwndParent, idMenu)
-
- HWND hwndParent; // Menu parent
- USHORT idMenu; // Menu identifier
-
- // Define function data
-
- {HWND hMenu; // Menu
- HMODULE hmod; // DLL module handle
- CHAR szDLL[MAX_STRING]; // DLL name
- SEL sel; // Menu template selector
- PVOID pvmt; // Menu template address
- PCHAR pszDot; // Temporary pointer
-
- // Extract the DLL name from our name
-
- strcpy (szDLL, MDI_MODNAME);
- if ((pszDot = strrchr (szDLL, '.')) != NULL)
- *pszDot = 0;
-
- // Load menu
-
- DosLoadModule (szDLL, sizeof (szDLL), szDLL, &hmod);
- DosGetResource (hmod, RT_MENU, idMenu, &sel);
- pvmt = MAKEP (sel, 0);
- hMenu = WinCreateWindow (hwndParent, WC_MENU, NULL, NULL,
- 0, 0, 0, 0, hwndParent, HWND_BOTTOM, idMenu, pvmt, NULL);
- DosFreeSeg (sel);
- DosFreeModule (hmod);
-
- // Return handle
-
- return hMenu;
-
- }