Fix possible hang after clearing wxTAB_TRAVERSAL style in wxMSW

Clearing this style by calling SetWindowStyleFlag() could reset
WS_EX_CONTROLPARENT extended flags bit, breaking the invariant that the
parent of any window with this bit set has it as well and resulting in
hangs due to infinite loops inside Windows own code iterating over the
controls.

Prevent this from happening by always preserving this style bit if it
was previously set in MSWUpdateStyle(). This is a bit ugly, but there
doesn't seem to be any obviously better way to do it.

Closes #18091.
This commit is contained in:
Vadim Zeitlin 2018-02-28 16:55:16 +01:00
parent 6b3b05e5f7
commit e87544ae70
2 changed files with 12 additions and 1 deletions

View File

@ -71,6 +71,10 @@ All:
- Make wxList and wxVector iterators conform to input iterator requirements. - Make wxList and wxVector iterators conform to input iterator requirements.
wxMSW:
- Fix hang after clearing wxTAB_TRAVERSAL style on a window with children.
3.1.1: (released 2018-02-19) 3.1.1: (released 2018-02-19)
---------------------------- ----------------------------

View File

@ -1409,7 +1409,14 @@ void wxWindowMSW::MSWUpdateStyle(long flagsOld, long exflagsOld)
WS_SYSMENU) ) != 0; WS_SYSMENU) ) != 0;
} }
// and the extended style // There is one extra complication with the extended style: we must never
// reset WS_EX_CONTROLPARENT because it may break the invariant that the
// parent of any window with this style bit set has it as well. We enforce
// this invariant elsewhere and must not clear it here to avoid the fatal
// problems (hangs) which happen if we break it, so ensure it is preserved.
if ( exstyleOld & WS_EX_CONTROLPARENT )
exstyle |= WS_EX_CONTROLPARENT;
wxMSWWinExStyleUpdater updateExStyle(GetHwnd()); wxMSWWinExStyleUpdater updateExStyle(GetHwnd());
if ( updateExStyle.TurnOff(exstyleOld).TurnOn(exstyle).Apply() ) if ( updateExStyle.TurnOff(exstyleOld).TurnOn(exstyle).Apply() )
{ {