X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/8efbb8ad3005aee070d6e8da5729b50efa02afe5..b512ed93206f70d502c52df705cad47c3ba2cc7f:/src/msw/frame.cpp diff --git a/src/msw/frame.cpp b/src/msw/frame.cpp index 4cba8083e1..33b6df22bb 100644 --- a/src/msw/frame.cpp +++ b/src/msw/frame.cpp @@ -209,7 +209,8 @@ bool wxFrame::Create(wxWindow *parent, wxFrame::~wxFrame() { - m_isBeingDeleted = true; + SendDestroyEvent(); + DeleteAllBars(); } @@ -310,15 +311,24 @@ void wxFrame::Raise() } // generate an artificial resize event -void wxFrame::SendSizeEvent() +void wxFrame::SendSizeEvent(int flags) { if ( !m_iconized ) { RECT r = wxGetWindowRect(GetHwnd()); - (void)::PostMessage(GetHwnd(), WM_SIZE, - IsMaximized() ? SIZE_MAXIMIZED : SIZE_RESTORED, - MAKELPARAM(r.right - r.left, r.bottom - r.top)); + if ( flags & wxSEND_EVENT_POST ) + { + ::PostMessage(GetHwnd(), WM_SIZE, + IsMaximized() ? SIZE_MAXIMIZED : SIZE_RESTORED, + MAKELPARAM(r.right - r.left, r.bottom - r.top)); + } + else // send it + { + ::SendMessage(GetHwnd(), WM_SIZE, + IsMaximized() ? SIZE_MAXIMIZED : SIZE_RESTORED, + MAKELPARAM(r.right - r.left, r.bottom - r.top)); + } } } @@ -398,7 +408,7 @@ void wxFrame::AttachMenuBar(wxMenuBar *menubar) if( menubar->GetMenuCount() == 1 ) { autoMenu = wxTopLevelWindowMSW::ButtonMenu::DuplicateMenu(menubar->GetMenu(0)); - SetRightMenu(wxID_ANY, menubar->GetLabelTop(0), autoMenu); + SetRightMenu(wxID_ANY, menubar->GetMenuLabel(0), autoMenu); } else { @@ -407,7 +417,7 @@ void wxFrame::AttachMenuBar(wxMenuBar *menubar) for( size_t n = 0; n < menubar->GetMenuCount(); n++ ) { wxMenu *item = menubar->GetMenu(n); - wxString label = menubar->GetLabelTop(n); + wxString label = menubar->GetMenuLabel(n); wxMenu *new_item = wxTopLevelWindowMSW::ButtonMenu::DuplicateMenu(item); autoMenu->Append(wxID_ANY, label, new_item); } @@ -425,19 +435,23 @@ void wxFrame::AttachMenuBar(wxMenuBar *menubar) SetToolBar(toolBar); menubar->SetToolBar(toolBar); } - // Now adjust size for menu bar - int menuHeight = 26; - //When the main window is created using CW_USEDEFAULT the height of the - // is created is not taken into account). So we resize the window after - // if a menubar is present + // When the main window is created using CW_USEDEFAULT the height of the + // menubar is not taken into account, so we resize it afterwards if a + // menubar is present + HWND hwndMenuBar = SHFindMenuBar(GetHwnd()); + if ( hwndMenuBar ) { + RECT mbRect; + ::GetWindowRect(hwndMenuBar, &mbRect); + const int menuHeight = mbRect.bottom - mbRect.top; + RECT rc; - ::GetWindowRect((HWND) GetHWND(), &rc); + ::GetWindowRect(GetHwnd(), &rc); // adjust for menu / titlebar height rc.bottom -= (2*menuHeight-1); - ::MoveWindow((HWND) GetHWND(), rc.left, rc.top, rc.right, rc.bottom, FALSE); + ::MoveWindow(Gethwnd(), rc.left, rc.top, rc.right, rc.bottom, FALSE); } #endif @@ -497,7 +511,7 @@ void wxFrame::OnSysColourChanged(wxSysColourChangedEvent& event) { wxSysColourChangedEvent event2; event2.SetEventObject( m_frameStatusBar ); - m_frameStatusBar->GetEventHandler()->ProcessEvent(event2); + m_frameStatusBar->HandleWindowEvent(event2); } #endif // wxUSE_STATUSBAR @@ -563,27 +577,14 @@ bool wxFrame::ShowFullScreen(bool show, long style) } #endif // wxUSE_TOOLBAR +#if wxUSE_MENUS if (m_fsStyle & wxFULLSCREEN_NOMENUBAR) { - WXHMENU menu = m_hMenu; - -#if wxUSE_MDI_ARCHITECTURE - wxMDIParentFrame *frame = wxDynamicCast(this, wxMDIParentFrame); - if (frame) - { - wxMDIChildFrame *child = frame->GetActiveChild(); - if (child) - { - menu = child->GetWinMenu(); - } - } -#endif // wxUSE_MDI_ARCHITECTURE - - if (menu) - { - ::SetMenu(GetHwnd(), (HMENU)menu); - } + const WXHMENU hmenu = MSWGetActiveMenu(); + if ( hmenu ) + ::SetMenu(GetHwnd(), (HMENU)hmenu); } +#endif // wxUSE_MENUS #if wxUSE_STATUSBAR wxStatusBar *theStatusBar = GetStatusBar(); @@ -623,16 +624,13 @@ wxToolBar* wxFrame::CreateToolBar(long style, wxWindowID id, const wxString& nam void wxFrame::PositionToolBar() { - int x = 0, y = 0; + // TODO: we want to do something different in WinCE, because the toolbar + // should be associated with the commandbar, instead of being + // independent window. +#if !defined(WINCE_WITHOUT_COMMANDBAR) wxToolBar *toolbar = GetToolBar(); if ( toolbar && toolbar->IsShown() ) { -#if defined(WINCE_WITHOUT_COMMANDBAR) - // We want to do something different in WinCE, because - // the toolbar should be associated with the commandbar, - // and not an independent window. - // TODO -#else // don't call our (or even wxTopLevelWindow) version because we want // the real (full) client area size, not excluding the tool/status bar int width, height; @@ -650,6 +648,7 @@ void wxFrame::PositionToolBar() toolbar->GetPosition( &tx, &ty ); toolbar->GetSize( &tw, &th ); + int x, y; if ( toolbar->HasFlag(wxTB_BOTTOM) ) { x = 0; @@ -742,8 +741,8 @@ void wxFrame::PositionToolBar() if (tx != 0 || ty != 0 || widthChanging || heightChanging) toolbar->SetSize(x, y, desiredW, desiredH, wxSIZE_NO_ADJUSTMENTS); -#endif // __WXWINCE__ } +#endif // !WINCE_WITH_COMMANDBAR } #endif // wxUSE_TOOLBAR @@ -819,13 +818,10 @@ bool wxFrame::MSWDoTranslateMessage(wxFrame *frame, WXMSG *pMsg) return true; #if wxUSE_MENUS && wxUSE_ACCEL && !defined(__WXUNIVERSAL__) - // try the menu bar accels + // try the menu bar accelerators wxMenuBar *menuBar = GetMenuBar(); - if ( menuBar ) - { - const wxAcceleratorTable& acceleratorTable = menuBar->GetAccelTable(); - return acceleratorTable.Translate(frame, pMsg); - } + if ( menuBar && menuBar->GetAcceleratorTable()->Translate(frame, pMsg) ) + return true; #endif // wxUSE_MENUS && wxUSE_ACCEL return false; @@ -835,58 +831,6 @@ bool wxFrame::MSWDoTranslateMessage(wxFrame *frame, WXMSG *pMsg) // our private (non virtual) message handlers // --------------------------------------------------------------------------- -bool wxFrame::HandlePaint() -{ - RECT rect; - if ( ::GetUpdateRect(GetHwnd(), &rect, FALSE) ) - { -#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__) - if ( m_iconized ) - { - const wxIcon& icon = GetIcon(); - HICON hIcon = icon.Ok() ? GetHiconOf(icon) - : (HICON)GetDefaultIcon(); - - // Hold a pointer to the dc so long as the OnPaint() message - // is being processed - PAINTSTRUCT ps; - HDC hdc = ::BeginPaint(GetHwnd(), &ps); - - // Erase background before painting or we get white background - MSWDefWindowProc(WM_ICONERASEBKGND, (WORD)(LONG)ps.hdc, 0L); - - if ( hIcon ) - { - RECT rect; - ::GetClientRect(GetHwnd(), &rect); - - // FIXME: why hardcoded? - static const int icon_width = 32; - static const int icon_height = 32; - - int icon_x = (int)((rect.right - icon_width)/2); - int icon_y = (int)((rect.bottom - icon_height)/2); - - ::DrawIcon(hdc, icon_x, icon_y, hIcon); - } - - ::EndPaint(GetHwnd(), &ps); - - return true; - } - else - #endif - { - return wxWindow::HandlePaint(); - } - } - else - { - // nothing to paint - processed - return true; - } -} - bool wxFrame::HandleSize(int WXUNUSED(x), int WXUNUSED(y), WXUINT id) { #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__) @@ -948,73 +892,49 @@ bool wxFrame::HandleSize(int WXUNUSED(x), int WXUNUSED(y), WXUINT id) bool wxFrame::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control) { - if ( control ) - { - // In case it's e.g. a toolbar. - wxWindow *win = wxFindWinFromHandle(control); - if ( win ) - return win->MSWCommand(cmd, id); - } - - // handle here commands from menus and accelerators - if ( cmd == 0 || cmd == 1 ) +#if wxUSE_MENUS + // we only need to handle the menu and accelerator commands from the items + // of our menu bar, base wxWindow class already handles the rest + if ( !control && (cmd == 0 /* menu */ || cmd == 1 /* accel */) ) { #if wxUSE_MENUS_NATIVE - if ( wxCurrentPopupMenu ) - { - wxMenu *popupMenu = wxCurrentPopupMenu; - wxCurrentPopupMenu = NULL; - - return popupMenu->MSWCommand(cmd, id); - } + if ( !wxCurrentPopupMenu ) #endif // wxUSE_MENUS_NATIVE - -#if defined(__SMARTPHONE__) && defined(__WXWINCE__) - // handle here commands from Smartphone menu bar - if ( wxTopLevelWindow::HandleCommand(id, cmd, control ) ) - { - return true; - } -#endif // __SMARTPHONE__ && __WXWINCE__ - - if ( ProcessCommand(id) ) { - return true; + wxMenuItem * const mitem = FindItemInMenuBar((signed short)id); + if ( mitem ) + return ProcessCommand(mitem); } } +#endif // wxUSE_MENUS - return false; + return wxFrameBase::HandleCommand(id, cmd, control);; } -bool wxFrame::HandleMenuSelect(WXWORD nItem, WXWORD flags, WXHMENU hMenu) -{ - int item; - if ( flags == 0xFFFF && hMenu == 0 ) - { - // menu was removed from screen - item = -1; - } -#ifndef __WXMICROWIN__ - else if ( !(flags & MF_POPUP) && !(flags & MF_SEPARATOR) ) - { - item = nItem; - } -#endif - else - { - // don't give hints for separators (doesn't make sense) nor for the - // items opening popup menus (they don't have them anyhow) but do clear - // the status line - otherwise, we would be left with the help message - // for the previous item which doesn't apply any more - DoGiveHelp(wxEmptyString, false); +#if wxUSE_MENUS - return false; - } +bool +wxFrame::HandleMenuSelect(WXWORD nItem, WXWORD flags, WXHMENU WXUNUSED(hMenu)) +{ + // WM_MENUSELECT is generated for both normal items and menus, including + // the top level menus of the menu bar, which can't be represented using + // any valid identifier in wxMenuEvent so use -1 for them + // the menu highlight events for n + const int item = flags & (MF_POPUP | MF_SEPARATOR) ? -1 : nItem; wxMenuEvent event(wxEVT_MENU_HIGHLIGHT, item); event.SetEventObject(this); - return GetEventHandler()->ProcessEvent(event); + if ( HandleWindowEvent(event) ) + return true; + + // by default, i.e. if the event wasn't handled above, clear the status bar + // text when an item which can't have any associated help string in wx API + // is selected + if ( item == -1 ) + DoGiveHelp(wxEmptyString, true); + + return false; } bool wxFrame::HandleMenuLoop(const wxEventType& evtType, WXWORD isPopup) @@ -1024,9 +944,33 @@ bool wxFrame::HandleMenuLoop(const wxEventType& evtType, WXWORD isPopup) wxMenuEvent event(evtType, isPopup ? -1 : 0); event.SetEventObject(this); - return GetEventHandler()->ProcessEvent(event); + return HandleWindowEvent(event); } +bool wxFrame::HandleInitMenuPopup(WXHMENU hMenu) +{ + wxMenu* menu = NULL; + if (GetMenuBar()) + { + int nCount = GetMenuBar()->GetMenuCount(); + for (int n = 0; n < nCount; n++) + { + if (GetMenuBar()->GetMenu(n)->GetHMenu() == hMenu) + { + menu = GetMenuBar()->GetMenu(n); + break; + } + } + } + + wxMenuEvent event(wxEVT_MENU_OPEN, 0, menu); + event.SetEventObject(this); + + return HandleWindowEvent(event); +} + +#endif // wxUSE_MENUS + // --------------------------------------------------------------------------- // the window proc for wxFrame // --------------------------------------------------------------------------- @@ -1055,19 +999,23 @@ WXLRESULT wxFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lPara UnpackCommand((WXWPARAM)wParam, (WXLPARAM)lParam, &id, &hwnd, &cmd); - processed = HandleCommand(id, cmd, (WXHWND)hwnd); - } - break; + HandleCommand(id, cmd, (WXHWND)hwnd); - case WM_PAINT: - processed = HandlePaint(); + // don't pass WM_COMMAND to the base class whether we processed + // it or not because we did generate an event for it (our + // HandleCommand() calls the base class version) and we must + // not do it again or the handlers which skip the event would + // be called twice + processed = true; + } break; +#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__) +#if wxUSE_MENUS case WM_INITMENUPOPUP: processed = HandleInitMenuPopup((WXHMENU) wParam); break; -#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__) case WM_MENUSELECT: { WXWORD item, flags; @@ -1081,13 +1029,14 @@ WXLRESULT wxFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lPara case WM_EXITMENULOOP: processed = HandleMenuLoop(wxEVT_MENU_CLOSE, (WXWORD)wParam); break; +#endif // wxUSE_MENUS case WM_QUERYDRAGICON: { const wxIcon& icon = GetIcon(); HICON hIcon = icon.Ok() ? GetHiconOf(icon) : (HICON)GetDefaultIcon(); - rc = (long)hIcon; + rc = (WXLRESULT)hIcon; processed = rc != 0; } break; @@ -1100,29 +1049,6 @@ WXLRESULT wxFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lPara return rc; } -// handle WM_INITMENUPOPUP message -bool wxFrame::HandleInitMenuPopup(WXHMENU hMenu) -{ - wxMenu* menu = NULL; - if (GetMenuBar()) - { - int nCount = GetMenuBar()->GetMenuCount(); - for (int n = 0; n < nCount; n++) - { - if (GetMenuBar()->GetMenu(n)->GetHMenu() == hMenu) - { - menu = GetMenuBar()->GetMenu(n); - break; - } - } - } - - wxMenuEvent event(wxEVT_MENU_OPEN, 0, menu); - event.SetEventObject(this); - - return GetEventHandler()->ProcessEvent(event); -} - // ---------------------------------------------------------------------------- // wxFrame size management: we exclude the areas taken by menu/status/toolbars // from the client area, so the client area is what's really available for the