diff options
Diffstat (limited to 'mmc_updater/depends/win32cpp/mdi.h')
-rw-r--r-- | mmc_updater/depends/win32cpp/mdi.h | 783 |
1 files changed, 783 insertions, 0 deletions
diff --git a/mmc_updater/depends/win32cpp/mdi.h b/mmc_updater/depends/win32cpp/mdi.h new file mode 100644 index 00000000..0aa35ffc --- /dev/null +++ b/mmc_updater/depends/win32cpp/mdi.h @@ -0,0 +1,783 @@ +// Released: 5th AUgust 2011 +// +// David Nash +// email: dnash@bigpond.net.au +// url: https://sourceforge.net/projects/win32-framework +// +// +// Copyright (c) 2005-2011 David Nash +// +// Permission is hereby granted, free of charge, to +// any person obtaining a copy of this software and +// associated documentation files (the "Software"), +// to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, +// merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom +// the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice +// shall be included in all copies or substantial portions +// of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. +// +//////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////// +// mdi.h +// Declaration of the CMDIChild and CMDIFrame classes + +// The classes defined here add MDI frames support to Win32++. MDI +// (Multiple Document Interface) frames host one or more child windows. The +// child windows hosted by a MDI frame can be different types. For example, +// some MDI child windows could be used to edit text, while others could be +// used to display a bitmap. Four classes are defined here to support MDI +// frames: + + +// 1) CMDIFrame. This class inherits from CFrame, and adds the functionality +// required by MDI frames. It keeps track of the MDI children created and +// destroyed, and adjusts the menu when a MDI child is activated. Use the +// AddMDIChild function to add MDI child windows to the MDI frame. Inherit +// from CMDIFrame to create your own MDI frame. +// +// 2) CMDIChild: All MDI child windows (ie. CWnd classes) should inherit from +// this class. Each MDI child type can have a different frame menu. + +// Use the MDIFrame generic application as the starting point for your own MDI +// frame applications. +// Refer to the MDIDemo sample for an example on how to use these classes to +// create a MDI frame application with different types of MDI child windows. + + +#ifndef _WIN32XX_MDI_H_ +#define _WIN32XX_MDI_H_ + +#include "frame.h" +#include <vector> + + + +namespace Win32xx +{ + class CMDIChild; + class CMDIFrame; + typedef Shared_Ptr<CMDIChild> MDIChildPtr; + + ///////////////////////////////////// + // Declaration of the CMDIChild class + // + class CMDIChild : public CWnd + { + friend class CMDIFrame; + public: + CMDIChild(); + virtual ~CMDIChild(); + + // These are the functions you might wish to override + virtual HWND Create(CWnd* pParent = NULL); + virtual void RecalcLayout(); + + // These functions aren't virtual, and shouldn't be overridden + void SetHandles(HMENU MenuName, HACCEL AccelName); + CMDIFrame* GetMDIFrame() const; + CWnd* GetView() const {return m_pView;} + void SetView(CWnd& pwndView); + void MDIActivate() const; + void MDIDestroy() const; + void MDIMaximize() const; + void MDIRestore() const; + + protected: + // Its unlikely you would need to override these functions + virtual LRESULT FinalWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam); + virtual void OnCreate(); + virtual LRESULT WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam); + + private: + CMDIChild(const CMDIChild&); // Disable copy construction + CMDIChild& operator = (const CMDIChild&); // Disable assignment operator + + CWnd* m_pView; // pointer to the View CWnd object + HMENU m_hChildMenu; + HACCEL m_hChildAccel; + }; + + + ///////////////////////////////////// + // Declaration of the CMDIFrame class + // + class CMDIFrame : public CFrame + { + friend class CMDIChild; // CMDIChild uses m_hOrigMenu + typedef Shared_Ptr<CMDIChild> MDIChildPtr; + + public: + class CMDIClient : public CWnd // a nested class within CMDIFrame + { + public: + CMDIClient() {} + virtual ~CMDIClient() {} + virtual HWND Create(CWnd* pParent = NULL); + virtual LRESULT WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam); + CMDIFrame* GetMDIFrame() const { return (CMDIFrame*)GetParent(); } + + private: + CMDIClient(const CMDIClient&); // Disable copy construction + CMDIClient& operator = (const CMDIClient&); // Disable assignment operator + }; + + + CMDIFrame(); + virtual ~CMDIFrame() {} + + virtual CMDIChild* AddMDIChild(MDIChildPtr pMDIChild); + virtual CMDIClient& GetMDIClient() const { return (CMDIClient&)m_MDIClient; } + virtual BOOL IsMDIFrame() const { return TRUE; } + virtual void RemoveMDIChild(HWND hWnd); + virtual BOOL RemoveAllMDIChildren(); + virtual void UpdateCheckMarks(); + + // These functions aren't virtual, so don't override them + std::vector <MDIChildPtr>& GetAllMDIChildren() {return m_vMDIChild;} + CMDIChild* GetActiveMDIChild() const; + BOOL IsMDIChildMaxed() const; + void MDICascade(int nType = 0) const; + void MDIIconArrange() const; + void MDIMaximize() const; + void MDINext() const; + void MDIPrev() const; + void MDIRestore() const; + void MDITile(int nType = 0) const; + void SetActiveMDIChild(CMDIChild* pChild); + + protected: + // These are the functions you might wish to override + virtual void OnClose(); + virtual void OnViewStatusBar(); + virtual void OnViewToolBar(); + virtual void OnWindowPosChanged(); + virtual void RecalcLayout(); + virtual BOOL PreTranslateMessage(MSG* pMsg); + virtual LRESULT WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam); + + private: + CMDIFrame(const CMDIFrame&); // Disable copy construction + CMDIFrame& operator = (const CMDIFrame&); // Disable assignment operator + void AppendMDIMenu(HMENU hMenuWindow); + LRESULT FinalWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam); + void UpdateFrameMenu(HMENU hMenu); + + CMDIClient m_MDIClient; + std::vector <MDIChildPtr> m_vMDIChild; + HWND m_hActiveMDIChild; + }; + +} + + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +namespace Win32xx +{ + + ///////////////////////////////////// + // Definitions for the CMDIFrame class + // + inline CMDIFrame::CMDIFrame() : m_hActiveMDIChild(NULL) + { + SetView(GetMDIClient()); + } + + inline CMDIChild* CMDIFrame::AddMDIChild(MDIChildPtr pMDIChild) + { + assert(NULL != pMDIChild.get()); // Cannot add Null MDI Child + + m_vMDIChild.push_back(pMDIChild); + pMDIChild->Create(GetView()); + + return pMDIChild.get(); + } + + inline void CMDIFrame::AppendMDIMenu(HMENU hMenuWindow) + { + // Adds the additional menu items the the "Window" submenu when + // MDI child windows are created + + if (!IsMenu(hMenuWindow)) + return; + + // Delete previously appended items + int nItems = ::GetMenuItemCount(hMenuWindow); + UINT uLastID = ::GetMenuItemID(hMenuWindow, --nItems); + if ((uLastID >= IDW_FIRSTCHILD) && (uLastID < IDW_FIRSTCHILD + 10)) + { + while ((uLastID >= IDW_FIRSTCHILD) && (uLastID < IDW_FIRSTCHILD + 10)) + { + ::DeleteMenu(hMenuWindow, nItems, MF_BYPOSITION); + uLastID = ::GetMenuItemID(hMenuWindow, --nItems); + } + //delete the separator too + ::DeleteMenu(hMenuWindow, nItems, MF_BYPOSITION); + } + + int nWindow = 0; + + // Allocate an iterator for our MDIChild vector + std::vector <MDIChildPtr>::iterator v; + + for (v = GetAllMDIChildren().begin(); v < GetAllMDIChildren().end(); ++v) + { + if ((*v)->GetWindowLongPtr(GWL_STYLE) & WS_VISIBLE) // IsWindowVisible is unreliable here + { + // Add Separator + if (0 == nWindow) + ::AppendMenu(hMenuWindow, MF_SEPARATOR, 0, NULL); + + // Add a menu entry for each MDI child (up to 9) + if (nWindow < 9) + { + tString tsMenuItem ( (*v)->GetWindowText() ); + + if (tsMenuItem.length() > MAX_MENU_STRING -10) + { + // Truncate the string if its too long + tsMenuItem.erase(tsMenuItem.length() - MAX_MENU_STRING +10); + tsMenuItem += _T(" ..."); + } + + TCHAR szMenuString[MAX_MENU_STRING+1]; + wsprintf(szMenuString, _T("&%d %s"), nWindow+1, tsMenuItem.c_str()); + + ::AppendMenu(hMenuWindow, MF_STRING, IDW_FIRSTCHILD + nWindow, szMenuString); + + if (GetActiveMDIChild() == (*v).get()) + ::CheckMenuItem(hMenuWindow, IDW_FIRSTCHILD+nWindow, MF_CHECKED); + + ++nWindow; + } + else if (9 == nWindow) + // For the 10th MDI child, add this menu item and return + { + ::AppendMenu(hMenuWindow, MF_STRING, IDW_FIRSTCHILD + nWindow, _T("&Windows...")); + return; + } + } + } + } + + inline LRESULT CMDIFrame::FinalWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam) + { + return ::DefFrameProc(m_hWnd, GetMDIClient(), uMsg, wParam, lParam); + } + + inline CMDIChild* CMDIFrame::GetActiveMDIChild() const + { + return (CMDIChild*)FromHandle(m_hActiveMDIChild); + } + + inline BOOL CMDIFrame::IsMDIChildMaxed() const + { + BOOL bMaxed = FALSE; + GetMDIClient().SendMessage(WM_MDIGETACTIVE, 0L, (LPARAM)&bMaxed); + return bMaxed; + } + + inline void CMDIFrame::MDICascade(int nType /* = 0*/) const + { + // Possible values for nType are: + // MDITILE_SKIPDISABLED Prevents disabled MDI child windows from being cascaded. + + assert(::IsWindow(m_hWnd)); + GetView()->SendMessage(WM_MDICASCADE, (WPARAM)nType, 0L); + } + + inline void CMDIFrame::MDIIconArrange() const + { + assert(::IsWindow(m_hWnd)); + GetView()->SendMessage(WM_MDIICONARRANGE, 0L, 0L); + } + + inline void CMDIFrame::MDIMaximize() const + { + assert(::IsWindow(m_hWnd)); + GetView()->SendMessage(WM_MDIMAXIMIZE, 0L, 0L); + } + + inline void CMDIFrame::MDINext() const + { + assert(::IsWindow(m_hWnd)); + HWND hMDIChild = GetActiveMDIChild()->GetHwnd(); + GetView()->SendMessage(WM_MDINEXT, (WPARAM)hMDIChild, FALSE); + } + + inline void CMDIFrame::MDIPrev() const + { + assert(::IsWindow(m_hWnd)); + HWND hMDIChild = GetActiveMDIChild()->GetHwnd(); + GetView()->SendMessage(WM_MDINEXT, (WPARAM)hMDIChild, TRUE); + } + + inline void CMDIFrame::MDIRestore() const + { + assert(::IsWindow(m_hWnd)); + GetView()->SendMessage(WM_MDIRESTORE, 0L, 0L); + } + + inline void CMDIFrame::MDITile(int nType /* = 0*/) const + { + // Possible values for nType are: + // MDITILE_HORIZONTAL Tiles MDI child windows so that one window appears above another. + // MDITILE_SKIPDISABLED Prevents disabled MDI child windows from being tiled. + // MDITILE_VERTICAL Tiles MDI child windows so that one window appears beside another. + + assert(::IsWindow(m_hWnd)); + GetView()->SendMessage(WM_MDITILE, (WPARAM)nType, 0L); + } + + inline void CMDIFrame::OnClose() + { + if (RemoveAllMDIChildren()) + { + CFrame::OnClose(); + Destroy(); + } + } + + inline void CMDIFrame::OnViewStatusBar() + { + CFrame::OnViewStatusBar(); + UpdateCheckMarks(); + GetView()->RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN); + } + + inline void CMDIFrame::OnViewToolBar() + { + CFrame::OnViewToolBar(); + UpdateCheckMarks(); + GetView()->RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN); + } + + inline void CMDIFrame::OnWindowPosChanged() + { + if (IsMenuBarUsed()) + { + // Refresh MenuBar Window + HMENU hMenu= GetMenuBar().GetMenu(); + GetMenuBar().SetMenu(hMenu); + UpdateCheckMarks(); + } + } + + inline BOOL CMDIFrame::PreTranslateMessage(MSG* pMsg) + { + if (WM_KEYFIRST <= pMsg->message && pMsg->message <= WM_KEYLAST) + { + if (TranslateMDISysAccel(GetView()->GetHwnd(), pMsg)) + return TRUE; + } + + return CFrame::PreTranslateMessage(pMsg); + } + + inline void CMDIFrame::RecalcLayout() + { + CFrame::RecalcLayout(); + + if (GetView()->IsWindow()) + MDIIconArrange(); + } + + inline BOOL CMDIFrame::RemoveAllMDIChildren() + { + BOOL bResult = TRUE; + int Children = (int)m_vMDIChild.size(); + + // Remove the children in reverse order + for (int i = Children-1; i >= 0; --i) + { + if (IDNO == m_vMDIChild[i]->SendMessage(WM_CLOSE, 0L, 0L)) // Also removes the MDI child + bResult = FALSE; + } + + return bResult; + } + + inline void CMDIFrame::RemoveMDIChild(HWND hWnd) + { + // Allocate an iterator for our HWND map + std::vector <MDIChildPtr>::iterator v; + + for (v = m_vMDIChild.begin(); v!= m_vMDIChild.end(); ++v) + { + if ((*v)->GetHwnd() == hWnd) + { + m_vMDIChild.erase(v); + break; + } + } + + if (GetActiveMDIChild()) + { + if (GetActiveMDIChild()->m_hChildMenu) + UpdateFrameMenu(GetActiveMDIChild()->m_hChildMenu); + if (GetActiveMDIChild()->m_hChildAccel) + GetApp()->SetAccelerators(GetActiveMDIChild()->m_hChildAccel, this); + } + else + { + if (IsMenuBarUsed()) + GetMenuBar().SetMenu(GetFrameMenu()); + else + SetMenu(FromHandle(GetFrameMenu())); + + GetApp()->SetAccelerators(GetFrameAccel(), this); + } + } + + inline void CMDIFrame::SetActiveMDIChild(CMDIChild* pChild) + { + assert ( pChild->IsWindow() ); + + GetMDIClient().SendMessage(WM_MDIACTIVATE, (WPARAM)pChild->GetHwnd(), 0L); + + // Verify + assert ( m_hActiveMDIChild == pChild->GetHwnd() ); + } + + inline void CMDIFrame::UpdateCheckMarks() + { + if ((GetActiveMDIChild()) && GetActiveMDIChild()->m_hChildMenu) + { + HMENU hMenu = GetActiveMDIChild()->m_hChildMenu; + + UINT uCheck = GetToolBar().IsWindowVisible()? MF_CHECKED : MF_UNCHECKED; + ::CheckMenuItem(hMenu, IDW_VIEW_TOOLBAR, uCheck); + + uCheck = GetStatusBar().IsWindowVisible()? MF_CHECKED : MF_UNCHECKED; + ::CheckMenuItem (hMenu, IDW_VIEW_STATUSBAR, uCheck); + } + } + + inline void CMDIFrame::UpdateFrameMenu(HMENU hMenu) + { + int nMenuItems = GetMenuItemCount(hMenu); + if (nMenuItems > 0) + { + // The Window menu is typically second from the right + int nWindowItem = MAX (nMenuItems -2, 0); + HMENU hMenuWindow = ::GetSubMenu (hMenu, nWindowItem); + + if (hMenuWindow) + { + if (IsMenuBarUsed()) + { + AppendMDIMenu(hMenuWindow); + GetMenuBar().SetMenu(hMenu); + } + else + { + GetView()->SendMessage (WM_MDISETMENU, (WPARAM) hMenu, (LPARAM)hMenuWindow); + DrawMenuBar(); + } + } + } + UpdateCheckMarks(); + } + + inline LRESULT CMDIFrame::WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam) + { + switch (uMsg) + { + case WM_CLOSE: + OnClose(); + return 0; + + case WM_WINDOWPOSCHANGED: + // MDI Child or MDI frame has been resized + OnWindowPosChanged(); + break; // Continue with default processing + + } // switch uMsg + return CFrame::WndProcDefault(uMsg, wParam, lParam); + } + + inline HWND CMDIFrame::CMDIClient::Create(CWnd* pParent) + { + assert(pParent != 0); + + CLIENTCREATESTRUCT clientcreate ; + clientcreate.hWindowMenu = m_hWnd; + clientcreate.idFirstChild = IDW_FIRSTCHILD ; + DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | MDIS_ALLCHILDSTYLES; + + // Create the view window + CreateEx(WS_EX_CLIENTEDGE, _T("MDICLient"), TEXT(""), dwStyle, 0, 0, 0, 0, pParent, NULL, (PSTR) &clientcreate); + + return m_hWnd; + } + + inline LRESULT CMDIFrame::CMDIClient::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam) + { + switch (uMsg) + { + case WM_MDIDESTROY: + { + // Do default processing first + CallWindowProc(GetPrevWindowProc(), uMsg, wParam, lParam); + + // Now remove MDI child + GetMDIFrame()->RemoveMDIChild((HWND) wParam); + } + return 0; // Discard message + + case WM_MDISETMENU: + { + if (GetMDIFrame()->IsMenuBarUsed()) + { + return 0L; + } + } + break; + + case WM_MDIACTIVATE: + { + // Suppress redraw to avoid flicker when activating maximised MDI children + SendMessage(WM_SETREDRAW, FALSE, 0L); + LRESULT lr = CallWindowProc(GetPrevWindowProc(), WM_MDIACTIVATE, wParam, lParam); + SendMessage(WM_SETREDRAW, TRUE, 0L); + RedrawWindow(0, 0, RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); + + return lr; + } + } + return CWnd::WndProcDefault(uMsg, wParam, lParam); + } + + + ///////////////////////////////////// + //Definitions for the CMDIChild class + // + inline CMDIChild::CMDIChild() : m_pView(NULL), m_hChildMenu(NULL) + { + // Set the MDI Child's menu and accelerator in the constructor, like this ... + // HMENU hChildMenu = LoadMenu(GetApp()->GetResourceHandle(), _T("MdiMenuView")); + // HACCEL hChildAccel = LoadAccelerators(GetApp()->GetResourceHandle(), _T("MDIAccelView")); + // SetHandles(hChildMenu, hChildAccel); + } + + inline CMDIChild::~CMDIChild() + { + if (IsWindow()) + GetParent()->SendMessage(WM_MDIDESTROY, (WPARAM)m_hWnd, 0L); + + if (m_hChildMenu) + ::DestroyMenu(m_hChildMenu); + } + + inline HWND CMDIChild::Create(CWnd* pParent /*= NULL*/) + // We create the MDI child window and then maximize if required. + // This technique avoids unnecessary flicker when creating maximized MDI children. + { + //Call PreCreate in case its overloaded + PreCreate(*m_pcs); + + //Determine if the window should be created maximized + BOOL bMax = FALSE; + pParent->SendMessage(WM_MDIGETACTIVE, 0L, (LPARAM)&bMax); + bMax = bMax | (m_pcs->style & WS_MAXIMIZE); + + // Set the Window Class Name + TCHAR szClassName[MAX_STRING_SIZE + 1] = _T("Win32++ MDI Child"); + if (m_pcs->lpszClass) + lstrcpyn(szClassName, m_pcs->lpszClass, MAX_STRING_SIZE); + + // Set the window style + DWORD dwStyle; + dwStyle = m_pcs->style & ~WS_MAXIMIZE; + dwStyle |= WS_VISIBLE | WS_OVERLAPPEDWINDOW ; + + // Set window size and position + int x = CW_USEDEFAULT; + int y = CW_USEDEFAULT; + int cx = CW_USEDEFAULT; + int cy = CW_USEDEFAULT; + if(m_pcs->cx && m_pcs->cy) + { + x = m_pcs->x; + y = m_pcs->y; + cx = m_pcs->cx; + cy = m_pcs->cy; + } + + // Set the extended style + DWORD dwExStyle = m_pcs->dwExStyle | WS_EX_MDICHILD; + + // Turn off redraw while creating the window + pParent->SendMessage(WM_SETREDRAW, FALSE, 0L); + + // Create the window + if (!CreateEx(dwExStyle, szClassName, m_pcs->lpszName, dwStyle, x, y, + cx, cy, pParent, FromHandle(m_pcs->hMenu), m_pcs->lpCreateParams)) + throw CWinException(_T("CMDIChild::Create ... CreateEx failed")); + + if (bMax) + ShowWindow(SW_MAXIMIZE); + + // Turn redraw back on + pParent->SendMessage(WM_SETREDRAW, TRUE, 0L); + pParent->RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN); + + // Ensure bits revealed by round corners (XP themes) are redrawn + SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_FRAMECHANGED); + + if (m_hChildMenu) + GetMDIFrame()->UpdateFrameMenu(m_hChildMenu); + if (m_hChildAccel) + GetApp()->SetAccelerators(m_hChildAccel, this); + + return m_hWnd; + } + + inline CMDIFrame* CMDIChild::GetMDIFrame() const + { + CMDIFrame* pMDIFrame = (CMDIFrame*)GetParent()->GetParent(); + assert(dynamic_cast<CMDIFrame*>(pMDIFrame)); + return pMDIFrame; + } + + inline LRESULT CMDIChild::FinalWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam) + { + return ::DefMDIChildProc(m_hWnd, uMsg, wParam, lParam); + } + + inline void CMDIChild::MDIActivate() const + { + GetParent()->SendMessage(WM_MDIACTIVATE, (WPARAM)m_hWnd, 0L); + } + + inline void CMDIChild::MDIDestroy() const + { + GetParent()->SendMessage(WM_MDIDESTROY, (WPARAM)m_hWnd, 0L); + } + + inline void CMDIChild::MDIMaximize() const + { + GetParent()->SendMessage(WM_MDIMAXIMIZE, (WPARAM)m_hWnd, 0L); + } + + inline void CMDIChild::MDIRestore() const + { + GetParent()->SendMessage(WM_MDIRESTORE, (WPARAM)m_hWnd, 0L); + } + + inline void CMDIChild::OnCreate() + { + // Create the view window + assert(GetView()); // Use SetView in CMDIChild's constructor to set the view window + GetView()->Create(this); + RecalcLayout(); + } + + inline void CMDIChild::RecalcLayout() + { + // Resize the View window + CRect rc = GetClientRect(); + m_pView->SetWindowPos( NULL, rc.left, rc.top, rc.Width(), rc.Height(), SWP_SHOWWINDOW ); + } + + inline void CMDIChild::SetHandles(HMENU hMenu, HACCEL hAccel) + { + m_hChildMenu = hMenu; + m_hChildAccel = hAccel; + + // Note: It is valid to call SetChildMenu before the window is created + if (IsWindow()) + { + CWnd* pWnd = GetMDIFrame()->GetActiveMDIChild(); + if (pWnd == this) + { + if (m_hChildMenu) + GetMDIFrame()->UpdateFrameMenu(m_hChildMenu); + + if (m_hChildAccel) + GetApp()->SetAccelerators(m_hChildAccel, GetMDIFrame()); + } + } + } + + inline void CMDIChild::SetView(CWnd& wndView) + // Sets or changes the View window displayed within the frame + { + if (m_pView != &wndView) + { + // Destroy the existing view window (if any) + if (m_pView) m_pView->Destroy(); + + // Assign the view window + m_pView = &wndView; + + if (m_hWnd) + { + // The frame is already created, so create and position the new view too + assert(GetView()); // Use SetView in CMDIChild's constructor to set the view window + GetView()->Create(this); + RecalcLayout(); + } + } + } + + inline LRESULT CMDIChild::WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam) + { + switch (uMsg) + { + case WM_MDIACTIVATE: + { + // This child is being activated + if (lParam == (LPARAM) m_hWnd) + { + GetMDIFrame()->m_hActiveMDIChild = m_hWnd; + // Set the menu to child default menu + if (m_hChildMenu) + GetMDIFrame()->UpdateFrameMenu(m_hChildMenu); + if (m_hChildAccel) + GetApp()->SetAccelerators(m_hChildAccel, this); + } + + // No child is being activated + if (0 == lParam) + { + GetMDIFrame()->m_hActiveMDIChild = NULL; + // Set the menu to frame's original menu + GetMDIFrame()->UpdateFrameMenu(GetMDIFrame()->GetFrameMenu()); + GetApp()->SetAccelerators(GetMDIFrame()->GetFrameAccel(), this); + } + } + return 0L ; + + case WM_WINDOWPOSCHANGED: + { + RecalcLayout(); + break; + } + } + return CWnd::WndProcDefault(uMsg, wParam, lParam); + } + + +} // namespace Win32xx + +#endif // _WIN32XX_MDI_H_ + |