summaryrefslogtreecommitdiffstats
path: root/mmc_updater/depends/win32cpp/mdi.h
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2013-12-02 00:55:24 +0100
committerPetr Mrázek <peterix@gmail.com>2013-12-02 00:55:24 +0100
commit6aa9bd0f77dcb5128167fae62e32aa5252fe85c6 (patch)
tree632994a61888929af9289927d338bd19a2b3f32c /mmc_updater/depends/win32cpp/mdi.h
parent613699b3626aea750093ab7eaaeccaa28c0e87c6 (diff)
downloadMultiMC-6aa9bd0f77dcb5128167fae62e32aa5252fe85c6.tar
MultiMC-6aa9bd0f77dcb5128167fae62e32aa5252fe85c6.tar.gz
MultiMC-6aa9bd0f77dcb5128167fae62e32aa5252fe85c6.tar.lz
MultiMC-6aa9bd0f77dcb5128167fae62e32aa5252fe85c6.tar.xz
MultiMC-6aa9bd0f77dcb5128167fae62e32aa5252fe85c6.zip
Renew the updater branch
Now with some actual consensus on what the updater will do!
Diffstat (limited to 'mmc_updater/depends/win32cpp/mdi.h')
-rw-r--r--mmc_updater/depends/win32cpp/mdi.h783
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_
+