1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxRadioButton
4 // Author: David Webster
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
22 #include "wx/radiobut.h"
24 #include "wx/dcscreen.h"
25 #include "wx/settings.h"
28 #include "wx/os2/private.h"
30 IMPLEMENT_DYNAMIC_CLASS(wxRadioButton
, wxControl
)
32 extern void wxAssociateWinWithHandle( HWND hWnd
36 void wxRadioButton::Init()
38 m_bFocusJustSet
= FALSE
;
39 } // end of wxRadioButton::Init
41 void wxRadioButton::Command (
42 wxCommandEvent
& rEvent
45 SetValue ((rEvent
.GetInt() != 0) );
46 ProcessCommand (rEvent
);
47 } // end of wxRadioButton::Command
49 bool wxRadioButton::Create(
52 , const wxString
& rsLabel
57 , const wxValidator
& rValidator
59 , const wxString
& rsName
62 if ( !CreateControl( pParent
73 long lSstyle
= WS_TABSTOP
;
75 if (HasFlag(wxRB_GROUP
))
79 // wxRB_SINGLE is a temporary workaround for the following problem: if you
80 // have 2 radiobuttons in the same group but which are not consecutive in
81 // the dialog, Windows can enter an infinite loop! The simplest way to
82 // reproduce it is to create radio button, then a panel and then another
83 // radio button: then checking the last button hangs the app.
85 // Ideally, we'd detect (and avoid) such situation automatically but for
86 // now, as I don't know how to do it, just allow the user to create
87 // BS_RADIOBUTTON buttons for such situations.
89 lSstyle
|= HasFlag(wxRB_SINGLE
) ? BS_RADIOBUTTON
: BS_AUTORADIOBUTTON
;
91 if (HasFlag(wxCLIP_SIBLINGS
))
92 lSstyle
|= WS_CLIPSIBLINGS
;
94 if (!OS2CreateControl( _T("BUTTON")
103 wxAssociateWinWithHandle(m_hWnd
, this);
104 if (HasFlag(wxRB_GROUP
))
107 SetFont(*wxSMALL_FONT
);
114 } // end of wxRadioButton::Create
116 wxSize
wxRadioButton::DoGetBestSize() const
118 static int snRadioSize
= 0;
124 vDC
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
125 snRadioSize
= vDC
.GetCharHeight();
128 wxString sStr
= GetLabel();
138 nRadioWidth
+= snRadioSize
+ GetCharWidth();
139 if (nRadioHeight
< snRadioSize
)
140 nRadioHeight
= snRadioSize
;
144 nRadioWidth
= snRadioSize
;
145 nRadioHeight
= snRadioSize
;
147 return wxSize( nRadioWidth
150 } // end of wxRadioButton::DoGetBestSize
153 // Get single selection, for single choice list items
155 bool wxRadioButton::GetValue() const
157 return((::WinSendMsg((HWND
) GetHWND(), BM_QUERYCHECK
, (MPARAM
)0L, (MPARAM
)0L) != 0));
158 } // end of wxRadioButton::GetValue
160 bool wxRadioButton::OS2Command(
165 if (wParam
!= BN_CLICKED
)
171 // See above: we want to ignore this event
173 m_bFocusJustSet
= FALSE
;
177 bool bIsChecked
= GetValue();
179 if (HasFlag(wxRB_SINGLE
))
182 // When we use a "manual" radio button, we have to check the button
183 // ourselves -- but it's reset to unchecked state by the user code
184 // (presumably when another button is pressed)
189 wxCommandEvent
rEvent( wxEVT_COMMAND_RADIOBUTTON_SELECTED
193 rEvent
.SetEventObject(this);
194 ProcessCommand(rEvent
);
197 } // end of wxRadioButton::OS2Command
199 void wxRadioButton::SetFocus()
201 // when the radio button receives a WM_SETFOCUS message it generates a
202 // BN_CLICKED which is totally unexpected and leads to catastrophic results
203 // if you pop up a dialog from the radio button event handler as, when the
204 // dialog is dismissed, the focus is returned to the radio button which
205 // generates BN_CLICKED which leads to showing another dialog and so on
208 // to aviod this, we drop the pseudo BN_CLICKED events generated when the
209 // button gains focus
210 m_bFocusJustSet
= TRUE
;
212 wxControl::SetFocus();
215 void wxRadioButton::SetLabel(
216 const wxString
& rsLabel
219 ::WinSetWindowText((HWND
)GetHWND(), (const char *)rsLabel
.c_str());
220 } // end of wxRadioButton::SetLabel
222 void wxRadioButton::SetValue(
226 ::WinSendMsg((HWND
)GetHWND(), BM_SETCHECK
, (MPARAM
)bValue
, (MPARAM
)0);
229 const wxWindowList
& rSiblings
= GetParent()->GetChildren();
230 wxWindowList::Node
* pNodeThis
= rSiblings
.Find(this);
232 wxCHECK_RET(pNodeThis
, _T("radio button not a child of its parent?"));
235 // Turn off all radio buttons before this one
237 for ( wxWindowList::Node
* pNodeBefore
= pNodeThis
->GetPrevious();
239 pNodeBefore
= pNodeBefore
->GetPrevious() )
241 wxRadioButton
* pBtn
= wxDynamicCast( pNodeBefore
->GetData()
247 // The radio buttons in a group must be consecutive, so there
248 // are no more of them
252 pBtn
->SetValue(FALSE
);
253 if (pBtn
->HasFlag(wxRB_GROUP
))
256 // Even if there are other radio buttons before this one,
257 // they're not in the same group with us
264 // ... and all after this one
266 for (wxWindowList::Node
* pNodeAfter
= pNodeThis
->GetNext();
268 pNodeAfter
= pNodeAfter
->GetNext())
270 wxRadioButton
* pBtn
= wxDynamicCast( pNodeAfter
->GetData()
274 if (!pBtn
|| pBtn
->HasFlag(wxRB_GROUP
) )
277 // No more buttons or the first button of the next group
281 pBtn
->SetValue(FALSE
);
284 } // end of wxRadioButton::SetValue
286 MRESULT
wxRadioButton::OS2WindowProc(
292 if (uMsg
== WM_SETFOCUS
)
294 m_bFocusJustSet
= TRUE
;
296 MRESULT mRc
= wxControl::OS2WindowProc( uMsg
301 m_bFocusJustSet
= FALSE
;
304 return wxControl::OS2WindowProc( uMsg
308 } // end of wxRadioButton::OS2WindowProc