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:
@@ -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...
|
||||||
|
Reference in New Issue
Block a user