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
This commit is contained in:
Vadim Zeitlin
2014-12-05 22:19:19 +00:00
parent 79f93d5535
commit bf08ea2666
3 changed files with 31 additions and 0 deletions

View File

@@ -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;

View File

@@ -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:
{

View File

@@ -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