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 extern void  wxAssociateWinWithHandle( HWND         hWnd
 
  34 void wxRadioButton::Init() 
  36     m_bFocusJustSet 
= false; 
  37 } // end of wxRadioButton::Init 
  39 void wxRadioButton::Command ( wxCommandEvent
& rEvent 
) 
  41     SetValue ((rEvent
.GetInt() != 0) ); 
  42     ProcessCommand (rEvent
); 
  43 } // end of wxRadioButton::Command 
  45 bool wxRadioButton::Create( wxWindow
* pParent
, 
  47                             const wxString
& rsLabel
, 
  51                             const wxValidator
& rValidator
, 
  52                             const wxString
& rsName 
) 
  54     if ( !CreateControl( pParent
 
  63     long                            lSstyle 
= WS_TABSTOP
; 
  65     if (HasFlag(wxRB_GROUP
)) 
  69     // wxRB_SINGLE is a temporary workaround for the following problem: if you 
  70     // have 2 radiobuttons in the same group but which are not consecutive in 
  71     // the dialog, Windows can enter an infinite loop! The simplest way to 
  72     // reproduce it is to create radio button, then a panel and then another 
  73     // radio button: then checking the last button hangs the app. 
  75     // Ideally, we'd detect (and avoid) such situation automatically but for 
  76     // now, as I don't know how to do it, just allow the user to create 
  77     // BS_RADIOBUTTON buttons for such situations. 
  79     lSstyle 
|= HasFlag(wxRB_SINGLE
) ? BS_RADIOBUTTON 
: BS_AUTORADIOBUTTON
; 
  81     if (HasFlag(wxCLIP_SIBLINGS
)) 
  82         lSstyle 
|= WS_CLIPSIBLINGS
; 
  84     if (!OS2CreateControl( wxT("BUTTON") 
  93     wxAssociateWinWithHandle(m_hWnd
, this); 
  94     if (HasFlag(wxRB_GROUP
)) 
  97     SetFont(*wxSMALL_FONT
); 
  98     SetSize( rPos
.x
, rPos
.y
, rSize
.x
, rSize
.y 
); 
 100 } // end of wxRadioButton::Create 
 102 wxSize 
wxRadioButton::DoGetBestSize() const 
 104     // We should probably compute snRadioSize but it seems to be a constant 
 105     // independent of its label's font size and not made available by OS/2. 
 106     static int                      snRadioSize 
= RADIO_SIZE
; 
 108     wxString                        sStr 
= wxGetWindowText(GetHwnd()); 
 118         nRadioWidth 
+= snRadioSize
; 
 119         if (nRadioHeight 
< snRadioSize
) 
 120             nRadioHeight 
= snRadioSize
; 
 124         nRadioWidth  
= snRadioSize
; 
 125         nRadioHeight 
= snRadioSize
; 
 127     return wxSize( nRadioWidth
 
 130 } // end of wxRadioButton::DoGetBestSize 
 133 // Get single selection, for single choice list items 
 135 bool wxRadioButton::GetValue() const 
 137     return((::WinSendMsg((HWND
) GetHWND(), BM_QUERYCHECK
, (MPARAM
)0L, (MPARAM
)0L) != 0)); 
 138 } // end of wxRadioButton::GetValue 
 140 bool wxRadioButton::OS2Command( WXUINT wParam
, WXWORD 
WXUNUSED(wId
) ) 
 142     if (wParam 
!= BN_CLICKED
) 
 148         // See above: we want to ignore this event 
 150         m_bFocusJustSet 
= false; 
 154         bool bIsChecked 
= GetValue(); 
 156         if (HasFlag(wxRB_SINGLE
)) 
 159             // When we use a "manual" radio button, we have to check the button 
 160             // ourselves -- but it's reset to unchecked state by the user code 
 161             // (presumably when another button is pressed) 
 166         wxCommandEvent 
rEvent( wxEVT_COMMAND_RADIOBUTTON_SELECTED
, m_windowId 
); 
 167         rEvent
.SetEventObject(this); 
 168         ProcessCommand(rEvent
); 
 171 } // end of wxRadioButton::OS2Command 
 173 void wxRadioButton::SetFocus() 
 175     // when the radio button receives a WM_SETFOCUS message it generates a 
 176     // BN_CLICKED which is totally unexpected and leads to catastrophic results 
 177     // if you pop up a dialog from the radio button event handler as, when the 
 178     // dialog is dismissed, the focus is returned to the radio button which 
 179     // generates BN_CLICKED which leads to showing another dialog and so on 
 182     // to avoid this, we drop the pseudo BN_CLICKED events generated when the 
 183     // button gains focus 
 184     m_bFocusJustSet 
= true; 
 186     wxControl::SetFocus(); 
 189 void wxRadioButton::SetLabel( const wxString
& rsLabel 
) 
 191     wxString                        sLabel 
= ::wxPMTextToLabel(rsLabel
); 
 192     ::WinSetWindowText((HWND
)GetHWND(), (const char *)sLabel
.c_str()); 
 193 } // end of wxRadioButton::SetLabel 
 195 void wxRadioButton::SetValue( bool bValue 
) 
 197     ::WinSendMsg((HWND
)GetHWND(), BM_SETCHECK
, (MPARAM
)bValue
, (MPARAM
)0); 
 200         const wxWindowList
&         rSiblings 
= GetParent()->GetChildren(); 
 201         wxWindowList::compatibility_iterator nodeThis 
= rSiblings
.Find(this); 
 203         wxCHECK_RET(nodeThis
, wxT("radio button not a child of its parent?")); 
 206         // If it's not the first item of the group ... 
 208         if ( !HasFlag(wxRB_GROUP
) ) 
 211             // ...turn off all radio buttons before this one 
 213             for ( wxWindowList::compatibility_iterator nodeBefore 
= nodeThis
->GetPrevious(); 
 215                   nodeBefore 
= nodeBefore
->GetPrevious() ) 
 217                 wxRadioButton
*      pBtn 
= wxDynamicCast( nodeBefore
->GetData() 
 223                     // The radio buttons in a group must be consecutive, so there 
 224                     // are no more of them 
 228                 pBtn
->SetValue(false); 
 229                 if (pBtn
->HasFlag(wxRB_GROUP
)) 
 232                     // Even if there are other radio buttons before this one, 
 233                     // they're not in the same group with us 
 241         // ... and all after this one 
 243         for (wxWindowList::compatibility_iterator nodeAfter 
= nodeThis
->GetNext(); 
 245              nodeAfter 
= nodeAfter
->GetNext()) 
 247             wxRadioButton
*          pBtn 
= wxDynamicCast( nodeAfter
->GetData() 
 251             if (!pBtn 
|| pBtn
->HasFlag(wxRB_GROUP
) ) 
 254                 // No more buttons or the first button of the next group 
 258             pBtn
->SetValue(false); 
 261 } // end of wxRadioButton::SetValue 
 263 MRESULT 
wxRadioButton::OS2WindowProc( 
 269     if (uMsg 
== WM_SETFOCUS
) 
 271         m_bFocusJustSet 
= true; 
 273         MRESULT                     mRc 
= wxControl::OS2WindowProc( uMsg
 
 278         m_bFocusJustSet 
= false; 
 281     return wxControl::OS2WindowProc( uMsg
 
 285 } // end of wxRadioButton::OS2WindowProc