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" 
  19 #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 ( wxCommandEvent
& rEvent 
) 
  43     SetValue ((rEvent
.GetInt() != 0) ); 
  44     ProcessCommand (rEvent
); 
  45 } // end of wxRadioButton::Command 
  47 bool wxRadioButton::Create( wxWindow
* pParent
, 
  49                             const wxString
& rsLabel
, 
  53                             const wxValidator
& rValidator
, 
  54                             const wxString
& rsName 
) 
  56     if ( !CreateControl( pParent
 
  65     long                            lSstyle 
= WS_TABSTOP
; 
  67     if (HasFlag(wxRB_GROUP
)) 
  71     // wxRB_SINGLE is a temporary workaround for the following problem: if you 
  72     // have 2 radiobuttons in the same group but which are not consecutive in 
  73     // the dialog, Windows can enter an infinite loop! The simplest way to 
  74     // reproduce it is to create radio button, then a panel and then another 
  75     // radio button: then checking the last button hangs the app. 
  77     // Ideally, we'd detect (and avoid) such situation automatically but for 
  78     // now, as I don't know how to do it, just allow the user to create 
  79     // BS_RADIOBUTTON buttons for such situations. 
  81     lSstyle 
|= HasFlag(wxRB_SINGLE
) ? BS_RADIOBUTTON 
: BS_AUTORADIOBUTTON
; 
  83     if (HasFlag(wxCLIP_SIBLINGS
)) 
  84         lSstyle 
|= WS_CLIPSIBLINGS
; 
  86     if (!OS2CreateControl( _T("BUTTON") 
  95     wxAssociateWinWithHandle(m_hWnd
, this); 
  96     if (HasFlag(wxRB_GROUP
)) 
  99     SetFont(*wxSMALL_FONT
); 
 100     SetSize( rPos
.x
, rPos
.y
, rSize
.x
, rSize
.y 
); 
 102 } // end of wxRadioButton::Create 
 104 wxSize 
wxRadioButton::DoGetBestSize() const 
 106     // We should probably compute snRadioSize but it seems to be a constant 
 107     // independent of its label's font size and not made available by OS/2. 
 108     static int                      snRadioSize 
= RADIO_SIZE
; 
 110     wxString                        sStr 
= wxGetWindowText(GetHwnd()); 
 120         nRadioWidth 
+= snRadioSize
; 
 121         if (nRadioHeight 
< snRadioSize
) 
 122             nRadioHeight 
= snRadioSize
; 
 126         nRadioWidth  
= snRadioSize
; 
 127         nRadioHeight 
= snRadioSize
; 
 129     return wxSize( nRadioWidth
 
 132 } // end of wxRadioButton::DoGetBestSize 
 135 // Get single selection, for single choice list items 
 137 bool wxRadioButton::GetValue() const 
 139     return((::WinSendMsg((HWND
) GetHWND(), BM_QUERYCHECK
, (MPARAM
)0L, (MPARAM
)0L) != 0)); 
 140 } // end of wxRadioButton::GetValue 
 142 bool wxRadioButton::OS2Command( WXUINT wParam
, WXWORD 
WXUNUSED(wId
) ) 
 144     if (wParam 
!= BN_CLICKED
) 
 150         // See above: we want to ignore this event 
 152         m_bFocusJustSet 
= false; 
 156         bool bIsChecked 
= GetValue(); 
 158         if (HasFlag(wxRB_SINGLE
)) 
 161             // When we use a "manual" radio button, we have to check the button 
 162             // ourselves -- but it's reset to unchecked state by the user code 
 163             // (presumably when another button is pressed) 
 168         wxCommandEvent 
rEvent( wxEVT_COMMAND_RADIOBUTTON_SELECTED
, m_windowId 
); 
 169         rEvent
.SetEventObject(this); 
 170         ProcessCommand(rEvent
); 
 173 } // end of wxRadioButton::OS2Command 
 175 void wxRadioButton::SetFocus() 
 177     // when the radio button receives a WM_SETFOCUS message it generates a 
 178     // BN_CLICKED which is totally unexpected and leads to catastrophic results 
 179     // if you pop up a dialog from the radio button event handler as, when the 
 180     // dialog is dismissed, the focus is returned to the radio button which 
 181     // generates BN_CLICKED which leads to showing another dialog and so on 
 184     // to avoid this, we drop the pseudo BN_CLICKED events generated when the 
 185     // button gains focus 
 186     m_bFocusJustSet 
= true; 
 188     wxControl::SetFocus(); 
 191 void wxRadioButton::SetLabel( const wxString
& rsLabel 
) 
 193     wxString                        sLabel 
= ::wxPMTextToLabel(rsLabel
); 
 194     ::WinSetWindowText((HWND
)GetHWND(), (const char *)sLabel
.c_str()); 
 195 } // end of wxRadioButton::SetLabel 
 197 void wxRadioButton::SetValue( bool bValue 
) 
 199     ::WinSendMsg((HWND
)GetHWND(), BM_SETCHECK
, (MPARAM
)bValue
, (MPARAM
)0); 
 202         const wxWindowList
&         rSiblings 
= GetParent()->GetChildren(); 
 203         wxWindowList::compatibility_iterator nodeThis 
= rSiblings
.Find(this); 
 205         wxCHECK_RET(nodeThis
, _T("radio button not a child of its parent?")); 
 208         // If it's not the first item of the group ... 
 210         if ( !HasFlag(wxRB_GROUP
) ) 
 213             // ...turn off all radio buttons before this one 
 215             for ( wxWindowList::compatibility_iterator nodeBefore 
= nodeThis
->GetPrevious(); 
 217                   nodeBefore 
= nodeBefore
->GetPrevious() ) 
 219                 wxRadioButton
*      pBtn 
= wxDynamicCast( nodeBefore
->GetData() 
 225                     // The radio buttons in a group must be consecutive, so there 
 226                     // are no more of them 
 230                 pBtn
->SetValue(false); 
 231                 if (pBtn
->HasFlag(wxRB_GROUP
)) 
 234                     // Even if there are other radio buttons before this one, 
 235                     // they're not in the same group with us 
 243         // ... and all after this one 
 245         for (wxWindowList::compatibility_iterator nodeAfter 
= nodeThis
->GetNext(); 
 247              nodeAfter 
= nodeAfter
->GetNext()) 
 249             wxRadioButton
*          pBtn 
= wxDynamicCast( nodeAfter
->GetData() 
 253             if (!pBtn 
|| pBtn
->HasFlag(wxRB_GROUP
) ) 
 256                 // No more buttons or the first button of the next group 
 260             pBtn
->SetValue(false); 
 263 } // end of wxRadioButton::SetValue 
 265 MRESULT 
wxRadioButton::OS2WindowProc( 
 271     if (uMsg 
== WM_SETFOCUS
) 
 273         m_bFocusJustSet 
= true; 
 275         MRESULT                     mRc 
= wxControl::OS2WindowProc( uMsg
 
 280         m_bFocusJustSet 
= false; 
 283     return wxControl::OS2WindowProc( uMsg
 
 287 } // end of wxRadioButton::OS2WindowProc