home *** CD-ROM | disk | FTP | other *** search
- #define _FRAME_C
- //-----------------------------------------------------------------
- // APP.C - <description>
- //
- // MAKEMDI adaptation of Windows 3.1 SDK MAKEAPP system.
- //
- // MDI application design based on Chapter 7 of
- // "Windows 3: A Developer's Guide" by Jeffrey Richter.
- //
- // Adaptation developed with permission of the author by
- // John F. Holliday, Technisoft Corporation
- // Telephone: (515) 472-9803, CompuServe: 71271,634
- //
- // [DMM] 25-Nov-1992: Fixed crashing on exit
- // Also tabified file to tabsize of 4
- //
- // David M. Miller, Business Visions, Inc.
- // Telephone: (212) 747-6118
- // CompuServe: 72676,327
- // internet: dmiller@hera.sbi.com
- //-----------------------------------------------------------------
- #include "makemdi.h"
-
-
- BOOL Frame_Initialize(APP * papp)
- {
- WNDCLASS cls;
-
- cls.hCursor = LoadCursor(NULL, IDC_ARROW);
- cls.hIcon = LoadIcon(papp->hinst, MAKEINTRESOURCE(IDR_FRAMEICON));
- cls.lpszMenuName = MAKEINTRESOURCE(IDR_FRAMEMENU);
- cls.hInstance = papp->hinst;
- cls.lpszClassName = CLASS_FRAME;
- cls.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
- cls.lpfnWndProc = Frame_WndProc;
- cls.style = CS_HREDRAW | CS_VREDRAW;
- cls.cbWndExtra = sizeof(FRAME *);
- cls.cbClsExtra = 0;
-
- if (!RegisterClass(&cls))
- return FALSE;
-
- return TRUE;
- }
-
- void Frame_Terminate(APP * papp)
- {
- }
-
- LRESULT CALLBACK _export Frame_WndProc(HWND hWnd,
- UINT msg,
- WPARAM wParam,
- LPARAM lParam)
- {
- LRESULT lResult = 0;
- FRAME *pfrm = Frame_GetPtr(hWnd);
-
- if (pfrm == NULL) {
- if (msg == WM_NCCREATE) {
- pfrm = (FRAME *) LocalAlloc(LPTR, sizeof(FRAME));
-
- if (pfrm == NULL)
- return (LRESULT) FALSE;
-
- pfrm->hWnd = hWnd;
- Frame_SetPtr(hWnd, pfrm);
- }
- else
- return DefWindowProc(hWnd, msg, wParam, lParam);
- }
-
- if (msg == WM_NCDESTROY) {
- // [DMM] Added: save hwndClient before freeing pfrm
- HWND hWndClient = pfrm->hWndClient;
-
- if (pfrm->fpProcRibbon != NULL)
- FreeProcInstance((FARPROC) pfrm->fpProcRibbon);
-
- if (pfrm->hMenu != NULL)
- DestroyMenu(pfrm->hMenu);
-
- LocalFree((HLOCAL)OFFSETOF(pfrm));
- pfrm = NULL;
- Frame_SetPtr(hWnd, NULL);
-
- // [DMM] Added: execution ends here on NCDESTROY
- return DefFrameProc(hWnd, hWndClient, msg, wParam, lParam);
- }
-
-
- // Get the window handle of the active MDI child.
- // This is NULL if no MDI children exist.
- // Determine if the MDI child is maximized.
-
- if (IsWindow(pfrm->hWndClient))
- lResult = SendMessage(pfrm->hWndClient, WM_MDIGETACTIVE, 0, 0);
-
- pfrm->hWndActiveMDIChild = (HWND) LOWORD(lResult);
- pfrm->fMDIChildIsMaximized = HIWORD(lResult);
-
-
- switch (msg) {
- // Windows messages
-
- HANDLE_MSG(pfrm, WM_CREATE, Frame_OnCreate);
- HANDLE_MSG(pfrm, WM_DESTROY, Frame_OnDestroy);
- HANDLE_MSG(pfrm, WM_CLOSE, Frame_OnClose);
- HANDLE_MSG(pfrm, WM_QUERYENDSESSION, Frame_OnQueryEndSession);
- HANDLE_MSG(pfrm, WM_ENDSESSION, Frame_OnEndSession);
- HANDLE_MSG(pfrm, WM_PAINT, Frame_OnPaint);
- HANDLE_MSG(pfrm, WM_ERASEBKGND, Frame_OnEraseBkgnd);
- HANDLE_MSG(pfrm, WM_SIZE, Frame_OnSize);
- HANDLE_MSG(pfrm, WM_ACTIVATE, Frame_OnActivate);
- HANDLE_MSG(pfrm, WM_INITMENU, Frame_OnInitMenu);
- HANDLE_MSG(pfrm, WM_INITMENUPOPUP, Frame_OnInitMenuPopup);
- HANDLE_MSG(pfrm, WM_COMMAND, Frame_OnCommand);
-
- HANDLE_MSG(pfrm, WM_SYSCOMMAND, Frame_OnSysCommand);
- HANDLE_MSG(pfrm, WM_NCLBUTTONDBLCLK, Frame_OnNclButtonDown);
- HANDLE_MSG(pfrm, WM_MENUSELECT, Frame_OnMenuSelect);
- HANDLE_MSG(pfrm, WM_ENTERIDLE, Frame_OnEnterIdle);
-
- // Frame window specific messages
-
- HANDLE_MSG(pfrm, FW_MDICHILDDESTROY, Frame_OnMdiChildDestroy);
- HANDLE_MSG(pfrm, FW_GETSTATBARRECT, Frame_OnGetStatBarRect);
- HANDLE_MSG(pfrm, FW_DRAWSTATUSDIVIDE, Frame_OnDrawStatusDivide);
- HANDLE_MSG(pfrm, FW_RESIZEMDICLIENT, Frame_OnResizeMdiClient);
- HANDLE_MSG(pfrm, FW_SETMENUHELP, Frame_OnSetMenuHelp);
- HANDLE_MSG(pfrm, FW_GETMENUHELP, Frame_OnGetMenuHelp);
-
- // Application messages
-
- HANDLE_MSG(pfrm, AW_PAINTMENUHELP, Frame_OnPaintMenuHelp);
-
- default:
- return DefFrameProc(hWnd, pfrm->hWndClient, msg, wParam, lParam);
- }
- }
-
- HWND Frame_CreateWindow(LPCSTR lpszText,
- int x,
- int y,
- int cx,
- int cy,
- HINSTANCE hinst)
- {
- return CreateWindowEx(0L,
- CLASS_FRAME,
- lpszText,
- WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
- x, y, cx, cy,
- NULL,
- NULL,
- hinst,
- NULL);
- }
-
- //-Message handlers------------------------------------------------
-
- BOOL Frame_OnCreate(FRAME * pfrm, CREATESTRUCT FAR * lpCreateStruct)
- {
- CLIENTCREATESTRUCT ccs;
-
- pfrm->hMenu = LoadMenu(lpCreateStruct->hInstance,
- MAKEINTRESOURCE(IDR_FRAMEMENU));
-
- pfrm->fStatusBarOn = TRUE;
-
- // Create the MDICLIENT window as a child of the frame.
-
- ccs.hWindowMenu = GetSubMenu(GetMenu(pfrm->hWnd), 1);
- ccs.idFirstChild = CMD_WINDOWCHILD;
-
- pfrm->hWndClient = CreateWindow("MDIClient", "",
- WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL |
- WS_VISIBLE | WS_CLIPSIBLINGS, 0, 0, 0, 0,
- pfrm->hWnd, NULL, lpCreateStruct->hInstance,
- (LPSTR) (LPCLIENTCREATESTRUCT) & ccs);
-
- // Create the Ribbon dialog box with Frame as owner.
-
- pfrm->fpProcRibbon = (DLGPROC) MakeProcInstance((FARPROC) Ribbon_DlgProc, g_app.hinst);
-
- pfrm->hdlgRibbon = CreateDialog(g_app.hinst,
- MAKEINTRESOURCE(DLG_RIBBON), pfrm->hWnd,
- pfrm->fpProcRibbon);
-
- if (pfrm->hdlgRibbon == NULL) {
- FreeProcInstance((FARPROC) pfrm->fpProcRibbon);
- return (0);
- }
-
- return pfrm->hWndClient != NULL;
- }
-
- void Frame_OnDestroy(FRAME * pfrm)
- {
- PostQuitMessage(0);
- }
-
- void Frame_OnClose(FRAME * pfrm)
- {
- // Before closing the application, ask the MDI children if it
- // is ok?
-
- if ((BOOL) SendMessage(pfrm->hWnd, WM_QUERYENDSESSION, 0, 0)) {
- SendMessage(pfrm->hWnd, WM_ENDSESSION, TRUE, 0);
- DefFrameProc(pfrm->hWnd, pfrm->hWndClient, WM_CLOSE, 0, 0L);
- }
- }
-
- BOOL Frame_OnQueryEndSession(FRAME * pfrm)
- {
- BOOL bResult = TRUE;
- HWND hWndChild;
-
- // Get the handle of the first MDI Child.
-
- hWndChild = GetWindow(pfrm->hWndClient, GW_CHILD);
-
- if (hWndChild != NULL) {
- // 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;
-
- bResult = FORWARD_WM_QUERYENDSESSION(hWndChild, SendMessage);
-
- // If the MDI Child says that it is NOT OK, don't ask the
- // rest of the MDI Children.
-
- if (bResult == 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 (bResult == FALSE) {
- HWND hWndTemp = hWndChild;
-
- hWndChild = GetWindow(pfrm->hWndClient, GW_CHILD);
-
- do {
- // If this child is the one that said NO, stop.
-
- if (hWndTemp == 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);
- }
-
- }
-
- return bResult;
- }
-
- void Frame_OnEndSession(FRAME * pfrm, BOOL fEnding)
- {
- HWND hWndChild;
-
- // Get handle of first MDI Child window.
-
- hWndChild = GetWindow(pfrm->hWndClient, GW_CHILD);
-
- // If no MDI Children exist, we are done.
-
- if (hWndChild != NULL) {
- // 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;
-
- FORWARD_WM_ENDSESSION(hWndChild, fEnding, SendMessage);
- }
- while ((hWndChild = GetWindow(hWndChild, GW_HWNDNEXT)) != NULL);
- }
- }
-
- void Frame_OnPaint(FRAME * pfrm)
- {
- PAINTSTRUCT ps;
-
- // 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(pfrm->hWnd, &ps);
-
- SendMessage(pfrm->hWnd, FW_GETSTATBARRECT, 0, (LPARAM)((LPRECT)&ps.rcPaint));
- SetBkMode(ps.hdc, TRANSPARENT);
-
- // If an MDI Child exists, the status bar must be updated by it.
-
- if (pfrm->hWndActiveMDIChild) {
- SendMessage( pfrm->hWndActiveMDIChild,
- AC_PAINTSTATBAR,
- (WPARAM) ps.hdc,
- (LPARAM)((LPPAINTSTRUCT)&ps));
- }
- else {
- // No MDI Child exists, the Frame can do whatever it wants here.
-
- ps.rcPaint.top += (int) SendMessage(pfrm->hWnd, FW_DRAWSTATUSDIVIDE, 0,
- (LPARAM)((LPPAINTSTRUCT)&ps));
-
- LoadString(g_app.hinst, IDS_FRAMESTATUSBAR, g_app.szBuf, sizeof(g_app.szBuf));
- TextOut(ps.hdc, 0, ps.rcPaint.top, g_app.szBuf, lstrlen(g_app.szBuf));
- }
-
- EndPaint(pfrm->hWnd, &ps);
- }
-
- BOOL Frame_OnEraseBkgnd(FRAME * pfrm, HDC hdc)
- {
- return FORWARD_WM_ERASEBKGND(pfrm->hWnd, hdc, DefWindowProc);
- }
-
- void Frame_OnSize(FRAME * pfrm, UINT state, int cx, int cy)
- //-----------------------------------------------------------------
- // Force MDICHILD window to be resized.
- //-----------------------------------------------------------------
- {
- SendMessage(pfrm->hWnd, FW_RESIZEMDICLIENT, 0, 0);
- }
-
- void Frame_OnActivate(FRAME * pfrm, UINT state, HWND hWndActDeact, BOOL fMinimized)
- {
- switch (state) {
- case WA_INACTIVE:
- break;
-
- case WA_ACTIVE:
- SetFocus(pfrm->hWndClient);
- break;
-
- case WA_CLICKACTIVE:
- break;
- }
- }
-
- void Frame_OnInitMenu(FRAME * pfrm, HMENU hMenu)
- //-----------------------------------------------------------------
- // The user has entered the menu system, set any options.
- //-----------------------------------------------------------------
- {
- CheckMenuItem(hMenu, CMD_OPTIONSSTATUS, MF_BYCOMMAND |
- (pfrm->fStatusBarOn ? MF_CHECKED : MF_UNCHECKED));
-
- CheckMenuItem(hMenu, CMD_OPTIONSRIBBON, MF_BYCOMMAND |
- (IsWindowVisible(pfrm->hdlgRibbon) ? MF_CHECKED : MF_UNCHECKED));
- }
-
- void Frame_OnInitMenuPopup(FRAME * pfrm, HMENU hMenu, int item, BOOL fSystemMenu)
- {
- }
-
- void Frame_OnCommand(FRAME * pfrm, int id, HWND hWndCtl, UINT code)
- {
- BOOL fCallDefProc = FALSE;
- WORD wTemp;
-
- // If a child is being activated via the "Window" menu, let
- // the DefFrameProc handle it.
-
- if (id >= CMD_WINDOWCHILD)
- fCallDefProc = TRUE;
- else
- switch (id) {
- case CMD_FILEOPENSHEET:
- // Get the # of sheets already created and increment by 1.
-
- wTemp = pfrm->wNumSheets + 1;
- pfrm->wNumSheets = wTemp;
-
- // The sheet's caption should display the sheet number.
-
- wsprintf(g_app.szBuf, "Sheet%d", wTemp);
-
- // Create the MDI Child window.
-
- Frame_CreateMDIChild(CLASS_SHEET, g_app.szBuf, 0,
- CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
- pfrm->hWndClient, g_app.hinst, 0);
-
- // Make sure the ribbon is enabled when any children exist.
-
- EnableWindow(pfrm->hdlgRibbon, TRUE);
- break;
-
- case CMD_FILEOPENCHART:
- // Get the # of charts already created and increment by 1.
-
- wTemp = pfrm->wNumCharts + 1;
- pfrm->wNumCharts = wTemp;
-
- // The chart's caption should display the chart number.
-
- wsprintf(g_app.szBuf, "Chart%d", wTemp);
-
- // Create the MDI Child window.
-
- Frame_CreateMDIChild(CLASS_CHART, g_app.szBuf, 0,
- CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
- pfrm->hWndClient, g_app.hinst, 0);
-
- // Make sure the ribbon is enabled when any children exist.
-
- EnableWindow(pfrm->hdlgRibbon, TRUE);
- break;
-
- case CMD_OPTIONSSTATUS:
- // Toggle the status of the status bar, resize the MDICLIENT.
-
- pfrm->fStatusBarOn = !pfrm->fStatusBarOn;
- SendMessage(pfrm->hWnd, FW_RESIZEMDICLIENT, 0, 0);
- break;
-
- case CMD_OPTIONSRIBBON:
- // Toggle the status of the ribbon, resize the MDICLIENT.
-
- ShowWindow(pfrm->hdlgRibbon,
- IsWindowVisible(pfrm->hdlgRibbon) ? SW_HIDE : SW_SHOW);
-
- SendMessage(pfrm->hWnd, FW_RESIZEMDICLIENT, 0, 0);
- break;
-
- case CMD_EXIT:
- SendMessage(pfrm->hWnd, WM_CLOSE, 0, 0L);
- break;
-
- case CMD_HELPINDEX:
- case CMD_HELPKEYBOARD:
- case CMD_HELPCOMMANDS:
- case CMD_HELPPROCEDURES:
- case CMD_HELPUSINGHELP:
- MessageBox(pfrm->hWnd, "Option not implemented.", g_app.szName, MB_OK);
- break;
-
- // case CMD_ABOUT:
- // {
- // FARPROC fpProc;
- // fpProc = MakeProcInstance(AboutProc, g_app.hinst);
- // DialogBox(g_app.hinst, "About", pfrm->hWnd, fpProc);
- // FreeProcInstance(fpProc);
- // break;
- // }
-
- case CMD_WINDOWTILEVERT:
- // Call our own function to perform vertical tiling.
-
- Frame_TileVertically(pfrm->hWndClient);
- break;
-
- case CMD_WINDOWTILEHORIZ:
- // Let the MDICLIENT window do the repositioning.
-
- SendMessage(pfrm->hWndClient, WM_MDITILE, 0, 0);
- break;
-
- case CMD_WINDOWCASCADE:
- // Let the MDICLIENT window do the repositioning.
-
- SendMessage(pfrm->hWndClient, WM_MDICASCADE, 0, 0);
- break;
-
- case CMD_WINDOWARRANGEICONS:
- // Let the MDICLIENT window do the repositioning.
-
- SendMessage(pfrm->hWndClient, WM_MDIICONARRANGE, 0, 0);
- break;
-
- default:
- // Menu options not processed by the Frame window must
- // be passed to the MDI Children for processing.
-
- FORWARD_WM_COMMAND(pfrm->hWndActiveMDIChild,
- id, hWndCtl, code,
- SendMessage);
- break;
- }
-
- if (fCallDefProc)
- DefFrameProc(pfrm->hWnd,
- pfrm->hWndClient, WM_COMMAND,
- (WPARAM) id, MAKELPARAM(hWndCtl, code));
- }
-
- void Frame_OnSysCommand(FRAME * pfrm, WORD cmd, int x, int y)
- //-----------------------------------------------------------------
- // Set focus to frame window. This causes any comboboxes
- // in the ribbon to be closed.
- //-----------------------------------------------------------------
- {
- SetFocus(pfrm->hWnd);
- DefFrameProc(pfrm->hWnd,
- pfrm->hWndClient, WM_SYSCOMMAND,
- (WPARAM) cmd,
- MAKELPARAM(x, y));
- }
-
- void Frame_OnNclButtonDown(FRAME * pfrm, BOOL fDoubleClick, int x, int y, UINT codeHitTest)
- //-----------------------------------------------------------------
- // Code to allow double-clicking the MDI Child's system menu
- // to close the MDI Child window.
- //-----------------------------------------------------------------
- {
- RECT rc;
- BITMAP Bitmap;
- HBITMAP hBitmap;
- DWORD dwResult;
- LPARAM lParam;
- BOOL fCallDefProc = TRUE;
-
-
- if (fDoubleClick && (codeHitTest == HTMENU)) {
- // If the active child is not maximized, nothing to do.
-
- dwResult = SendMessage(pfrm->hWndClient, WM_MDIGETACTIVE, 0, 0);
-
- if (HIWORD(dwResult) == 1) {
- // 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(pfrm->hWnd, &rc);
-
- // Get handle to the CLOSE BOX bitmaps.
-
- hBitmap = LoadBitmap(NULL, MAKEINTRESOURCE(OBM_CLOSE));
-
- // Get dimensions of the bitmaps.
-
- GetObject(hBitmap, sizeof(BITMAP), (LPSTR) (LPBITMAP) & Bitmap);
- DeleteBitmap(hBitmap);
-
- // 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.
-
- lParam = MAKELPARAM(x, y);
- if (PtInRect(&rc, MAKEPOINT(lParam))) {
- SendMessage((HWND) LOWORD(dwResult),
- WM_SYSCOMMAND, SC_CLOSE, lParam);
- fCallDefProc = FALSE;
- }
- }
- }
-
- if (fCallDefProc)
- DefFrameProc(pfrm->hWnd,
- pfrm->hWndClient,
- (fDoubleClick) ? WM_NCLBUTTONDBLCLK : WM_NCLBUTTONDOWN,
- (WPARAM) (UINT) codeHitTest,
- MAKELPARAM(x, y));
- }
-
- void Frame_OnMenuSelect(FRAME * pfrm, HMENU hMenu, int item, HMENU hMenuPopup, UINT flags)
- //-----------------------------------------------------------------
- // The user has highlighted a menu item.
- //-----------------------------------------------------------------
- {
- WORD wTemp;
-
- if (flags == -1 && (hMenu == (HMENU) 0)) {
- // User has stopped using the menu system.
-
- SendMessage(pfrm->hWnd, FW_SETMENUHELP, 0, 0);
- return;
- }
-
- // If wTemp == 0, at end of switch, MDI Child handled the message.
-
- wTemp = 0;
-
- switch (flags & (MF_POPUP | MF_SYSMENU)) {
- case 0:
- // item is a menu item ID NOT on the app's system menu.
-
- if (pfrm->hWndActiveMDIChild != NULL) {
- // An MDI Child exists.
-
- if (pfrm->fMDIChildIsMaximized) {
- // If menu item from the MDI Child's system menu, set
- // the MF_SYSMENU bit in the lParam parameter.
-
- HMENU hTemp = GetSubMenu(GetMenu(pfrm->hWnd), 0);
-
- if ((int) GetMenuState(hTemp, item, MF_BYCOMMAND) != -1)
- flags |= MF_SYSMENU;
- }
-
- // Make active MDI Child think that it received the
- // WM_MENUSELECT message.
-
- FORWARD_WM_MENUSELECT(
- pfrm->hWndActiveMDIChild,
- hMenu, item, hMenuPopup,
- flags,
- SendMessage);
-
- wTemp = 0; // MDI Child handled the message.
- break;
- }
-
- wTemp = IDS_FRAMEMENUID + item;
- break;
-
- case MF_POPUP:
-
- if (pfrm->hWndActiveMDIChild != NULL) {
- // An MDI Child exists.
-
- if (pfrm->fMDIChildIsMaximized) {
- // If popup menu is first top-level menu, it is the
- // MDI Child's system menu, set the MF_SYSMENU flag.
-
- if (hMenuPopup == GetSubMenu(GetMenu(pfrm->hWnd), 0))
- flags |= MF_SYSMENU;
- }
-
- // Make active MDI Child think that it received the
- // WM_MENUSELECT message.
-
- FORWARD_WM_MENUSELECT(
- pfrm->hWndActiveMDIChild,
- hMenu, item, hMenuPopup,
- flags,
- SendMessage);
-
- wTemp = 0; // MDI Child handled the message.
- break;
- }
-
- // Calculate the index of the top-level menu.
-
- hMenu = GetMenu(pfrm->hWnd);
- wTemp = GetMenuItemCount(hMenu);
-
- while (wTemp--)
- if (GetSubMenu(hMenu, wTemp) == hMenuPopup)
- break;
-
- wTemp += IDS_FRAMEPOPUPID + 1; // Jump over system menu.
- break;
-
- case MF_SYSMENU:
- // item is menu item ID from system menu.
- wTemp = IDS_FRAMEMENUID + ((item & 0x0FFF) >> 4);
- break;
-
- case MF_POPUP | MF_SYSMENU:
- // item is handle to app's sys menu.
- wTemp = IDS_FRAMEPOPUPID;
- break;
- }
-
- // If message handled by MDI Child, nothing more to do.
-
- if (wTemp != 0) {
- // Tell the Frame that the Frame window should display the
- // help text and the identifier for the help text.
-
- SendMessage(pfrm->hWnd, FW_SETMENUHELP,
- (WPARAM) pfrm->hWnd, (LPARAM) wTemp);
- }
- }
-
- void Frame_OnEnterIdle(FRAME * pfrm, WORD source, HWND hWndSource)
- {
- RECT rc;
- PAINTSTRUCT ps;
-
- if (source == MSGF_MENU) {
- // 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 (pfrm->hWndMenuHelp != (HWND) - 1) {
- // Display new menu help, invalidate the status bar.
-
- SendMessage(pfrm->hWnd, FW_GETSTATBARRECT, 0, (LPARAM)((LPRECT)&rc));
- InvalidateRect(pfrm->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(pfrm->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(pfrm->hWndMenuHelp, AW_PAINTMENUHELP, 0,
- (LPARAM)((LPPAINTSTRUCT)&ps));
-
- EndPaint(pfrm->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.
-
- pfrm->hWndMenuHelp = (HWND) - 1;
- }
- }
- }
-
-
- void Frame_OnMdiChildDestroy(FRAME * pfrm)
- //-----------------------------------------------------------------
- // Message is posted by an MDI Child just before it is destroyed.
- //-----------------------------------------------------------------
- {
- // If another MDI Child exists, nothing to do.
-
- if (pfrm->hWndActiveMDIChild != NULL)
- return;
-
- // Set the menu bar and accelerator table to the Frame's defaults.
-
- Frame_ChangeMDIMenu( pfrm->hWnd,
- pfrm->hWndClient,
- pfrm->hMenu,
- CMD_WINDOWTILEVERT);
-
- g_app.hAccelTable = NULL;
-
- // Force the status bar to be updated.
-
- InvalidateRect(pfrm->hWnd, NULL, TRUE);
-
- // Disable the Ribbon.
-
- EnableWindow(pfrm->hdlgRibbon, FALSE);
- }
-
- void Frame_OnGetStatBarRect(FRAME * pfrm, LPRECT lpRect)
- {
- // Get the client area of the Frame window.
-
- GetClientRect(pfrm->hWnd, lpRect);
-
- // If the status bar is OFF, set the status bar to have no height.
-
- if (pfrm->fStatusBarOn) {
- // Change the dimensions so that the status bar is the height of
- // one line of text plus a small border.
-
- HDC hdc;
- TEXTMETRIC tm;
-
- hdc = GetDC(pfrm->hWnd);
- GetTextMetrics(hdc, &tm);
- ReleaseDC(pfrm->hWnd, hdc);
-
- lpRect->top = lpRect->bottom - tm.tmHeight -
- GetSystemMetrics(SM_CYBORDER);
- }
- else
- lpRect->top = lpRect->bottom;
- }
-
- void Frame_OnDrawStatusDivide(FRAME * pfrm, LPPAINTSTRUCT ps)
- {
- HPEN hPen;
- DWORD dwResult = GetSystemMetrics(SM_CYBORDER);
-
- // Draw a line separating the status bar from the MDICLIENT window.
-
- hPen = CreatePen(PS_SOLID, (int) dwResult, RGB(0, 0, 0));
- hPen = SelectPen(ps->hdc, hPen);
-
- MoveTo(ps->hdc, 0, ps->rcPaint.top);
- LineTo(ps->hdc, ps->rcPaint.right, ps->rcPaint.top);
- DeletePen(SelectPen(ps->hdc, hPen));
- }
-
- void Frame_OnResizeMdiClient(FRAME * pfrm)
- {
- RECT rc, rcTemp;
-
- // Sent when the Frame window is resized or when the status bar
- // and ribbon are toggled.
-
- GetClientRect(pfrm->hWnd, &rc);
-
- if (IsWindow(pfrm->hdlgRibbon) && IsWindowVisible(pfrm->hdlgRibbon)) {
- // Ribbon is displayed, adjust rectangle.
-
- GetClientRect(pfrm->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(pfrm->hWnd, FW_GETSTATBARRECT, 0, (LPARAM)((LPRECT)&rcTemp));
- rc.bottom -= rcTemp.bottom - rcTemp.top;
- MoveWindow(pfrm->hWndClient, 0, rc.top, rc.right, rc.bottom, TRUE);
- }
-
- void Frame_OnSetMenuHelp(FRAME * pfrm, HWND hWndMenuHelp, DWORD dwMenuHelp)
- //-----------------------------------------------------------------
- // Called by the Frame and MDI Children whenever a
- // WM_MENUSELECT message is received.
- //-----------------------------------------------------------------
- {
- // Save the handle of the window sending the message.
-
- pfrm->hWndMenuHelp = hWndMenuHelp;
-
- // Save the menu help code that the window sent too.
-
- pfrm->dwMenuHelp = dwMenuHelp;
-
- // When the Frame or MDI Child receive a WM_MENUSELECT message
- // specifying that the menu system is closed
- // (dwMenuHelp == MAKELONG(-1, 0)), the menu help should disappear and
- // be replaced by the proper information on the status bar.
-
- if (hWndMenuHelp == NULL) {
- RECT rc;
-
- SendMessage(pfrm->hWnd, FW_GETSTATBARRECT, 0, (LPARAM)((LPRECT)&rc));
-
- // Force status bar to be updated.
-
- InvalidateRect(pfrm->hWnd, &rc, TRUE);
- }
- }
-
- DWORD Frame_OnGetMenuHelp(FRAME * pfrm)
- //-----------------------------------------------------------------
- // Sent by the Frame or MDI Child when they
- // receive a AW_PAINTMENUHELP message.
- //-----------------------------------------------------------------
- {
- return pfrm->dwMenuHelp;
- }
-
- void Frame_OnPaintMenuHelp(FRAME * pfrm, LPPAINTSTRUCT psStatus)
- //-----------------------------------------------------------------
- // Message sent from Frame window to notify Frame that it should
- // paint the status bar text for the last highlighted menu item.
- //-----------------------------------------------------------------
- {
- LRESULT lResult;
-
- // 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.
-
- lResult = SendMessage(pfrm->hWnd, FW_GETMENUHELP, 0, 0);
-
- // Draw the horizontal dividing line separating the Status bar
- // from the MDICLIENT window.
-
- psStatus->rcPaint.top += (int)
- SendMessage(pfrm->hWnd, FW_DRAWSTATUSDIVIDE, 0, (LPARAM) psStatus);
-
- // Construct the string that is to be displayed.
-
- LoadString(g_app.hinst, LOWORD(lResult), g_app.szBuf, sizeof(g_app.szBuf));
-
- // Paint the menu help text in the status bar.
-
- TextOut(psStatus->hdc, 0, psStatus->rcPaint.top, g_app.szBuf, lstrlen(g_app.szBuf));
- }
-
- //-Utility routines------------------------------------------------
-
- HWND WINAPI Frame_CreateMDIChild(LPSTR szClassName,
- LPSTR szWindowName,
- DWORD dwStyle,
- short x,
- short y,
- short nWidth,
- short nHeight,
- HWND hWndMDIClient,
- HANDLE hInstance,
- LONG lParam)
- {
- MDICREATESTRUCT cs;
- HWND hWndChild;
-
- cs.szClass = szClassName;
- cs.szTitle = szWindowName;
- cs.hOwner = hInstance;
- cs.x = x;
- cs.y = y;
- cs.cx = nWidth;
- cs.cy = nHeight;
- cs.style = dwStyle;
- cs.lParam = lParam;
-
- hWndChild = (HWND) SendMessage(hWndMDIClient, WM_MDICREATE,
- 0, (LPARAM)((LPMDICREATESTRUCT)&cs));
- return (hWndChild);
- }
-
- // Function to change the menu in the Frame window whenever a
- // new MDI Child becomes active.
-
- void WINAPI Frame_ChangeMDIMenu(HWND hWndFrame,
- HWND hWndClient,
- HMENU hMenuNew,
- WORD wMenuID)
- {
- WORD wCount;
- HMENU hSubMenu = 0;
-
- // Get number of top-level menu items in the menu used by the window
- // being activated.
-
- wCount = GetMenuItemCount(hMenuNew);
-
- // Locate the POPUP menu that contains the menu option with the
- // 'wMenuID' identifier in it. This must be an identifier for an option
- // in the new menu's "Window" popup menu.
-
- while (wCount) {
- hSubMenu = GetSubMenu(hMenuNew, wCount - 1);
- if ((int) GetMenuState(hSubMenu, wMenuID, MF_BYCOMMAND) != -1)
- break;
- wCount--;
- }
-
- // Tell the MDICLIENT window to setup the new menu.
-
- SendMessage(hWndClient, WM_MDISETMENU, 0, MAKELONG(hMenuNew, hSubMenu));
- DrawMenuBar(hWndFrame);
- }
-
- void WINAPI Frame_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((HWND) 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);
- }
-