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
 
  56 , const wxValidator
&                rValidator
 
  57 , const wxString
&                   rsName
 
  60     if ( !CreateControl( pParent
 
  69     long                            lSstyle 
= WS_TABSTOP
; 
  71     if (HasFlag(wxRB_GROUP
)) 
  75     // wxRB_SINGLE is a temporary workaround for the following problem: if you 
  76     // have 2 radiobuttons in the same group but which are not consecutive in 
  77     // the dialog, Windows can enter an infinite loop! The simplest way to 
  78     // reproduce it is to create radio button, then a panel and then another 
  79     // radio button: then checking the last button hangs the app. 
  81     // Ideally, we'd detect (and avoid) such situation automatically but for 
  82     // now, as I don't know how to do it, just allow the user to create 
  83     // BS_RADIOBUTTON buttons for such situations. 
  85     lSstyle 
|= HasFlag(wxRB_SINGLE
) ? BS_RADIOBUTTON 
: BS_AUTORADIOBUTTON
; 
  87     if (HasFlag(wxCLIP_SIBLINGS
)) 
  88         lSstyle 
|= WS_CLIPSIBLINGS
; 
  90     if (!OS2CreateControl( _T("BUTTON") 
  99     wxAssociateWinWithHandle(m_hWnd
, this); 
 100     if (HasFlag(wxRB_GROUP
)) 
 103     SetFont(*wxSMALL_FONT
); 
 110 } // end of wxRadioButton::Create 
 112 wxSize 
wxRadioButton::DoGetBestSize() const 
 114     static int                      snRadioSize 
= 0; 
 120         vDC
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
)); 
 121         snRadioSize 
= vDC
.GetCharHeight(); 
 124     wxString                        sStr 
= GetLabel(); 
 134         nRadioWidth 
+= snRadioSize 
+ GetCharWidth(); 
 135         if (nRadioHeight 
< snRadioSize
) 
 136             nRadioHeight 
= snRadioSize
; 
 140         nRadioWidth  
= snRadioSize
; 
 141         nRadioHeight 
= snRadioSize
; 
 143     return wxSize( nRadioWidth
 
 146 } // end of wxRadioButton::DoGetBestSize 
 149 // Get single selection, for single choice list items 
 151 bool wxRadioButton::GetValue() const 
 153     return((::WinSendMsg((HWND
) GetHWND(), BM_QUERYCHECK
, (MPARAM
)0L, (MPARAM
)0L) != 0)); 
 154 } // end of wxRadioButton::GetValue 
 156 bool wxRadioButton::OS2Command( WXUINT wParam
, WXWORD 
WXUNUSED(wId
) ) 
 158     if (wParam 
!= BN_CLICKED
) 
 164         // See above: we want to ignore this event 
 166         m_bFocusJustSet 
= false; 
 170         bool bIsChecked 
= GetValue(); 
 172         if (HasFlag(wxRB_SINGLE
)) 
 175             // When we use a "manual" radio button, we have to check the button 
 176             // ourselves -- but it's reset to unchecked state by the user code 
 177             // (presumably when another button is pressed) 
 182         wxCommandEvent 
rEvent( wxEVT_COMMAND_RADIOBUTTON_SELECTED
, m_windowId 
); 
 183         rEvent
.SetEventObject(this); 
 184         ProcessCommand(rEvent
); 
 187 } // end of wxRadioButton::OS2Command 
 189 void wxRadioButton::SetFocus() 
 191     // when the radio button receives a WM_SETFOCUS message it generates a 
 192     // BN_CLICKED which is totally unexpected and leads to catastrophic results 
 193     // if you pop up a dialog from the radio button event handler as, when the 
 194     // dialog is dismissed, the focus is returned to the radio button which 
 195     // generates BN_CLICKED which leads to showing another dialog and so on 
 198     // to avoid this, we drop the pseudo BN_CLICKED events generated when the 
 199     // button gains focus 
 200     m_bFocusJustSet 
= true; 
 202     wxControl::SetFocus(); 
 205 void wxRadioButton::SetLabel( 
 206   const wxString
&                   rsLabel
 
 209     wxString                        sLabel 
= ::wxPMTextToLabel(rsLabel
); 
 210     ::WinSetWindowText((HWND
)GetHWND(), (const char *)sLabel
.c_str()); 
 211 } // end of wxRadioButton::SetLabel 
 213 void wxRadioButton::SetValue( 
 217     ::WinSendMsg((HWND
)GetHWND(), BM_SETCHECK
, (MPARAM
)bValue
, (MPARAM
)0); 
 220         const wxWindowList
&         rSiblings 
= GetParent()->GetChildren(); 
 221         wxWindowList::compatibility_iterator nodeThis 
= rSiblings
.Find(this); 
 223         wxCHECK_RET(nodeThis
, _T("radio button not a child of its parent?")); 
 226         // If it's not the first item of the group ... 
 228         if ( !HasFlag(wxRB_GROUP
) ) 
 231             // ...turn off all radio buttons before this one 
 233             for ( wxWindowList::compatibility_iterator nodeBefore 
= nodeThis
->GetPrevious(); 
 235                   nodeBefore 
= nodeBefore
->GetPrevious() ) 
 237                 wxRadioButton
*      pBtn 
= wxDynamicCast( nodeBefore
->GetData() 
 243                     // The radio buttons in a group must be consecutive, so there 
 244                     // are no more of them 
 248                 pBtn
->SetValue(FALSE
); 
 249                 if (pBtn
->HasFlag(wxRB_GROUP
)) 
 252                     // Even if there are other radio buttons before this one, 
 253                     // they're not in the same group with us 
 261         // ... and all after this one 
 263         for (wxWindowList::compatibility_iterator nodeAfter 
= nodeThis
->GetNext(); 
 265              nodeAfter 
= nodeAfter
->GetNext()) 
 267             wxRadioButton
*          pBtn 
= wxDynamicCast( nodeAfter
->GetData() 
 271             if (!pBtn 
|| pBtn
->HasFlag(wxRB_GROUP
) ) 
 274                 // No more buttons or the first button of the next group 
 278             pBtn
->SetValue(FALSE
); 
 281 } // end of wxRadioButton::SetValue 
 283 MRESULT 
wxRadioButton::OS2WindowProc( 
 289     if (uMsg 
== WM_SETFOCUS
) 
 291         m_bFocusJustSet 
= TRUE
; 
 293         MRESULT                     mRc 
= wxControl::OS2WindowProc( uMsg
 
 298         m_bFocusJustSet 
= FALSE
; 
 301     return wxControl::OS2WindowProc( uMsg
 
 305 } // end of wxRadioButton::OS2WindowProc