Opened 8 years ago

Closed 2 years ago

#3897 closed defect (fixed)

wxMenu with images doesn't update

Reported by: hzd_byte Owned by:
Priority: normal Milestone:
Component: wxMSW Version: 2.9.4
Keywords: onmeasureitem, menu, width, update Cc: hzd_byte, p_michalczyk, vadz, dhyams
Blocked By: Blocking:
Patch: yes

Description

I created menu with:

wxMenuBar *menuBar = new wxMenuBar;
m_fileMenu = new wxMenu;
wxMenuItem *fileOpenItem = new wxMenuItem(m_fileMenu, ID_OPENGAME, wxT("-"));
fileOpenItem->SetBitmap(wxBitmap(open_xpm));
m_fileMenu->Append(fileOpenItem);
...
menuBar->Append(m_fileMenu, wxT(""));
SetMenuBar(menuBar);

such items (with images).
Then I changed labels with:

menuBar->SetLabel(ID_OPENGAME, _("New text!"));

and menu didn't change it's width!
I tried use of

menuBar->Refresh();

and

m_fileMenu->UpdateUI();

but result remains the same :(
When I use menu without images there is all ok and menu changes it's width.

Attachments (2)

image.jpg download (8.0 KB) - added by hzd_byte 8 years ago.
Screenshot of this
wx_test_menu_with_bitmap.py download (1.2 KB) - added by dhyams 2 years ago.
Test code that demonstrates this bug.

Download all attachments as: .zip

Change History (10)

Changed 8 years ago by hzd_byte

Screenshot of this

comment:1 Changed 8 years ago by hzd_byte

Look at attached file
File Added: image.jpg

comment:2 Changed 8 years ago by p_michalczyk

I cannot reproduce this error. It would be nice if you posted some working example. Also write what is your version of libGTK and wxWidgets.

comment:3 Changed 8 years ago by hzd_byte

It's for wxMSW

comment:4 Changed 7 years ago by vadz

Could you please provide a patch showing the problem in the menu (or minimal) sample?

P.S. Please don't change the bug priorities, this won't fix them more quickly.

comment:5 Changed 2 years ago by dhyams

  • Cc dhyams added
  • Keywords onmeasureitem menu added
  • Patch set
  • Status changed from new to confirmed
  • Version set to 2.9.4

I think that I've found the proper fix for this. In wxwidgets, file src/msw/menuitem.cpp, routine wxMenuItem::SetItemLabel.

If the menu item is set to owner drawn, there is a short circuit out of this routine:

if ( IsOwnerDrawn() )
{

we don't need to do anything for owner drawn items, they will redraw
themselves using the new text the next time they're displayed
return;

}

But we can't allow this.....even though there is technically nothing to be done in SetItemLabel, the Windows API (SetMenuItemInfo) below still need to be called, so that Windows knows that the name has been changed and therefore later sends WM_MEASUREITEM which therefore triggers the wxwidgets OnMeasureItem() handler, which appropriately recalculates the menu's width.

So if I just remove the short-circuit, everything works just fine, both in the test codes in this thread, and in my application. Personally I see no possible harm in removing the short-circuit, but perhaps others who know more than I can comment.

This bug occurs under the following conditions:

1) windows
2) a bitmap present anywhere in the menu
3) the length of the menu text changes dynamically, and drastically enough to look ugly if the menu width does not change. This is the situation if the user sets the menu text in response to wx.EVT_UPDATE_UI or wx.EVT_OPENMENU.

For further reference, including images and test codes that demonstrate the problem, https://groups.google.com/d/topic/wxpython-users/qz2_RJalkrI/discussion.

I've attached a test code that will reproduce the problem. Sorry that it's in python; I know that it's easier if it isn't. Hopefully someone who is set up to compile wx C++ code can quickly translate it over.

Changed 2 years ago by dhyams

Test code that demonstrates this bug.

comment:6 Changed 2 years ago by dhyams

For further information, the code that causes the problem shows up in rev. 58556:

http://svn.wxwidgets.org/viewvc/wx/wxWidgets/trunk/src/msw/menuitem.cpp?r1=56644&r2=58556

All that needs to be done is to remove this bit:

if ( IsOwnerDrawn() )
{
we don't need to do anything for owner drawn items, they will redraw
themselves using the new text the next time they're displayed
return;
}

comment:7 Changed 2 years ago by dhyams

  • Keywords width update added

comment:8 Changed 2 years ago by VZ

  • Resolution set to fixed
  • Status changed from confirmed to closed

(In [73400]) Fix changing labels of menu items with bitmaps in wxMSW.

We need to call SetMenuItemInfo() from wxMenuItem::SetItemLabel() even for the
owner-drawn items, otherwise their width is not recomputed.

Closes #3897.

Note: See TracTickets for help on using tickets.