home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- Module name: Frame.C
- Programmer : Jeffrey M. Richter & Elvira Peretsman.
- *****************************************************************************/
-
- #include "..\nowindws.h"
- #undef NOCOLOR
- #undef NOCTLMGR
- #undef NODEFERWINDOWPOS
- #undef NOGDI
- #undef NOKERNEL
- #undef NOLSTRING
- #undef NOMB
- #undef NOMDI
- #undef NOMENUS
- #undef NOMINMAX
- #undef NONCMESSAGES
- #undef NOSCROLL
- #undef NOSHOWWINDOW
- #undef NOSYSCOMMANDS
- #undef NOSYSMETRICS
- #undef NOTEXTMETRIC
- #undef NOUSER
- #undef NOWH
- #undef NOWINMESSAGES
- #undef NOWINOFFSETS
- #undef NOWINSTYLES
- #define OEMRESOURCE
- #include <windows.h>
-
- #include "mdi.h"
-
- static char _szClassName[] = "Frame";
-
- // Structure for use with Class Extra Bytes.
- typedef struct {
- WORD wNumSheets; // Number of Sheet windows created.
- WORD wNumCharts; // Number of Chart windows created.
- HMENU hMenu; // Menu used when no MDI Children are active.
- BOOL fStatusBarOn; // Is the status bar showing.
- HWND hWndMenuHelp; // Window that last received a WM_MENUSELECT message.
- DWORD dwMenuHelp; // Menu help code placed here by hWndMenuHelp window.
- } CLSEB;
-
- void NEAR PASCAL TileVertically (HWND hWndMDIClient);
- BOOL FAR PASCAL AboutProc (HWND hDlg, WORD wMsg, WORD wParam, LONG lParam);
-
- LONG FAR PASCAL FrameWndProc (HWND hWnd, WORD wMsg, WORD wParam, LONG lParam) {
- BOOL fCallDefProc = FALSE;
- DWORD dwResult = 0;
-
- CLIENTCREATESTRUCT ccs;
- HMENU hMenu;
- RECT rc, rcTemp;
- WORD wTemp = 0;
- FARPROC fpProc;
- char szBuf[100];
- PAINTSTRUCT ps;
- TEXTMETRIC tm;
- HPEN hPen;
- BITMAP Bitmap;
- HWND hWndActiveMDIChild, hWndChild;
- BOOL fMDIChildIsMaximized;
-
- if (IsWindow(_hWndMDIClient))
- dwResult = SendMessage(_hWndMDIClient, WM_MDIGETACTIVE, 0, 0);
-
- // Get the window handle of the active MDI Child.
- // This is NULL if no MDI Children exist.
- hWndActiveMDIChild = (HWND) LOWORD(dwResult);
-
- // Determine if the MDI Child is maximized.
- fMDIChildIsMaximized = HIWORD(dwResult);
- dwResult = 0;
-
- switch (wMsg) {
-
- case WM_CREATE:
- // Initialize default values in the class extra bytes.
- hMenu = LoadMenu(_hInstance, _szClassName);
- SETCLSEB(hWnd, CLSEB, hMenu, hMenu);
- SETCLSEB(hWnd, CLSEB, fStatusBarOn, TRUE);
-
- // Create the MDICLIENT window as a child of the Frame.
- ccs.hWindowMenu = GetSubMenu(GetMenu(hWnd), 1);
- ccs.idFirstChild = IDM_WINDOWCHILD;
-
- _hWndMDIClient = CreateWindow("MDIClient", "",
- WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL |
- WS_VISIBLE | WS_CLIPSIBLINGS, 0, 0, 0, 0, hWnd, NULL, _hInstance,
- (LPSTR) (LPCLIENTCREATESTRUCT) &ccs);
- break;
-
- case WM_CLOSE:
- // Before closing the application, ask the MDI Children if it is OK?
- // wParam is TRUE because the Windows session is NOT being ended.
- fCallDefProc = (BOOL) SendMessage(hWnd, WM_QUERYENDSESSION, TRUE, 0);
- if (fCallDefProc) SendMessage(hWnd, WM_ENDSESSION, TRUE, 0);
- break;
-
- case WM_QUERYENDSESSION:
- // If called by Windows, wParam is zero else wParam is TRUE.
-
- // Assume that it is OK to end the session.
- dwResult = TRUE;
-
- // Get the handle of the first MDI Child.
- hWndChild = GetWindow(_hWndMDIClient, GW_CHILD);
-
- // If no MDI Children exist, it is OK to terminate.
- if (hWndChild == NULL) break;
-
- // Ask each child if it is OK to terminate.
- do {
- // Do not ask caption bars of iconic MDI Children.
- if (GetWindow(hWndChild, GW_OWNER) != NULL) continue;
-
- dwResult = SendMessage(hWndChild, WM_QUERYENDSESSION, wParam, 0);
-
- // If the MDI Child says that it is NOT OK, don't ask the
- // rest of the MDI Children.
- if (dwResult == FALSE) break;
-
- } while ((hWndChild = GetWindow(hWndChild, GW_HWNDNEXT)) != NULL);
-
-
- // If any MDI Child said NO, tell the other children that
- // the session is NOT being terminated.
- if (dwResult == FALSE) {
- wTemp = hWndChild;
- hWndChild = GetWindow(_hWndMDIClient, GW_CHILD);
- do {
- // If this child is the one that said NO, stop.
- if (wTemp == hWndChild) break;
-
- // Do not send to caption bars of iconic MDI Children.
- if (GetWindow(hWndChild, GW_OWNER) != NULL) continue;
-
- // Tell child we are not ending the session (wParam is FALSE).
- SendMessage(hWndChild, WM_ENDSESSION, FALSE, 0);
- } while ((hWndChild = GetWindow(hWndChild, GW_HWNDNEXT)) != NULL);
- }
- // dwResult is TRUE if OK, FALSE if not Ok.
- break;
-
- case WM_ENDSESSION:
- // wParam != FALSE if shutting down.
-
- // Get handle of first MDI Child window.
- hWndChild = GetWindow(_hWndMDIClient, GW_CHILD);
-
- // If no MDI Children exist, we are done.
- if (hWndChild == NULL) break;
-
- // Tell each MDI Child whether or not the session is ending.
- do {
- // Do not send to caption bars of iconic MDI Children.
- if (GetWindow(hWndChild, GW_OWNER) != NULL) continue;
-
- SendMessage(hWndChild, WM_ENDSESSION, wParam, 0);
- } while ((hWndChild = GetWindow(hWndChild, GW_HWNDNEXT)) != NULL);
- break;
-
- case WM_DESTROY:
- PostQuitMessage(0);
- break;
-
- case WM_SYSCOMMAND:
- // Set focus to frame window. This causes any comboboxes
- // in the ribbon to be closed.
- SetFocus(hWnd);
- fCallDefProc = TRUE;
- break;
-
- case WM_NCLBUTTONDBLCLK:
- // Code to allow double-clicking the MDI Child's system menu
- // to close the MDI Child window.
- fCallDefProc = TRUE;
-
- // If mouse wasn't clicked in the application's menu, nothing to do.
- if (wParam != HTMENU) break;
-
- // If the active child is not maximized, nothing to do.
- dwResult = SendMessage(_hWndMDIClient, WM_MDIGETACTIVE, 0, 0);
- if (HIWORD(dwResult) != 1) break;
-
- // Get position and dimensions of the MDI Child's system menu in
- // the Frame's menu bar.
-
- // Get position and dimensions of the Frame window.
- GetWindowRect(hWnd, &rc);
-
- // Get handle to the CLOSE BOX bitmaps.
- wTemp = LoadBitmap(NULL, MAKEINTRESOURCE(OBM_CLOSE));
-
- // Get dimensions of the bitmaps.
- GetObject((HBITMAP) wTemp, sizeof(BITMAP), (LPSTR) (LPBITMAP) &Bitmap);
- DeleteObject((HBITMAP) wTemp);
-
- // Adjust the rectangle.
- rc.top += GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME);
- rc.bottom = rc.top + Bitmap.bmHeight;
- rc.left += GetSystemMetrics(SM_CXFRAME);
-
- // The close bitmap includes the Application and MDI Child CLOSE
- // boxes. So we only want half of the bitmap's width.
- rc.right = rc.left + Bitmap.bmWidth / 2;
-
- // If the mouse cursor is within this rectangle, tell the
- // MDI Child window to close.
- if (!PtInRect(&rc, MAKEPOINT(lParam))) break;
- SendMessage(LOWORD(dwResult), WM_SYSCOMMAND, SC_CLOSE, lParam);
- fCallDefProc = FALSE;
- break;
-
- case FW_MDICHILDDESTROY:
- // Message is posted by an MDI Child just before it is destroyed.
-
- // If another MDI Child exists, nothing to do.
- if (hWndActiveMDIChild != NULL) break;
-
- // Set the menu bar and accelerator table to the Frame's defaults.
- ChangeMDIMenu(hWnd, _hWndMDIClient,
- (HMENU) GETCLSEB(hWnd, CLSEB, hMenu), IDM_WINDOWTILEVERT);
- _hAccelTable = NULL;
-
- // Force the status bar to be updated.
- InvalidateRect(hWnd, NULL, TRUE);
-
- // Disable the Ribbon.
- EnableWindow(_hDlgRibbon, FALSE);
- break;
-
- case FW_GETSTATBARRECT:
- // lParam = LPRECT.
- // Get the client area of the Frame window.
- GetClientRect(hWnd, (LPRECT) lParam);
-
- // If the status bar is OFF, set the status bar to have no height.
- if (!GETCLSEB(hWnd, CLSEB, fStatusBarOn)) {
- ((LPRECT) lParam)->top = ((LPRECT) lParam)->bottom;
- break;
- }
-
- // Change the dimensions so that the status bar is the height of
- // one line of text plus a small border.
- wTemp = GetDC(hWnd);
- GetTextMetrics((HDC) wTemp, &tm);
- ReleaseDC(hWnd, (HDC) wTemp);
- ((LPRECT) lParam)->top = ((LPRECT) lParam)->bottom - tm.tmHeight -
- GetSystemMetrics(SM_CYBORDER);
- break;
-
-
- case FW_DRAWSTATUSDIVIDE:
- // lParam = (LPPAINTSTRUCT) &ps.
- // Draw a line separating the status bar from the MDICLIENT window.
- dwResult = GetSystemMetrics(SM_CYBORDER);
- hPen = CreatePen(PS_SOLID, (int) dwResult, RGB(0, 0, 0));
- hPen = SelectObject(((LPPAINTSTRUCT) lParam)->hdc, hPen);
- MoveTo(((LPPAINTSTRUCT) lParam)->hdc, 0,
- ((LPPAINTSTRUCT) lParam)->rcPaint.top);
- LineTo(((LPPAINTSTRUCT) lParam)->hdc,
- ((LPPAINTSTRUCT) lParam)->rcPaint.right,
- ((LPPAINTSTRUCT) lParam)->rcPaint.top);
- hPen = SelectObject(((LPPAINTSTRUCT) lParam)->hdc, hPen);
- DeleteObject(hPen);
- break;
-
- case FW_RESIZEMDICLIENT:
- // Sent when the Frame window is resized or when the status bar
- // and ribbon are toggled.
- GetClientRect(hWnd, &rc);
-
- if (IsWindow(_hDlgRibbon) && IsWindowVisible(_hDlgRibbon)) {
- // Ribbon is displayed, adjust rectangle.
- GetClientRect(_hDlgRibbon, &rcTemp);
- rc.top += rcTemp.bottom;
- rc.bottom -= rcTemp.bottom;
- }
-
- // Get the dimensions of the status bar rectangle and adjust the
- // dimensions of the MDICLIENT window.
- SendMessage(hWnd, FW_GETSTATBARRECT, 0, (LONG) (LPRECT) &rcTemp);
- rc.bottom -= rcTemp.bottom - rcTemp.top;
- MoveWindow(_hWndMDIClient, 0, rc.top, rc.right, rc.bottom, TRUE);
- break;
-
- case WM_SIZE:
- // Force MDICHILD window to be resized.
- SendMessage(hWnd, FW_RESIZEMDICLIENT, 0, 0);
- break;
-
- case WM_PAINT:
- // Since the only visible portion of the Frame's client area is
- // the status bar when it is ON, this must mean that the status
- // bar needs to be repainted.
-
- // Set up the device context.
- BeginPaint(hWnd, &ps);
- SendMessage(hWnd, FW_GETSTATBARRECT, 0, (LONG) (LPRECT) &ps.rcPaint);
- SetBkMode(ps.hdc, TRANSPARENT);
-
- // If an MDI Child exists, the status bar must be updated by it.
- if (hWndActiveMDIChild) {
- SendMessage(hWndActiveMDIChild, AC_PAINTSTATBAR, ps.hdc,
- (LONG) (LPPAINTSTRUCT) &ps);
- } else {
- // No MDI Child exists, the Frame can do whatever it wants here.
- ps.rcPaint.top += (int) SendMessage(hWnd, FW_DRAWSTATUSDIVIDE, 0,
- (LONG) (LPPAINTSTRUCT) &ps);
- LoadString(_hInstance, IDS_FRAMESTATUSBAR, szBuf, sizeof(szBuf));
- TextOut(ps.hdc, 0, ps.rcPaint.top, szBuf, lstrlen(szBuf));
- }
- EndPaint(hWnd, &ps);
- break;
-
- case WM_INITMENU:
- // The user has entered the menu system, set any options.
- CheckMenuItem(wParam, IDM_OPTIONSSTATUS, MF_BYCOMMAND |
- (GETCLSEB(hWnd, CLSEB, fStatusBarOn) ? MF_CHECKED : MF_UNCHECKED));
-
- CheckMenuItem(wParam, IDM_OPTIONSRIBBON, MF_BYCOMMAND |
- (IsWindowVisible(_hDlgRibbon) ? MF_CHECKED : MF_UNCHECKED));
- break;
-
- case FW_SETMENUHELP:
- // Called by the Frame and MDI Children whenever a
- // WM_MENUSELECT message is received.
- // wParam = HWND of sender.
- // lParam = Menu description code.
-
- // Save the handle of the window sending the message.
- SETCLSEB(hWnd, CLSEB, hWndMenuHelp, (HWND) wParam);
-
- // Save the menu help code that the window sent too.
- SETCLSEB(hWnd, CLSEB, dwMenuHelp, lParam);
-
-
- // When the Frame or MDI Child receive a WM_MENUSELECT message
- // specifying that the menu system is closed
- // (lParam == MAKELONG(-1, 0)), the menu help should disappear and
- // be replaced by the proper information on the status bar.
-
- if (wParam == NULL) {
- SendMessage(hWnd, FW_GETSTATBARRECT, 0, (LONG) (LPRECT) &rc);
- // Force status bar to be updated.
- InvalidateRect(hWnd, &rc, TRUE);
- }
- break;
-
- case FW_GETMENUHELP:
- // Sent by the Frame or MDI Child when they
- // receive a AW_PAINTMENUHELP message.
- dwResult = GETCLSEB(hWnd, CLSEB, dwMenuHelp);
- break;
-
- case WM_MENUSELECT:
- // The user has highlighted a menu item.
-
- if (lParam == MAKELONG(-1, 0)) {
- // User has stopped using the menu system.
- SendMessage(hWnd, FW_SETMENUHELP, 0, 0);
- break;
- }
-
- // If wTemp == 0, at end of switch, MDI Child handled the message.
- wTemp = 0;
-
- switch (LOWORD(lParam) & (MF_POPUP | MF_SYSMENU)) {
-
- case 0:
- // wParam is a menu item ID NOT on the app's system menu.
-
- if (hWndActiveMDIChild != NULL) {
- // An MDI Child exists.
- if (fMDIChildIsMaximized) {
-
- // If menu item from the MDI Child's system menu, set
- // the MF_SYSMENU bit in the lParam parameter.
- wTemp = GetSubMenu(GetMenu(hWnd), 0);
- if ((int) GetMenuState(wTemp, wParam, MF_BYCOMMAND) != -1)
- lParam |= MF_SYSMENU;
- }
-
- // Make active MDI Child think that it received the
- // WM_MENUSELECT message.
- SendMessage(hWndActiveMDIChild, wMsg, wParam, lParam);
- wTemp = 0; // MDI Child handled the message.
- break;
- }
-
- wTemp = IDS_FRAMEMENUID + wParam;
- break;
-
- case MF_POPUP:
- // wParam is handle to popup menu.
-
- if (hWndActiveMDIChild != NULL) {
- // An MDI Child exists.
- if (fMDIChildIsMaximized) {
- // If popup menu is first top-level menu, it is the
- // MDI Child's system menu, set the MF_SYSMENU flag.
- if (wParam == GetSubMenu(GetMenu(hWnd), 0))
- lParam |= MF_SYSMENU;
- }
-
- // Make active MDI Child think that it received the
- // WM_MENUSELECT message.
- SendMessage(hWndActiveMDIChild, wMsg, wParam, lParam);
- wTemp = 0; // MDI Child handled the message.
- break;
- }
-
- // Calculate the index of the top-level menu.
- hMenu = GetMenu(hWnd);
- wTemp = GetMenuItemCount(hMenu);
- while (wTemp--)
- if (GetSubMenu(hMenu, wTemp) == (HMENU) wParam) break;
- wTemp += IDS_FRAMEPOPUPID + 1; // Jump over system menu.
- break;
-
- case MF_SYSMENU:
- // wParam is menu item ID from system menu.
- wTemp = IDS_FRAMEMENUID + ((wParam & 0x0FFF) >> 4);
- break;
-
- case MF_POPUP | MF_SYSMENU:
- // wParam is handle to app's sys menu.
- wTemp = IDS_FRAMEPOPUPID;
- break;
- }
-
- // If message handled by MDI Child, nothing more to do.
- if (wTemp == 0) break;
-
- // Tell the Frame that the Frame window should display the
- // help text and the identifier for the help text.
- SendMessage(hWnd, FW_SETMENUHELP, hWnd, wTemp);
- break;
-
- case WM_ENTERIDLE:
- if (wParam != MSGF_MENU) break;
-
- // User has stopped scrolling through menu items.
-
- // If Menu help already displayed, nothing more to do.
- // This is signaled by hWndMenu help being -1.
- if (GETCLSEB(hWnd, CLSEB, hWndMenuHelp) == -1)
- break;
-
- // Display new menu help, invalidate the status bar.
- SendMessage(hWnd, FW_GETSTATBARRECT, 0, (LONG) (LPRECT) &rc);
- InvalidateRect(hWnd, &rc, TRUE);
-
- // BeginPaint is OK because an invalid rectangle must exist because
- // of the call to InvalidateRect above. This causes the background
- // for the Frame's client area to be drawn correctly.
- BeginPaint(hWnd, &ps);
-
- // Set up the device context.
- SetBkMode(ps.hdc, TRANSPARENT);
-
- // Send message to window that last received a WM_MENUSELECT
- // message to tell it to paint the status bar with the
- // appropriate menu help text.
- SendMessage((HWND) GETCLSEB(hWnd, CLSEB, hWndMenuHelp),
- AW_PAINTMENUHELP, 0, (LONG) (LPPAINTSTRUCT) &ps);
-
- EndPaint(hWnd, &ps);
-
- // Set flag notifying this message that the most recently selected
- // menu item has had its help text painted. This stops unsightly
- // screen flicker.
- SETCLSEB(hWnd, CLSEB, hWndMenuHelp, (HWND) -1);
- break;
-
- case AW_PAINTMENUHELP:
- // Message sent from Frame window to notify Frame that it should
- // paint the status bar text for the last highlighted menu item.
- // lParam = LPPAINTSTRUCT of Frame's status bar.
-
- // Ask the Frame window what the last selected menu ID was.
- // This value was sent to the frame by this window during the
- // processing for the WM_MENUSELECT message.
- dwResult = SendMessage(hWnd, FW_GETMENUHELP, 0, 0);
-
- // Draw the horizontal dividing line separating the Status bar
- // from the MDICLIENT window.
- ((LPPAINTSTRUCT) lParam)->rcPaint.top += (int)
- SendMessage(hWnd, FW_DRAWSTATUSDIVIDE, 0,
- (LONG) (LPPAINTSTRUCT) lParam);
-
- // Construct the string that is to be displayed.
- LoadString(_hInstance, LOWORD(dwResult), szBuf, sizeof(szBuf));
-
- // Paint the menu help text in the status bar.
- TextOut(((LPPAINTSTRUCT) lParam)->hdc,
- 0, ((LPPAINTSTRUCT) lParam)->rcPaint.top, szBuf, lstrlen(szBuf));
- break;
-
-
- case WM_COMMAND:
- // If a child is being activated via the "Window" menu, let
- // the DefFrameProc handle it.
- if (wParam >= IDM_WINDOWCHILD) {
- fCallDefProc = TRUE;
- break;
- }
-
- switch (wParam) {
-
- case IDM_FILEOPENSHEET:
- // Get the # of sheets already created and increment by 1.
- wTemp = GETCLSEB(hWnd, CLSEB, wNumSheets) + 1;
- SETCLSEB(hWnd, CLSEB, wNumSheets, wTemp);
-
- // The sheet's caption should display the sheet number.
- wsprintf(szBuf, "Sheet%d", wTemp);
-
- // Create the MDI Child window.
- CreateMDIChild("Sheet", szBuf, 0,
- CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
- _hWndMDIClient, _hInstance, 0);
-
- // Make sure the ribbon is enabled when any children exist.
- EnableWindow(_hDlgRibbon, TRUE);
- break;
-
- case IDM_FILEOPENCHART:
- // Get the # of charts already created and increment by 1.
- wTemp = GETCLSEB(hWnd, CLSEB, wNumCharts) + 1;
- SETCLSEB(hWnd, CLSEB, wNumCharts, wTemp);
-
- // The chart's caption should display the chart number.
- wsprintf(szBuf, "Chart%d", wTemp);
-
- // Create the MDI Child window.
- CreateMDIChild("Chart", szBuf, 0,
- CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
- _hWndMDIClient, _hInstance, 0);
-
- // Make sure the ribbon is enabled when any children exist.
- EnableWindow(_hDlgRibbon, TRUE);
- break;
-
- case IDM_OPTIONSSTATUS:
- // Toggle the status of the status bar, resize the MDICLIENT.
- wTemp = !GETCLSEB(hWnd, CLSEB, fStatusBarOn);
- SETCLSEB(hWnd, CLSEB, fStatusBarOn, wTemp);
- SendMessage(hWnd, FW_RESIZEMDICLIENT, 0, 0);
- break;
-
- case IDM_OPTIONSRIBBON:
- // Toggle the status of the ribbon, resize the MDICLIENT.
- ShowWindow(_hDlgRibbon,
- IsWindowVisible(_hDlgRibbon) ? SW_HIDE : SW_SHOW);
- SendMessage(hWnd, FW_RESIZEMDICLIENT, 0, 0);
- break;
-
- case IDM_EXIT:
- SendMessage(hWnd, WM_CLOSE, 0, 0L);
- break;
-
- case IDM_HELPINDEX:
- case IDM_HELPKEYBOARD:
- case IDM_HELPCOMMANDS:
- case IDM_HELPPROCEDURES:
- case IDM_HELPUSINGHELP:
- MessageBox(hWnd, "Option not implemented.", _szAppName, MB_OK);
- break;
-
- case IDM_ABOUT:
- fpProc = MakeProcInstance(AboutProc, _hInstance);
- DialogBox(_hInstance, "About", hWnd, fpProc);
- FreeProcInstance(fpProc);
- break;
-
- case IDM_WINDOWTILEVERT:
- // Call our own function to perform vertical tiling.
- TileVertically(_hWndMDIClient);
- break;
-
- case IDM_WINDOWTILEHORIZ:
- // Let the MDICLIENT window do the repositioning.
- SendMessage(_hWndMDIClient, WM_MDITILE, 0, 0);
- break;
-
- case IDM_WINDOWCASCADE:
- // Let the MDICLIENT window do the repositioning.
- SendMessage(_hWndMDIClient, WM_MDICASCADE, 0, 0);
- break;
-
- case IDM_WINDOWARRANGEICONS:
- // Let the MDICLIENT window do the repositioning.
- SendMessage(_hWndMDIClient, WM_MDIICONARRANGE, 0, 0);
- break;
-
- default:
- // Menu options not processed by the Frame window must
- // be passed to the MDI Children for processing.
- SendMessage(hWndActiveMDIChild, wMsg, wParam, lParam);
- break;
- }
- break;
-
- default:
- fCallDefProc = TRUE;
- break;
- }
-
- if (fCallDefProc)
- dwResult = DefFrameProc(hWnd, _hWndMDIClient, wMsg, wParam, lParam);
- return(dwResult);
- }
-
-
- BOOL FAR PASCAL RegisterFrameWndClass (void) {
- WNDCLASS wc;
-
- wc.style = CS_HREDRAW | CS_VREDRAW;
- wc.lpfnWndProc = FrameWndProc;
-
- // Number of class extra bytes used by structure.
- wc.cbClsExtra = sizeof(CLSEB);
-
- wc.cbWndExtra = 0;
- wc.hInstance = _hInstance;
- wc.hIcon = LoadIcon(_hInstance, _szClassName);
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.hbrBackground = COLOR_WINDOW + 1;
- wc.lpszMenuName = _szClassName;
- wc.lpszClassName = _szClassName;
- return(RegisterClass(&wc));
- }
-
-
- void NEAR PASCAL TileVertically (HWND hWndMDIClient) {
- int nNumWndsOnRow, nOpenMDIChildren = 0, nTopOfBottomIconRow = 0;
- int nCrntCol, nColWidth, nCrntRow, nNumRows, nRowHeight, nMinWndHeight;
- HWND hWndChild;
- HANDLE hWinPosInfo;
- RECT rc;
- POINT Point;
- DWORD dwChildInfo;
-
- // Assume that scrollbars will be off after windows are tiled.
- // By forcing them off now, GetClientRect will return the correct size.
- ShowScrollBar(hWndMDIClient, SB_BOTH, 0);
-
- // The WM_MDICASCADE and WM_MDITILE messages cause the icons to be
- // arranged. So we will too. In fact, this is necessary to locate
- // the top of the bottom icon row in the next step of this function.
- SendMessage(hWndMDIClient, WM_MDIICONARRANGE, 0, 0);
-
- // Get handle to first MDI Child window.
- hWndChild = GetWindow(hWndMDIClient, GW_CHILD);
- do {
- if (IsIconic(hWndChild) && GetWindow(hWndChild, GW_OWNER) == NULL) {
- // Window is iconic and window is NOT an icon's caption.
-
- // Get client area of the icon window.
- GetWindowRect(hWndChild, &rc);
-
- // rc.top is in screen coordinates.
- nTopOfBottomIconRow = max(nTopOfBottomIconRow, rc.top);
- }
-
- if (!IsIconic(hWndChild) && GetWindow(hWndChild, GW_OWNER) == NULL)
- ++nOpenMDIChildren;
-
- } while ((hWndChild = GetWindow(hWndChild, GW_HWNDNEXT)) != NULL);
-
-
- // All MDI Children are icons, no tiling is necessary.
- if (nOpenMDIChildren == 0) return;
-
-
- // Find height of usable client area for tiling.
- GetClientRect(hWndMDIClient, &rc);
-
- if (nTopOfBottomIconRow) {
- // At least one MDI Child is iconic.
-
- // Convert coordinates from screen to client.
- Point.x = 0; Point.y = nTopOfBottomIconRow;
- ScreenToClient(hWndMDIClient, &Point);
- // Point.y is top of bottom icon row in client coordinates.
- rc.bottom = Point.y;
- }
-
-
- // Restore the active MDI child if it's maximized
- dwChildInfo = SendMessage(hWndMDIClient, WM_MDIGETACTIVE, 0, 0);
- if (HIWORD(dwChildInfo) == 1)
- ShowWindow(LOWORD(dwChildInfo), SW_RESTORE);
-
- // Calculate the minimum desired height of each MDI Child.
- nMinWndHeight = max(1, rc.bottom / (5 * GetSystemMetrics(SM_CYCAPTION)));
-
- // Calculate the number of rows that will be tiled.
- nNumRows = min(nOpenMDIChildren, nMinWndHeight);
-
- // Calculate the height of each row.
- nRowHeight = rc.bottom / nNumRows;
-
- // Get the handle to the first MDI Child window.
- hWndChild = GetWindow(hWndMDIClient, GW_CHILD);
-
- // Prime the storage of positioning information.
- hWinPosInfo = BeginDeferWindowPos(nOpenMDIChildren);
-
- // Execute the loop for each row.
- for (nCrntRow = 0; nCrntRow < nNumRows; nCrntRow++) {
-
- // Calculate the number of MDI Children that will appear on this row.
- nNumWndsOnRow = nOpenMDIChildren / nNumRows +
- ((nOpenMDIChildren % nNumRows > (nNumRows - (nCrntRow + 1))) ? 1 : 0);
-
- // Calculate the width of each of these children.
- nColWidth = rc.right / nNumWndsOnRow;
-
- // Fill each column with an MDI Child window.
- for (nCrntCol = 0; nCrntCol < nNumWndsOnRow; ) {
-
- if (!IsIconic(hWndChild) && GetWindow(hWndChild, GW_OWNER) == NULL) {
- // Child is NOT iconic and not an icon's caption bar.
-
- // Tell windows what the new position and dimensions of this
- // MDI Child should be.
- hWinPosInfo = DeferWindowPos(hWinPosInfo, hWndChild, NULL,
- nCrntCol * nColWidth, nCrntRow * nRowHeight, nColWidth,
- nRowHeight, SWP_NOACTIVATE | SWP_NOZORDER);
-
- // Go to the next column.
- nCrntCol++;
- }
-
- // Get handle to the next MDI Child window.
- hWndChild = GetWindow(hWndChild, GW_HWNDNEXT);
- }
- }
-
- // All of the positioning has been set. Now, tell Windows to update
- // all of the windows at once.
- EndDeferWindowPos(hWinPosInfo);
- }
-