X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/838e6ed707632e9647ef5e463efb9499f82374b8..96c9640205933ad0673d5af2c96af0816c50160c:/src/msw/mdi.cpp?ds=sidebyside diff --git a/src/msw/mdi.cpp b/src/msw/mdi.cpp index af398a3de6..dd19650db6 100644 --- a/src/msw/mdi.cpp +++ b/src/msw/mdi.cpp @@ -138,6 +138,14 @@ END_EVENT_TABLE() // the children // =========================================================================== +void wxMDIParentFrame::Init() +{ +#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 +} + bool wxMDIParentFrame::Create(wxWindow *parent, wxWindowID id, const wxString& title, @@ -162,11 +170,6 @@ bool wxMDIParentFrame::Create(wxWindow *parent, m_windowMenu->Append(wxID_MDI_WINDOW_PREV, _("&Previous")); } -#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); @@ -186,7 +189,7 @@ bool wxMDIParentFrame::Create(wxWindow *parent, msflags &= ~WS_VSCROLL; msflags &= ~WS_HSCROLL; - if ( !wxWindow::MSWCreate(wxApp::GetRegisteredClassName(_T("wxMDIFrame")), + if ( !wxWindow::MSWCreate(wxApp::GetRegisteredClassName(wxT("wxMDIFrame")), title.wx_str(), pos, size, msflags, @@ -314,13 +317,23 @@ void wxMDIParentFrame::RemoveMDIChild(wxMDIChildFrame * WXUNUSED(child)) void wxMDIParentFrame::AddWindowMenu() { if ( m_windowMenu ) + { + // For correct handling of the events from this menu we also must + // attach it to the menu bar. + m_windowMenu->Attach(GetMenuBar()); + MDIInsertWindowMenu(GetClientWindow(), m_hMenu, GetMDIWindowMenu(this)); + } } void wxMDIParentFrame::RemoveWindowMenu() { if ( m_windowMenu ) + { MDIRemoveWindowMenu(GetClientWindow(), m_hMenu); + + m_windowMenu->Detach(); + } } void wxMDIParentFrame::UpdateWindowMenu(bool enable) @@ -366,8 +379,7 @@ void wxMDIParentFrame::SetWindowMenu(wxMenu* menu) } #if wxUSE_ACCEL - delete m_accelWindowMenu; - m_accelWindowMenu = NULL; + wxDELETE(m_accelWindowMenu); if ( menu && menu->HasAccels() ) m_accelWindowMenu = menu->CreateAccelTable(); @@ -406,14 +418,17 @@ void wxMDIParentFrame::DoMenuUpdates(wxMenu* menu) } } -const wxMenuItem *wxMDIParentFrame::FindItemInMenuBar(int menuId) const +wxMenuItem *wxMDIParentFrame::FindItemInMenuBar(int menuId) const { - const wxMenuItem *item = wxFrame::FindItemInMenuBar(menuId); + wxMenuItem *item = wxFrame::FindItemInMenuBar(menuId); if ( !item && GetActiveChild() ) { item = GetActiveChild()->FindItemInMenuBar(menuId); } + if ( !item && m_windowMenu ) + item = m_windowMenu->FindItem(menuId); + return item; } @@ -492,7 +507,7 @@ void wxMDIParentFrame::Cascade() void wxMDIParentFrame::Tile(wxOrientation orient) { wxASSERT_MSG( orient == wxHORIZONTAL || orient == wxVERTICAL, - _T("invalid orientation value") ); + wxT("invalid orientation value") ); ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDITILE, orient == wxHORIZONTAL ? MDITILE_HORIZONTAL @@ -519,8 +534,8 @@ void wxMDIParentFrame::ActivatePrevious() // --------------------------------------------------------------------------- WXLRESULT wxMDIParentFrame::MSWWindowProc(WXUINT message, - WXWPARAM wParam, - WXLPARAM lParam) + WXWPARAM wParam, + WXLPARAM lParam) { WXLRESULT rc = 0; bool processed = false; @@ -538,22 +553,22 @@ WXLRESULT wxMDIParentFrame::MSWWindowProc(WXUINT message, break; case WM_COMMAND: + // system messages such as SC_CLOSE are sent as WM_COMMANDs to the + // parent MDI frame and we must let the DefFrameProc() have them + // for these commands to work (without it, closing the maximized + // MDI children doesn't work, for example) { WXWORD id, cmd; WXHWND hwnd; UnpackCommand(wParam, lParam, &id, &hwnd, &cmd); - (void)HandleCommand(id, cmd, hwnd); - - // even if the frame didn't process it, there is no need to try it - // once again (i.e. call wxFrame::HandleCommand()) - we just did it, - // so pretend we processed the message anyhow - processed = true; + if ( cmd == 0 /* menu */ && + id >= SC_SIZE /* first system menu command */ ) + { + MSWDefWindowProc(message, wParam, lParam); + processed = true; + } } - - // always pass this message DefFrameProc(), otherwise MDI menu - // commands (and sys commands - more surprisingly!) won't work - MSWDefWindowProc(message, wParam, lParam); break; case WM_CREATE: @@ -568,18 +583,6 @@ WXLRESULT wxMDIParentFrame::MSWWindowProc(WXUINT message, processed = true; break; - - case WM_ERASEBKGND: - processed = true; - - // we erase background ourselves - rc = true; - break; - - case WM_SIZE: - // though we don't (usually) resize the MDI client to exactly fit the - // client area we need to pass this one to DefFrameProc to allow the children to show - break; } if ( !processed ) @@ -683,24 +686,20 @@ void wxMDIParentFrame::OnMDICommand(wxCommandEvent& event) ::SendMessage(GetWinHwnd(GetClientWindow()), msg, wParam, lParam); } -wxMenuItem *wxMDIParentFrame::MSWFindMenuBarItem(WXWORD id) -{ - wxMenuItem *mitem = wxFrame::MSWFindMenuBarItem(id); - if ( !mitem && m_windowMenu ) - mitem = m_windowMenu->FindItem((signed short)id); - - return mitem; -} - #endif // wxUSE_MENUS -bool wxMDIParentFrame::HandleCommand(WXWORD id, WXWORD cmd, WXHWND hwnd) +bool wxMDIParentFrame::TryBefore(wxEvent& event) { - wxMDIChildFrame * const child = GetActiveChild(); - if ( child && child->HandleCommand(id, cmd, hwnd) ) - return true; + // menu (and toolbar) events should be sent to the active child frame + // first, if any + if ( event.GetEventType() == wxEVT_COMMAND_MENU_SELECTED ) + { + wxMDIChildFrame * const child = GetActiveChild(); + if ( child && child->ProcessWindowEventLocally(event) ) + return true; + } - return wxFrame::HandleCommand(id, cmd, hwnd); + return wxMDIParentFrameBase::TryBefore(event); } WXLRESULT wxMDIParentFrame::MSWDefWindowProc(WXUINT message, @@ -738,7 +737,7 @@ bool wxMDIParentFrame::MSWTranslateMessage(WXMSG* msg) // 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) ) + if ( m_accelWindowMenu && m_accelWindowMenu->Translate(this, msg) ) return true; #endif // wxUSE_MENUS && wxUSE_ACCEL @@ -792,7 +791,7 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent, MDICREATESTRUCT mcs; wxString className = - wxApp::GetRegisteredClassName(_T("wxMDIChildFrame"), COLOR_WINDOW); + wxApp::GetRegisteredClassName(wxT("wxMDIChildFrame"), COLOR_WINDOW); if ( !(style & wxFULL_REPAINT_ON_RESIZE) ) className += wxApp::GetNoRedrawClassSuffix(); @@ -846,7 +845,7 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent, if ( !m_hWnd ) { - wxLogLastError(_T("WM_MDICREATE")); + wxLogLastError(wxT("WM_MDICREATE")); return false; } @@ -902,6 +901,14 @@ bool wxMDIChildFrame::Show(bool show) return true; } +void +wxMDIChildFrame::DoSetSize(int x, int y, int width, int height, int sizeFlags) +{ + // we need to disable client area origin adjustments used for the child + // windows for the frame itself + wxMDIChildFrameBase::DoSetSize(x, y, width, height, sizeFlags); +} + // Set the client size (i.e. leave the calculation of borders etc. // to wxWidgets) void wxMDIChildFrame::DoSetClientSize(int width, int height) @@ -1040,8 +1047,8 @@ void wxMDIChildFrame::Activate() // --------------------------------------------------------------------------- WXLRESULT wxMDIChildFrame::MSWWindowProc(WXUINT message, - WXWPARAM wParam, - WXLPARAM lParam) + WXWPARAM wParam, + WXLPARAM lParam) { WXLRESULT rc = 0; bool processed = false; @@ -1074,11 +1081,6 @@ WXLRESULT wxMDIChildFrame::MSWWindowProc(WXUINT message, MSWDefWindowProc(message, wParam, lParam); break; - case WM_SYSCOMMAND: - // DefMDIChildProc handles SC_{NEXT/PREV}WINDOW here, so pass it - // the message (the base class version does not) - return MSWDefWindowProc(message, wParam, lParam); - case WM_WINDOWPOSCHANGING: processed = HandleWindowPosChanging((LPWINDOWPOS)lParam); break; @@ -1119,7 +1121,7 @@ bool wxMDIChildFrame::HandleMDIActivate(long WXUNUSED(activate), WXHMENU hMenuParent = parent->m_hMenu; - // activate the the parent menu only when there is no other child + // activate the parent menu only when there is no other child // that has been activated if ( hMenuParent && !hwndAct ) hMenuToSet = hMenuParent; @@ -1429,11 +1431,11 @@ void MDISetMenu(wxWindow *win, HMENU hmenuFrame, HMENU hmenuWindow) (WPARAM)hmenuFrame, (LPARAM)hmenuWindow) ) { -#ifdef __WXDEBUG__ DWORD err = ::GetLastError(); if ( err ) - wxLogApiError(_T("SendMessage(WM_MDISETMENU)"), err); -#endif // __WXDEBUG__ + { + wxLogApiError(wxT("SendMessage(WM_MDISETMENU)"), err); + } } } @@ -1471,7 +1473,7 @@ void MDIInsertWindowMenu(wxWindow *win, WXHMENU hMenu, HMENU menuWin) inserted = true; ::InsertMenu(hmenu, i, MF_BYPOSITION | MF_POPUP | MF_STRING, (UINT_PTR)menuWin, - wxGetTranslation(WINDOW_MENU_LABEL).wx_str()); + wxString(wxGetTranslation(WINDOW_MENU_LABEL)).wx_str()); break; } } @@ -1480,7 +1482,7 @@ void MDIInsertWindowMenu(wxWindow *win, WXHMENU hMenu, HMENU menuWin) { ::AppendMenu(hmenu, MF_POPUP, (UINT_PTR)menuWin, - wxGetTranslation(WINDOW_MENU_LABEL).wx_str()); + wxString(wxGetTranslation(WINDOW_MENU_LABEL)).wx_str()); } }