home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / os2 / radiobut.cpp < prev    next >
C/C++ Source or Header  |  2002-12-27  |  10KB  |  305 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        radiobut.cpp
  3. // Purpose:     wxRadioButton
  4. // Author:      David Webster
  5. // Modified by:
  6. // Created:     10/12/99
  7. // RCS-ID:      $Id: RADIOBUT.CPP,v 1.16.2.3 2002/12/27 14:49:35 JS Exp $
  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. , const wxValidator&                rValidator
  57. , const wxString&                   rsName
  58. )
  59. {
  60.     if ( !CreateControl( pParent
  61.                         ,vId
  62.                         ,rPos
  63.                         ,rSize
  64.                         ,lStyle
  65.                         ,rValidator
  66.                         ,rsName))
  67.         return FALSE;
  68.  
  69.     long                            lSstyle = WS_TABSTOP;
  70.  
  71.     if (HasFlag(wxRB_GROUP))
  72.         lSstyle |= WS_GROUP;
  73.  
  74.     //
  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.
  80.     //
  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.
  84.     //
  85.     lSstyle |= HasFlag(wxRB_SINGLE) ? BS_RADIOBUTTON : BS_AUTORADIOBUTTON;
  86.  
  87.     if (HasFlag(wxCLIP_SIBLINGS))
  88.         lSstyle |= WS_CLIPSIBLINGS;
  89.  
  90.     if (!OS2CreateControl( _T("BUTTON")
  91.                           ,lSstyle
  92.                           ,rPos
  93.                           ,rSize
  94.                           ,rsLabel
  95.                           ,0
  96.                          ))
  97.         return FALSE;
  98.  
  99.     wxAssociateWinWithHandle(m_hWnd, this);
  100.     if (HasFlag(wxRB_GROUP))
  101.         SetValue(TRUE);
  102.  
  103.     SetFont(*wxSMALL_FONT);
  104.     SetSize( rPos.x
  105.             ,rPos.y
  106.             ,rSize.x
  107.             ,rSize.y
  108.            );
  109.     return TRUE;
  110. } // end of wxRadioButton::Create
  111.  
  112. wxSize wxRadioButton::DoGetBestSize() const
  113. {
  114.     static int                      snRadioSize = 0;
  115.  
  116.     if (!snRadioSize)
  117.     {
  118.         wxScreenDC                  vDC;
  119.  
  120.         vDC.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
  121.         snRadioSize = vDC.GetCharHeight();
  122.     }
  123.  
  124.     wxString                        sStr = GetLabel();
  125.     int                             nRadioWidth;
  126.     int                             nRadioHeight;
  127.  
  128.     if (!sStr.empty())
  129.     {
  130.         GetTextExtent( sStr
  131.                       ,&nRadioWidth
  132.                       ,&nRadioHeight
  133.                      );
  134.         nRadioWidth += snRadioSize + GetCharWidth();
  135.         if (nRadioHeight < snRadioSize)
  136.             nRadioHeight = snRadioSize;
  137.     }
  138.     else
  139.     {
  140.         nRadioWidth  = snRadioSize;
  141.         nRadioHeight = snRadioSize;
  142.     }
  143.     return wxSize( nRadioWidth
  144.                   ,nRadioHeight
  145.                  );
  146. } // end of wxRadioButton::DoGetBestSize
  147.  
  148. //
  149. // Get single selection, for single choice list items
  150. //
  151. bool wxRadioButton::GetValue() const
  152. {
  153.     return((::WinSendMsg((HWND) GetHWND(), BM_QUERYCHECK, (MPARAM)0L, (MPARAM)0L) != 0));
  154. } // end of wxRadioButton::GetValue
  155.  
  156. bool wxRadioButton::OS2Command(
  157.   WXUINT                            wParam
  158. , WXWORD                            wId
  159. )
  160. {
  161.     if (wParam != BN_CLICKED)
  162.         return FALSE;
  163.  
  164.     if (m_bFocusJustSet)
  165.     {
  166.         //
  167.         // See above: we want to ignore this event
  168.         //
  169.         m_bFocusJustSet = FALSE;
  170.     }
  171.     else
  172.     {
  173.         bool                        bIsChecked = GetValue();
  174.  
  175.         if (HasFlag(wxRB_SINGLE))
  176.         {
  177.             //
  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)
  181.             //
  182.             if (!bIsChecked )
  183.                 SetValue(TRUE);
  184.         }
  185.         wxCommandEvent              rEvent( wxEVT_COMMAND_RADIOBUTTON_SELECTED
  186.                                            ,m_windowId
  187.                                           );
  188.  
  189.         rEvent.SetEventObject(this);
  190.         ProcessCommand(rEvent);
  191.     }
  192.     return TRUE;
  193. } // end of wxRadioButton::OS2Command
  194.  
  195. void wxRadioButton::SetFocus()
  196. {
  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
  202.     // without end!
  203.     //
  204.     // to aviod this, we drop the pseudo BN_CLICKED events generated when the
  205.     // button gains focus
  206.     m_bFocusJustSet = TRUE;
  207.  
  208.     wxControl::SetFocus();
  209. }
  210.  
  211. void wxRadioButton::SetLabel(
  212.   const wxString&                   rsLabel
  213. )
  214. {
  215.     ::WinSetWindowText((HWND)GetHWND(), (const char *)rsLabel.c_str());
  216. } // end of wxRadioButton::SetLabel
  217.  
  218. void wxRadioButton::SetValue(
  219.   bool                              bValue
  220. )
  221. {
  222.     ::WinSendMsg((HWND)GetHWND(), BM_SETCHECK, (MPARAM)bValue, (MPARAM)0);
  223.     if (bValue)
  224.     {
  225.         const wxWindowList&         rSiblings = GetParent()->GetChildren();
  226.         wxWindowList::Node*         pNodeThis = rSiblings.Find(this);
  227.  
  228.         wxCHECK_RET(pNodeThis, _T("radio button not a child of its parent?"));
  229.  
  230.         // 
  231.         // Turn off all radio buttons before this one
  232.         //
  233.         for ( wxWindowList::Node* pNodeBefore = pNodeThis->GetPrevious();
  234.               pNodeBefore;
  235.               pNodeBefore = pNodeBefore->GetPrevious() )
  236.         {
  237.             wxRadioButton*          pBtn = wxDynamicCast( pNodeBefore->GetData()
  238.                                                          ,wxRadioButton
  239.                                                         );
  240.             if (!pBtn)
  241.             {
  242.                 // 
  243.                 // The radio buttons in a group must be consecutive, so there
  244.                 // are no more of them
  245.                 //
  246.                 break;
  247.             }
  248.             pBtn->SetValue(FALSE);
  249.             if (pBtn->HasFlag(wxRB_GROUP))
  250.             {
  251.                 // 
  252.                 // Even if there are other radio buttons before this one,
  253.                 // they're not in the same group with us
  254.                 //
  255.                 break;
  256.             }
  257.         }
  258.  
  259.         // 
  260.         // ... and all after this one
  261.         //
  262.         for (wxWindowList::Node* pNodeAfter = pNodeThis->GetNext();
  263.              pNodeAfter;
  264.              pNodeAfter = pNodeAfter->GetNext())
  265.         {
  266.             wxRadioButton*          pBtn = wxDynamicCast( pNodeAfter->GetData()
  267.                                                          ,wxRadioButton
  268.                                                         );
  269.  
  270.             if (!pBtn || pBtn->HasFlag(wxRB_GROUP) )
  271.             {
  272.                 // 
  273.                 // No more buttons or the first button of the next group
  274.                 //
  275.                 break;
  276.             }
  277.             pBtn->SetValue(FALSE);
  278.         }
  279.     }
  280. } // end of wxRadioButton::SetValue
  281.  
  282. MRESULT wxRadioButton::OS2WindowProc(
  283.   WXUINT                            uMsg
  284. , WXWPARAM                          wParam
  285. , WXLPARAM                          lParam
  286. )
  287. {
  288.     if (uMsg == WM_SETFOCUS)
  289.     {
  290.         m_bFocusJustSet = TRUE;
  291.  
  292.         MRESULT                     mRc = wxControl::OS2WindowProc( uMsg
  293.                                                                    ,wParam
  294.                                                                    ,lParam
  295.                                                                   );
  296.  
  297.         m_bFocusJustSet = FALSE;
  298.         return mRc;
  299.     }
  300.     return wxControl::OS2WindowProc( uMsg
  301.                                     ,wParam
  302.                                     ,lParam
  303.                                    );
  304. } // end of wxRadioButton::OS2WindowProc
  305.