1 // Win32++ Version 7.3
\r
2 // Released: 30th November 2011
\r
6 // url: https://sourceforge.net/projects/win32-framework
\r
9 // Copyright (c) 2005-2011 David Nash
\r
11 // Permission is hereby granted, free of charge, to
\r
12 // any person obtaining a copy of this software and
\r
13 // associated documentation files (the "Software"),
\r
14 // to deal in the Software without restriction, including
\r
15 // without limitation the rights to use, copy, modify,
\r
16 // merge, publish, distribute, sublicense, and/or sell
\r
17 // copies of the Software, and to permit persons to whom
\r
18 // the Software is furnished to do so, subject to the
\r
19 // following conditions:
\r
21 // The above copyright notice and this permission notice
\r
22 // shall be included in all copies or substantial portions
\r
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
\r
26 // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
\r
27 // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
\r
28 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
\r
29 // SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
\r
30 // ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
\r
31 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
\r
32 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
\r
33 // OR OTHER DEALINGS IN THE SOFTWARE.
\r
35 ////////////////////////////////////////////////////////
\r
38 ////////////////////////////////////////////////////////
\r
40 // Declaration of the CMDIChild and CMDIFrame classes
\r
42 // The classes defined here add MDI frames support to Win32++. MDI
\r
43 // (Multiple Document Interface) frames host one or more child windows. The
\r
44 // child windows hosted by a MDI frame can be different types. For example,
\r
45 // some MDI child windows could be used to edit text, while others could be
\r
46 // used to display a bitmap. Four classes are defined here to support MDI
\r
50 // 1) CMDIFrame. This class inherits from CFrame, and adds the functionality
\r
51 // required by MDI frames. It keeps track of the MDI children created and
\r
52 // destroyed, and adjusts the menu when a MDI child is activated. Use the
\r
53 // AddMDIChild function to add MDI child windows to the MDI frame. Inherit
\r
54 // from CMDIFrame to create your own MDI frame.
\r
56 // 2) CMDIChild: All MDI child windows (ie. CWnd classes) should inherit from
\r
57 // this class. Each MDI child type can have a different frame menu.
\r
59 // Use the MDIFrame generic application as the starting point for your own MDI
\r
60 // frame applications.
\r
61 // Refer to the MDIDemo sample for an example on how to use these classes to
\r
62 // create a MDI frame application with different types of MDI child windows.
\r
65 #ifndef _WIN32XX_MDI_H_
\r
66 #define _WIN32XX_MDI_H_
\r
77 typedef Shared_Ptr<CMDIChild> MDIChildPtr;
\r
79 /////////////////////////////////////
\r
80 // Declaration of the CMDIChild class
\r
82 class CMDIChild : public CWnd
\r
84 friend class CMDIFrame;
\r
87 virtual ~CMDIChild();
\r
89 // These are the functions you might wish to override
\r
90 virtual HWND Create(CWnd* pParent = NULL);
\r
91 virtual void RecalcLayout();
\r
93 // These functions aren't virtual, and shouldn't be overridden
\r
94 void SetHandles(HMENU MenuName, HACCEL AccelName);
\r
95 CMDIFrame* GetMDIFrame() const;
\r
96 CWnd* GetView() const {return m_pView;}
\r
97 void SetView(CWnd& pwndView);
\r
98 void MDIActivate() const;
\r
99 void MDIDestroy() const;
\r
100 void MDIMaximize() const;
\r
101 void MDIRestore() const;
\r
104 // Its unlikely you would need to override these functions
\r
105 virtual LRESULT FinalWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
\r
106 virtual void OnCreate();
\r
107 virtual LRESULT WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam);
\r
110 CMDIChild(const CMDIChild&); // Disable copy construction
\r
111 CMDIChild& operator = (const CMDIChild&); // Disable assignment operator
\r
113 CWnd* m_pView; // pointer to the View CWnd object
\r
114 HMENU m_hChildMenu;
\r
115 HACCEL m_hChildAccel;
\r
119 /////////////////////////////////////
\r
120 // Declaration of the CMDIFrame class
\r
122 class CMDIFrame : public CFrame
\r
124 friend class CMDIChild; // CMDIChild uses m_hOrigMenu
\r
125 typedef Shared_Ptr<CMDIChild> MDIChildPtr;
\r
128 class CMDIClient : public CWnd // a nested class within CMDIFrame
\r
132 virtual ~CMDIClient() {}
\r
133 virtual HWND Create(CWnd* pParent = NULL);
\r
134 virtual LRESULT WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
\r
135 CMDIFrame* GetMDIFrame() const { return (CMDIFrame*)GetParent(); }
\r
138 CMDIClient(const CMDIClient&); // Disable copy construction
\r
139 CMDIClient& operator = (const CMDIClient&); // Disable assignment operator
\r
144 virtual ~CMDIFrame() {}
\r
146 virtual CMDIChild* AddMDIChild(MDIChildPtr pMDIChild);
\r
147 virtual CMDIClient& GetMDIClient() const { return (CMDIClient&)m_MDIClient; }
\r
148 virtual BOOL IsMDIFrame() const { return TRUE; }
\r
149 virtual void RemoveMDIChild(HWND hWnd);
\r
150 virtual BOOL RemoveAllMDIChildren();
\r
151 virtual void UpdateCheckMarks();
\r
153 // These functions aren't virtual, so don't override them
\r
154 std::vector <MDIChildPtr>& GetAllMDIChildren() {return m_vMDIChild;}
\r
155 CMDIChild* GetActiveMDIChild() const;
\r
156 BOOL IsMDIChildMaxed() const;
\r
157 void MDICascade(int nType = 0) const;
\r
158 void MDIIconArrange() const;
\r
159 void MDIMaximize() const;
\r
160 void MDINext() const;
\r
161 void MDIPrev() const;
\r
162 void MDIRestore() const;
\r
163 void MDITile(int nType = 0) const;
\r
164 void SetActiveMDIChild(CMDIChild* pChild);
\r
167 // These are the functions you might wish to override
\r
168 virtual void OnClose();
\r
169 virtual void OnViewStatusBar();
\r
170 virtual void OnViewToolBar();
\r
171 virtual void OnWindowPosChanged();
\r
172 virtual void RecalcLayout();
\r
173 virtual BOOL PreTranslateMessage(MSG* pMsg);
\r
174 virtual LRESULT WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam);
\r
177 CMDIFrame(const CMDIFrame&); // Disable copy construction
\r
178 CMDIFrame& operator = (const CMDIFrame&); // Disable assignment operator
\r
179 void AppendMDIMenu(HMENU hMenuWindow);
\r
180 LRESULT FinalWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
\r
181 void UpdateFrameMenu(HMENU hMenu);
\r
183 CMDIClient m_MDIClient;
\r
184 std::vector <MDIChildPtr> m_vMDIChild;
\r
185 HWND m_hActiveMDIChild;
\r
191 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
197 /////////////////////////////////////
\r
198 // Definitions for the CMDIFrame class
\r
200 inline CMDIFrame::CMDIFrame() : m_hActiveMDIChild(NULL)
\r
202 SetView(GetMDIClient());
\r
205 inline CMDIChild* CMDIFrame::AddMDIChild(MDIChildPtr pMDIChild)
\r
207 assert(NULL != pMDIChild.get()); // Cannot add Null MDI Child
\r
209 m_vMDIChild.push_back(pMDIChild);
\r
210 pMDIChild->Create(GetView());
\r
212 return pMDIChild.get();
\r
215 inline void CMDIFrame::AppendMDIMenu(HMENU hMenuWindow)
\r
217 // Adds the additional menu items the the "Window" submenu when
\r
218 // MDI child windows are created
\r
220 if (!IsMenu(hMenuWindow))
\r
223 // Delete previously appended items
\r
224 int nItems = ::GetMenuItemCount(hMenuWindow);
\r
225 UINT uLastID = ::GetMenuItemID(hMenuWindow, --nItems);
\r
226 if ((uLastID >= IDW_FIRSTCHILD) && (uLastID < IDW_FIRSTCHILD + 10))
\r
228 while ((uLastID >= IDW_FIRSTCHILD) && (uLastID < IDW_FIRSTCHILD + 10))
\r
230 ::DeleteMenu(hMenuWindow, nItems, MF_BYPOSITION);
\r
231 uLastID = ::GetMenuItemID(hMenuWindow, --nItems);
\r
233 //delete the separator too
\r
234 ::DeleteMenu(hMenuWindow, nItems, MF_BYPOSITION);
\r
239 // Allocate an iterator for our MDIChild vector
\r
240 std::vector <MDIChildPtr>::iterator v;
\r
242 for (v = GetAllMDIChildren().begin(); v < GetAllMDIChildren().end(); ++v)
\r
244 if ((*v)->GetWindowLongPtr(GWL_STYLE) & WS_VISIBLE) // IsWindowVisible is unreliable here
\r
248 ::AppendMenu(hMenuWindow, MF_SEPARATOR, 0, NULL);
\r
250 // Add a menu entry for each MDI child (up to 9)
\r
253 CString strMenuItem ( (*v)->GetWindowText() );
\r
255 if (strMenuItem.GetLength() > MAX_MENU_STRING -10)
\r
257 // Truncate the string if its too long
\r
258 strMenuItem.Delete(strMenuItem.GetLength() - MAX_MENU_STRING +10);
\r
259 strMenuItem += _T(" ...");
\r
262 TCHAR szMenuString[MAX_MENU_STRING+1];
\r
263 wsprintf(szMenuString, _T("&%d %s"), nWindow+1, strMenuItem.c_str());
\r
265 ::AppendMenu(hMenuWindow, MF_STRING, IDW_FIRSTCHILD + nWindow, szMenuString);
\r
267 if (GetActiveMDIChild() == (*v).get())
\r
268 ::CheckMenuItem(hMenuWindow, IDW_FIRSTCHILD+nWindow, MF_CHECKED);
\r
272 else if (9 == nWindow)
\r
273 // For the 10th MDI child, add this menu item and return
\r
275 ::AppendMenu(hMenuWindow, MF_STRING, IDW_FIRSTCHILD + nWindow, _T("&Windows..."));
\r
282 inline LRESULT CMDIFrame::FinalWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
\r
284 return ::DefFrameProc(m_hWnd, GetMDIClient(), uMsg, wParam, lParam);
\r
287 inline CMDIChild* CMDIFrame::GetActiveMDIChild() const
\r
289 return (CMDIChild*)FromHandle(m_hActiveMDIChild);
\r
292 inline BOOL CMDIFrame::IsMDIChildMaxed() const
\r
294 BOOL bMaxed = FALSE;
\r
295 GetMDIClient().SendMessage(WM_MDIGETACTIVE, 0L, (LPARAM)&bMaxed);
\r
299 inline void CMDIFrame::MDICascade(int nType /* = 0*/) const
\r
301 // Possible values for nType are:
\r
302 // MDITILE_SKIPDISABLED Prevents disabled MDI child windows from being cascaded.
\r
304 assert(::IsWindow(m_hWnd));
\r
305 GetView()->SendMessage(WM_MDICASCADE, (WPARAM)nType, 0L);
\r
308 inline void CMDIFrame::MDIIconArrange() const
\r
310 assert(::IsWindow(m_hWnd));
\r
311 GetView()->SendMessage(WM_MDIICONARRANGE, 0L, 0L);
\r
314 inline void CMDIFrame::MDIMaximize() const
\r
316 assert(::IsWindow(m_hWnd));
\r
317 GetView()->SendMessage(WM_MDIMAXIMIZE, 0L, 0L);
\r
320 inline void CMDIFrame::MDINext() const
\r
322 assert(::IsWindow(m_hWnd));
\r
323 HWND hMDIChild = GetActiveMDIChild()->GetHwnd();
\r
324 GetView()->SendMessage(WM_MDINEXT, (WPARAM)hMDIChild, FALSE);
\r
327 inline void CMDIFrame::MDIPrev() const
\r
329 assert(::IsWindow(m_hWnd));
\r
330 HWND hMDIChild = GetActiveMDIChild()->GetHwnd();
\r
331 GetView()->SendMessage(WM_MDINEXT, (WPARAM)hMDIChild, TRUE);
\r
334 inline void CMDIFrame::MDIRestore() const
\r
336 assert(::IsWindow(m_hWnd));
\r
337 GetView()->SendMessage(WM_MDIRESTORE, 0L, 0L);
\r
340 inline void CMDIFrame::MDITile(int nType /* = 0*/) const
\r
342 // Possible values for nType are:
\r
343 // MDITILE_HORIZONTAL Tiles MDI child windows so that one window appears above another.
\r
344 // MDITILE_SKIPDISABLED Prevents disabled MDI child windows from being tiled.
\r
345 // MDITILE_VERTICAL Tiles MDI child windows so that one window appears beside another.
\r
347 assert(::IsWindow(m_hWnd));
\r
348 GetView()->SendMessage(WM_MDITILE, (WPARAM)nType, 0L);
\r
351 inline void CMDIFrame::OnClose()
\r
353 if (RemoveAllMDIChildren())
\r
360 inline void CMDIFrame::OnViewStatusBar()
\r
362 CFrame::OnViewStatusBar();
\r
363 UpdateCheckMarks();
\r
364 GetView()->RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN);
\r
367 inline void CMDIFrame::OnViewToolBar()
\r
369 CFrame::OnViewToolBar();
\r
370 UpdateCheckMarks();
\r
371 GetView()->RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN);
\r
374 inline void CMDIFrame::OnWindowPosChanged()
\r
376 if (IsMenuBarUsed())
\r
378 // Refresh MenuBar Window
\r
379 HMENU hMenu= GetMenuBar().GetMenu();
\r
380 GetMenuBar().SetMenu(hMenu);
\r
381 UpdateCheckMarks();
\r
385 inline BOOL CMDIFrame::PreTranslateMessage(MSG* pMsg)
\r
387 if (WM_KEYFIRST <= pMsg->message && pMsg->message <= WM_KEYLAST)
\r
389 if (TranslateMDISysAccel(GetView()->GetHwnd(), pMsg))
\r
393 return CFrame::PreTranslateMessage(pMsg);
\r
396 inline void CMDIFrame::RecalcLayout()
\r
398 CFrame::RecalcLayout();
\r
400 if (GetView()->IsWindow())
\r
404 inline BOOL CMDIFrame::RemoveAllMDIChildren()
\r
406 BOOL bResult = TRUE;
\r
407 int Children = (int)m_vMDIChild.size();
\r
409 // Remove the children in reverse order
\r
410 for (int i = Children-1; i >= 0; --i)
\r
412 if (IDNO == m_vMDIChild[i]->SendMessage(WM_CLOSE, 0L, 0L)) // Also removes the MDI child
\r
419 inline void CMDIFrame::RemoveMDIChild(HWND hWnd)
\r
421 // Allocate an iterator for our HWND map
\r
422 std::vector <MDIChildPtr>::iterator v;
\r
424 for (v = m_vMDIChild.begin(); v!= m_vMDIChild.end(); ++v)
\r
426 if ((*v)->GetHwnd() == hWnd)
\r
428 m_vMDIChild.erase(v);
\r
433 if (GetActiveMDIChild())
\r
435 if (GetActiveMDIChild()->m_hChildMenu)
\r
436 UpdateFrameMenu(GetActiveMDIChild()->m_hChildMenu);
\r
437 if (GetActiveMDIChild()->m_hChildAccel)
\r
438 GetApp()->SetAccelerators(GetActiveMDIChild()->m_hChildAccel, this);
\r
442 if (IsMenuBarUsed())
\r
443 GetMenuBar().SetMenu(GetFrameMenu());
\r
445 SetMenu(FromHandle(GetFrameMenu()));
\r
447 GetApp()->SetAccelerators(GetFrameAccel(), this);
\r
451 inline void CMDIFrame::SetActiveMDIChild(CMDIChild* pChild)
\r
453 assert ( pChild->IsWindow() );
\r
455 GetMDIClient().SendMessage(WM_MDIACTIVATE, (WPARAM)pChild->GetHwnd(), 0L);
\r
458 assert ( m_hActiveMDIChild == pChild->GetHwnd() );
\r
461 inline void CMDIFrame::UpdateCheckMarks()
\r
463 if ((GetActiveMDIChild()) && GetActiveMDIChild()->m_hChildMenu)
\r
465 HMENU hMenu = GetActiveMDIChild()->m_hChildMenu;
\r
467 UINT uCheck = GetToolBar().IsWindowVisible()? MF_CHECKED : MF_UNCHECKED;
\r
468 ::CheckMenuItem(hMenu, IDW_VIEW_TOOLBAR, uCheck);
\r
470 uCheck = GetStatusBar().IsWindowVisible()? MF_CHECKED : MF_UNCHECKED;
\r
471 ::CheckMenuItem (hMenu, IDW_VIEW_STATUSBAR, uCheck);
\r
475 inline void CMDIFrame::UpdateFrameMenu(HMENU hMenu)
\r
477 int nMenuItems = GetMenuItemCount(hMenu);
\r
478 if (nMenuItems > 0)
\r
480 // The Window menu is typically second from the right
\r
481 int nWindowItem = MAX (nMenuItems -2, 0);
\r
482 HMENU hMenuWindow = ::GetSubMenu (hMenu, nWindowItem);
\r
486 if (IsMenuBarUsed())
\r
488 AppendMDIMenu(hMenuWindow);
\r
489 GetMenuBar().SetMenu(hMenu);
\r
493 GetView()->SendMessage (WM_MDISETMENU, (WPARAM) hMenu, (LPARAM)hMenuWindow);
\r
498 UpdateCheckMarks();
\r
501 inline LRESULT CMDIFrame::WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam)
\r
509 case WM_WINDOWPOSCHANGED:
\r
510 // MDI Child or MDI frame has been resized
\r
511 OnWindowPosChanged();
\r
512 break; // Continue with default processing
\r
515 return CFrame::WndProcDefault(uMsg, wParam, lParam);
\r
518 inline HWND CMDIFrame::CMDIClient::Create(CWnd* pParent)
\r
520 assert(pParent != 0);
\r
522 CLIENTCREATESTRUCT clientcreate ;
\r
523 clientcreate.hWindowMenu = m_hWnd;
\r
524 clientcreate.idFirstChild = IDW_FIRSTCHILD ;
\r
525 DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | MDIS_ALLCHILDSTYLES;
\r
527 // Create the view window
\r
528 CreateEx(WS_EX_CLIENTEDGE, _T("MDICLient"), TEXT(""), dwStyle, 0, 0, 0, 0, pParent, NULL, (PSTR) &clientcreate);
\r
533 inline LRESULT CMDIFrame::CMDIClient::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
\r
537 case WM_MDIDESTROY:
\r
539 // Do default processing first
\r
540 CallWindowProc(GetPrevWindowProc(), uMsg, wParam, lParam);
\r
542 // Now remove MDI child
\r
543 GetMDIFrame()->RemoveMDIChild((HWND) wParam);
\r
545 return 0; // Discard message
\r
547 case WM_MDISETMENU:
\r
549 if (GetMDIFrame()->IsMenuBarUsed())
\r
556 case WM_MDIACTIVATE:
\r
558 // Suppress redraw to avoid flicker when activating maximised MDI children
\r
559 SendMessage(WM_SETREDRAW, FALSE, 0L);
\r
560 LRESULT lr = CallWindowProc(GetPrevWindowProc(), WM_MDIACTIVATE, wParam, lParam);
\r
561 SendMessage(WM_SETREDRAW, TRUE, 0L);
\r
562 RedrawWindow(0, 0, RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
\r
567 return CWnd::WndProcDefault(uMsg, wParam, lParam);
\r
571 /////////////////////////////////////
\r
572 //Definitions for the CMDIChild class
\r
574 inline CMDIChild::CMDIChild() : m_pView(NULL), m_hChildMenu(NULL)
\r
576 // Set the MDI Child's menu and accelerator in the constructor, like this ...
\r
577 // HMENU hChildMenu = LoadMenu(GetApp()->GetResourceHandle(), _T("MdiMenuView"));
\r
578 // HACCEL hChildAccel = LoadAccelerators(GetApp()->GetResourceHandle(), _T("MDIAccelView"));
\r
579 // SetHandles(hChildMenu, hChildAccel);
\r
582 inline CMDIChild::~CMDIChild()
\r
585 GetParent()->SendMessage(WM_MDIDESTROY, (WPARAM)m_hWnd, 0L);
\r
588 ::DestroyMenu(m_hChildMenu);
\r
591 inline HWND CMDIChild::Create(CWnd* pParent /*= NULL*/)
\r
592 // We create the MDI child window and then maximize if required.
\r
593 // This technique avoids unnecessary flicker when creating maximized MDI children.
\r
595 //Call PreCreate in case its overloaded
\r
598 //Determine if the window should be created maximized
\r
600 pParent->SendMessage(WM_MDIGETACTIVE, 0L, (LPARAM)&bMax);
\r
601 bMax = bMax | (m_pcs->style & WS_MAXIMIZE);
\r
603 // Set the Window Class Name
\r
604 TCHAR szClassName[MAX_STRING_SIZE + 1] = _T("Win32++ MDI Child");
\r
605 if (m_pcs->lpszClass)
\r
606 lstrcpyn(szClassName, m_pcs->lpszClass, MAX_STRING_SIZE);
\r
608 // Set the window style
\r
610 dwStyle = m_pcs->style & ~WS_MAXIMIZE;
\r
611 dwStyle |= WS_VISIBLE | WS_OVERLAPPEDWINDOW ;
\r
613 // Set window size and position
\r
614 int x = CW_USEDEFAULT;
\r
615 int y = CW_USEDEFAULT;
\r
616 int cx = CW_USEDEFAULT;
\r
617 int cy = CW_USEDEFAULT;
\r
618 if(m_pcs->cx && m_pcs->cy)
\r
626 // Set the extended style
\r
627 DWORD dwExStyle = m_pcs->dwExStyle | WS_EX_MDICHILD;
\r
629 // Turn off redraw while creating the window
\r
630 pParent->SendMessage(WM_SETREDRAW, FALSE, 0L);
\r
632 // Create the window
\r
633 if (!CreateEx(dwExStyle, szClassName, m_pcs->lpszName, dwStyle, x, y,
\r
634 cx, cy, pParent, FromHandle(m_pcs->hMenu), m_pcs->lpCreateParams))
\r
635 throw CWinException(_T("CMDIChild::Create ... CreateEx failed"));
\r
638 ShowWindow(SW_MAXIMIZE);
\r
640 // Turn redraw back on
\r
641 pParent->SendMessage(WM_SETREDRAW, TRUE, 0L);
\r
642 pParent->RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
\r
644 // Ensure bits revealed by round corners (XP themes) are redrawn
\r
645 SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_FRAMECHANGED);
\r
648 GetMDIFrame()->UpdateFrameMenu(m_hChildMenu);
\r
650 GetApp()->SetAccelerators(m_hChildAccel, this);
\r
655 inline CMDIFrame* CMDIChild::GetMDIFrame() const
\r
657 CMDIFrame* pMDIFrame = (CMDIFrame*)GetParent()->GetParent();
\r
658 assert(dynamic_cast<CMDIFrame*>(pMDIFrame));
\r
662 inline LRESULT CMDIChild::FinalWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
\r
664 return ::DefMDIChildProc(m_hWnd, uMsg, wParam, lParam);
\r
667 inline void CMDIChild::MDIActivate() const
\r
669 GetParent()->SendMessage(WM_MDIACTIVATE, (WPARAM)m_hWnd, 0L);
\r
672 inline void CMDIChild::MDIDestroy() const
\r
674 GetParent()->SendMessage(WM_MDIDESTROY, (WPARAM)m_hWnd, 0L);
\r
677 inline void CMDIChild::MDIMaximize() const
\r
679 GetParent()->SendMessage(WM_MDIMAXIMIZE, (WPARAM)m_hWnd, 0L);
\r
682 inline void CMDIChild::MDIRestore() const
\r
684 GetParent()->SendMessage(WM_MDIRESTORE, (WPARAM)m_hWnd, 0L);
\r
687 inline void CMDIChild::OnCreate()
\r
689 // Create the view window
\r
690 assert(GetView()); // Use SetView in CMDIChild's constructor to set the view window
\r
691 GetView()->Create(this);
\r
695 inline void CMDIChild::RecalcLayout()
\r
697 // Resize the View window
\r
698 CRect rc = GetClientRect();
\r
699 m_pView->SetWindowPos( NULL, rc.left, rc.top, rc.Width(), rc.Height(), SWP_SHOWWINDOW );
\r
702 inline void CMDIChild::SetHandles(HMENU hMenu, HACCEL hAccel)
\r
704 m_hChildMenu = hMenu;
\r
705 m_hChildAccel = hAccel;
\r
707 // Note: It is valid to call SetChildMenu before the window is created
\r
710 CWnd* pWnd = GetMDIFrame()->GetActiveMDIChild();
\r
714 GetMDIFrame()->UpdateFrameMenu(m_hChildMenu);
\r
717 GetApp()->SetAccelerators(m_hChildAccel, GetMDIFrame());
\r
722 inline void CMDIChild::SetView(CWnd& wndView)
\r
723 // Sets or changes the View window displayed within the frame
\r
725 if (m_pView != &wndView)
\r
727 // Destroy the existing view window (if any)
\r
728 if (m_pView) m_pView->Destroy();
\r
730 // Assign the view window
\r
731 m_pView = &wndView;
\r
735 // The frame is already created, so create and position the new view too
\r
736 assert(GetView()); // Use SetView in CMDIChild's constructor to set the view window
\r
737 GetView()->Create(this);
\r
743 inline LRESULT CMDIChild::WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam)
\r
747 case WM_MDIACTIVATE:
\r
749 // This child is being activated
\r
750 if (lParam == (LPARAM) m_hWnd)
\r
752 GetMDIFrame()->m_hActiveMDIChild = m_hWnd;
\r
753 // Set the menu to child default menu
\r
755 GetMDIFrame()->UpdateFrameMenu(m_hChildMenu);
\r
757 GetApp()->SetAccelerators(m_hChildAccel, this);
\r
760 // No child is being activated
\r
763 GetMDIFrame()->m_hActiveMDIChild = NULL;
\r
764 // Set the menu to frame's original menu
\r
765 GetMDIFrame()->UpdateFrameMenu(GetMDIFrame()->GetFrameMenu());
\r
766 GetApp()->SetAccelerators(GetMDIFrame()->GetFrameAccel(), this);
\r
771 case WM_WINDOWPOSCHANGED:
\r
777 return CWnd::WndProcDefault(uMsg, wParam, lParam);
\r
781 } // namespace Win32xx
\r
783 #endif // _WIN32XX_MDI_H_
\r