show the "Window" menu only when we have any MDI children, it's unnecessary otherwise; some minor formatting/comments changes

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@55458 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2008-09-04 12:47:53 +00:00
parent 509f339a81
commit ecc63060e7
2 changed files with 124 additions and 38 deletions

View File

@@ -51,7 +51,7 @@ public:
// accessors // accessors
// --------- // ---------
// Get the active MDI child window (Windows only) // Get the active MDI child window
wxMDIChildFrame *GetActiveChild() const; wxMDIChildFrame *GetActiveChild() const;
// Get the client window // Get the client window
@@ -59,11 +59,20 @@ public:
// Create the client window class (don't Create the window, // Create the client window class (don't Create the window,
// just return a new class) // just return a new class)
virtual wxMDIClientWindow *OnCreateClient(void); virtual wxMDIClientWindow *OnCreateClient();
// MDI windows menu // MDI windows menu functions
wxMenu* GetWindowMenu() const { return m_windowMenu; } // --------------------------
// return the pointer to the current window menu or NULL if we don't have
// because of wxFRAME_NO_WINDOW_MENU style
wxMenu *GetWindowMenu() const { return m_windowMenu; }
// use the given menu instead of the default window menu
//
// menu can be NULL to disable the window menu completely
void SetWindowMenu(wxMenu* menu) ; void SetWindowMenu(wxMenu* menu) ;
virtual void DoMenuUpdates(wxMenu* menu = NULL); virtual void DoMenuUpdates(wxMenu* menu = NULL);
// MDI operations // MDI operations
@@ -74,6 +83,18 @@ public:
virtual void ActivateNext(); virtual void ActivateNext();
virtual void ActivatePrevious(); virtual void ActivatePrevious();
// implementation only from now on
// MDI helpers
// -----------
// called by wxMDIChildFrame after it was successfully created
virtual void AddMDIChild(wxMDIChildFrame *child);
// called by wxMDIChildFrame just before it is destroyed
virtual void RemoveMDIChild(wxMDIChildFrame *child);
// handlers // handlers
// -------- // --------
@@ -108,12 +129,21 @@ protected:
wxMDIClientWindow * m_clientWindow; wxMDIClientWindow * m_clientWindow;
wxMDIChildFrame * m_currentChild; wxMDIChildFrame * m_currentChild;
wxMenu* m_windowMenu;
// the current window menu or NULL if we are not using it
wxMenu *m_windowMenu;
// true if MDI Frame is intercepting commands, not child // true if MDI Frame is intercepting commands, not child
bool m_parentFrameActive; bool m_parentFrameActive;
private: private:
// add/remove window menu if we have it (i.e. m_windowMenu != NULL)
void AddWindowMenu();
void RemoveWindowMenu();
// return the number of child frames we currently have (maybe 0)
int GetChildFramesCount() const;
friend class WXDLLIMPEXP_FWD_CORE wxMDIChildFrame; friend class WXDLLIMPEXP_FWD_CORE wxMDIChildFrame;
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()

View File

@@ -82,10 +82,10 @@ static void MDISetMenu(wxWindow *win, HMENU hmenuFrame, HMENU hmenuWindow);
// insert the window menu (subMenu) into menu just before "Help" submenu or at // insert the window menu (subMenu) into menu just before "Help" submenu or at
// the very end if not found // the very end if not found
static void InsertWindowMenu(wxWindow *win, WXHMENU menu, HMENU subMenu); static void MDIInsertWindowMenu(wxWindow *win, WXHMENU menu, HMENU subMenu);
// Remove the window menu // Remove the window menu
static void RemoveWindowMenu(wxWindow *win, WXHMENU menu); static void MDIRemoveWindowMenu(wxWindow *win, WXHMENU menu);
// is this an id of an MDI child? // is this an id of an MDI child?
inline bool IsMdiCommandId(int id) inline bool IsMdiCommandId(int id)
@@ -98,6 +98,9 @@ static void UnpackMDIActivate(WXWPARAM wParam, WXLPARAM lParam,
WXWORD *activate, WXHWND *hwndAct, WXHWND *hwndDeact); WXWORD *activate, WXHWND *hwndAct, WXHWND *hwndDeact);
// return the HMENU of the MDI menu // return the HMENU of the MDI menu
//
// this function works correctly even when we don't have a window menu and just
// returns 0 then
static inline HMENU GetMDIWindowMenu(wxMDIParentFrame *frame) static inline HMENU GetMDIWindowMenu(wxMDIParentFrame *frame)
{ {
wxMenu *menu = frame->GetWindowMenu(); wxMenu *menu = frame->GetWindowMenu();
@@ -139,7 +142,7 @@ wxMDIParentFrame::wxMDIParentFrame()
{ {
m_clientWindow = NULL; m_clientWindow = NULL;
m_currentChild = NULL; m_currentChild = NULL;
m_windowMenu = (wxMenu*) NULL; m_windowMenu = NULL;
m_parentFrameActive = true; m_parentFrameActive = true;
} }
@@ -158,7 +161,7 @@ bool wxMDIParentFrame::Create(wxWindow *parent,
// "Window" menu // "Window" menu
if ( style & wxFRAME_NO_WINDOW_MENU ) if ( style & wxFRAME_NO_WINDOW_MENU )
{ {
m_windowMenu = (wxMenu *)NULL; m_windowMenu = NULL;
} }
else // normal case: we have the window menu, so construct it else // normal case: we have the window menu, so construct it
{ {
@@ -223,19 +226,12 @@ wxMDIParentFrame::~wxMDIParentFrame()
DestroyChildren(); DestroyChildren();
if (m_windowMenu) delete m_windowMenu;
{
delete m_windowMenu;
m_windowMenu = (wxMenu*) NULL;
}
// the MDI frame menubar is not automatically deleted by Windows unlike for // the MDI frame menubar is not automatically deleted by Windows unlike for
// the normal frames // the normal frames
if ( m_hMenu ) if ( m_hMenu )
{
::DestroyMenu((HMENU)m_hMenu); ::DestroyMenu((HMENU)m_hMenu);
m_hMenu = (WXHMENU)NULL;
}
if ( m_clientWindow ) if ( m_clientWindow )
{ {
@@ -247,13 +243,76 @@ wxMDIParentFrame::~wxMDIParentFrame()
} }
} }
// ----------------------------------------------------------------------------
// wxMDIParentFrame child management
// ----------------------------------------------------------------------------
int wxMDIParentFrame::GetChildFramesCount() const
{
int count = 0;
for ( wxWindowList::const_iterator i = GetChildren().begin();
i != GetChildren().end();
++i )
{
if ( wxDynamicCast(*i, wxMDIChildFrame) )
count++;
}
return count;
}
void wxMDIParentFrame::AddMDIChild(wxMDIChildFrame * WXUNUSED(child))
{
if ( GetChildFramesCount() == 1 )
{
// first MDI child added, we need to insert the window menu now if we
// have it
AddWindowMenu();
}
}
void wxMDIParentFrame::RemoveMDIChild(wxMDIChildFrame * WXUNUSED(child))
{
if ( GetChildFramesCount() == 1 )
{
// last MDI child is being removed, remove the now unnecessary window
// menu too
RemoveWindowMenu();
}
}
// ----------------------------------------------------------------------------
// wxMDIParentFrame window menu handling
// ----------------------------------------------------------------------------
void wxMDIParentFrame::AddWindowMenu()
{
if ( m_windowMenu )
MDIInsertWindowMenu(GetClientWindow(), m_hMenu, GetMDIWindowMenu(this));
}
void wxMDIParentFrame::RemoveWindowMenu()
{
if ( m_windowMenu )
MDIRemoveWindowMenu(GetClientWindow(), m_hMenu);
}
#if wxUSE_MENUS_NATIVE #if wxUSE_MENUS_NATIVE
void wxMDIParentFrame::InternalSetMenuBar() void wxMDIParentFrame::InternalSetMenuBar()
{ {
m_parentFrameActive = true; m_parentFrameActive = true;
InsertWindowMenu(GetClientWindow(), m_hMenu, GetMDIWindowMenu(this)); if ( GetActiveChild() )
{
AddWindowMenu();
}
else // we don't have any MDI children yet
{
// wait until we do to add the window menu but do set the main menu for
// now (this is done by AddWindowMenu() as a side effect)
MDISetMenu(GetClientWindow(), (HMENU)m_hMenu, NULL);
}
} }
#endif // wxUSE_MENUS_NATIVE #endif // wxUSE_MENUS_NATIVE
@@ -262,24 +321,17 @@ void wxMDIParentFrame::SetWindowMenu(wxMenu* menu)
{ {
if (m_windowMenu) if (m_windowMenu)
{ {
if (GetMenuBar()) RemoveWindowMenu();
{
// Remove old window menu
RemoveWindowMenu(GetClientWindow(), m_hMenu);
}
delete m_windowMenu; delete m_windowMenu;
m_windowMenu = (wxMenu*) NULL; m_windowMenu = NULL;
} }
if (menu) if (menu)
{ {
m_windowMenu = menu; m_windowMenu = menu;
if (GetMenuBar())
{ AddWindowMenu();
InsertWindowMenu(GetClientWindow(), m_hMenu,
GetHmenuOf(m_windowMenu));
}
} }
} }
@@ -355,8 +407,8 @@ wxMDIChildFrame *wxMDIParentFrame::GetActiveChild() const
WM_MDIGETACTIVE, 0, 0L); WM_MDIGETACTIVE, 0, 0L);
if ( hWnd == 0 ) if ( hWnd == 0 )
return NULL; return NULL;
else
return (wxMDIChildFrame *)wxFindWinFromHandle((WXHWND) hWnd); return (wxMDIChildFrame *)wxFindWinFromHandle(hWnd);
} }
// Create the client window class (don't Create the window, just return a new // Create the client window class (don't Create the window, just return a new
@@ -763,6 +815,8 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
SubclassWin(m_hWnd); SubclassWin(m_hWnd);
parent->AddMDIChild(this);
return true; return true;
} }
@@ -772,6 +826,8 @@ wxMDIChildFrame::~wxMDIChildFrame()
if ( !m_hWnd ) if ( !m_hWnd )
return; return;
GetMDIParent()->RemoveMDIChild(this);
// will be destroyed by DestroyChildren() but reset them before calling it // will be destroyed by DestroyChildren() but reset them before calling it
// to avoid using dangling pointers if a callback comes in the meanwhile // to avoid using dangling pointers if a callback comes in the meanwhile
#if wxUSE_TOOLBAR #if wxUSE_TOOLBAR
@@ -783,7 +839,7 @@ wxMDIChildFrame::~wxMDIChildFrame()
DestroyChildren(); DestroyChildren();
RemoveWindowMenu(NULL, m_hMenu); MDIRemoveWindowMenu(NULL, m_hMenu);
MSWDestroyWindow(); MSWDestroyWindow();
} }
@@ -891,7 +947,7 @@ void wxMDIChildFrame::InternalSetMenuBar()
{ {
wxMDIParentFrame *parent = GetMDIParent(); wxMDIParentFrame *parent = GetMDIParent();
InsertWindowMenu(parent->GetClientWindow(), MDIInsertWindowMenu(parent->GetClientWindow(),
m_hMenu, GetMDIWindowMenu(parent)); m_hMenu, GetMDIWindowMenu(parent));
parent->m_parentFrameActive = false; parent->m_parentFrameActive = false;
@@ -899,7 +955,7 @@ void wxMDIChildFrame::InternalSetMenuBar()
void wxMDIChildFrame::DetachMenuBar() void wxMDIChildFrame::DetachMenuBar()
{ {
RemoveWindowMenu(NULL, m_hMenu); MDIRemoveWindowMenu(NULL, m_hMenu);
wxFrame::DetachMenuBar(); wxFrame::DetachMenuBar();
} }
@@ -1191,8 +1247,8 @@ void wxMDIChildFrame::MSWDestroyWindow()
SendMessage(GetWinHwnd(parent->GetClientWindow()), WM_MDIDESTROY, SendMessage(GetWinHwnd(parent->GetClientWindow()), WM_MDIDESTROY,
(WPARAM)oldHandle, 0); (WPARAM)oldHandle, 0);
if (parent->GetActiveChild() == (wxMDIChildFrame*) NULL) if (parent->GetActiveChild() == NULL)
ResetWindowStyle((void*) NULL); ResetWindowStyle(NULL);
if (m_hMenu) if (m_hMenu)
{ {
@@ -1405,7 +1461,7 @@ static void MDISetMenu(wxWindow *win, HMENU hmenuFrame, HMENU hmenuWindow)
::DrawMenuBar(GetWinHwnd(parent)); ::DrawMenuBar(GetWinHwnd(parent));
} }
static void InsertWindowMenu(wxWindow *win, WXHMENU menu, HMENU subMenu) static void MDIInsertWindowMenu(wxWindow *win, WXHMENU menu, HMENU subMenu)
{ {
// Try to insert Window menu in front of Help, otherwise append it. // Try to insert Window menu in front of Help, otherwise append it.
HMENU hmenu = (HMENU)menu; HMENU hmenu = (HMENU)menu;
@@ -1445,7 +1501,7 @@ static void InsertWindowMenu(wxWindow *win, WXHMENU menu, HMENU subMenu)
MDISetMenu(win, hmenu, subMenu); MDISetMenu(win, hmenu, subMenu);
} }
static void RemoveWindowMenu(wxWindow *win, WXHMENU menu) static void MDIRemoveWindowMenu(wxWindow *win, WXHMENU menu)
{ {
HMENU hMenu = (HMENU)menu; HMENU hMenu = (HMENU)menu;