check the radio buttons when they get focus (closes 777500)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@23774 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -58,6 +58,7 @@ wxMSW:
|
|||||||
- fixed wxTE_*WRAP styles handling
|
- fixed wxTE_*WRAP styles handling
|
||||||
- wxTextCtrl::GetValue() works with text in non default encoding
|
- wxTextCtrl::GetValue() works with text in non default encoding
|
||||||
- changed wxCrashReport to generate minidumps instead of text files
|
- changed wxCrashReport to generate minidumps instead of text files
|
||||||
|
- wxRadioButtons are now checked when they get focus (standard behaviour)
|
||||||
|
|
||||||
wxGTK:
|
wxGTK:
|
||||||
|
|
||||||
|
@@ -52,9 +52,6 @@ public:
|
|||||||
// implementation only from now on
|
// implementation only from now on
|
||||||
virtual bool MSWCommand(WXUINT param, WXWORD id);
|
virtual bool MSWCommand(WXUINT param, WXWORD id);
|
||||||
virtual void Command(wxCommandEvent& event);
|
virtual void Command(wxCommandEvent& event);
|
||||||
virtual long MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
|
|
||||||
|
|
||||||
virtual void SetFocus();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual wxSize DoGetBestSize() const;
|
virtual wxSize DoGetBestSize() const;
|
||||||
@@ -63,8 +60,9 @@ private:
|
|||||||
// common part of all ctors
|
// common part of all ctors
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
// see the comments in SetFocus()
|
// we need to store the state internally as the result of GetValue()
|
||||||
bool m_focusJustSet;
|
// sometimes gets out of sync in WM_COMMAND handler
|
||||||
|
bool m_isChecked;
|
||||||
|
|
||||||
DECLARE_DYNAMIC_CLASS_NO_COPY(wxRadioButton)
|
DECLARE_DYNAMIC_CLASS_NO_COPY(wxRadioButton)
|
||||||
};
|
};
|
||||||
|
@@ -18,23 +18,22 @@
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
|
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
|
||||||
#pragma implementation "radiobut.h"
|
#pragma implementation "radiobut.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// For compilers that support precompilation, includes "wx.h".
|
// For compilers that support precompilation, includes "wx.h".
|
||||||
#include "wx/wxprec.h"
|
#include "wx/wxprec.h"
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
#ifdef __BORLANDC__
|
||||||
#pragma hdrstop
|
#pragma hdrstop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if wxUSE_RADIOBTN
|
#if wxUSE_RADIOBTN
|
||||||
|
|
||||||
#ifndef WX_PRECOMP
|
#ifndef WX_PRECOMP
|
||||||
#include "wx/radiobut.h"
|
#include "wx/radiobut.h"
|
||||||
#include "wx/settings.h"
|
#include "wx/settings.h"
|
||||||
#include "wx/brush.h"
|
#include "wx/dcscreen.h"
|
||||||
#include "wx/dcscreen.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wx/msw/private.h"
|
#include "wx/msw/private.h"
|
||||||
@@ -86,10 +85,10 @@ wxEND_FLAGS( wxRadioButtonStyle )
|
|||||||
IMPLEMENT_DYNAMIC_CLASS_XTI(wxRadioButton, wxControl,"wx/radiobut.h")
|
IMPLEMENT_DYNAMIC_CLASS_XTI(wxRadioButton, wxControl,"wx/radiobut.h")
|
||||||
|
|
||||||
wxBEGIN_PROPERTIES_TABLE(wxRadioButton)
|
wxBEGIN_PROPERTIES_TABLE(wxRadioButton)
|
||||||
wxEVENT_PROPERTY( Click , wxEVT_COMMAND_RADIOBUTTON_SELECTED , wxCommandEvent )
|
wxEVENT_PROPERTY( Click , wxEVT_COMMAND_RADIOBUTTON_SELECTED , wxCommandEvent )
|
||||||
wxPROPERTY( Font , wxFont , SetFont , GetFont , , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
|
wxPROPERTY( Font , wxFont , SetFont , GetFont , , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
|
||||||
wxPROPERTY( Label,wxString, SetLabel, GetLabel, wxString(), 0 /*flags*/ , wxT("Helpstring") , wxT("group") )
|
wxPROPERTY( Label,wxString, SetLabel, GetLabel, wxString(), 0 /*flags*/ , wxT("Helpstring") , wxT("group") )
|
||||||
wxPROPERTY( Value ,bool, SetValue, GetValue,, 0 /*flags*/ , wxT("Helpstring") , wxT("group") )
|
wxPROPERTY( Value ,bool, SetValue, GetValue,, 0 /*flags*/ , wxT("Helpstring") , wxT("group") )
|
||||||
wxPROPERTY_FLAGS( WindowStyle , wxRadioButtonStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style
|
wxPROPERTY_FLAGS( WindowStyle , wxRadioButtonStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style
|
||||||
wxEND_PROPERTIES_TABLE()
|
wxEND_PROPERTIES_TABLE()
|
||||||
|
|
||||||
@@ -105,7 +104,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxRadioButton, wxControl)
|
|||||||
|
|
||||||
void wxRadioButton::Init()
|
void wxRadioButton::Init()
|
||||||
{
|
{
|
||||||
m_focusJustSet = FALSE;
|
m_isChecked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxRadioButton::Create(wxWindow *parent,
|
bool wxRadioButton::Create(wxWindow *parent,
|
||||||
@@ -118,7 +117,7 @@ bool wxRadioButton::Create(wxWindow *parent,
|
|||||||
const wxString& name)
|
const wxString& name)
|
||||||
{
|
{
|
||||||
if ( !CreateControl(parent, id, pos, size, style, validator, name) )
|
if ( !CreateControl(parent, id, pos, size, style, validator, name) )
|
||||||
return FALSE;
|
return false;
|
||||||
|
|
||||||
long msStyle = WS_TABSTOP;
|
long msStyle = WS_TABSTOP;
|
||||||
if ( HasFlag(wxRB_GROUP) )
|
if ( HasFlag(wxRB_GROUP) )
|
||||||
@@ -141,16 +140,16 @@ bool wxRadioButton::Create(wxWindow *parent,
|
|||||||
msStyle |= WS_CLIPSIBLINGS;
|
msStyle |= WS_CLIPSIBLINGS;
|
||||||
|
|
||||||
if ( !MSWCreateControl(_T("BUTTON"), msStyle, pos, size, label, 0) )
|
if ( !MSWCreateControl(_T("BUTTON"), msStyle, pos, size, label, 0) )
|
||||||
return FALSE;
|
return false;
|
||||||
|
|
||||||
// for compatibility with wxGTK, the first radio button in a group is
|
// for compatibility with wxGTK, the first radio button in a group is
|
||||||
// always checked (this makes sense anyhow as you need to ensure that at
|
// always checked (this makes sense anyhow as you need to ensure that at
|
||||||
// least one button in the group is checked and this is the simlpest way to
|
// least one button in the group is checked and this is the simlpest way to
|
||||||
// do it)
|
// do it)
|
||||||
if ( HasFlag(wxRB_GROUP) )
|
if ( HasFlag(wxRB_GROUP) )
|
||||||
SetValue(TRUE);
|
SetValue(true);
|
||||||
|
|
||||||
return TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -163,9 +162,11 @@ void wxRadioButton::SetValue(bool value)
|
|||||||
// value as is (we don't use BST_XXX here as they're not defined for Win16)
|
// value as is (we don't use BST_XXX here as they're not defined for Win16)
|
||||||
(void)::SendMessage(GetHwnd(), BM_SETCHECK, (WPARAM)value, 0L);
|
(void)::SendMessage(GetHwnd(), BM_SETCHECK, (WPARAM)value, 0L);
|
||||||
|
|
||||||
|
m_isChecked = value;
|
||||||
|
|
||||||
// if we set the value of one radio button we also must clear all the other
|
// if we set the value of one radio button we also must clear all the other
|
||||||
// buttons in the same group: Windows doesn't do it automatically
|
// buttons in the same group: Windows doesn't do it automatically
|
||||||
if ( value )
|
if ( m_isChecked )
|
||||||
{
|
{
|
||||||
const wxWindowList& siblings = GetParent()->GetChildren();
|
const wxWindowList& siblings = GetParent()->GetChildren();
|
||||||
wxWindowList::compatibility_iterator nodeThis = siblings.Find(this);
|
wxWindowList::compatibility_iterator nodeThis = siblings.Find(this);
|
||||||
@@ -188,7 +189,7 @@ void wxRadioButton::SetValue(bool value)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
btn->SetValue(FALSE);
|
btn->SetValue(false);
|
||||||
|
|
||||||
if ( btn->HasFlag(wxRB_GROUP) )
|
if ( btn->HasFlag(wxRB_GROUP) )
|
||||||
{
|
{
|
||||||
@@ -213,16 +214,18 @@ void wxRadioButton::SetValue(bool value)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
btn->SetValue(FALSE);
|
btn->SetValue(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxRadioButton::GetValue() const
|
bool wxRadioButton::GetValue() const
|
||||||
{
|
{
|
||||||
// NB: this will also return TRUE for BST_INDETERMINATE value if we ever
|
wxASSERT_MSG( m_isChecked ==
|
||||||
// have 3-state radio buttons
|
(::SendMessage(GetHwnd(), BM_GETCHECK, 0, 0L) != 0),
|
||||||
return ::SendMessage(GetHwnd(), BM_GETCHECK, 0, 0L) != 0;
|
_T("wxRadioButton::m_isChecked is out of sync?") );
|
||||||
|
|
||||||
|
return m_isChecked;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -235,53 +238,26 @@ void wxRadioButton::Command (wxCommandEvent& event)
|
|||||||
ProcessCommand(event);
|
ProcessCommand(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxRadioButton::SetFocus()
|
|
||||||
{
|
|
||||||
// when the radio button receives a WM_SETFOCUS message it generates a
|
|
||||||
// BN_CLICKED which is totally unexpected and leads to catastrophic results
|
|
||||||
// if you pop up a dialog from the radio button event handler as, when the
|
|
||||||
// dialog is dismissed, the focus is returned to the radio button which
|
|
||||||
// generates BN_CLICKED which leads to showing another dialog and so on
|
|
||||||
// without end!
|
|
||||||
//
|
|
||||||
// to avoid this, we drop the pseudo BN_CLICKED events generated when the
|
|
||||||
// button gains focus
|
|
||||||
m_focusJustSet = TRUE;
|
|
||||||
|
|
||||||
wxControl::SetFocus();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxRadioButton::MSWCommand(WXUINT param, WXWORD WXUNUSED(id))
|
bool wxRadioButton::MSWCommand(WXUINT param, WXWORD WXUNUSED(id))
|
||||||
{
|
{
|
||||||
if ( param != BN_CLICKED )
|
if ( param != BN_CLICKED )
|
||||||
return FALSE;
|
return false;
|
||||||
|
|
||||||
if ( m_focusJustSet )
|
if ( !m_isChecked )
|
||||||
{
|
{
|
||||||
// see above: we want to ignore this event
|
// we have to do this for BS_RADIOBUTTON anyhow and, strangely enough,
|
||||||
m_focusJustSet = FALSE;
|
// sometimes this is needed even for BS_AUTORADIOBUTTON (when we
|
||||||
}
|
// receive focus the button gets BN_CLICKED but stays unchecked!)
|
||||||
else // a real clicked event
|
SetValue(true);
|
||||||
{
|
|
||||||
bool isChecked = GetValue();
|
|
||||||
|
|
||||||
if ( HasFlag(wxRB_SINGLE) )
|
|
||||||
{
|
|
||||||
// when we use a "manual" radio button, we have to check the button
|
|
||||||
// ourselves -- but it's reset to unchecked state by the user code
|
|
||||||
// (presumably when another button is pressed)
|
|
||||||
if ( !isChecked )
|
|
||||||
SetValue(TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
wxCommandEvent event(wxEVT_COMMAND_RADIOBUTTON_SELECTED, GetId());
|
wxCommandEvent event(wxEVT_COMMAND_RADIOBUTTON_SELECTED, GetId());
|
||||||
event.SetEventObject( this );
|
event.SetEventObject( this );
|
||||||
event.SetInt(isChecked);
|
event.SetInt(true); // always checked
|
||||||
|
|
||||||
ProcessCommand(event);
|
ProcessCommand(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -320,19 +296,5 @@ wxSize wxRadioButton::DoGetBestSize() const
|
|||||||
return wxSize(wRadio, hRadio);
|
return wxSize(wRadio, hRadio);
|
||||||
}
|
}
|
||||||
|
|
||||||
long wxRadioButton::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
|
|
||||||
{
|
|
||||||
if (nMsg == WM_SETFOCUS)
|
|
||||||
{
|
|
||||||
m_focusJustSet = TRUE;
|
|
||||||
|
|
||||||
long ret = wxControl::MSWWindowProc(nMsg, wParam, lParam);
|
|
||||||
|
|
||||||
m_focusJustSet = FALSE;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
return wxControl::MSWWindowProc(nMsg, wParam, lParam);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // wxUSE_RADIOBTN
|
#endif // wxUSE_RADIOBTN
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user