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:
Vadim Zeitlin
2003-09-21 15:09:13 +00:00
parent 54cf600d4e
commit f607434a0f
3 changed files with 37 additions and 76 deletions

View File

@@ -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:

View File

@@ -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)
}; };

View File

@@ -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