ensure that IsDialogMessage() is not called in the situations when it may hang not only from the immediate parent of the control which has focus but also from its grandparents

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@41134 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2006-09-10 16:52:20 +00:00
parent fdc62f4462
commit 98ebf9194b

View File

@@ -2254,27 +2254,69 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
} }
} }
if ( ::IsDialogMessage(GetHwnd(), msg) )
{
// IsDialogMessage() did something...
return true;
}
}
#endif // __WXUNIVERSAL__
#if wxUSE_TOOLTIPS
if ( m_tooltip )
{
// relay mouse move events to the tooltip control
MSG *msg = (MSG *)pMsg;
if ( msg->message == WM_MOUSEMOVE )
wxToolTip::RelayEvent(pMsg);
}
#endif // wxUSE_TOOLTIPS
return false;
}
bool wxWindowMSW::MSWTranslateMessage(WXMSG* pMsg)
{
#if wxUSE_ACCEL && !defined(__WXUNIVERSAL__)
return m_acceleratorTable.Translate(this, pMsg);
#else
(void) pMsg;
return false;
#endif // wxUSE_ACCEL
}
bool wxWindowMSW::MSWShouldPreProcessMessage(WXMSG* msg)
{
// all tests below have to deal with various bugs/misfeatures of
// IsDialogMessage(): we have to prevent it from being called from our
// MSWProcessMessage() in some situations
// don't let IsDialogMessage() get VK_ESCAPE as it _always_ eats the // don't let IsDialogMessage() get VK_ESCAPE as it _always_ eats the
// message even when there is no cancel button and when the message is // message even when there is no cancel button and when the message is
// needed by the control itself: in particular, it prevents the tree in // needed by the control itself: in particular, it prevents the tree in
// place edit control from being closed with Escape in a dialog // place edit control from being closed with Escape in a dialog
if ( msg->message != WM_KEYDOWN || msg->wParam != VK_ESCAPE ) if ( msg->message == WM_KEYDOWN && msg->wParam == VK_ESCAPE )
{ {
// ::IsDialogMessage() is broken and may sometimes hang the return false;
// application by going into an infinite loop, so we try to detect }
// [some of] the situations when this may happen and not call it
// then // ::IsDialogMessage() is broken and may sometimes hang the application by
// going into an infinite loop when it tries to find the control to give
// focus to when Alt-<key> is pressed, so we try to detect [some of] the
// situations when this may happen and not call it then
if ( msg->message != WM_SYSCHAR )
return true;
// assume we can call it by default // assume we can call it by default
bool canSafelyCallIsDlgMsg = true; bool canSafelyCallIsDlgMsg = true;
HWND hwndFocus = ::GetFocus(); HWND hwndFocus = ::GetFocus();
// if the currently focused window itself has WS_EX_CONTROLPARENT style, ::IsDialogMessage() will also enter // if the currently focused window itself has WS_EX_CONTROLPARENT style,
// an infinite loop, because it will recursively check the child // ::IsDialogMessage() will also enter an infinite loop, because it will
// windows but not the window itself and so if none of the children // recursively check the child windows but not the window itself and so if
// accepts focus it loops forever (as it only stops when it gets // none of the children accepts focus it loops forever (as it only stops
// back to the window it started from) // when it gets back to the window it started from)
// //
// while it is very unusual that a window with WS_EX_CONTROLPARENT // while it is very unusual that a window with WS_EX_CONTROLPARENT
// style has the focus, it can happen. One such possibility is if // style has the focus, it can happen. One such possibility is if
@@ -2332,43 +2374,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
} }
} }
// let IsDialogMessage() have the message if it's safe to call it return canSafelyCallIsDlgMsg;
if ( canSafelyCallIsDlgMsg && ::IsDialogMessage(GetHwnd(), msg) )
{
// IsDialogMessage() did something...
return true;
}
}
}
#endif // __WXUNIVERSAL__
#if wxUSE_TOOLTIPS
if ( m_tooltip )
{
// relay mouse move events to the tooltip control
MSG *msg = (MSG *)pMsg;
if ( msg->message == WM_MOUSEMOVE )
wxToolTip::RelayEvent(pMsg);
}
#endif // wxUSE_TOOLTIPS
return false;
}
bool wxWindowMSW::MSWTranslateMessage(WXMSG* pMsg)
{
#if wxUSE_ACCEL && !defined(__WXUNIVERSAL__)
return m_acceleratorTable.Translate(this, pMsg);
#else
(void) pMsg;
return false;
#endif // wxUSE_ACCEL
}
bool wxWindowMSW::MSWShouldPreProcessMessage(WXMSG* WXUNUSED(pMsg))
{
// preprocess all messages by default
return true;
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------