From 1f2a74014f5ab8a3107296338af15939ca157425 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 3 Oct 2014 01:51:59 +0000 Subject: [PATCH] Fix changing the label of a submenu in wxMSW. Use position, not the ID, to find the native menu items to allow the code in wxMenuItem::SetItemLabel() and DoSetBitmap() to also work with submenus and not just the normal items. Closes #16246. [This is the backport of r76676 from trunk.] git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_3_0_BRANCH@77945 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 1 + include/wx/msw/menuitem.h | 5 ++++ src/msw/menuitem.cpp | 51 ++++++++++++++++++++++++++++++++------- 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 91489a2fb1..412b909d03 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -616,6 +616,7 @@ wxMSW: - Fix wxFileName::GetShortcutTarget() in console applications. - Fix wxFileName::MakeRelativeTo() for shortcut files (gafatoa). - Fix height of initially empty wxBitmapComboBox (Artur Wieczorek). +- Fix setting label of submenu items (Artur Wieczorek). 3.0.1: (released 2014-06-15) diff --git a/include/wx/msw/menuitem.h b/include/wx/msw/menuitem.h index d76bd11950..7e6eacd199 100644 --- a/include/wx/msw/menuitem.h +++ b/include/wx/msw/menuitem.h @@ -133,6 +133,11 @@ private: // common part of all ctors void Init(); + // Return the item position in the menu containing it. + // + // Returns -1 if the item is not attached to a menu or if we can't find its + // position (which is not really supposed to ever happen). + int MSGetMenuItemPos() const; #if wxUSE_OWNER_DRAWN // item bitmaps diff --git a/src/msw/menuitem.cpp b/src/msw/menuitem.cpp index 3c09d878fa..7d10a044ac 100644 --- a/src/msw/menuitem.cpp +++ b/src/msw/menuitem.cpp @@ -671,14 +671,11 @@ void wxMenuItem::SetItemLabel(const wxString& txt) m_parentMenu->UpdateAccel(this); #endif // wxUSE_ACCEL - const UINT id = GetMSWId(); - HMENU hMenu = GetHMenuOf(m_parentMenu); - if ( !hMenu ) + const int itemPos = MSGetMenuItemPos(); + if ( itemPos == -1 ) return; - const UINT state = ::GetMenuState(hMenu, id, MF_BYCOMMAND); - if ( state == (UINT)-1 ) - return; + HMENU hMenu = GetHMenuOf(m_parentMenu); // update the text of the native menu item WinStruct info; @@ -696,7 +693,7 @@ void wxMenuItem::SetItemLabel(const wxString& txt) info.fMask |= MIIM_BITMAP | MIIM_FTYPE; else info.fMask |= MIIM_TYPE; - if ( !::GetMenuItemInfo(hMenu, id, FALSE, &info) ) + if ( !::GetMenuItemInfo(hMenu, itemPos, TRUE, &info) ) { wxLogLastError(wxT("GetMenuItemInfo")); return; @@ -716,7 +713,7 @@ void wxMenuItem::SetItemLabel(const wxString& txt) // Also notice that we shouldn't use our IsOwnerDrawn() because it can be // true because it was set by e.g. SetBitmap(), even if the item wasn't // made owner drawn at Windows level. - if ( !(state & MF_OWNERDRAW) ) + if ( !(info.fState & MF_OWNERDRAW) ) #endif // wxUSE_OWNER_DRAWN { if ( isLaterThanWin95 ) @@ -726,7 +723,7 @@ void wxMenuItem::SetItemLabel(const wxString& txt) info.cch = m_text.length(); } - if ( !::SetMenuItemInfo(hMenu, id, FALSE, &info) ) + if ( !::SetMenuItemInfo(hMenu, itemPos, TRUE, &info) ) { wxLogLastError(wxT("SetMenuItemInfo")); } @@ -1251,6 +1248,42 @@ void wxMenuItem::GetColourToUse(wxODStatus stat, wxColour& colText, wxColour& co } #endif // wxUSE_OWNER_DRAWN +int wxMenuItem::MSGetMenuItemPos() const +{ + if ( !m_parentMenu ) + return -1; + + const HMENU hMenu = GetHMenuOf(m_parentMenu); + if ( !hMenu ) + return -1; + + const UINT id = GetMSWId(); + const int menuItems = ::GetMenuItemCount(hMenu); + for ( int i = 0; i < menuItems; i++ ) + { + const UINT state = ::GetMenuState(hMenu, i, MF_BYPOSITION); + if ( state == (UINT)-1 ) + { + // This indicates that the item at this position and is not + // supposed to happen here, but test for it just in case. + continue; + } + + if ( state & MF_POPUP ) + { + if ( ::GetSubMenu(hMenu, i) == (HMENU)id ) + return i; + } + else if ( !(state & MF_SEPARATOR) ) + { + if ( ::GetMenuItemID(hMenu, i) == id ) + return i; + } + } + + return -1; +} + // ---------------------------------------------------------------------------- // wxMenuItemBase // ----------------------------------------------------------------------------