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.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@76676 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2014-06-09 20:33:17 +00:00
parent af692f090b
commit b6469b4369
3 changed files with 55 additions and 23 deletions

View File

@@ -68,6 +68,7 @@ wxMSW:
- Improve wxMimeTypesManager open command detection (Eric Jensen). - Improve wxMimeTypesManager open command detection (Eric Jensen).
- Make wxFILTER_INCLUDE_LIST in wxTextValidator actually usable. - Make wxFILTER_INCLUDE_LIST in wxTextValidator actually usable.
- Fix setting menu item bitmaps after appending them (Artur Wieczorek). - Fix setting menu item bitmaps after appending them (Artur Wieczorek).
- Fix setting label of submenu items (Artur Wieczorek).
- Fix handling of selected images in wxBitmapButton (Artur Wieczorek). - Fix handling of selected images in wxBitmapButton (Artur Wieczorek).
- Fix loading of bitmap with non-pre-multiplied alpha (Artur Wieczorek). - Fix loading of bitmap with non-pre-multiplied alpha (Artur Wieczorek).
- Support multiline strings in wxDC::DrawRotatedText() (Artur Wieczorek). - Support multiline strings in wxDC::DrawRotatedText() (Artur Wieczorek).

View File

@@ -127,6 +127,11 @@ private:
// common part of all ctors // common part of all ctors
void Init(); 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;
// item bitmaps // item bitmaps
wxBitmap m_bmpChecked, // bitmap to put near the item wxBitmap m_bmpChecked, // bitmap to put near the item

View File

@@ -677,14 +677,11 @@ void wxMenuItem::SetItemLabel(const wxString& txt)
m_parentMenu->UpdateAccel(this); m_parentMenu->UpdateAccel(this);
#endif // wxUSE_ACCEL #endif // wxUSE_ACCEL
const UINT id = GetMSWId(); const int itemPos = MSGetMenuItemPos();
HMENU hMenu = GetHMenuOf(m_parentMenu); if ( itemPos == -1 )
if ( !hMenu )
return; return;
const UINT state = ::GetMenuState(hMenu, id, MF_BYCOMMAND); HMENU hMenu = GetHMenuOf(m_parentMenu);
if ( state == (UINT)-1 )
return;
// update the text of the native menu item // update the text of the native menu item
WinStruct<MENUITEMINFO> info; WinStruct<MENUITEMINFO> info;
@@ -699,7 +696,7 @@ void wxMenuItem::SetItemLabel(const wxString& txt)
MIIM_DATA | MIIM_DATA |
MIIM_BITMAP | MIIM_BITMAP |
MIIM_FTYPE; MIIM_FTYPE;
if ( !::GetMenuItemInfo(hMenu, id, FALSE, &info) ) if ( !::GetMenuItemInfo(hMenu, itemPos, TRUE, &info) )
{ {
wxLogLastError(wxT("GetMenuItemInfo")); wxLogLastError(wxT("GetMenuItemInfo"));
return; return;
@@ -719,7 +716,7 @@ void wxMenuItem::SetItemLabel(const wxString& txt)
// Also notice that we shouldn't use our IsOwnerDrawn() because it can be // 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 // true because it was set by e.g. SetBitmap(), even if the item wasn't
// made owner drawn at Windows level. // made owner drawn at Windows level.
if ( !(state & MF_OWNERDRAW) ) if ( !(info.fState & MF_OWNERDRAW) )
#endif // wxUSE_OWNER_DRAWN #endif // wxUSE_OWNER_DRAWN
{ {
info.fMask |= MIIM_STRING; info.fMask |= MIIM_STRING;
@@ -727,7 +724,7 @@ void wxMenuItem::SetItemLabel(const wxString& txt)
info.cch = m_text.length(); info.cch = m_text.length();
} }
if ( !::SetMenuItemInfo(hMenu, id, FALSE, &info) ) if ( !::SetMenuItemInfo(hMenu, itemPos, TRUE, &info) )
{ {
wxLogLastError(wxT("SetMenuItemInfo")); wxLogLastError(wxT("SetMenuItemInfo"));
} }
@@ -778,20 +775,13 @@ void wxMenuItem::DoSetBitmap(const wxBitmap& bmp, bool bChecked)
} }
#endif // wxUSE_OWNER_DRAWN #endif // wxUSE_OWNER_DRAWN
// the item can be not attached to any menu yet and SetBitmap() is still const int itemPos = MSGetMenuItemPos();
// valid to call in this case and should do nothing else if ( itemPos == -1 )
if ( !m_parentMenu ) {
return; // The item is probably not attached to any menu yet. SetBitmap() is
// still valid to call in this case, just do nothing else here.
HMENU hMenu = GetHMenuOf(m_parentMenu);
if ( !hMenu )
return;
const UINT id = GetMSWId();
const UINT state = ::GetMenuState(hMenu, id, MF_BYCOMMAND);
if ( state == (UINT)-1 )
return; return;
}
// update the bitmap of the native menu item // update the bitmap of the native menu item
// don't set hbmpItem for the checkable items as it would // don't set hbmpItem for the checkable items as it would
@@ -809,7 +799,7 @@ void wxMenuItem::DoSetBitmap(const wxBitmap& bmp, bool bChecked)
mii.hbmpItem = GetHBitmapForMenu(); mii.hbmpItem = GetHBitmapForMenu();
} }
if ( !::SetMenuItemInfo(hMenu, id, FALSE, &mii) ) if ( !::SetMenuItemInfo(GetHMenuOf(m_parentMenu), itemPos, TRUE, &mii) )
{ {
wxLogLastError(wxT("SetMenuItemInfo")); wxLogLastError(wxT("SetMenuItemInfo"));
} }
@@ -1407,6 +1397,42 @@ HBITMAP wxMenuItem::GetHBitmapForMenu(bool checked)
return HBMMENU_CALLBACK; return HBMMENU_CALLBACK;
} }
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 // wxMenuItemBase
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------