]> git.saurik.com Git - wxWidgets.git/blob - src/os2/radiobut.cpp
Checked for stream validity in wxImage::GetImageCount.
[wxWidgets.git] / src / os2 / radiobut.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: radiobut.cpp
3 // Purpose: wxRadioButton
4 // Author: David Webster
5 // Modified by:
6 // Created: 10/12/99
7 // RCS-ID: $Id$
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #ifndef WX_PRECOMP
20 #include <stdio.h>
21 #include "wx/setup.h"
22 #include "wx/radiobut.h"
23 #include "wx/brush.h"
24 #include "wx/dcscreen.h"
25 #include "wx/settings.h"
26 #endif
27
28 #include "wx/os2/private.h"
29
30 IMPLEMENT_DYNAMIC_CLASS(wxRadioButton, wxControl)
31
32 extern void wxAssociateWinWithHandle( HWND hWnd
33 ,wxWindowOS2* pWin
34 );
35
36 void wxRadioButton::Init()
37 {
38 m_bFocusJustSet = FALSE;
39 } // end of wxRadioButton::Init
40
41 void wxRadioButton::Command (
42 wxCommandEvent& rEvent
43 )
44 {
45 SetValue ((rEvent.GetInt() != 0) );
46 ProcessCommand (rEvent);
47 } // end of wxRadioButton::Command
48
49 bool wxRadioButton::Create(
50 wxWindow* pParent
51 , wxWindowID vId
52 , const wxString& rsLabel
53 , const wxPoint& rPos
54 , const wxSize& rSize
55 , long lStyle
56 #if wxUSE_VALIDATORS
57 , const wxValidator& rValidator
58 #endif
59 , const wxString& rsName
60 )
61 {
62 if ( !CreateControl( pParent
63 ,vId
64 ,rPos
65 ,rSize
66 ,lStyle
67 #if wxUSE_VALIDATORS
68 ,rValidator
69 #endif
70 ,rsName))
71 return FALSE;
72
73 long lSstyle = WS_TABSTOP;
74
75 if (HasFlag(wxRB_GROUP))
76 lSstyle |= WS_GROUP;
77
78 //
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.
84 //
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.
88 //
89 lSstyle |= HasFlag(wxRB_SINGLE) ? BS_RADIOBUTTON : BS_AUTORADIOBUTTON;
90
91 if (HasFlag(wxCLIP_SIBLINGS))
92 lSstyle |= WS_CLIPSIBLINGS;
93
94 if (!OS2CreateControl( _T("BUTTON")
95 ,lSstyle
96 ,rPos
97 ,rSize
98 ,rsLabel
99 ,0
100 ))
101 return FALSE;
102
103 wxAssociateWinWithHandle(m_hWnd, this);
104 if (HasFlag(wxRB_GROUP))
105 SetValue(TRUE);
106
107 SetFont(*wxSMALL_FONT);
108 SetSize( rPos.x
109 ,rPos.y
110 ,rSize.x
111 ,rSize.y
112 );
113 return TRUE;
114 } // end of wxRadioButton::Create
115
116 wxSize wxRadioButton::DoGetBestSize() const
117 {
118 static int snRadioSize = 0;
119
120 if (!snRadioSize)
121 {
122 wxScreenDC vDC;
123
124 vDC.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
125 snRadioSize = vDC.GetCharHeight();
126 }
127
128 wxString sStr = GetLabel();
129 int nRadioWidth;
130 int nRadioHeight;
131
132 if (!sStr.empty())
133 {
134 GetTextExtent( sStr
135 ,&nRadioWidth
136 ,&nRadioHeight
137 );
138 nRadioWidth += snRadioSize + GetCharWidth();
139 if (nRadioHeight < snRadioSize)
140 nRadioHeight = snRadioSize;
141 }
142 else
143 {
144 nRadioWidth = snRadioSize;
145 nRadioHeight = snRadioSize;
146 }
147 return wxSize( nRadioWidth
148 ,nRadioHeight
149 );
150 } // end of wxRadioButton::DoGetBestSize
151
152 //
153 // Get single selection, for single choice list items
154 //
155 bool wxRadioButton::GetValue() const
156 {
157 return((::WinSendMsg((HWND) GetHWND(), BM_QUERYCHECK, (MPARAM)0L, (MPARAM)0L) != 0));
158 } // end of wxRadioButton::GetValue
159
160 bool wxRadioButton::OS2Command(
161 WXUINT wParam
162 , WXWORD wId
163 )
164 {
165 if (wParam != BN_CLICKED)
166 return FALSE;
167
168 if (m_bFocusJustSet)
169 {
170 //
171 // See above: we want to ignore this event
172 //
173 m_bFocusJustSet = FALSE;
174 }
175 else
176 {
177 bool bIsChecked = GetValue();
178
179 if (HasFlag(wxRB_SINGLE))
180 {
181 //
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)
185 //
186 if (!bIsChecked )
187 SetValue(TRUE);
188 }
189 wxCommandEvent rEvent( wxEVT_COMMAND_RADIOBUTTON_SELECTED
190 ,m_windowId
191 );
192
193 rEvent.SetEventObject(this);
194 ProcessCommand(rEvent);
195 }
196 return TRUE;
197 } // end of wxRadioButton::OS2Command
198
199 void wxRadioButton::SetFocus()
200 {
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
206 // without end!
207 //
208 // to aviod this, we drop the pseudo BN_CLICKED events generated when the
209 // button gains focus
210 m_bFocusJustSet = TRUE;
211
212 wxControl::SetFocus();
213 }
214
215 void wxRadioButton::SetLabel(
216 const wxString& rsLabel
217 )
218 {
219 ::WinSetWindowText((HWND)GetHWND(), (const char *)rsLabel.c_str());
220 } // end of wxRadioButton::SetLabel
221
222 void wxRadioButton::SetValue(
223 bool bValue
224 )
225 {
226 ::WinSendMsg((HWND)GetHWND(), BM_SETCHECK, (MPARAM)bValue, (MPARAM)0);
227 if (bValue)
228 {
229 const wxWindowList& rSiblings = GetParent()->GetChildren();
230 wxWindowList::Node* pNodeThis = rSiblings.Find(this);
231
232 wxCHECK_RET(pNodeThis, _T("radio button not a child of its parent?"));
233
234 //
235 // Turn off all radio buttons before this one
236 //
237 for ( wxWindowList::Node* pNodeBefore = pNodeThis->GetPrevious();
238 pNodeBefore;
239 pNodeBefore = pNodeBefore->GetPrevious() )
240 {
241 wxRadioButton* pBtn = wxDynamicCast( pNodeBefore->GetData()
242 ,wxRadioButton
243 );
244 if (!pBtn)
245 {
246 //
247 // The radio buttons in a group must be consecutive, so there
248 // are no more of them
249 //
250 break;
251 }
252 pBtn->SetValue(FALSE);
253 if (pBtn->HasFlag(wxRB_GROUP))
254 {
255 //
256 // Even if there are other radio buttons before this one,
257 // they're not in the same group with us
258 //
259 break;
260 }
261 }
262
263 //
264 // ... and all after this one
265 //
266 for (wxWindowList::Node* pNodeAfter = pNodeThis->GetNext();
267 pNodeAfter;
268 pNodeAfter = pNodeAfter->GetNext())
269 {
270 wxRadioButton* pBtn = wxDynamicCast( pNodeAfter->GetData()
271 ,wxRadioButton
272 );
273
274 if (!pBtn || pBtn->HasFlag(wxRB_GROUP) )
275 {
276 //
277 // No more buttons or the first button of the next group
278 //
279 break;
280 }
281 pBtn->SetValue(FALSE);
282 }
283 }
284 } // end of wxRadioButton::SetValue
285
286 MRESULT wxRadioButton::OS2WindowProc(
287 WXUINT uMsg
288 , WXWPARAM wParam
289 , WXLPARAM lParam
290 )
291 {
292 if (uMsg == WM_SETFOCUS)
293 {
294 m_bFocusJustSet = TRUE;
295
296 MRESULT mRc = wxControl::OS2WindowProc( uMsg
297 ,wParam
298 ,lParam
299 );
300
301 m_bFocusJustSet = FALSE;
302 return mRc;
303 }
304 return wxControl::OS2WindowProc( uMsg
305 ,wParam
306 ,lParam
307 );
308 } // end of wxRadioButton::OS2WindowProc