1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/radiobut.cpp
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"
21 #include "wx/radiobut.h"
23 #include "wx/dcscreen.h"
24 #include "wx/settings.h"
27 #include "wx/os2/private.h"
29 IMPLEMENT_DYNAMIC_CLASS(wxRadioButton
, wxControl
)
31 extern void wxAssociateWinWithHandle( HWND hWnd
35 void wxRadioButton::Init()
37 m_bFocusJustSet
= FALSE
;
38 } // end of wxRadioButton::Init
40 void wxRadioButton::Command (
41 wxCommandEvent
& rEvent
44 SetValue ((rEvent
.GetInt() != 0) );
45 ProcessCommand (rEvent
);
46 } // end of wxRadioButton::Command
48 bool wxRadioButton::Create(
51 , const wxString
& rsLabel
55 , const wxValidator
& rValidator
56 , const wxString
& rsName
59 if ( !CreateControl( pParent
68 long lSstyle
= WS_TABSTOP
;
70 if (HasFlag(wxRB_GROUP
))
74 // wxRB_SINGLE is a temporary workaround for the following problem: if you
75 // have 2 radiobuttons in the same group but which are not consecutive in
76 // the dialog, Windows can enter an infinite loop! The simplest way to
77 // reproduce it is to create radio button, then a panel and then another
78 // radio button: then checking the last button hangs the app.
80 // Ideally, we'd detect (and avoid) such situation automatically but for
81 // now, as I don't know how to do it, just allow the user to create
82 // BS_RADIOBUTTON buttons for such situations.
84 lSstyle
|= HasFlag(wxRB_SINGLE
) ? BS_RADIOBUTTON
: BS_AUTORADIOBUTTON
;
86 if (HasFlag(wxCLIP_SIBLINGS
))
87 lSstyle
|= WS_CLIPSIBLINGS
;
89 if (!OS2CreateControl( _T("BUTTON")
98 wxAssociateWinWithHandle(m_hWnd
, this);
99 if (HasFlag(wxRB_GROUP
))
102 SetFont(*wxSMALL_FONT
);
109 } // end of wxRadioButton::Create
111 wxSize
wxRadioButton::DoGetBestSize() const
113 // We should probably compute snRadioSize but it seems to be a constant
114 // independent of its label's font size and not made available by OS/2.
115 static int snRadioSize
= RADIO_SIZE
;
117 wxString sStr
= wxGetWindowText(GetHwnd());
127 nRadioWidth
+= snRadioSize
;
128 if (nRadioHeight
< snRadioSize
)
129 nRadioHeight
= snRadioSize
;
133 nRadioWidth
= snRadioSize
;
134 nRadioHeight
= snRadioSize
;
136 return wxSize( nRadioWidth
139 } // end of wxRadioButton::DoGetBestSize
142 // Get single selection, for single choice list items
144 bool wxRadioButton::GetValue() const
146 return((::WinSendMsg((HWND
) GetHWND(), BM_QUERYCHECK
, (MPARAM
)0L, (MPARAM
)0L) != 0));
147 } // end of wxRadioButton::GetValue
149 bool wxRadioButton::OS2Command( WXUINT wParam
, WXWORD
WXUNUSED(wId
) )
151 if (wParam
!= BN_CLICKED
)
157 // See above: we want to ignore this event
159 m_bFocusJustSet
= false;
163 bool bIsChecked
= GetValue();
165 if (HasFlag(wxRB_SINGLE
))
168 // When we use a "manual" radio button, we have to check the button
169 // ourselves -- but it's reset to unchecked state by the user code
170 // (presumably when another button is pressed)
175 wxCommandEvent
rEvent( wxEVT_COMMAND_RADIOBUTTON_SELECTED
, m_windowId
);
176 rEvent
.SetEventObject(this);
177 ProcessCommand(rEvent
);
180 } // end of wxRadioButton::OS2Command
182 void wxRadioButton::SetFocus()
184 // when the radio button receives a WM_SETFOCUS message it generates a
185 // BN_CLICKED which is totally unexpected and leads to catastrophic results
186 // if you pop up a dialog from the radio button event handler as, when the
187 // dialog is dismissed, the focus is returned to the radio button which
188 // generates BN_CLICKED which leads to showing another dialog and so on
191 // to avoid this, we drop the pseudo BN_CLICKED events generated when the
192 // button gains focus
193 m_bFocusJustSet
= true;
195 wxControl::SetFocus();
198 void wxRadioButton::SetLabel(
199 const wxString
& rsLabel
202 wxString sLabel
= ::wxPMTextToLabel(rsLabel
);
203 ::WinSetWindowText((HWND
)GetHWND(), (const char *)sLabel
.c_str());
204 } // end of wxRadioButton::SetLabel
206 void wxRadioButton::SetValue(
210 ::WinSendMsg((HWND
)GetHWND(), BM_SETCHECK
, (MPARAM
)bValue
, (MPARAM
)0);
213 const wxWindowList
& rSiblings
= GetParent()->GetChildren();
214 wxWindowList::compatibility_iterator nodeThis
= rSiblings
.Find(this);
216 wxCHECK_RET(nodeThis
, _T("radio button not a child of its parent?"));
219 // If it's not the first item of the group ...
221 if ( !HasFlag(wxRB_GROUP
) )
224 // ...turn off all radio buttons before this one
226 for ( wxWindowList::compatibility_iterator nodeBefore
= nodeThis
->GetPrevious();
228 nodeBefore
= nodeBefore
->GetPrevious() )
230 wxRadioButton
* pBtn
= wxDynamicCast( nodeBefore
->GetData()
236 // The radio buttons in a group must be consecutive, so there
237 // are no more of them
241 pBtn
->SetValue(FALSE
);
242 if (pBtn
->HasFlag(wxRB_GROUP
))
245 // Even if there are other radio buttons before this one,
246 // they're not in the same group with us
254 // ... and all after this one
256 for (wxWindowList::compatibility_iterator nodeAfter
= nodeThis
->GetNext();
258 nodeAfter
= nodeAfter
->GetNext())
260 wxRadioButton
* pBtn
= wxDynamicCast( nodeAfter
->GetData()
264 if (!pBtn
|| pBtn
->HasFlag(wxRB_GROUP
) )
267 // No more buttons or the first button of the next group
271 pBtn
->SetValue(FALSE
);
274 } // end of wxRadioButton::SetValue
276 MRESULT
wxRadioButton::OS2WindowProc(
282 if (uMsg
== WM_SETFOCUS
)
284 m_bFocusJustSet
= TRUE
;
286 MRESULT mRc
= wxControl::OS2WindowProc( uMsg
291 m_bFocusJustSet
= FALSE
;
294 return wxControl::OS2WindowProc( uMsg
298 } // end of wxRadioButton::OS2WindowProc