home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / C++-7 / DISK10 / MFC / SRC / WINMDI.CP$ / winmdi
Encoding:
Text File  |  1992-03-10  |  6.6 KB  |  283 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library. 
  2. // Copyright (C) 1992 Microsoft Corporation 
  3. // All rights reserved. 
  4. //  
  5. // This source code is only intended as a supplement to the 
  6. // Microsoft Foundation Classes Reference and Microsoft 
  7. // QuickHelp documentation provided with the library. 
  8. // See these sources for detailed information regarding the 
  9. // Microsoft Foundation Classes product. 
  10.  
  11.  
  12. #include "afxwin.h"
  13. #pragma hdrstop
  14.  
  15. #include "winhand_.h"
  16. #include "window_.h"
  17.  
  18. #ifdef AFX_CORE_SEG
  19. #pragma code_seg(AFX_CORE_SEG)
  20. #endif
  21.  
  22. #ifdef _DEBUG
  23. #undef THIS_FILE
  24. static char BASED_CODE THIS_FILE[] = __FILE__;
  25. #define new DEBUG_NEW
  26. #endif
  27.  
  28.  
  29. /////////////////////////////////////////////////////////////////////////////
  30. // CMDIFrameWnd
  31.  
  32. IMPLEMENT_DYNAMIC(CMDIFrameWnd, CFrameWnd)
  33.  
  34. CMDIFrameWnd::CMDIFrameWnd()
  35. {
  36.     m_hWndMDIClient = NULL;
  37. }
  38.  
  39. #ifdef _DEBUG
  40. void CMDIFrameWnd::AssertValid() const
  41. {
  42.     CFrameWnd::AssertValid();
  43.     ASSERT(m_hWndMDIClient == NULL || ::IsWindow(m_hWndMDIClient));
  44. }
  45. #endif
  46.  
  47. BEGIN_MESSAGE_MAP(CMDIFrameWnd, CFrameWnd)
  48.     ON_WM_CREATE()
  49. END_MESSAGE_MAP()
  50.  
  51. int 
  52. CMDIFrameWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
  53. {
  54.     CMenu* pMenu = GetMenu();
  55.     // This is attempting to guess which sub-menu is the Window menu.
  56.     // The Windows user interface guidelines say that the right-most
  57.     // menu on the menu bar should be Help and Window should be one
  58.     // to the left of that.
  59.     int iMenu = pMenu->GetMenuItemCount() - 2;
  60.     
  61.     // If this assertion fails, your menu bar does not follow the guidelines
  62.     // so you will have to override this function and call CreateClient
  63.     // appropriately.
  64.     ASSERT(iMenu >= 0);
  65.     
  66.     return CreateClient(lpCreateStruct, pMenu->GetSubMenu(iMenu)) ? 0 : -1;
  67. }
  68.  
  69.  
  70. BOOL 
  71. CMDIFrameWnd::OnCommand(UINT wParam, LONG lParam)
  72. {
  73.     CWnd* pActiveChild = GetChildFrame();
  74.     
  75.     if (pActiveChild != this && _AfxCallWndProc(pActiveChild,
  76.       pActiveChild->m_hWnd, WM_COMMAND, wParam, lParam) != 0)
  77.     {
  78.         // handled by child
  79.         return TRUE;
  80.     }
  81.  
  82.     if (CFrameWnd::OnCommand(wParam, lParam))
  83.     {
  84.         // handled by us
  85.         return TRUE;
  86.     }
  87.  
  88.     if (LOWORD(lParam) == 0 && (wParam & 0xf000) == 0xf000)
  89.     {
  90.         // menu or accelerator within range of MDI children
  91.         // default frame proc will handle it
  92.         DefWindowProc(WM_COMMAND, wParam, lParam);
  93.         return TRUE;
  94.     }
  95.  
  96.     return FALSE;   // not handled
  97. }
  98.  
  99.  
  100. BOOL
  101. CMDIFrameWnd::CreateClient(LPCREATESTRUCT /* lpCreateStruct */, 
  102.     CMenu* pWindowMenu)
  103. {
  104.     ASSERT(m_hWnd != NULL);
  105.     
  106.     CLIENTCREATESTRUCT ccs;
  107.     
  108.     ccs.hWindowMenu = pWindowMenu->m_hMenu;
  109.     ccs.idFirstChild = AFX_IDM_FIRST_MDICHILD;
  110.     
  111.     if ((m_hWndMDIClient = ::CreateWindowEx(0, "mdiclient", NULL, 
  112.         WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN, 0, 0, 0, 0, m_hWnd, NULL, 
  113.         AfxGetInstanceHandle(), (LPSTR)(LPCLIENTCREATESTRUCT)&ccs)) == NULL)
  114.     {
  115.         TRACE("Warning: CMDIFrameWnd::CreateClient: failed to create MDICLIENT\n");
  116.         return FALSE;
  117.     }
  118.  
  119.     return TRUE;
  120. }
  121.  
  122.  
  123. CFrameWnd* 
  124. CMDIFrameWnd::GetChildFrame()
  125. {
  126.     CFrameWnd* pActiveWnd = MDIGetActive();
  127.     
  128.     if (pActiveWnd != NULL)
  129.         return pActiveWnd;
  130.     
  131.     return this;
  132. }
  133.  
  134.  
  135. LONG 
  136. CMDIFrameWnd::DefWindowProc(UINT nMsg, UINT wParam, LONG lParam)
  137. {
  138.     return ::DefFrameProc(m_hWnd, m_hWndMDIClient, nMsg, wParam, lParam);
  139. }
  140.  
  141.  
  142. BOOL 
  143. CMDIFrameWnd::PreTranslateMessage(MSG* pMsg)
  144. {
  145.     CMDIChildWnd * pChildWnd = MDIGetActive();
  146.     
  147.     // current active child gets first crack at it
  148.     if (pChildWnd != NULL && pChildWnd->PreTranslateMessage(pMsg))
  149.         return TRUE;
  150.     
  151.     // translate accelerators for frame and any children
  152.     if (m_hAccelTable != NULL &&
  153.         ::TranslateAccelerator(m_hWnd, m_hAccelTable, pMsg))
  154.     {
  155.         return TRUE;
  156.     }
  157.     
  158.     // special processing for MDI accelerators last
  159.     if (pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN)
  160.     {
  161.         // the MDICLIENT window may translate it
  162.         if (::TranslateMDISysAccel(m_hWndMDIClient, pMsg))
  163.             return TRUE;
  164.     }
  165.  
  166.     return FALSE;
  167. }
  168.  
  169. BOOL 
  170. CMDIFrameWnd::Create(LPCSTR lpClassName,
  171.     LPCSTR lpWindowName, DWORD dwStyle, const RECT& rect, 
  172.     const CWnd* pParentWnd, LPCSTR lpMenuName)
  173. {
  174.     ASSERT(lpMenuName != NULL);
  175.  
  176.     if (lpClassName == NULL)
  177.         lpClassName = _afxMDIFrameWnd;
  178.  
  179.     return CFrameWnd::Create(lpClassName,
  180.         lpWindowName, dwStyle, rect, pParentWnd, lpMenuName);
  181. }
  182.  
  183. /////////////////////////////////////////////////////////////////////////////
  184. // CMDIChildWnd
  185.  
  186. IMPLEMENT_DYNAMIC(CMDIChildWnd, CFrameWnd)
  187.  
  188. #ifdef _DEBUG
  189. void 
  190. CMDIChildWnd::AssertValid() const
  191. {
  192.     CFrameWnd::AssertValid();
  193. }
  194.  
  195. void 
  196. CMDIChildWnd::Dump(CDumpContext& dc) const
  197. {
  198.     CFrameWnd::Dump(dc);
  199.     dc << "\nm_pMDIFrameWnd = " << (void *)m_pMDIFrameWnd;
  200. }
  201. #endif
  202.  
  203. LONG
  204. CMDIChildWnd::DefWindowProc(UINT nMsg, UINT wParam, LONG lParam)
  205. {
  206.     return ::DefMDIChildProc(m_hWnd, nMsg, wParam, lParam);
  207. }
  208.  
  209.  
  210. BOOL
  211. CMDIChildWnd::DestroyWindow()
  212. {
  213.     if (m_hWnd == NULL)
  214.         return FALSE;
  215.     MDIDestroy();
  216.     return TRUE;
  217. }
  218.  
  219. BOOL 
  220. CMDIChildWnd::PreTranslateMessage(MSG* pMsg)
  221. {
  222.     // we can't call 'CFrameWnd::PreTranslate' since it will translate
  223.     //  accelerators in the context of the MDI Child - but since MDI Child
  224.     //  windows don't have menus this doesn't work properly.  MDI Child
  225.     //  accelerators must be translated in context of their MDI Frame.
  226.  
  227.     return (m_hAccelTable != NULL &&
  228.       ::TranslateAccelerator(m_pMDIFrameWnd->m_hWnd, m_hAccelTable, pMsg));
  229. }
  230.  
  231.  
  232. BOOL 
  233. CMDIChildWnd::Create(LPCSTR lpClassName,
  234.     LPCSTR lpWindowName, DWORD dwStyle,
  235.     const RECT& rect,
  236.     CMDIFrameWnd* pParentWnd)
  237. {
  238.     MDICREATESTRUCT mcs;
  239.     
  240.     if (lpClassName == NULL)
  241.         lpClassName = _afxFrameWnd;
  242.     mcs.szClass = lpClassName;
  243.     mcs.szTitle = lpWindowName;
  244.     mcs.hOwner = AfxGetInstanceHandle();
  245.     mcs.x = rect.left;
  246.     mcs.y = rect.top;
  247.     mcs.cx = rect.right - rect.left;
  248.     mcs.cy = rect.bottom - rect.top;
  249.     mcs.style = dwStyle;
  250.     mcs.lParam = 0;
  251.     
  252.     if (pParentWnd == NULL)
  253.     {
  254.         CWnd* pMainWnd = AfxGetApp()->m_pMainWnd;
  255.         ASSERT(pMainWnd != NULL);
  256.         ASSERT(pMainWnd->IsKindOf(RUNTIME_CLASS(CMDIFrameWnd)));
  257.         pParentWnd = (CMDIFrameWnd*)pMainWnd;
  258.     }
  259.     
  260.     m_pMDIFrameWnd = pParentWnd;
  261.     
  262.     // Restore the currently active MDI child if it is maximized since
  263.     // Windows will do this anyway when this one is created and if we
  264.     // wait until then several more messages go through our hook...
  265.     BOOL bMaximized;
  266.     CMDIChildWnd* pActiveMDIChild = pParentWnd->MDIGetActive(&bMaximized);
  267.     if (bMaximized)
  268.         pParentWnd->MDIRestore(pActiveMDIChild);
  269.  
  270.     _AfxHookWindowCreate(this);
  271.     BOOL bReturn = (BOOL)::SendMessage(pParentWnd->m_hWndMDIClient, 
  272.         WM_MDICREATE, 0, (LONG)(LPSTR)&mcs);
  273.     _AfxUnhookWindowCreate();
  274.     return bReturn;
  275. }
  276.  
  277. CFrameWnd* 
  278. CMDIChildWnd::GetParentFrame()
  279. {
  280.     return m_pMDIFrameWnd;
  281. }
  282.  
  283.