X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/092fdc46a9bbed16ca2f0d50426f9f415b5ac684..b3818fbe8e439bc9af8c20371774520a5a2bc9c7:/src/msw/menu.cpp?ds=inline diff --git a/src/msw/menu.cpp b/src/msw/menu.cpp index 2e56379a77..b89b794879 100644 --- a/src/msw/menu.cpp +++ b/src/msw/menu.cpp @@ -32,6 +32,7 @@ #include "wx/frame.h" #include "wx/menu.h" #include "wx/utils.h" + #include "wx/intl.h" #endif #if wxUSE_OWNER_DRAWN @@ -143,7 +144,70 @@ void wxMenu::Break() // function appends a new item or submenu to the menu void wxMenu::Append(wxMenuItem *pItem) { - wxCHECK_RET( pItem != NULL, "can't append NULL item to the menu" ); + wxCHECK_RET( pItem != NULL, _T("can't append NULL item to the menu") ); + +#if wxUSE_ACCEL + // check for accelerators: they are given after '\t' + wxString label = pItem->GetName(); + int posTab = label.Find(_T('\t')); + if ( posTab != wxNOT_FOUND ) { + // parse the accelerator string + int keyCode = 0; + int accelFlags = wxACCEL_NORMAL; + wxString current; + for ( size_t n = (size_t)posTab + 1; n < label.Len(); n++ ) { + if ( (label[n] == '+') || (label[n] == '-') ) { + if ( current == _("ctrl") ) + accelFlags |= wxACCEL_CTRL; + else if ( current == _("alt") ) + accelFlags |= wxACCEL_ALT; + else if ( current == _("shift") ) + accelFlags |= wxACCEL_SHIFT; + else { + wxLogDebug(_T("Unknown accel modifier: '%s'"), + current.c_str()); + } + + current.Empty(); + } + else { + current += wxTolower(label[n]); + } + } + + if ( current.IsEmpty() ) { + wxLogDebug(_T("No accel key found, accel string ignored.")); + } + else { + if ( current.Len() == 1 ) { + // it's a letter + keyCode = wxToupper(current[0U]); + } + else { + // it should be a function key + if ( current[0U] == 'f' && isdigit(current[1U]) && + (current.Len() == 2 || + (current.Len() == 3 && isdigit(current[2U]))) ) { + int n; + wxSscanf(current.c_str() + 1, _T("%d"), &n); + + keyCode = VK_F1 + n - 1; + } + else { + wxLogDebug(_T("Unrecognized accel key '%s', accel " + "string ignored."), current.c_str()); + } + } + } + + if ( keyCode ) { + // do add an entry + m_accelKeyCodes.Add(keyCode); + m_accelFlags.Add(accelFlags); + m_accelIds.Add(pItem->GetId()); + } + } +#endif // wxUSE_ACCEL UINT flags = 0; @@ -177,26 +241,20 @@ void wxMenu::Append(wxMenuItem *pItem) id = pItem->GetId(); } - LPCSTR pData; + LPCTSTR pData; #if wxUSE_OWNER_DRAWN if ( pItem->IsOwnerDrawn() ) { // want to get {Measure|Draw}Item messages? // item draws itself, pass pointer to it in data parameter flags |= MF_OWNERDRAW; - pData = (LPCSTR)pItem; + pData = (LPCTSTR)pItem; } else #endif { // menu is just a normal string (passed in data parameter) flags |= MF_STRING; - pData = pItem->GetName(); - } - - // visually select the menu title - if ( id == idMenuTitle ) - { - // TODO use SetMenuItemInfo(MFS_DEFAULT) to put it in bold face + pData = label; } if ( !::AppendMenu(GetHMENU(), flags, id, pData) ) @@ -205,6 +263,22 @@ void wxMenu::Append(wxMenuItem *pItem) } else { +#ifdef __WIN32__ + if ( id == idMenuTitle ) + { + // visually select the menu title + MENUITEMINFO mii; + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_STATE; + mii.fState = MFS_DEFAULT; + + if ( !SetMenuItemInfo(GetHMENU(), (unsigned)id, FALSE, &mii) ) + { + wxLogLastError(_T("SetMenuItemInfo")); + } + } +#endif // __WIN32__ + m_menuItems.Append(pItem); m_noItems++; } @@ -247,7 +321,7 @@ void wxMenu::Delete(int id) break; } - wxCHECK_RET( node, "wxMenu::Delete(): item doesn't exist" ); + wxCHECK_RET( node, _T("wxMenu::Delete(): item doesn't exist") ); HMENU menu = GetHMENU(); @@ -272,6 +346,27 @@ void wxMenu::Delete(int id) delete item; } +#if wxUSE_ACCEL + +// --------------------------------------------------------------------------- +// accelerator helpers +// --------------------------------------------------------------------------- + +// create the wxAcceleratorEntries for our accels and put them into provided +// array - return the number of accels we have +size_t wxMenu::CopyAccels(wxAcceleratorEntry *accels) const +{ + size_t count = GetAccelCount(); + for ( size_t n = 0; n < count; n++ ) + { + (*accels++).Set(m_accelFlags[n], m_accelKeyCodes[n], m_accelIds[n]); + } + + return count; +} + +#endif // wxUSE_ACCEL + // --------------------------------------------------------------------------- // wxMenu functions implemented in wxMenuItem // --------------------------------------------------------------------------- @@ -279,7 +374,7 @@ void wxMenu::Delete(int id) void wxMenu::Enable(int id, bool Flag) { wxMenuItem *item = FindItemForId(id); - wxCHECK_RET( item != NULL, "can't enable non-existing menu item" ); + wxCHECK_RET( item != NULL, _T("can't enable non-existing menu item") ); item->Enable(Flag); } @@ -287,7 +382,7 @@ void wxMenu::Enable(int id, bool Flag) bool wxMenu::IsEnabled(int id) const { wxMenuItem *item = FindItemForId(id); - wxCHECK_MSG( item != NULL, FALSE, "invalid item id" ); + wxCHECK_MSG( item != NULL, FALSE, _T("invalid item id") ); return item->IsEnabled(); } @@ -295,7 +390,7 @@ bool wxMenu::IsEnabled(int id) const void wxMenu::Check(int id, bool Flag) { wxMenuItem *item = FindItemForId(id); - wxCHECK_RET( item != NULL, "can't get status of non-existing menu item" ); + wxCHECK_RET( item != NULL, _T("can't get status of non-existing menu item") ); item->Check(Flag); } @@ -303,7 +398,7 @@ void wxMenu::Check(int id, bool Flag) bool wxMenu::IsChecked(int id) const { wxMenuItem *item = FindItemForId(id); - wxCHECK_MSG( item != NULL, FALSE, "invalid item id" ); + wxCHECK_MSG( item != NULL, FALSE, _T("invalid item id") ); return item->IsChecked(); } @@ -311,7 +406,7 @@ bool wxMenu::IsChecked(int id) const void wxMenu::SetLabel(int id, const wxString& label) { wxMenuItem *item = FindItemForId(id) ; - wxCHECK_RET( item, "wxMenu::SetLabel: no such item" ); + wxCHECK_RET( item, _T("wxMenu::SetLabel: no such item") ); item->SetName(label); } @@ -323,7 +418,7 @@ wxString wxMenu::GetLabel(int id) const if (pItem) label = pItem->GetName() ; else - wxFAIL_MSG("wxMenu::GetLabel: item doesn't exist"); + wxFAIL_MSG(_T("wxMenu::GetLabel: item doesn't exist")); return label; } @@ -334,7 +429,7 @@ void wxMenu::SetHelpString(int itemId, const wxString& helpString) if (item) item->SetHelp(helpString); else - wxFAIL_MSG("wxMenu::SetHelpString: item doesn't exist"); + wxFAIL_MSG(_T("wxMenu::SetHelpString: item doesn't exist")); } wxString wxMenu::GetHelpString (int itemId) const @@ -344,7 +439,7 @@ wxString wxMenu::GetHelpString (int itemId) const if (item) help = item->GetHelp(); else - wxFAIL_MSG("wxMenu::GetHelpString: item doesn't exist"); + wxFAIL_MSG(_T("wxMenu::GetHelpString: item doesn't exist")); return help; } @@ -368,7 +463,7 @@ void wxMenu::SetTitle(const wxString& label) (unsigned)idMenuTitle, m_title) || !InsertMenu(hMenu, 1u, MF_BYPOSITION, (unsigned)-1, NULL) ) { - wxLogLastError("InsertMenu"); + wxLogLastError(_T("InsertMenu")); } } } @@ -395,7 +490,7 @@ void wxMenu::SetTitle(const wxString& label) } } -#ifndef __WIN16__ +#ifdef __WIN32__ // put the title string in bold face if ( !m_title.IsEmpty() ) { @@ -438,7 +533,7 @@ bool wxMenu::MSWCommand(WXUINT WXUNUSED(param), WXWORD id) return TRUE; } -void wxMenu::ProcessCommand(wxCommandEvent & event) +bool wxMenu::ProcessCommand(wxCommandEvent & event) { bool processed = FALSE; @@ -462,6 +557,8 @@ void wxMenu::ProcessCommand(wxCommandEvent & event) wxWindow *win = GetInvokingWindow(); if ( !processed && win ) processed = win->GetEventHandler()->ProcessEvent(event); + + return processed; } // --------------------------------------------------------------------------- @@ -550,7 +647,7 @@ void wxMenu::Attach(wxMenuBar *menubar) { // menu can be in at most one menubar because otherwise they would both // delete the menu pointer - wxASSERT_MSG( !m_menuBar, "menu belongs to 2 menubars, expect a crash" ); + wxASSERT_MSG( !m_menuBar, _T("menu belongs to 2 menubars, expect a crash") ); m_menuBar = menubar; m_savehMenu = m_hMenu; @@ -559,7 +656,7 @@ void wxMenu::Attach(wxMenuBar *menubar) void wxMenu::Detach() { - wxASSERT_MSG( m_menuBar, "can't detach menu if it's not attached" ); + wxASSERT_MSG( m_menuBar, _T("can't detach menu if it's not attached") ); m_hMenu = m_savehMenu; m_savehMenu = 0; @@ -622,14 +719,14 @@ wxMenuBar::~wxMenuBar() void wxMenuBar::Refresh() { - wxCHECK_RET( m_menuBarFrame, "can't refresh a menubar withotu a frame" ); + wxCHECK_RET( m_menuBarFrame, _T("can't refresh a menubar withotu a frame") ); DrawMenuBar((HWND)m_menuBarFrame->GetHWND()) ; } WXHMENU wxMenuBar::Create() { - wxCHECK_MSG( !m_hMenu, TRUE, "menubar already created" ); + wxCHECK_MSG( !m_hMenu, TRUE, _T("menubar already created") ); m_hMenu = (WXHMENU)::CreateMenu(); @@ -664,7 +761,7 @@ void wxMenuBar::Enable(int id, bool enable) wxMenu *itemMenu = NULL; wxMenuItem *item = FindItemForId(id, &itemMenu) ; - wxCHECK_RET( item, "attempt to enable an item which doesn't exist" ); + wxCHECK_RET( item, _T("attempt to enable an item which doesn't exist") ); item->Enable(enable); } @@ -683,8 +780,8 @@ void wxMenuBar::Check(int id, bool check) wxMenu *itemMenu = NULL; wxMenuItem *item = FindItemForId(id, &itemMenu) ; - wxCHECK_RET( item, "attempt to check an item which doesn't exist" ); - wxCHECK_RET( item->IsCheckable(), "attempt to check an uncheckable item" ); + wxCHECK_RET( item, _T("attempt to check an item which doesn't exist") ); + wxCHECK_RET( item->IsCheckable(), _T("attempt to check an uncheckable item") ); item->Check(check); } @@ -694,7 +791,7 @@ bool wxMenuBar::IsChecked(int id) const wxMenu *itemMenu = NULL; wxMenuItem *item = FindItemForId(id, &itemMenu) ; - wxCHECK_MSG( item, FALSE, "wxMenuBar::IsChecked(): no such item" ); + wxCHECK_MSG( item, FALSE, _T("wxMenuBar::IsChecked(): no such item") ); int flag = ::GetMenuState(GetHMenuOf(itemMenu), id, MF_BYCOMMAND); @@ -706,7 +803,7 @@ bool wxMenuBar::IsEnabled(int id) const wxMenu *itemMenu = NULL; wxMenuItem *item = FindItemForId(id, &itemMenu) ; - wxCHECK_MSG( item, FALSE, "wxMenuBar::IsEnabled(): no such item" ); + wxCHECK_MSG( item, FALSE, _T("wxMenuBar::IsEnabled(): no such item") ); int flag = ::GetMenuState(GetHMenuOf(itemMenu), id, MF_BYCOMMAND) ; @@ -718,7 +815,7 @@ void wxMenuBar::SetLabel(int id, const wxString& label) wxMenu *itemMenu = NULL; wxMenuItem *item = FindItemForId(id, &itemMenu) ; - wxCHECK_RET( item, "wxMenuBar::SetLabel(): no such item" ); + wxCHECK_RET( item, _T("wxMenuBar::SetLabel(): no such item") ); item->SetName(label); } @@ -728,7 +825,7 @@ wxString wxMenuBar::GetLabel(int id) const wxMenu *itemMenu = NULL; wxMenuItem *item = FindItemForId(id, &itemMenu) ; - wxCHECK_MSG( item, "", "wxMenuBar::GetLabel(): no such item" ); + wxCHECK_MSG( item, _T(""), _T("wxMenuBar::GetLabel(): no such item") ); return item->GetName(); } @@ -738,7 +835,7 @@ void wxMenuBar::SetHelpString (int id, const wxString& helpString) wxMenu *itemMenu = NULL; wxMenuItem *item = FindItemForId(id, &itemMenu) ; - wxCHECK_RET( item, "wxMenuBar::SetHelpString(): no such item" ); + wxCHECK_RET( item, _T("wxMenuBar::SetHelpString(): no such item") ); item->SetHelp(helpString); } @@ -748,7 +845,7 @@ wxString wxMenuBar::GetHelpString (int id) const wxMenu *itemMenu = NULL; wxMenuItem *item = FindItemForId(id, &itemMenu) ; - wxCHECK_MSG( item, "", "wxMenuBar::GetHelpString(): no such item" ); + wxCHECK_MSG( item, _T(""), _T("wxMenuBar::GetHelpString(): no such item") ); return item->GetHelp(); } @@ -766,7 +863,7 @@ void wxMenuBar::SetLabelTop(int pos, const wxString& label) UINT flagsOld = ::GetMenuState((HMENU)m_hMenu, pos, MF_BYPOSITION); if ( flagsOld == 0xFFFFFFFF ) { - wxLogLastError("GetMenuState"); + wxLogLastError(_T("GetMenuState")); return; } @@ -813,7 +910,7 @@ bool wxMenuBar::OnDelete(wxMenu *a_menu, int pos) if ( ::RemoveMenu((HMENU)m_hMenu, (UINT)pos, MF_BYPOSITION) ) { // VZ: I'm not sure about what's going on here, so I leave an assert - wxASSERT_MSG( m_menus[pos] == a_menu, "what is this parameter for??" ); + wxASSERT_MSG( m_menus[pos] == a_menu, _T("what is this parameter for??") ); a_menu->Detach(); @@ -830,7 +927,7 @@ bool wxMenuBar::OnDelete(wxMenu *a_menu, int pos) return FALSE; } -bool wxMenuBar::OnAppend(wxMenu *a_menu, const char *title) +bool wxMenuBar::OnAppend(wxMenu *a_menu, const wxChar *title) { WXHMENU submenu = a_menu->GetHMenu(); if ( !submenu ) @@ -844,7 +941,7 @@ bool wxMenuBar::OnAppend(wxMenu *a_menu, const char *title) if ( !::AppendMenu(GetHMENU(), MF_POPUP | MF_STRING, (UINT)submenu, title) ) { - wxLogLastError("AppendMenu"); + wxLogLastError(_T("AppendMenu")); } Refresh(); @@ -871,7 +968,7 @@ void wxMenuBar::Append (wxMenu * menu, const wxString& title) new_menus[i] = m_menus[i]; m_menus[i] = NULL; new_titles[i] = m_titles[i]; - m_titles[i] = ""; + m_titles[i] = _T(""); } if (m_menus) { @@ -917,6 +1014,39 @@ void wxMenuBar::Delete(wxMenu * menu, int i) } } +void wxMenuBar::Attach(wxFrame *frame) +{ + wxASSERT_MSG( !m_menuBarFrame, _T("menubar already attached!") ); + + m_menuBarFrame = frame; + +#if wxUSE_ACCEL + // 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++ ) + { + nAccelCount += m_menus[i]->GetAccelCount(); + } + + if ( nAccelCount ) + { + wxAcceleratorEntry *accelEntries = new wxAcceleratorEntry[nAccelCount]; + + nAccelCount = 0; + for ( i = 0; i < m_menuCount; i++ ) + { + nAccelCount += m_menus[i]->CopyAccels(&accelEntries[nAccelCount]); + } + + m_accelTable = wxAcceleratorTable(nAccelCount, accelEntries); + + delete [] accelEntries; + } +#endif // wxUSE_ACCEL +} + // --------------------------------------------------------------------------- // wxMenuBar searching for menu items // --------------------------------------------------------------------------- @@ -972,7 +1102,7 @@ WXHMENU wxMenu::GetHMenu() const else if ( m_savehMenu != 0 ) return m_savehMenu; - wxFAIL_MSG("wxMenu without HMENU"); + wxFAIL_MSG(_T("wxMenu without HMENU")); return 0; }