Opened 3 years ago

Closed 6 months ago

#13544 closed defect (fixed)

SetMenuItemInfo not called for precreated and/or owner-drawn menu items

Reported by: yaroslavp Owned by:
Priority: normal Milestone:
Component: wxMSW Version: 2.9.2
Keywords: menus Cc:
Blocked By: Blocking:
Patch: no

Description

Hello,

I am migrating my application from wxWidgets 2.8.8 to 2.9.2. After the upgrade, my automation testing suite (implemented in AutoIT) stopped recognizing menus in the tested application. Windows reports they are empty, though they look perfectly normal.

In wxMenuItem::SetItemLabel() ( \wxWidgets-2.9.2\src\msw\menuitem.cpp ) I believe the following code is to blame:

    if ( !hMenu || ::GetMenuState(hMenu, id, MF_BYCOMMAND) == (UINT)-1 )
        return;

#if wxUSE_OWNER_DRAWN
    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;
    }
#endif // owner drawn

Firstly, the GetMenuState() check is detrimental: in my application code, I am creating a new wxMenuItem, but have not yet appended it to a wxMenu - it is a valid scenario. Were it not for GetMenuState(), still IsOwnerDrawn() would also cause an early return and prevent SetMenuItemInfo() below from executing.

Removing both checks worked for me: the menus were recognized again. I am not sure this doesn't introduce some new bugs, though, so I refrained from making a patch.

Thanks!

Change History (6)

comment:1 Changed 3 years ago by yaroslavp

Correction:

"Removing both checks worked for me: the menus were recognized again."

should read

"Removing the first check and making the menu items non-onwerdrawn by removing icons worked for me."

comment:2 Changed 3 years ago by vadz

  • Status changed from new to infoneeded_new

This code has changed significantly and I don't know whether your problem that you report is still present in the latest svn, could you please check it?

Also, if it does still exist, could you please find some way to reproduce it not involving AutoIT so that I could test it myself?

Thanks!

comment:3 Changed 3 years ago by yaroslavp

  • Status changed from infoneeded_new to new

Thanks for responding. The problematic code in wxMenuItem::SetItemLabel() didn't change (verified here: http://trac.wxwidgets.org/browser/wxWidgets/trunk/src/msw/menuitem.cpp ).

The easy way to check for the bug is to use WinAPI's GetMenuString(). In the menu sample ( wxwidgets/samples/menu.cpp ), after this section

#if USE_LOG_WINDOW
    wxMenuItem *item = new wxMenuItem(fileMenu, Menu_File_ClearLog,
                                      wxT("Clear &log\tCtrl-L"));
#if wxUSE_OWNER_DRAWN || defined(__WXGTK__)
    item->SetBitmap(copy_xpm);
#endif
    fileMenu->Append(item);

insert the following verification code

	wchar_t tmp[256]; GetMenuString(fileMenu->GetHMenu(), Menu_File_ClearLog, tmp, 256, MF_BYCOMMAND);

and observe that tmp is initialized to empty string. On the other hand, the same verification code after this line

    menubarMenu->Append(Menu_MenuBar_Append, wxT("&Append menu\tCtrl-A"),
                        wxT("Append a menu to the menubar"));

correctly yields the menu text.

As you can see, in the first case a menu item object is precreated and also has an icon, unlike the second case.

Please tell if this is good enough.

comment:4 Changed 10 months ago by vadz

Sorry for returning to it so late but I'm still not sure what the problem is, exactly. I agree that we don't do anything at Windows level if the menu item is not appended to the menu yet but why exactly is it a problem, again? Do the menu items labels remain wrong after it is attached?

I'd really like to have a patch to the menu sample showing the problem just to understand what are we trying to fix here...

comment:5 Changed 6 months ago by vadz

I've looked at this again and the problem here is that we create the item with copy_xpm bitmap in the sample as an owner-drawn item, not as a normal item with a bitmap. And owner drawn items don't have any associated text as it's rendered on demand, of course. So the only way to avoid this problem is to create normal items and not owner-drawn ones.

The code to check for the bitmap size and create owner-drawn items if it's too big was added in r58557 and was related to #10452 where we had really big communication problems, so I'm not sure what the problem really was. But testing it now, everything seems to work just fine under Win7, even with large bitmaps, when using native support for them. So I'm going to keep this code enabled for XP only as there the too wide bitmaps are indeed truncated.

To summarize, retrieving the item text should now work in all cases except when too big (i.e. bigger than standard) bitmaps are used under XP or earlier. And I don't really know what can we do about this remaining case, so AFAICS there is nothing remaining to do here.

comment:6 Changed 6 months ago by VZ

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

(In [75001]) Don't use owner drawn items under Win7 even when using larger bitmaps.

The check for menu bitmaps size added in r58557 was apparently only needed for
XP and earlier versions and doesn't seem to be necessary under Win7, so don't
use it there, if only because it allows to retrieve the menu item text which
is useful for automation/screen reader tools.

Closes #13544.

Note: See TracTickets for help on using tickets.