applied a patch to prevent another IsDialogMessage() hang

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@21714 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2003-07-06 19:43:14 +00:00
parent 13e4c4d981
commit ae79d31557

View File

@@ -1927,12 +1927,50 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
// 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() can enter in an infinite loop when the // ::IsDialogMessage() is broken and may sometimes hang the
// currently focused window is disabled or hidden and its parent // application by going into an infinite loop, so we try to detect
// has WS_EX_CONTROLPARENT style, so don't call it in this case // [some of] the situatations when this may happen and not call it
// then
// 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
// an infinite loop, because it will recursively check the child
// windows but not the window itself and so if none of the children
// accepts focus it loops forever (as it only stops when it gets
// back to the window it started from)
//
// while it is very unusual that a window with WS_EX_CONTROLPARENT
// style has the focus, it can happen. One such possibility is if
// all windows are either toplevel, wxDialog, wxPanel or static
// controls and no window can actually accept keyboard input.
if ( ::GetWindowLong(hwndFocus, GWL_EXSTYLE) & WS_EX_CONTROLPARENT )
{
// passimistic by default
canSafelyCallIsDlgMsg = FALSE;
for ( wxWindowList::Node *node = GetChildren().GetFirst();
node;
node = node->GetNext() )
{
if ( node->GetData()->AcceptsFocus() )
{
// it shouldn't hang...
canSafelyCallIsDlgMsg = TRUE;
break;
}
}
}
if ( canSafelyCallIsDlgMsg )
{
// ::IsDialogMessage() can enter in an infinite loop when the
// currently focused window is disabled or hidden and its
// parent has WS_EX_CONTROLPARENT style, so don't call it in
// this case
while ( hwndFocus ) while ( hwndFocus )
{ {
if ( !::IsWindowEnabled(hwndFocus) || if ( !::IsWindowEnabled(hwndFocus) ||
@@ -1954,7 +1992,9 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
hwndFocus = ::GetParent(hwndFocus); hwndFocus = ::GetParent(hwndFocus);
} }
}
// let IsDialogMessage() have the message if it's safe to call it
if ( canSafelyCallIsDlgMsg && ::IsDialogMessage(GetHwnd(), msg) ) if ( canSafelyCallIsDlgMsg && ::IsDialogMessage(GetHwnd(), msg) )
{ {
// IsDialogMessage() did something... // IsDialogMessage() did something...