// constants
// ---------------------------------------------------------------------------
-static const int IDM_WINDOWTILEHOR = 4001;
-static const int IDM_WINDOWCASCADE = 4002;
-static const int IDM_WINDOWICONS = 4003;
-static const int IDM_WINDOWNEXT = 4004;
-static const int IDM_WINDOWTILEVERT = 4005;
-static const int IDM_WINDOWPREV = 4006;
-
// This range gives a maximum of 500 MDI children. Should be enough :-)
static const int wxFIRST_MDI_CHILD = 4100;
static const int wxLAST_MDI_CHILD = 4600;
// Remove the window menu
static void MDIRemoveWindowMenu(wxWindow *win, WXHMENU menu);
-// is this an id of an MDI child?
-inline bool IsMdiCommandId(int id)
-{
- return (id >= wxFIRST_MDI_CHILD) && (id <= wxLAST_MDI_CHILD);
-}
-
// unpack the parameters of WM_MDIACTIVATE message
static void UnpackMDIActivate(WXWPARAM wParam, WXLPARAM lParam,
WXWORD *activate, WXHWND *hwndAct, WXHWND *hwndDeact);
EVT_SIZE(wxMDIParentFrame::OnSize)
EVT_ICONIZE(wxMDIParentFrame::OnIconized)
EVT_SYS_COLOUR_CHANGED(wxMDIParentFrame::OnSysColourChanged)
+
+#if wxUSE_MENUS
+ EVT_MENU_RANGE(wxFIRST_MDI_CHILD, wxLAST_MDI_CHILD,
+ wxMDIParentFrame::OnMDIChild)
+ EVT_MENU_RANGE(wxID_MDI_WINDOW_FIRST, wxID_MDI_WINDOW_LAST,
+ wxMDIParentFrame::OnMDICommand)
+#endif // wxUSE_MENUS
END_EVENT_TABLE()
BEGIN_EVENT_TABLE(wxMDIChildFrame, wxFrame)
// the children
// ===========================================================================
-wxMDIParentFrame::wxMDIParentFrame()
-{
- m_parentFrameActive = true;
-}
-
bool wxMDIParentFrame::Create(wxWindow *parent,
wxWindowID id,
const wxString& title,
// normal case: we have the window menu, so construct it
m_windowMenu = new wxMenu;
- m_windowMenu->Append(IDM_WINDOWCASCADE, _("&Cascade"));
- m_windowMenu->Append(IDM_WINDOWTILEHOR, _("Tile &Horizontally"));
- m_windowMenu->Append(IDM_WINDOWTILEVERT, _("Tile &Vertically"));
+ m_windowMenu->Append(wxID_MDI_WINDOW_CASCADE, _("&Cascade"));
+ m_windowMenu->Append(wxID_MDI_WINDOW_TILE_HORZ, _("Tile &Horizontally"));
+ m_windowMenu->Append(wxID_MDI_WINDOW_TILE_VERT, _("Tile &Vertically"));
m_windowMenu->AppendSeparator();
- m_windowMenu->Append(IDM_WINDOWICONS, _("&Arrange Icons"));
- m_windowMenu->Append(IDM_WINDOWNEXT, _("&Next"));
- m_windowMenu->Append(IDM_WINDOWPREV, _("&Previous"));
+ m_windowMenu->Append(wxID_MDI_WINDOW_ARRANGE_ICONS, _("&Arrange Icons"));
+ m_windowMenu->Append(wxID_MDI_WINDOW_NEXT, _("&Next"));
+ m_windowMenu->Append(wxID_MDI_WINDOW_PREV, _("&Previous"));
}
- m_parentFrameActive = true;
+#if wxUSE_MENUS && wxUSE_ACCEL
+ // the default menu doesn't have any accelerators (even if we have it)
+ m_accelWindowMenu = NULL;
+#endif // wxUSE_MENUS && wxUSE_ACCEL
if (!parent)
wxTopLevelWindows.Append(this);
m_frameStatusBar = NULL;
#endif // wxUSE_STATUSBAR
+#if wxUSE_MENUS && wxUSE_ACCEL
+ delete m_accelWindowMenu;
+#endif // wxUSE_MENUS && wxUSE_ACCEL
+
DestroyChildren();
// the MDI frame menubar is not automatically deleted by Windows unlike for
{
HWND hWnd = (HWND)::SendMessage(GetWinHwnd(GetClientWindow()),
WM_MDIGETACTIVE, 0, 0L);
- if ( hWnd == 0 )
+ if ( !hWnd )
return NULL;
- return (wxMDIChildFrame *)wxFindWinFromHandle(hWnd);
+ return static_cast<wxMDIChildFrame *>(wxFindWinFromHandle(hWnd));
}
int wxMDIParentFrame::GetChildFramesCount() const
{
if ( m_windowMenu )
{
- m_windowMenu->Enable(IDM_WINDOWNEXT, enable);
- m_windowMenu->Enable(IDM_WINDOWPREV, enable);
+ m_windowMenu->Enable(wxID_MDI_WINDOW_NEXT, enable);
+ m_windowMenu->Enable(wxID_MDI_WINDOW_PREV, enable);
}
}
void wxMDIParentFrame::InternalSetMenuBar()
{
- m_parentFrameActive = true;
-
if ( GetActiveChild() )
{
AddWindowMenu();
void wxMDIParentFrame::SetWindowMenu(wxMenu* menu)
{
- // notice that Remove/AddWindowMenu() are safe to call even when
- // m_windowMenu is NULL
- RemoveWindowMenu();
+ if ( menu != m_windowMenu )
+ {
+ // notice that Remove/AddWindowMenu() are safe to call even when
+ // m_windowMenu is NULL
+ RemoveWindowMenu();
+
+ delete m_windowMenu;
+
+ m_windowMenu = menu;
- delete m_windowMenu;
+ AddWindowMenu();
+ }
- m_windowMenu = menu;
+#if wxUSE_ACCEL
+ delete m_accelWindowMenu;
+ m_accelWindowMenu = NULL;
- AddWindowMenu();
+ if ( menu && menu->HasAccels() )
+ m_accelWindowMenu = menu->CreateAccelTable();
+#endif // wxUSE_ACCEL
}
// ----------------------------------------------------------------------------
const wxMenuItem *wxMDIParentFrame::FindItemInMenuBar(int menuId) const
{
const wxMenuItem *item = wxFrame::FindItemInMenuBar(menuId);
- if ( !item && m_currentChild )
+ if ( !item && GetActiveChild() )
{
- item = m_currentChild->FindItemInMenuBar(menuId);
+ item = GetActiveChild()->FindItemInMenuBar(menuId);
}
return item;
// If this window is an MDI parent, we must also send an OnActivate message
// to the current child.
- if ( (m_currentChild != NULL) &&
+ if ( GetActiveChild() &&
((state == WA_ACTIVE) || (state == WA_CLICKACTIVE)) )
{
- wxActivateEvent event(wxEVT_ACTIVATE, true, m_currentChild->GetId());
- event.SetEventObject( m_currentChild );
- if ( m_currentChild->HandleWindowEvent(event) )
+ wxActivateEvent event(wxEVT_ACTIVATE, true, GetActiveChild()->GetId());
+ event.SetEventObject( GetActiveChild() );
+ if ( GetActiveChild()->HandleWindowEvent(event) )
processed = true;
}
return processed;
}
-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_;
+#if wxUSE_MENUS
- // In case it's e.g. a toolbar.
- if ( hwnd )
+void wxMDIParentFrame::OnMDIChild(wxCommandEvent& event)
+{
+ wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
+ while ( node )
{
- wxWindow *win = wxFindWinFromHandle(hwnd);
- if ( win )
- return win->MSWCommand(cmd, id);
- }
+ wxWindow *child = node->GetData();
+ if ( child->GetHWND() )
+ {
+ int childId = wxGetWindowId(child->GetHWND());
+ if ( childId == event.GetId() )
+ {
+ ::SendMessage( GetWinHwnd(GetClientWindow()),
+ WM_MDIACTIVATE,
+ (WPARAM)child->GetHWND(), 0);
+ return;
+ }
+ }
- if (wxCurrentPopupMenu)
- {
- wxMenu *popupMenu = wxCurrentPopupMenu;
- wxCurrentPopupMenu = NULL;
- if (popupMenu->MSWCommand(cmd, id))
- return true;
+ node = node->GetNext();
}
- // is it one of standard MDI commands?
+ wxFAIL_MSG( "unknown MDI child selected?" );
+}
+
+void wxMDIParentFrame::OnMDICommand(wxCommandEvent& event)
+{
WXWPARAM wParam = 0;
WXLPARAM lParam = 0;
int msg;
- switch ( id )
+ switch ( event.GetId() )
{
- case IDM_WINDOWCASCADE:
+ case wxID_MDI_WINDOW_CASCADE:
msg = WM_MDICASCADE;
wParam = MDITILE_SKIPDISABLED;
break;
- case IDM_WINDOWTILEHOR:
+ case wxID_MDI_WINDOW_TILE_HORZ:
wParam |= MDITILE_HORIZONTAL;
// fall through
- case IDM_WINDOWTILEVERT:
+ case wxID_MDI_WINDOW_TILE_VERT:
if ( !wParam )
wParam = MDITILE_VERTICAL;
msg = WM_MDITILE;
wParam |= MDITILE_SKIPDISABLED;
break;
- case IDM_WINDOWICONS:
+ case wxID_MDI_WINDOW_ARRANGE_ICONS:
msg = WM_MDIICONARRANGE;
break;
- case IDM_WINDOWNEXT:
+ case wxID_MDI_WINDOW_NEXT:
msg = WM_MDINEXT;
lParam = 0; // next child
break;
- case IDM_WINDOWPREV:
+ case wxID_MDI_WINDOW_PREV:
msg = WM_MDINEXT;
lParam = 1; // previous child
break;
default:
- msg = 0;
+ wxFAIL_MSG( "unknown MDI command" );
+ return;
}
- if ( msg )
- {
- ::SendMessage(GetWinHwnd(GetClientWindow()), msg, wParam, lParam);
+ ::SendMessage(GetWinHwnd(GetClientWindow()), msg, wParam, lParam);
+}
- return true;
- }
+wxMenuItem *wxMDIParentFrame::MSWFindMenuBarItem(WXWORD id)
+{
+ wxMenuItem *mitem = wxFrame::MSWFindMenuBarItem(id);
+ if ( !mitem && m_windowMenu )
+ mitem = m_windowMenu->FindItem((signed short)id);
- // FIXME VZ: what does this test do??
- if (id >= 0xF000)
- {
- return false; // Get WndProc to call default proc
- }
+ return mitem;
+}
- if ( IsMdiCommandId(id) )
- {
- wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
- while ( node )
- {
- wxWindow *child = node->GetData();
- if ( child->GetHWND() )
- {
- int childId = wxGetWindowId(child->GetHWND());
- if ( childId == (signed short)id )
- {
- ::SendMessage( GetWinHwnd(GetClientWindow()),
- WM_MDIACTIVATE,
- (WPARAM)child->GetHWND(), 0);
- return true;
- }
- }
- node = node->GetNext();
- }
- }
- else if ( m_parentFrameActive )
- {
- return ProcessCommand(id);
- }
- else if ( m_currentChild )
- {
- return m_currentChild->HandleCommand(id, cmd, hwnd);
- }
- else
- {
- // this shouldn't happen because it means that our messages are being
- // lost (they're not sent to the parent frame nor to the children)
- wxFAIL_MSG(wxT("MDI parent frame is not active, yet there is no active MDI child?"));
- }
+#endif // wxUSE_MENUS
- return false;
+bool wxMDIParentFrame::HandleCommand(WXWORD id, WXWORD cmd, WXHWND hwnd)
+{
+ wxMDIChildFrame * const child = GetActiveChild();
+ if ( child && child->HandleCommand(id, cmd, hwnd) )
+ return true;
+
+ return wxFrame::HandleCommand(id, cmd, hwnd);
}
WXLRESULT wxMDIParentFrame::MSWDefWindowProc(WXUINT message,
MSG *pMsg = (MSG *)msg;
// first let the current child get it
- if ( m_currentChild && m_currentChild->GetHWND() &&
- m_currentChild->MSWTranslateMessage(msg) )
+ wxMDIChildFrame * const child = GetActiveChild();
+ if ( child && child->MSWTranslateMessage(msg) )
{
return true;
}
- // then try out accel table (will also check the menu accels)
+ // then try out accelerator table (will also check the accelerators for the
+ // normal menu items)
if ( wxFrame::MSWTranslateMessage(msg) )
{
return true;
}
- // finally, check for MDI specific built in accel keys
+#if wxUSE_MENUS && wxUSE_ACCEL
+ // but it doesn't check for the (custom) accelerators of the window menu
+ // items as it's not part of the menu bar as it's handled by Windows itself
+ // so we need to do this explicitly
+ if ( m_accelWindowMenu->Translate(this, msg) )
+ return true;
+#endif // wxUSE_MENUS && wxUSE_ACCEL
+
+ // finally, check for MDI specific built-in accelerators
if ( pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN )
{
if ( ::TranslateMDISysAccel(GetWinHwnd(GetClientWindow()), pMsg))
MDIInsertWindowMenu(parent->GetClientWindow(),
m_hMenu, GetMDIWindowMenu(parent));
-
- parent->m_parentFrameActive = false;
}
void wxMDIChildFrame::DetachMenuBar()
switch ( message )
{
- case WM_COMMAND:
- {
- WORD id, cmd;
- WXHWND hwnd;
- UnpackCommand((WXWPARAM)wParam, (WXLPARAM)lParam,
- &id, &hwnd, &cmd);
-
- processed = HandleCommand(id, cmd, (WXHWND)hwnd);
- }
- break;
-
case WM_GETMINMAXINFO:
processed = HandleGetMinMaxInfo((MINMAXINFO *)lParam);
break;
return rc;
}
-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 )
- {
- wxWindow *win = wxFindWinFromHandle(hwnd);
- if (win)
- return win->MSWCommand(cmd, id);
- }
-
- if (wxCurrentPopupMenu)
- {
- wxMenu *popupMenu = wxCurrentPopupMenu;
- wxCurrentPopupMenu = NULL;
- if (popupMenu->MSWCommand(cmd, id))
- return true;
- }
-
- bool processed;
- if (GetMenuBar() && GetMenuBar()->FindItem(id))
- {
- processed = ProcessCommand(id);
- }
- else
- {
- processed = false;
- }
-
- return processed;
-}
-
bool wxMDIChildFrame::HandleMDIActivate(long WXUNUSED(activate),
WXHWND hwndAct,
WXHWND hwndDeact)
if ( m_hWnd == hwndAct )
{
activated = true;
- parent->m_currentChild = this;
+ parent->SetActiveChild(this);
WXHMENU hMenuChild = m_hMenu;
if ( hMenuChild )
- {
- parent->m_parentFrameActive = false;
-
hMenuToSet = hMenuChild;
- }
}
else if ( m_hWnd == hwndDeact )
{
- wxASSERT_MSG( parent->m_currentChild == this,
+ wxASSERT_MSG( parent->GetActiveChild() == this,
wxT("can't deactivate MDI child which wasn't active!") );
activated = false;
- parent->m_currentChild = NULL;
+ parent->SetActiveChild(NULL);
WXHMENU hMenuParent = parent->m_hMenu;
// activate the the parent menu only when there is no other child
// that has been activated
if ( hMenuParent && !hwndAct )
- {
- parent->m_parentFrameActive = true;
-
hMenuToSet = hMenuParent;
- }
}
else
{