Factor out methods for clicking the default button in wxMSW

This will make it possible to reproduce the default "Enter" key functionality
from elsewhere.

Almost no changes yet, the only minor change is that we now wouldn't try to
"click" any windows using DLGC_DEFPUSHBUTTON dialog code but which are not
really buttons -- but then this shouldn't ever happen anyhow.
This commit is contained in:
Vadim Zeitlin
2015-11-19 01:03:56 +01:00
parent d3e7833a90
commit 99a1526ee3
2 changed files with 50 additions and 18 deletions

View File

@@ -14,6 +14,8 @@
#include "wx/settings.h" // solely for wxSystemColour
class WXDLLIMPEXP_FWD_CORE wxButton;
// if this is set to 1, we use deferred window sizing to reduce flicker when
// resizing complicated window hierarchies, but this can in theory result in
// different behaviour than the old code so we keep the possibility to use it
@@ -534,6 +536,16 @@ public:
virtual wxMenu* MSWFindMenuFromHMENU(WXHMENU hMenu);
#endif // wxUSE_MENUS && !__WXUNIVERSAL__
// Return the default button for the TLW containing this window or NULL if
// none.
static wxButton* MSWGetDefaultButtonFor(wxWindow* win);
// Simulate a click on the given button if it is non-null, enabled and
// shown.
//
// Return true if the button was clicked, false otherwise.
static bool MSWClickButtonIfPossible(wxButton* btn);
protected:
// this allows you to implement standard control borders without
// repeating the code in different classes that are not derived from

View File

@@ -2316,7 +2316,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
// currently active button should get enter press even
// if there is a default button elsewhere so check if
// this window is a button first
wxWindow *btn = NULL;
wxButton *btn = NULL;
if ( lDlgCode & DLGC_DEFPUSHBUTTON )
{
// let IsDialogMessage() handle this for all
@@ -2325,8 +2325,11 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
long style = ::GetWindowLong(msg->hwnd, GWL_STYLE);
if ( (style & BS_OWNERDRAW) == BS_OWNERDRAW )
{
// emulate the button click
btn = wxFindWinFromHandle(msg->hwnd);
btn = wxDynamicCast
(
wxFindWinFromHandle(msg->hwnd),
wxButton
);
}
}
else // not a button itself, do we have default button?
@@ -2367,25 +2370,12 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
);
}
}
else // bCtrlDown
{
win = wxGetTopLevelParent(win);
btn = MSWGetDefaultButtonFor(win);
}
wxTopLevelWindow * const
tlw = wxDynamicCast(win, wxTopLevelWindow);
if ( tlw )
{
btn = wxDynamicCast(tlw->GetDefaultItem(),
wxButton);
}
}
if ( btn && btn->IsEnabled() && btn->IsShownOnScreen() )
{
btn->MSWCommand(BN_CLICKED, 0 /* unused */);
if ( MSWClickButtonIfPossible(btn) )
return true;
}
// This "Return" key press won't be actually used for
// navigation so don't generate wxNavigationKeyEvent
@@ -2544,6 +2534,36 @@ bool wxWindowMSW::MSWSafeIsDialogMessage(WXMSG* msg)
#endif // __WXUNIVERSAL__
/* static */
wxButton* wxWindowMSW::MSWGetDefaultButtonFor(wxWindow* win)
{
#if wxUSE_BUTTON
win = wxGetTopLevelParent(win);
wxTopLevelWindow *const tlw = wxDynamicCast(win, wxTopLevelWindow);
if ( tlw )
return wxDynamicCast(tlw->GetDefaultItem(), wxButton);
#endif // wxUSE_BUTTON
return NULL;
}
/* static */
bool wxWindowMSW::MSWClickButtonIfPossible(wxButton* btn)
{
#if wxUSE_BUTTON
if ( btn && btn->IsEnabled() && btn->IsShownOnScreen() )
{
btn->MSWCommand(BN_CLICKED, 0 /* unused */);
return true;
}
#endif // wxUSE_BUTTON
wxUnusedVar(btn);
return false;
}
// ---------------------------------------------------------------------------
// message params unpackers
// ---------------------------------------------------------------------------