From a8cfd0cbf1899a3a41fe21a202d40f5448702b5a Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 26 Oct 1999 19:35:25 +0000 Subject: [PATCH] wxMenuBarBase for MSW (untested) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4205 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/msw/menu.h | 77 ++++++---------- include/wx/msw/menuitem.h | 2 +- src/msw/menu.cpp | 182 ++++++++++++++------------------------ src/msw/menuitem.cpp | 4 +- 4 files changed, 95 insertions(+), 170 deletions(-) diff --git a/include/wx/msw/menu.h b/include/wx/msw/menu.h index e8fed5225a..4c4ecc8640 100644 --- a/include/wx/msw/menu.h +++ b/include/wx/msw/menu.h @@ -197,10 +197,8 @@ private: // Menu Bar (a la Windows) // ---------------------------------------------------------------------------- -class WXDLLEXPORT wxMenuBar : public wxEvtHandler +class WXDLLEXPORT wxMenuBar : public wxMenuBarBase { - DECLARE_DYNAMIC_CLASS(wxMenuBar) - public: // ctors & dtor // default constructor @@ -212,66 +210,38 @@ public: virtual ~wxMenuBar(); // menubar construction - WXHMENU Create(); - void Append(wxMenu *menu, const wxString& title); - void Insert(int pos, wxMenu * menu, const wxString& title); - void ReplaceMenu(int pos, wxMenu * new_menu, const wxString& title); - int FindMenu(const wxString& title); - void Detach(); - virtual void Delete(wxMenu *menu, int index = 0); /* Menu not destroyed */ + virtual bool Append( wxMenu *menu, const wxString &title ); + virtual bool Insert(size_t pos, wxMenu *menu, const wxString& title); + virtual wxMenu *Replace(size_t pos, wxMenu *menu, const wxString& title); + virtual wxMenu *Remove(size_t pos); - // state control - // NB: must only be used AFTER menu has been attached to frame, - // otherwise use individual menus to enable/disable items - // enable the item - void Enable(int id, bool enable); - // TRUE if item enabled - bool IsEnabled(int id) const; - // - void EnableTop(int pos, bool enable); - - // works only with checkable items - void Check(int id, bool check); - // TRUE if checked - bool IsChecked(int id) const; - - void SetLabel(int id, const wxString& label) ; - wxString GetLabel(int id) const ; - - virtual void SetHelpString(int id, const wxString& helpString); - virtual wxString GetHelpString(int id) const ; + virtual int FindMenuItem(const wxString& menuString, + const wxString& itemString) const; + virtual wxMenuItem* FindItem( int id, wxMenu **menu = NULL ) const; - void SetLabelTop(int pos, const wxString& label) ; - wxString GetLabelTop(int pos) const ; + virtual void EnableTop( size_t pos, bool flag ); + virtual void SetLabelTop( size_t pos, const wxString& label ); + virtual wxString GetLabelTop( size_t pos ) const; // notifications: return FALSE to prevent the menu from being // appended/deleted virtual bool OnAppend(wxMenu *menu, const wxChar *title); virtual bool OnDelete(wxMenu *menu, int index); - // item search - // by menu and item names, returns wxNOT_FOUND if not found - virtual int FindMenuItem(const wxString& menuString, - const wxString& itemString) const; - // returns NULL if not found - wxMenuItem* FindItem(int id) const { return FindItemForId(id); } - // returns NULL if not found, fills menuForItem if !NULL - wxMenuItem *FindItemForId(int itemId, wxMenu **menuForItem = NULL) const; - - // submenus access - int GetMenuCount() const { return m_menuCount; } - wxMenu *GetMenu(int i) const { return m_menus[i]; } - + // compatibility: these functions are deprecated +#ifdef WXWIN_COMPATIBILITY void SetEventHandler(wxEvtHandler *handler) { m_eventHandler = handler; } wxEvtHandler *GetEventHandler() { return m_eventHandler; } -#ifdef WXWIN_COMPATIBILITY - // compatibility: these functions are deprecated bool Enabled(int id) const { return IsEnabled(id); } bool Checked(int id) const { return IsChecked(id); } #endif // WXWIN_COMPATIBILITY - // IMPLEMENTATION + // implementation from now on + WXHMENU Create(); + int FindMenu(const wxString& title); + void Detach(); + // returns TRUE if we're attached to a frame bool IsAttached() const { return m_menuBarFrame != NULL; } // get the frame we live in @@ -295,10 +265,12 @@ protected: // common part of all ctors void Init(); +#ifdef WXWIN_COMPATIBILITY wxEvtHandler *m_eventHandler; - int m_menuCount; - wxMenu **m_menus; - wxString *m_titles; +#endif // WXWIN_COMPATIBILITY + + wxArrayString m_titles; + wxFrame *m_menuBarFrame; WXHMENU m_hMenu; @@ -306,6 +278,9 @@ protected: // the accelerator table for all accelerators in all our menus wxAcceleratorTable m_accelTable; #endif // wxUSE_ACCEL + +private: + DECLARE_DYNAMIC_CLASS(wxMenuBar) }; #endif // _WX_MENU_H_ diff --git a/include/wx/msw/menuitem.h b/include/wx/msw/menuitem.h index eaced8f990..e07225ee6a 100644 --- a/include/wx/msw/menuitem.h +++ b/include/wx/msw/menuitem.h @@ -49,7 +49,7 @@ public: virtual void Enable(bool bDoEnable = TRUE); virtual void Check(bool bDoCheck = TRUE); - virtual void IsChecked() const; + virtual bool IsChecked() const; // unfortunately needed to resolve ambiguity between // wxMenuItemBase::IsCheckable() and wxOwnerDrawn::IsCheckable() diff --git a/src/msw/menu.cpp b/src/msw/menu.cpp index 887bccd4e2..46437db55e 100644 --- a/src/msw/menu.cpp +++ b/src/msw/menu.cpp @@ -585,8 +585,6 @@ void wxMenu::Detach() void wxMenuBar::Init() { m_eventHandler = this; - m_menuCount = 0; - m_menus = NULL; m_titles = NULL; m_menuBarFrame = NULL; m_hMenu = 0; @@ -606,27 +604,19 @@ wxMenuBar::wxMenuBar(int count, wxMenu *menus[], const wxString titles[]) { Init(); - m_menuCount = count; - m_menus = menus; - m_titles = new wxString[count]; + m_titles.Alloc(count); - int i; - for ( i = 0; i < count; i++ ) - m_titles[i] = titles[i]; + for ( int i = 0; i < count; i++ ) + { + m_menus.Append(menus[i]); + m_titles.Add(titles[i]); - for ( i = 0; i < count; i++ ) - m_menus[i]->Attach(this); + menus[i]->Attach(this); + } } wxMenuBar::~wxMenuBar() { - for ( int i = 0; i < m_menuCount; i++ ) - { - delete m_menus[i]; - } - - delete[] m_menus; - delete[] m_titles; } // --------------------------------------------------------------------------- @@ -655,7 +645,8 @@ WXHMENU wxMenuBar::Create() } else { - for ( int i = 0; i < m_menuCount; i++ ) + size_t count = GetMenuCount(); + for ( size_t i = 0; i < count; i++ ) { if ( !::AppendMenu((HMENU)m_hMenu, MF_POPUP | MF_STRING, (UINT)m_menus[i]->GetHMenu(), @@ -676,7 +667,7 @@ WXHMENU wxMenuBar::Create() // NB: we don't support owner drawn top level items for now, if we do these // functions would have to be changed to use wxMenuItem as well -void wxMenuBar::EnableTop(int pos, bool enable) +void wxMenuBar::EnableTop(size_t pos, bool enable) { int flag = enable ? MF_ENABLED : MF_GRAYED;; @@ -685,7 +676,7 @@ void wxMenuBar::EnableTop(int pos, bool enable) Refresh(); } -void wxMenuBar::SetLabelTop(int pos, const wxString& label) +void wxMenuBar::SetLabelTop(size_t pos, const wxString& label) { UINT id; UINT flagsOld = ::GetMenuState((HMENU)m_hMenu, pos, MF_BYPOSITION); @@ -714,7 +705,7 @@ void wxMenuBar::SetLabelTop(int pos, const wxString& label) } } -wxString wxMenuBar::GetLabelTop(int pos) const +wxString wxMenuBar::GetLabelTop(size_t pos) const { int len = ::GetMenuString((HMENU)m_hMenu, pos, NULL, 0, MF_BYCOMMAND); @@ -780,10 +771,13 @@ bool wxMenuBar::OnAppend(wxMenu *a_menu, const wxChar *title) // --------------------------------------------------------------------------- // wxMenuBar construction // --------------------------------------------------------------------------- + int wxMenuBar::FindMenu(const wxString& title) { wxString menuTitle = wxStripMenuCodes(title); - for ( int i = 0; i < m_menuCount; i++ ) + + size_t count = GetMenuCount(); + for ( size_t i = 0; i < count; i++ ) { wxString title = wxStripMenuCodes(m_titles[i]); if ( menuTitle == title ) @@ -794,121 +788,75 @@ int wxMenuBar::FindMenu(const wxString& title) } - -void wxMenuBar::ReplaceMenu(int pos, wxMenu * new_menu, const wxString& title) +wxMenu *wxMenuBar::Replace(size_t pos, wxMenu *menu, const wxString& title) { - if (m_menuBarFrame) return; - - if ( pos >= 0 && pos < m_menuCount ) + if ( m_menuBarFrame ) { - wxMenu *old_menu = m_menus[pos]; - m_menus[pos] = new_menu; - delete old_menu; + wxFAIL_MSG(wxT("not implemented")); + + return NULL; } + else + { + wxMenu *menuOld = wxMenuBarBase::Replace(pos, menu, title); + if ( menuOld ) + { + m_titles[pos] = title; + } + return menuOld; + } } - -void wxMenuBar::Insert(int pos, wxMenu * menu, const wxString& title) +bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title) { - if (m_menuBarFrame) return; - if ( pos < 0 && pos >= m_menuCount ) return; - - m_menuCount ++; - wxMenu **new_menus = new wxMenu *[m_menuCount]; - wxString *new_titles = new wxString[m_menuCount]; - int i; - - for (i = 0; i < pos; i++) + if ( m_menuBarFrame ) { - new_menus[i] = m_menus[i]; - m_menus[i] = NULL; - new_titles[i] = m_titles[i]; - m_titles[i] = wxT(""); - } + wxFAIL_MSG(wxT("not implemented")); - new_menus[pos] = (wxMenu *)menu; - new_titles[i] = title; - - for (i = pos+1; i < m_menuCount; i++) - { - new_menus[i] = m_menus[i-1]; - m_menus[i-1] = NULL; - new_titles[i] = m_titles[i-1]; - m_titles[i-1] = wxT(""); + return FALSE; } - if (m_menus) + else { - delete[]m_menus; - delete[]m_titles; - } - m_menus = new_menus; - m_titles = new_titles; + if ( !wxMenuBarBase::Insert(pos, menu, title) ) + return FALSE; - menu->SetParent(this); + m_titles.Insert(title, pos); + return TRUE; + } } - -void wxMenuBar::Append (wxMenu * menu, const wxString& title) +bool wxMenuBar::Append(wxMenu * menu, const wxString& title) { - if (!OnAppend(menu, title)) - return; + if ( !wxMenuBarBase::Append(menu, title) ) + return FALSE; - m_menuCount ++; - wxMenu **new_menus = new wxMenu *[m_menuCount]; - wxString *new_titles = new wxString[m_menuCount]; - int i; + // menu is already appended, ignore errors + (void)OnAppend(menu, title); - for (i = 0; i < m_menuCount - 1; i++) - { - new_menus[i] = m_menus[i]; - m_menus[i] = NULL; - new_titles[i] = m_titles[i]; - m_titles[i] = wxT(""); - } - if (m_menus) - { - delete[]m_menus; - delete[]m_titles; - } - m_menus = new_menus; - m_titles = new_titles; - - m_menus[m_menuCount - 1] = (wxMenu *)menu; - m_titles[m_menuCount - 1] = title; + m_titles.Add(title); menu->SetParent(this); + + return TRUE; } -void wxMenuBar::Delete(wxMenu * menu, int i) +wxMenu *wxMenuBar::Remove(size_t pos) { - int j; - int ii = (int) i; + wxMenu *menu = wxMenuBarBase::Remove(pos); + if ( !menu ) + return NULL; - if (menu != 0) { - for (ii = 0; ii < m_menuCount; ii++) { - if (m_menus[ii] == menu) - break; - } - if (ii >= m_menuCount) - return; - } else { - if (ii < 0 || ii >= m_menuCount) - return; - menu = m_menus[ii]; - } + menu->SetParent(NULL); - if (!OnDelete(menu, ii)) - return; + // the menu is deleted from the list anyhow, so we have to ignore all + // possible errors here + (void)OnDelete(menu, pos); - menu->SetParent(NULL); + m_titles.Remove(pos); - -- m_menuCount; - for (j = ii; j < m_menuCount; j++) { - m_menus[j] = m_menus[j + 1]; - m_titles[j] = m_titles[j + 1]; - } + return menu; } void wxMenuBar::Attach(wxFrame *frame) @@ -921,8 +869,8 @@ void wxMenuBar::Attach(wxFrame *frame) // create the accel table - we consider that the menubar construction is // finished size_t nAccelCount = 0; - int i; - for ( i = 0; i < m_menuCount; i++ ) + size_t i, count = GetMenuCount(); + for ( i = 0; i < count; i++ ) { nAccelCount += m_menus[i]->GetAccelCount(); } @@ -932,7 +880,7 @@ void wxMenuBar::Attach(wxFrame *frame) wxAcceleratorEntry *accelEntries = new wxAcceleratorEntry[nAccelCount]; nAccelCount = 0; - for ( i = 0; i < m_menuCount; i++ ) + for ( i = 0; i < count; i++ ) { nAccelCount += m_menus[i]->CopyAccels(&accelEntries[nAccelCount]); } @@ -961,7 +909,8 @@ int wxMenuBar::FindMenuItem(const wxString& menuString, const wxString& itemString) const { wxString menuLabel = wxStripMenuCodes(menuString); - for ( int i = 0; i < m_menuCount; i++ ) + size_t count = GetMenuCount(); + for ( size_t i = 0; i < count; i++ ) { wxString title = wxStripMenuCodes(m_titles[i]); if ( menuString == title ) @@ -971,13 +920,14 @@ int wxMenuBar::FindMenuItem(const wxString& menuString, return wxNOT_FOUND; } -wxMenuItem *wxMenuBar::FindItemForId (int id, wxMenu **itemMenu) const +wxMenuItem *wxMenuBar::FindItem(int id, wxMenu **itemMenu) const { if ( itemMenu ) *itemMenu = NULL; wxMenuItem *item = NULL; - for ( int i = 0; !item && (i < m_menuCount); i++ ) + size_t count = GetMenuCount(); + for ( size_t i = 0; !item && (i < count); i++ ) { item = m_menus[i]->FindItemForId(id, itemMenu); } diff --git a/src/msw/menuitem.cpp b/src/msw/menuitem.cpp index ee2562727e..822bd0bfd6 100644 --- a/src/msw/menuitem.cpp +++ b/src/msw/menuitem.cpp @@ -140,9 +140,9 @@ void wxMenuItem::DeleteSubMenu() // get item state // -------------- -void wxMenuItem::IsChecked() const +bool wxMenuItem::IsChecked() const { - int flag = ::GetMenuState(GetHMenuOf(m_parentMenu), id, MF_BYCOMMAND); + int flag = ::GetMenuState(GetHMenuOf(m_parentMenu), GetId(), MF_BYCOMMAND); // don't "and" with MF_ENABLED because its value is 0 return (flag & MF_DISABLED) == 0; -- 2.45.2