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( 
 161     if (wParam 
!= BN_CLICKED
) 
 167         // See above: we want to ignore this event 
 169         m_bFocusJustSet 
= FALSE
; 
 173         bool                        bIsChecked 
= GetValue(); 
 175         if (HasFlag(wxRB_SINGLE
)) 
 178             // When we use a "manual" radio button, we have to check the button 
 179             // ourselves -- but it's reset to unchecked state by the user code 
 180             // (presumably when another button is pressed) 
 185         wxCommandEvent              
rEvent( wxEVT_COMMAND_RADIOBUTTON_SELECTED
 
 189         rEvent
.SetEventObject(this); 
 190         ProcessCommand(rEvent
); 
 193 } // end of wxRadioButton::OS2Command 
 195 void wxRadioButton::SetFocus() 
 197     // when the radio button receives a WM_SETFOCUS message it generates a 
 198     // BN_CLICKED which is totally unexpected and leads to catastrophic results 
 199     // if you pop up a dialog from the radio button event handler as, when the 
 200     // dialog is dismissed, the focus is returned to the radio button which 
 201     // generates BN_CLICKED which leads to showing another dialog and so on 
 204     // to aviod this, we drop the pseudo BN_CLICKED events generated when the 
 205     // button gains focus 
 206     m_bFocusJustSet 
= TRUE
; 
 208     wxControl::SetFocus(); 
 211 void wxRadioButton::SetLabel( 
 212   const wxString
&                   rsLabel
 
 215     ::WinSetWindowText((HWND
)GetHWND(), (const char *)rsLabel
.c_str()); 
 216 } // end of wxRadioButton::SetLabel 
 218 void wxRadioButton::SetValue( 
 222     ::WinSendMsg((HWND
)GetHWND(), BM_SETCHECK
, (MPARAM
)bValue
, (MPARAM
)0); 
 225         const wxWindowList
&         rSiblings 
= GetParent()->GetChildren(); 
 226         wxWindowList::compatibility_iterator nodeThis 
= rSiblings
.Find(this); 
 228         wxCHECK_RET(nodeThis
, _T("radio button not a child of its parent?")); 
 231         // If it's not the first item of the group ... 
 233         if ( !HasFlag(wxRB_GROUP
) ) 
 236             // ...turn off all radio buttons before this one 
 238             for ( wxWindowList::compatibility_iterator nodeBefore 
= nodeThis
->GetPrevious(); 
 240                   nodeBefore 
= nodeBefore
->GetPrevious() ) 
 242                 wxRadioButton
*      pBtn 
= wxDynamicCast( nodeBefore
->GetData() 
 248                     // The radio buttons in a group must be consecutive, so there 
 249                     // are no more of them 
 253                 pBtn
->SetValue(FALSE
); 
 254                 if (pBtn
->HasFlag(wxRB_GROUP
)) 
 257                     // Even if there are other radio buttons before this one, 
 258                     // they're not in the same group with us 
 266         // ... and all after this one 
 268         for (wxWindowList::compatibility_iterator nodeAfter 
= nodeThis
->GetNext(); 
 270              nodeAfter 
= nodeAfter
->GetNext()) 
 272             wxRadioButton
*          pBtn 
= wxDynamicCast( nodeAfter
->GetData() 
 276             if (!pBtn 
|| pBtn
->HasFlag(wxRB_GROUP
) ) 
 279                 // No more buttons or the first button of the next group 
 283             pBtn
->SetValue(FALSE
); 
 286 } // end of wxRadioButton::SetValue 
 288 MRESULT 
wxRadioButton::OS2WindowProc( 
 294     if (uMsg 
== WM_SETFOCUS
) 
 296         m_bFocusJustSet 
= TRUE
; 
 298         MRESULT                     mRc 
= wxControl::OS2WindowProc( uMsg
 
 303         m_bFocusJustSet 
= FALSE
; 
 306     return wxControl::OS2WindowProc( uMsg
 
 310 } // end of wxRadioButton::OS2WindowProc