Fix busy cursor handling in modal dialogs under MSW.

Modal dialogs shown during wxBusyCursor effect shouldn't show the busy cursor
as they do accept input, but did in wxMSW (as could be seen in e.g. the
widgets sample after enabling the "Global busy cursor" in the menu and showing
the text entry dialog via "Text|Set Help Hint").

Fix this by explicitly checking for the special case of having a modal dialog
as parent at wxWindow level as doing it in wxDialog simply didn't work as its
WM_SETCURSOR handler wasn't called at all for determining the cursor to use
for its children because they handled WM_SETCURSOR themselves in the global
busy state, without letting DefWindowProc(), which propagates this message
upwards the window hierarchy, to have it at all.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@76449 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2014-05-04 22:12:32 +00:00
parent e3979f5186
commit 07427c4fbd
2 changed files with 14 additions and 28 deletions

View File

@ -430,34 +430,6 @@ WXLRESULT wxDialog::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lPar
::InvalidateRect(GetHwnd(), NULL, false /* erase bg */);
}
break;
#ifndef __WXMICROWIN__
case WM_SETCURSOR:
// we want to override the busy cursor for modal dialogs:
// typically, wxBeginBusyCursor() is called and then a modal dialog
// is shown, but the modal dialog shouldn't have hourglass cursor
if ( IsModal() && wxIsBusy() )
{
// set our cursor for all windows (but see below)
wxCursor cursor = m_cursor;
if ( !cursor.IsOk() )
cursor = wxCURSOR_ARROW;
::SetCursor(GetHcursorOf(cursor));
// in any case, stop here and don't let wxWindow process this
// message (it would set the busy cursor)
processed = true;
// but return false to tell the child window (if the event
// comes from one of them and not from ourselves) that it can
// set its own cursor if it has one: thus, standard controls
// (e.g. text ctrl) still have correct cursors in a dialog
// invoked while wxIsBusy()
rc = false;
}
break;
#endif // __WXMICROWIN__
}
if ( !processed )

View File

@ -34,6 +34,7 @@
#include "wx/dc.h"
#include "wx/dcclient.h"
#include "wx/dcmemory.h"
#include "wx/dialog.h"
#include "wx/utils.h"
#include "wx/app.h"
#include "wx/layout.h"
@ -4198,7 +4199,20 @@ bool wxWindowMSW::HandleSetCursor(WXHWND WXUNUSED(hWnd),
// 3. if still no cursor but we're in a TLW, set the global cursor
HCURSOR hcursor = 0;
// Check for "business" is complicated by the fact that modal dialogs shown
// while busy cursor is in effect shouldn't show it as they are active and
// accept input from the user, unlike all the other windows.
bool isBusy = false;
if ( wxIsBusy() )
{
wxDialog* const
dlg = wxDynamicCast(wxGetTopLevelParent(this), wxDialog);
if ( !dlg || !dlg->IsModal() )
isBusy = true;
}
if ( isBusy )
{
hcursor = wxGetCurrentBusyCursor();
}