|
|
1.1 root 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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.