#include "wx/stockitem.h"
#include "wx/msw/private.h"
-#if wxUSE_STATUSBAR && wxUSE_NATIVE_STATUSBAR
- #include "wx/msw/statbr95.h"
-#endif
-
#include <string.h>
// ---------------------------------------------------------------------------
// insert the window menu (subMenu) into menu just before "Help" submenu or at
// 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
-static void RemoveWindowMenu(wxWindow *win, WXHMENU menu);
+static void MDIRemoveWindowMenu(wxWindow *win, WXHMENU menu);
// is this an id of an MDI child?
inline bool IsMdiCommandId(int id)
WXWORD *activate, WXHWND *hwndAct, WXHWND *hwndDeact);
// 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)
{
wxMenu *menu = frame->GetWindowMenu();
{
m_clientWindow = NULL;
m_currentChild = NULL;
- m_windowMenu = (wxMenu*) NULL;
+ m_windowMenu = NULL;
m_parentFrameActive = true;
}
// "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
{
DestroyChildren();
- if (m_windowMenu)
- {
- delete m_windowMenu;
- m_windowMenu = (wxMenu*) NULL;
- }
+ delete m_windowMenu;
// the MDI frame menubar is not automatically deleted by Windows unlike for
// the normal frames
if ( m_hMenu )
- {
::DestroyMenu((HMENU)m_hMenu);
- m_hMenu = (WXHMENU)NULL;
- }
if ( m_clientWindow )
{
}
}
+// ----------------------------------------------------------------------------
+// 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
void wxMDIParentFrame::InternalSetMenuBar()
{
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
{
if (m_windowMenu)
{
- if (GetMenuBar())
- {
- // Remove old window menu
- RemoveWindowMenu(GetClientWindow(), m_hMenu);
- }
+ RemoveWindowMenu();
delete m_windowMenu;
- m_windowMenu = (wxMenu*) NULL;
+ m_windowMenu = NULL;
}
if (menu)
{
m_windowMenu = menu;
- if (GetMenuBar())
- {
- InsertWindowMenu(GetClientWindow(), m_hMenu,
- GetHmenuOf(m_windowMenu));
- }
+
+ AddWindowMenu();
}
}
{
event.Skip();
- if ( !event.Iconized() )
- {
+ if ( !event.IsIconized() )
UpdateClientSize();
- }
}
// Returns the active MDI child window
WM_MDIGETACTIVE, 0, 0L);
if ( hWnd == 0 )
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
return processed;
}
-bool wxMDIParentFrame::HandleCommand(WXWORD id, WXWORD cmd, WXHWND hwnd)
+bool wxMDIParentFrame::HandleCommand(WXWORD id_, WXWORD cmd, WXHWND hwnd)
{
+ // sign extend to int from short before comparing with the other int ids
+ int id = (signed short)id_;
+
// In case it's e.g. a toolbar.
if ( hwnd )
{
wxWindowCreationHook hook(this);
m_hWnd = (WXHWND)::SendMessage(GetWinHwnd(parent->GetClientWindow()),
- WM_MDICREATE, 0, (LONG)(LPSTR)&mcs);
+ WM_MDICREATE, 0, (LPARAM)&mcs);
if ( !m_hWnd )
{
SubclassWin(m_hWnd);
+ parent->AddMDIChild(this);
+
return true;
}
if ( !m_hWnd )
return;
+ GetMDIParent()->RemoveMDIChild(this);
+
// will be destroyed by DestroyChildren() but reset them before calling it
// to avoid using dangling pointers if a callback comes in the meanwhile
#if wxUSE_TOOLBAR
DestroyChildren();
- RemoveWindowMenu(NULL, m_hMenu);
+ MDIRemoveWindowMenu(NULL, m_hMenu);
MSWDestroyWindow();
}
// we need to refresh the MDI frame window menu to include (or exclude if
// we've been hidden) this frame
- wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
+ wxMDIParentFrame *parent = GetMDIParent();
MDISetMenu(parent->GetClientWindow(), NULL, NULL);
return true;
// If there's an MDI parent, must subtract the parent's top left corner
// since MoveWindow moves relative to the parent
- wxMDIParentFrame *mdiParent = (wxMDIParentFrame *)GetParent();
+ wxMDIParentFrame *mdiParent = GetMDIParent();
::ScreenToClient((HWND) mdiParent->GetClientWindow()->GetHWND(), &point);
MoveWindow(hWnd, point.x, point.y, actual_width, actual_height, (BOOL)true);
// Since we now have the absolute screen coords,
// if there's a parent we must subtract its top left corner
- wxMDIParentFrame *mdiParent = (wxMDIParentFrame *)GetParent();
+ wxMDIParentFrame *mdiParent = GetMDIParent();
::ScreenToClient((HWND) mdiParent->GetClientWindow()->GetHWND(), &point);
if (x)
void wxMDIChildFrame::InternalSetMenuBar()
{
- wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
+ wxMDIParentFrame *parent = GetMDIParent();
- InsertWindowMenu(parent->GetClientWindow(),
+ MDIInsertWindowMenu(parent->GetClientWindow(),
m_hMenu, GetMDIWindowMenu(parent));
parent->m_parentFrameActive = false;
void wxMDIChildFrame::DetachMenuBar()
{
- RemoveWindowMenu(NULL, m_hMenu);
+ MDIRemoveWindowMenu(NULL, m_hMenu);
wxFrame::DetachMenuBar();
}
void wxMDIChildFrame::Maximize(bool maximize)
{
- wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
+ wxMDIParentFrame *parent = GetMDIParent();
if ( parent && parent->GetClientWindow() )
{
::SendMessage(GetWinHwnd(parent->GetClientWindow()),
void wxMDIChildFrame::Restore()
{
- wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
+ wxMDIParentFrame *parent = GetMDIParent();
if ( parent && parent->GetClientWindow() )
{
::SendMessage(GetWinHwnd(parent->GetClientWindow()), WM_MDIRESTORE,
void wxMDIChildFrame::Activate()
{
- wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
+ wxMDIParentFrame *parent = GetMDIParent();
if ( parent && parent->GetClientWindow() )
{
::SendMessage(GetWinHwnd(parent->GetClientWindow()), WM_MDIACTIVATE,
return rc;
}
-bool wxMDIChildFrame::HandleCommand(WXWORD id, WXWORD cmd, WXHWND hwnd)
+bool wxMDIChildFrame::HandleCommand(WXWORD id_, WXWORD cmd, WXHWND hwnd)
{
+ // sign extend to int from short before comparing with the other int ids
+ int id = (signed short)id_;
+
// In case it's e.g. a toolbar.
if ( hwnd )
{
WXHWND hwndAct,
WXHWND hwndDeact)
{
- wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
+ wxMDIParentFrame *parent = GetMDIParent();
HMENU menuToSet = 0;
{
// we must pass the parent frame to ::TranslateAccelerator(), otherwise it
// doesn't do its job correctly for MDI child menus
- return MSWDoTranslateMessage((wxMDIChildFrame *)GetParent(), msg);
+ return MSWDoTranslateMessage(GetMDIParent(), msg);
}
// ---------------------------------------------------------------------------
void wxMDIChildFrame::MSWDestroyWindow()
{
- wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
+ wxMDIParentFrame *parent = GetMDIParent();
// Must make sure this handle is invalidated (set to NULL) since all sorts
// of things could happen after the child client is destroyed, but before
SendMessage(GetWinHwnd(parent->GetClientWindow()), WM_MDIDESTROY,
(WPARAM)oldHandle, 0);
- if (parent->GetActiveChild() == (wxMDIChildFrame*) NULL)
- ResetWindowStyle((void*) NULL);
+ if (parent->GetActiveChild() == NULL)
+ ResetWindowStyle(NULL);
if (m_hMenu)
{
bool wxMDIChildFrame::ResetWindowStyle(void *vrect)
{
RECT *rect = (RECT *)vrect;
- wxMDIParentFrame* pFrameWnd = (wxMDIParentFrame *)GetParent();
+ wxMDIParentFrame* pFrameWnd = GetMDIParent();
wxMDIChildFrame* pChild = pFrameWnd->GetActiveChild();
if (!pChild || (pChild == this))
::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.
HMENU hmenu = (HMENU)menu;
{
success = true;
::InsertMenu(hmenu, i, MF_BYPOSITION | MF_POPUP | MF_STRING,
- (UINT)subMenu, _("&Window").wx_str());
+ (UINT_PTR)subMenu, _("&Window").wx_str());
break;
}
}
if ( !success )
{
- ::AppendMenu(hmenu, MF_POPUP, (UINT)subMenu, _("&Window").wx_str());
+ ::AppendMenu(hmenu, MF_POPUP,
+ (UINT_PTR)subMenu, _("&Window").wx_str());
}
}
MDISetMenu(win, hmenu, subMenu);
}
-static void RemoveWindowMenu(wxWindow *win, WXHMENU menu)
+static void MDIRemoveWindowMenu(wxWindow *win, WXHMENU menu)
{
HMENU hMenu = (HMENU)menu;