From bf08ea26669b236c5857a8d530bb4dd892d309f7 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 5 Dec 2014 22:19:19 +0000 Subject: [PATCH] Don't generate wxEVT_MENU_{OPEN,CLOSE} for disabled top menus in wxMSW. Windows still sends these messages even if a top level menu is disabled, for some reason, so filter them out manually. Closes #2168. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@78247 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/msw/menu.h | 3 +++ src/msw/frame.cpp | 16 ++++++++++++++++ src/msw/menu.cpp | 12 ++++++++++++ 3 files changed, 31 insertions(+) diff --git a/include/wx/msw/menu.h b/include/wx/msw/menu.h index 56f009ab89..7ecdf485be 100644 --- a/include/wx/msw/menu.h +++ b/include/wx/msw/menu.h @@ -235,6 +235,9 @@ public: void Refresh( bool eraseBackground, const wxRect *rect = (const wxRect *) NULL ) { wxWindow::Refresh(eraseBackground, rect); } + // Get a top level menu position or wxNOT_FOUND from its handle. + int MSWGetTopMenuPos(WXHMENU hMenu) const; + // Get a top level or sub menu with given handle (recursively). wxMenu* MSWGetMenu(WXHMENU hMenu) const; diff --git a/src/msw/frame.cpp b/src/msw/frame.cpp index 9b7e456ba0..078888b33c 100644 --- a/src/msw/frame.cpp +++ b/src/msw/frame.cpp @@ -985,6 +985,22 @@ WXLRESULT wxFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lPara } break; + case WM_INITMENUPOPUP: + case WM_UNINITMENUPOPUP: + // We get these messages from the menu bar even if the menu is + // disabled, which is unexpected, so ignore them in this case. + if ( wxMenuBar* mbar = GetMenuBar() ) + { + const int pos = mbar->MSWGetTopMenuPos((WXHMENU)wParam); + if ( pos != wxNOT_FOUND && !mbar->IsEnabledTop(pos) ) + { + // This event comes from a disabled top level menu, don't + // handle it. + return MSWDefWindowProc(message, wParam, lParam); + } + } + break; + #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__) case WM_QUERYDRAGICON: { diff --git a/src/msw/menu.cpp b/src/msw/menu.cpp index 3a9ecd594a..1a1e6e0038 100644 --- a/src/msw/menu.cpp +++ b/src/msw/menu.cpp @@ -1629,6 +1629,18 @@ void wxMenuBar::Detach() wxMenuBarBase::Detach(); } +int wxMenuBar::MSWGetTopMenuPos(WXHMENU hMenu) const +{ + for ( size_t n = 0 ; n < GetMenuCount(); ++n ) + { + wxMenu* menu = GetMenu(n)->MSWGetMenu(hMenu); + if ( menu ) + return n; + } + + return wxNOT_FOUND; +} + wxMenu* wxMenuBar::MSWGetMenu(WXHMENU hMenu) const { // If we're called with the handle of the menu bar itself, we can return