diff --git a/include/wx/event.h b/include/wx/event.h index a7670bd0f5..42060febb5 100644 --- a/include/wx/event.h +++ b/include/wx/event.h @@ -45,6 +45,7 @@ class WXDLLIMPEXP_FWD_BASE wxEventFilter; #if wxUSE_GUI class WXDLLIMPEXP_FWD_CORE wxDC; class WXDLLIMPEXP_FWD_CORE wxMenu; + class WXDLLIMPEXP_FWD_CORE wxMenuItem; class WXDLLIMPEXP_FWD_CORE wxReadOnlyDC; class WXDLLIMPEXP_FWD_CORE wxWindow; class WXDLLIMPEXP_FWD_CORE wxWindowBase; @@ -2576,12 +2577,12 @@ private: class WXDLLIMPEXP_CORE wxMenuEvent : public wxEvent { public: - wxMenuEvent(wxEventType type = wxEVT_NULL, int winid = 0, wxMenu* menu = nullptr) + wxMenuEvent(wxEventType type = wxEVT_NULL, int winid = 0, wxMenu* menu = nullptr, wxMenuItem* menuItem = nullptr) : wxEvent(winid, type) - { m_menuId = winid; m_menu = menu; } + { m_menuId = winid; m_menu = menu; m_menuItem = menuItem; } wxMenuEvent(const wxMenuEvent& event) : wxEvent(event) - { m_menuId = event.m_menuId; m_menu = event.m_menu; } + { m_menuId = event.m_menuId; m_menu = event.m_menu; m_menuItem = event.m_menuItem; } // only for wxEVT_MENU_HIGHLIGHT int GetMenuId() const { return m_menuId; } @@ -2592,11 +2593,14 @@ public: // only for wxEVT_MENU_OPEN/CLOSE wxMenu* GetMenu() const { return m_menu; } + wxMenuItem* GetMenuItem() const { return m_menuItem; } + virtual wxEvent *Clone() const override { return new wxMenuEvent(*this); } private: - int m_menuId; - wxMenu* m_menu; + int m_menuId; + wxMenu* m_menu; + wxMenuItem* m_menuItem; wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxMenuEvent); }; diff --git a/include/wx/msw/window.h b/include/wx/msw/window.h index dcf558d559..e24d34a29d 100644 --- a/include/wx/msw/window.h +++ b/include/wx/msw/window.h @@ -574,6 +574,10 @@ public: // Find the menu corresponding to the given handle. virtual wxMenu* MSWFindMenuFromHMENU(WXHMENU hMenu); + + // Find the the current menu item using the given handle and the item id + virtual wxMenuItem* MSWFindMenuItemFromHMENU(WXHMENU hMenu, int nItem); + #endif // wxUSE_MENUS && !__WXUNIVERSAL__ // Return the default button for the TLW containing this window or nullptr if diff --git a/src/common/framecmn.cpp b/src/common/framecmn.cpp index 3a7c667c8d..d4bec2c5cd 100644 --- a/src/common/framecmn.cpp +++ b/src/common/framecmn.cpp @@ -343,7 +343,14 @@ void wxFrameBase::OnMenuHighlight(wxMenuEvent& event) { event.Skip(); - (void)ShowMenuHelp(event.GetMenuId()); + if ( wxMenuItem* menuItem = event.GetMenuItem() ) + { + DoGiveHelp(menuItem->GetHelp(), true); + } + else + { + (void)ShowMenuHelp(event.GetMenuId()); + } } void wxFrameBase::OnMenuClose(wxMenuEvent& event) diff --git a/src/msw/window.cpp b/src/msw/window.cpp index e882a5cdb7..971b182784 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -2524,11 +2524,13 @@ wxWindowMSW::HandleMenuSelect(WXWORD nItem, WXWORD flags, WXHMENU hMenu) // the top level menus of the menu bar, which can't be represented using // any valid identifier in wxMenuEvent so use an otherwise unused value for // them - if ( flags & (MF_POPUP | MF_SEPARATOR) ) + if ( flags & MF_SEPARATOR ) item = wxID_NONE; wxMenu* menu = MSWFindMenuFromHMENU(hMenu); - wxMenuEvent event(wxEVT_MENU_HIGHLIGHT, item, menu); + wxMenuItem* menuItem = MSWFindMenuItemFromHMENU(hMenu, item); + + wxMenuEvent event(wxEVT_MENU_HIGHLIGHT, item, menu, menuItem); if ( wxMenu::ProcessMenuEvent(menu, event, this) ) return true; @@ -2577,6 +2579,37 @@ wxMenu* wxWindowMSW::MSWFindMenuFromHMENU(WXHMENU hMenu) return nullptr; } +wxMenuItem* wxWindowMSW::MSWFindMenuItemFromHMENU(WXHMENU hMenu, int item) +{ + WinStruct mii; + mii.fMask = MIIM_ID | MIIM_DATA; // Include MIIM_DATA to access dwItemData + + const int count = ::GetMenuItemCount(hMenu); + for ( int i = 0; i < count; i++ ) + { + if ( ::GetMenuItemInfo(hMenu, i, TRUE, &mii) ) + { + wxMenuItem* menuItem = (wxMenuItem*)mii.dwItemData; + if ( mii.wID == (unsigned int)item && menuItem ) + { + return menuItem; + } + + // Check for submenus + if ( mii.hSubMenu ) + { + wxMenuItem* foundInSubmenu = MSWFindMenuItemFromHMENU(mii.hSubMenu, item); + if ( foundInSubmenu ) + { + return foundInSubmenu; + } + } + } + } + + return nullptr; // Not found +} + #endif // wxUSE_MENUS && !defined(__WXUNIVERSAL__) // ===========================================================================