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
This commit is contained in:
Vadim Zeitlin
2014-10-03 01:51:59 +00:00
parent 2e91798e96
commit 1f2a74014f
3 changed files with 48 additions and 9 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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<MENUITEMINFO> 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
// ----------------------------------------------------------------------------