1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/radiobut.cpp
3 // Purpose: wxRadioButton
4 // Author: David Webster
7 // Copyright: (c) David Webster
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
18 #include "wx/radiobut.h"
23 #include "wx/dcscreen.h"
24 #include "wx/settings.h"
27 #include "wx/os2/private.h"
29 extern void wxAssociateWinWithHandle( HWND hWnd
33 void wxRadioButton::Init()
35 m_bFocusJustSet
= false;
36 } // end of wxRadioButton::Init
38 void wxRadioButton::Command ( wxCommandEvent
& rEvent
)
40 SetValue ((rEvent
.GetInt() != 0) );
41 ProcessCommand (rEvent
);
42 } // end of wxRadioButton::Command
44 bool wxRadioButton::Create( wxWindow
* pParent
,
46 const wxString
& rsLabel
,
50 const wxValidator
& rValidator
,
51 const wxString
& rsName
)
53 if ( !CreateControl( pParent
62 long lSstyle
= WS_TABSTOP
;
64 if (HasFlag(wxRB_GROUP
))
68 // wxRB_SINGLE is a temporary workaround for the following problem: if you
69 // have 2 radiobuttons in the same group but which are not consecutive in
70 // the dialog, Windows can enter an infinite loop! The simplest way to
71 // reproduce it is to create radio button, then a panel and then another
72 // radio button: then checking the last button hangs the app.
74 // Ideally, we'd detect (and avoid) such situation automatically but for
75 // now, as I don't know how to do it, just allow the user to create
76 // BS_RADIOBUTTON buttons for such situations.
78 lSstyle
|= HasFlag(wxRB_SINGLE
) ? BS_RADIOBUTTON
: BS_AUTORADIOBUTTON
;
80 if (HasFlag(wxCLIP_SIBLINGS
))
81 lSstyle
|= WS_CLIPSIBLINGS
;
83 if (!OS2CreateControl( wxT("BUTTON")
92 wxAssociateWinWithHandle(m_hWnd
, this);
93 if (HasFlag(wxRB_GROUP
))
96 SetFont(*wxSMALL_FONT
);
97 SetSize( rPos
.x
, rPos
.y
, rSize
.x
, rSize
.y
);
99 } // end of wxRadioButton::Create
101 wxSize
wxRadioButton::DoGetBestSize() const
103 // We should probably compute snRadioSize but it seems to be a constant
104 // independent of its label's font size and not made available by OS/2.
105 static int snRadioSize
= RADIO_SIZE
;
107 wxString sStr
= wxGetWindowText(GetHwnd());
117 nRadioWidth
+= snRadioSize
;
118 if (nRadioHeight
< snRadioSize
)
119 nRadioHeight
= snRadioSize
;
123 nRadioWidth
= snRadioSize
;
124 nRadioHeight
= snRadioSize
;
126 return wxSize( nRadioWidth
129 } // end of wxRadioButton::DoGetBestSize
132 // Get single selection, for single choice list items
134 bool wxRadioButton::GetValue() const
136 return((::WinSendMsg((HWND
) GetHWND(), BM_QUERYCHECK
, (MPARAM
)0L, (MPARAM
)0L) != 0));
137 } // end of wxRadioButton::GetValue
139 bool wxRadioButton::OS2Command( WXUINT wParam
, WXWORD
WXUNUSED(wId
) )
141 if (wParam
!= BN_CLICKED
)
147 // See above: we want to ignore this event
149 m_bFocusJustSet
= false;
153 bool bIsChecked
= GetValue();
155 if (HasFlag(wxRB_SINGLE
))
158 // When we use a "manual" radio button, we have to check the button
159 // ourselves -- but it's reset to unchecked state by the user code
160 // (presumably when another button is pressed)
165 wxCommandEvent
rEvent( wxEVT_RADIOBUTTON
, m_windowId
);
166 rEvent
.SetEventObject(this);
167 ProcessCommand(rEvent
);
170 } // end of wxRadioButton::OS2Command
172 void wxRadioButton::SetFocus()
174 // when the radio button receives a WM_SETFOCUS message it generates a
175 // BN_CLICKED which is totally unexpected and leads to catastrophic results
176 // if you pop up a dialog from the radio button event handler as, when the
177 // dialog is dismissed, the focus is returned to the radio button which
178 // generates BN_CLICKED which leads to showing another dialog and so on
181 // to avoid this, we drop the pseudo BN_CLICKED events generated when the
182 // button gains focus
183 m_bFocusJustSet
= true;
185 wxControl::SetFocus();
188 void wxRadioButton::SetLabel( const wxString
& rsLabel
)
190 wxString sLabel
= ::wxPMTextToLabel(rsLabel
);
191 ::WinSetWindowText((HWND
)GetHWND(), (const char *)sLabel
.c_str());
192 } // end of wxRadioButton::SetLabel
194 void wxRadioButton::SetValue( bool bValue
)
196 ::WinSendMsg((HWND
)GetHWND(), BM_SETCHECK
, (MPARAM
)bValue
, (MPARAM
)0);
199 const wxWindowList
& rSiblings
= GetParent()->GetChildren();
200 wxWindowList::compatibility_iterator nodeThis
= rSiblings
.Find(this);
202 wxCHECK_RET(nodeThis
, wxT("radio button not a child of its parent?"));
205 // If it's not the first item of the group ...
207 if ( !HasFlag(wxRB_GROUP
) )
210 // ...turn off all radio buttons before this one
212 for ( wxWindowList::compatibility_iterator nodeBefore
= nodeThis
->GetPrevious();
214 nodeBefore
= nodeBefore
->GetPrevious() )
216 wxRadioButton
* pBtn
= wxDynamicCast( nodeBefore
->GetData()
222 // The radio buttons in a group must be consecutive, so there
223 // are no more of them
227 pBtn
->SetValue(false);
228 if (pBtn
->HasFlag(wxRB_GROUP
))
231 // Even if there are other radio buttons before this one,
232 // they're not in the same group with us
240 // ... and all after this one
242 for (wxWindowList::compatibility_iterator nodeAfter
= nodeThis
->GetNext();
244 nodeAfter
= nodeAfter
->GetNext())
246 wxRadioButton
* pBtn
= wxDynamicCast( nodeAfter
->GetData()
250 if (!pBtn
|| pBtn
->HasFlag(wxRB_GROUP
) )
253 // No more buttons or the first button of the next group
257 pBtn
->SetValue(false);
260 } // end of wxRadioButton::SetValue
262 MRESULT
wxRadioButton::OS2WindowProc(
268 if (uMsg
== WM_SETFOCUS
)
270 m_bFocusJustSet
= true;
272 MRESULT mRc
= wxControl::OS2WindowProc( uMsg
277 m_bFocusJustSet
= false;
280 return wxControl::OS2WindowProc( uMsg
284 } // end of wxRadioButton::OS2WindowProc