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

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        radiobox.cpp
  3. // Purpose:     wxRadioBox
  4. // Author:      David Webster
  5. // Modified by:
  6. // Created:     10/12/99
  7. // RCS-ID:      $Id: RADIOBOX.CPP,v 1.16.2.1 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. #ifndef WX_PRECOMP
  16.     #include <stdio.h>
  17.     #include "wx/setup.h"
  18.     #include "wx/wxchar.h"
  19.     #include "wx/string.h"
  20.     #include "wx/bitmap.h"
  21.     #include "wx/brush.h"
  22.     #include "wx/radiobox.h"
  23. #endif
  24.  
  25. #include "wx/os2/private.h"
  26.  
  27. IMPLEMENT_DYNAMIC_CLASS(wxRadioBox, wxControl)
  28.  
  29. // ---------------------------------------------------------------------------
  30. // private functions
  31. // ---------------------------------------------------------------------------
  32.  
  33. // wnd proc for radio buttons
  34. MRESULT EXPENTRY wxRadioBtnWndProc( HWND hWnd
  35.                                    ,UINT uMessage
  36.                                    ,MPARAM wParam
  37.                                    ,MPARAM lParam
  38.                                   );
  39. MRESULT EXPENTRY wxRadioBoxWndProc( HWND   hWnd
  40.                                    ,UINT   uMessage
  41.                                    ,MPARAM wParam
  42.                                    ,MPARAM lParam
  43.                                   );
  44.  
  45. // ---------------------------------------------------------------------------
  46. // global vars
  47. // ---------------------------------------------------------------------------
  48.  
  49. // the pointer to standard radio button wnd proc
  50. extern void  wxAssociateWinWithHandle( HWND         hWnd
  51.                                       ,wxWindowOS2* pWin
  52.                                      );
  53. static WXFARPROC                    fnWndProcRadioBtn = NULL;
  54. static WXFARPROC                    fnWndProcRadioBox = NULL;
  55.  
  56. // ===========================================================================
  57. // implementation
  58. // ===========================================================================
  59.  
  60. // ---------------------------------------------------------------------------
  61. // wxRadioBox
  62. // ---------------------------------------------------------------------------
  63.  
  64. // Radio box item
  65. wxRadioBox::wxRadioBox()
  66. {
  67.     m_nSelectedButton = -1;
  68.     m_nNoItems = 0;
  69.     m_nNoRowsOrCols = 0;
  70.     m_ahRadioButtons = NULL;
  71.     m_nMajorDim = 0;
  72.     m_pnRadioWidth = NULL;
  73.     m_pnRadioHeight = NULL;
  74. } // end of wxRadioBox::wxRadioBox
  75.  
  76. wxRadioBox::~wxRadioBox()
  77. {
  78.     m_isBeingDeleted = TRUE;
  79.  
  80.     if (m_ahRadioButtons)
  81.     {
  82.         int                         i;
  83.         for (i = 0; i < m_nNoItems; i++)
  84.             ::WinDestroyWindow((HWND)m_ahRadioButtons[i]);
  85.         delete[] m_ahRadioButtons;
  86.     }
  87.     if (m_pnRadioWidth)
  88.         delete[] m_pnRadioWidth;
  89.     if (m_pnRadioHeight)
  90.         delete[] m_pnRadioHeight;
  91. } // end of wxRadioBox::~wxRadioBox
  92.  
  93. void wxRadioBox::AdjustButtons(
  94.   int                               nX
  95. , int                               nY
  96. , int                               nWidth
  97. , int                               nHeight
  98. , int                               nSizeFlags
  99. )
  100. {
  101.     wxSize                          vMaxSize;
  102.     int                             nXOffset = nX;
  103.     int                             nYOffset = nY + nHeight;
  104.     int                             nCx1;
  105.     int                             nCy1;
  106.     int                             nStartX;
  107.     int                             nStartY;
  108.     int                             nMaxWidth;
  109.     int                             nMaxHeight;
  110.     int                             nTotWidth;
  111.     int                             nTotHeight;
  112.  
  113.     wxGetCharSize( m_hWnd
  114.                   ,&nCx1
  115.                   ,&nCy1
  116.                   ,&GetFont()
  117.                  );
  118.     vMaxSize   = GetMaxButtonSize();
  119.     nMaxWidth  = vMaxSize.x;
  120.     nMaxHeight = vMaxSize.y;
  121.  
  122.     nXOffset += nCx1;
  123.     nYOffset -= (nMaxHeight + ((3*nCy1)/2));
  124.  
  125.     nStartX = nXOffset;
  126.     nStartY = nYOffset;
  127.  
  128.     for (int i = 0; i < m_nNoItems; i++)
  129.     {
  130.         //
  131.         // The last button in the row may be wider than the other ones as the
  132.         // radiobox may be wider than the sum of the button widths (as it
  133.         // happens, for example, when the radiobox label is very long)
  134.         //
  135.         bool                        bIsLastInTheRow;
  136.  
  137.         if (m_windowStyle & wxRA_SPECIFY_COLS)
  138.         {
  139.             //
  140.             // Item is the last in its row if it is a multiple of the number of
  141.             // columns or if it is just the last item
  142.             //
  143.             int                     n = i + 1;
  144.  
  145.             bIsLastInTheRow = ((n % m_nMajorDim) == 0) || (n == m_nNoItems);
  146.         }
  147.         else // winRA_SPECIFY_ROWS
  148.         {
  149.             //
  150.             // Item is the last in the row if it is in the last columns
  151.             //
  152.             bIsLastInTheRow = i >= (m_nNoItems/m_nMajorDim) * m_nMajorDim;
  153.         }
  154.  
  155.         //
  156.         // Is this the start of new row/column?
  157.         //
  158.         if (i && (i % m_nMajorDim == 0))
  159.         {
  160.             if (m_windowStyle & wxRA_SPECIFY_ROWS)
  161.             {
  162.  
  163.                 //
  164.                 // Start of new column
  165.                 //
  166.                 nYOffset = nStartY;
  167.                 nXOffset += nMaxWidth + nCx1;
  168.             }
  169.             else // start of new row
  170.             {
  171.                 nXOffset = nStartX;
  172.                 nYOffset -= nMaxHeight;
  173.                 if (m_pnRadioWidth[0] > 0L)
  174.                     nYOffset -= nCy1/2;
  175.             }
  176.         }
  177.  
  178.         int                         nWidthBtn;
  179.  
  180.         if (bIsLastInTheRow)
  181.         {
  182.             //
  183.             // Make the button go to the end of radio box
  184.             //
  185.             nWidthBtn = nStartX + nWidth - nXOffset - (2 * nCx1);
  186.             if (nWidthBtn < nMaxWidth)
  187.                 nWidthBtn = nMaxWidth;
  188.         }
  189.         else
  190.         {
  191.             //
  192.             // Normal button, always of the same size
  193.             //
  194.             nWidthBtn = nMaxWidth;
  195.         }
  196.  
  197.         //
  198.         // Make all buttons of the same, maximal size - like this they
  199.         // cover the radiobox entirely and the radiobox tooltips are always
  200.         // shown (otherwise they are not when the mouse pointer is in the
  201.         // radiobox part not beYInt32ing to any radiobutton)
  202.         //
  203.         ::WinSetWindowPos( (HWND)m_ahRadioButtons[i]
  204.                           ,HWND_TOP
  205.                           ,(LONG)nXOffset
  206.                           ,(LONG)nYOffset
  207.                           ,(LONG)nWidthBtn
  208.                           ,(LONG)nMaxHeight
  209.                           ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
  210.                          );
  211.         //
  212.         // Where do we put the next button?
  213.         //
  214.         if (m_windowStyle & wxRA_SPECIFY_ROWS)
  215.         {
  216.             //
  217.             // Below this one
  218.             //
  219.             nYOffset -= nMaxHeight;
  220.             if (m_pnRadioWidth[0] > 0)
  221.                 nYOffset -= nCy1/2;
  222.         }
  223.         else
  224.         {
  225.             //
  226.             // To the right of this one
  227.             //
  228.             nXOffset += nWidthBtn + nCx1;
  229.         }
  230.     }
  231. } // end of wxRadioBox::AdjustButtons
  232.  
  233. void wxRadioBox::Command (
  234.   wxCommandEvent&                   rEvent
  235. )
  236. {
  237.     SetSelection (rEvent.GetInt());
  238.     ProcessCommand(rEvent);
  239. } // end of wxRadioBox::Command
  240.  
  241. bool wxRadioBox::ContainsHWND(
  242.   WXHWND                            hWnd
  243. ) const
  244. {
  245.     size_t                          nCount = GetCount();
  246.     size_t                          i;
  247.  
  248.     for (i = 0; i < nCount; i++)
  249.     {
  250.         if (GetRadioButtons()[i] == hWnd)
  251.             return TRUE;
  252.     }
  253.     return FALSE;
  254. } // end of wxRadioBox::ContainsHWND
  255.  
  256. bool wxRadioBox::Create(
  257.   wxWindow*                         pParent
  258. , wxWindowID                        vId
  259. , const wxString&                   rsTitle
  260. , const wxPoint&                    rPos
  261. , const wxSize&                     rSize
  262. , int                               nNum
  263. , const wxString                    asChoices[]
  264. , int                               nMajorDim
  265. , long                              lStyle
  266. , const wxValidator&                rVal
  267. , const wxString&                   rsName
  268. )
  269. {
  270.     wxColour                        vColour;
  271.     LONG                            lColor;
  272.  
  273.     vColour.Set(wxString("BLACK"));
  274.     m_backgroundColour = pParent->GetBackgroundColour();
  275.     m_nSelectedButton = -1;
  276.     m_nNoItems = 0;
  277.  
  278.     m_nMajorDim     = nMajorDim == 0 ? nNum : nMajorDim;
  279.     m_nNoRowsOrCols = nMajorDim;
  280.  
  281.     //
  282.     // Common initialization
  283.     //
  284.     if (!CreateControl( pParent
  285.                        ,vId
  286.                        ,rPos
  287.                        ,rSize
  288.                        ,lStyle
  289.                        ,rVal
  290.                        ,rsName
  291.                       ))
  292.         return FALSE;
  293.     if (!OS2CreateControl( "STATIC"
  294.                           ,SS_GROUPBOX
  295.                           ,rPos
  296.                           ,rSize
  297.                           ,rsTitle
  298.                          ))
  299.         return FALSE;
  300.  
  301.     wxAssociateWinWithHandle(m_hWnd, this);
  302. #if RADIOBTN_PARENT_IS_RADIOBOX
  303.     HWND                            hWndParent = GetHwnd();
  304. #else
  305.     HWND                            hWndParent = GetHwndOf(pParent);
  306. #endif
  307.     HFONT                           hFont;
  308.  
  309.     //
  310.     // Some radio boxes test consecutive id.
  311.     //
  312.     m_nNoItems = nNum;
  313.     (void)NewControlId();
  314.     m_ahRadioButtons = new WXHWND[nNum];
  315.     m_pnRadioWidth   = new int[nNum];
  316.     m_pnRadioHeight  = new int[nNum];
  317.  
  318.     for (int i = 0; i < nNum; i++)
  319.     {
  320.         m_pnRadioWidth[i] = m_pnRadioHeight[i] = -1;
  321.  
  322.         long                        lStyleBtn = BS_AUTORADIOBUTTON | WS_TABSTOP | WS_VISIBLE;
  323.         int                         nNewId = NewControlId();
  324.  
  325.         if (i == 0 && lStyle == 0)
  326.             lStyleBtn |= WS_GROUP;
  327.  
  328.         HWND                        hWndBtn = (WXHWND)::WinCreateWindow ( GetHwndOf(pParent)
  329.                                                                          ,WC_BUTTON
  330.                                                                          ,asChoices[i]
  331.                                                                          ,lStyleBtn
  332.                                                                          ,0, 0, 0, 0
  333.                                                                          ,GetWinHwnd(pParent)
  334.                                                                          ,HWND_TOP
  335.                                                                          ,(HMENU)nNewId
  336.                                                                          ,NULL
  337.                                                                          ,NULL
  338.                                                                         );
  339.         lColor = (LONG)vColour.GetPixel();
  340.         ::WinSetPresParam( hWndBtn
  341.                           ,PP_FOREGROUNDCOLOR
  342.                           ,sizeof(LONG)
  343.                           ,(PVOID)&lColor
  344.                          );
  345.         lColor = (LONG)m_backgroundColour.GetPixel();
  346.  
  347.         ::WinSetPresParam( hWndBtn
  348.                           ,PP_BACKGROUNDCOLOR
  349.                           ,sizeof(LONG)
  350.                           ,(PVOID)&lColor
  351.                          );
  352.         if (!hWndBtn)
  353.         {
  354.             return FALSE;
  355.         }
  356.         m_ahRadioButtons[i] = (WXHWND)hWndBtn;
  357.         SubclassRadioButton((WXHWND)hWndBtn);
  358.         wxAssociateWinWithHandle(hWndBtn, this);
  359.         wxOS2SetFont( hWndBtn
  360.                      ,*wxSMALL_FONT
  361.                     );
  362.         ::WinSetWindowULong(hWndBtn, QWL_USER, (ULONG)this);
  363.         m_aSubControls.Add(nNewId);
  364.     }
  365.  
  366.     //
  367.     // Create a dummy radio control to end the group.
  368.     //
  369.     (void)::WinCreateWindow ( GetHwndOf(pParent)
  370.                              ,WC_BUTTON
  371.                              ,""
  372.                              ,WS_GROUP | BS_AUTORADIOBUTTON
  373.                              ,0, 0, 0, 0
  374.                              ,GetWinHwnd(pParent)
  375.                              ,HWND_TOP
  376.                              ,(HMENU)NewControlId()
  377.                              ,NULL
  378.                              ,NULL
  379.                             );
  380.     SetFont(*wxSMALL_FONT);
  381.     fnWndProcRadioBox = (WXFARPROC)::WinSubclassWindow( GetHwnd()
  382.                                                        ,(PFNWP)wxRadioBoxWndProc
  383.                                                       );
  384.     ::WinSetWindowULong(GetHwnd(), QWL_USER, (ULONG)this);
  385.     lColor = (LONG)vColour.GetPixel();
  386.     ::WinSetPresParam( m_hWnd
  387.                       ,PP_FOREGROUNDCOLOR
  388.                       ,sizeof(LONG)
  389.                       ,(PVOID)&lColor
  390.                      );
  391.     ::WinSetPresParam( m_hWnd
  392.                       ,PP_BORDERDARKCOLOR
  393.                       ,sizeof(LONG)
  394.                       ,(PVOID)&lColor
  395.                      );
  396.     lColor = (LONG)m_backgroundColour.GetPixel();
  397.  
  398.     ::WinSetPresParam( m_hWnd
  399.                       ,PP_BACKGROUNDCOLOR
  400.                       ,sizeof(LONG)
  401.                       ,(PVOID)&lColor
  402.                      );
  403.     ::WinSetPresParam( m_hWnd
  404.                       ,PP_BORDERLIGHTCOLOR
  405.                       ,sizeof(LONG)
  406.                       ,(PVOID)&lColor
  407.                      );
  408.     SetXComp(0);
  409.     SetYComp(0);
  410.     SetSelection(0);
  411.     SetSize( rPos.x
  412.             ,rPos.y
  413.             ,rSize.x
  414.             ,rSize.y
  415.            );
  416.     return TRUE;
  417. } // end of wxRadioBox::Create
  418.  
  419. wxSize wxRadioBox::DoGetBestSize() const
  420. {
  421.     return (GetTotalButtonSize(GetMaxButtonSize()));
  422. } // end of WinGuiBase_CRadioBox::DoGetBestSize
  423.  
  424. void wxRadioBox::DoSetSize(
  425.   int                               nX
  426. , int                               nY
  427. , int                               nWidth
  428. , int                               nHeight
  429. , int                               nSizeFlags
  430. )
  431. {
  432.     int                             nCurrentX;
  433.     int                             nCurrentY;
  434.     int                             nWidthOld;
  435.     int                             nHeightOld;
  436.     int                             nXx = nX;
  437.     int                             nYy = nY;
  438. #if RADIOBTN_PARENT_IS_RADIOBOX
  439.     int                             nXOffset = 0;
  440.     int                             nYOffset = 0;
  441. #else
  442.     int                             nXOffset = nXx;
  443.     int                             nYOffset = nYy;
  444. #endif
  445.     int                             nCx1;
  446.     int                             nCy1;
  447.     wxSize                          vMaxSize = GetMaxButtonSize();
  448.     int                             nMaxWidth;
  449.     int                             nMaxHeight;
  450.     wxSize                          vTotSize;
  451.     int                             nTotWidth;
  452.     int                             nTotHeight;
  453.     int                             nStartX;
  454.     int                             nStartY;
  455.  
  456.     m_nSizeFlags = nSizeFlags;
  457.     GetPosition( &nCurrentX
  458.                 ,&nCurrentY
  459.                );
  460.     GetSize( &nWidthOld
  461.             ,&nHeightOld
  462.            );
  463.  
  464.     if (nX == -1 && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
  465.         nXx = nCurrentX;
  466.     if (nY == -1 && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
  467.         nYy = nCurrentY;
  468.     if (nYy < 0)
  469.         nYy = 0;
  470.     if (nXx < 0)
  471.         nXx = 0;
  472.  
  473.     wxGetCharSize( m_hWnd
  474.                   ,&nCx1
  475.                   ,&nCy1
  476.                   ,&GetFont()
  477.                  );
  478.  
  479.     //
  480.     // Attempt to have a look coherent with other platforms: We compute the
  481.     // biggest toggle dim, then we align all items according this value.
  482.     //
  483.     vMaxSize   = GetMaxButtonSize();
  484.     nMaxWidth  = vMaxSize.x;
  485.     nMaxHeight = vMaxSize.y;
  486.  
  487.     vTotSize   = GetTotalButtonSize(vMaxSize);
  488.     nTotWidth  = vTotSize.x;
  489.     nTotHeight = vTotSize.y;
  490.  
  491.     //
  492.     // Only change our width/height if asked for
  493.     //
  494.     if (nWidth == -1)
  495.     {
  496.         if (nSizeFlags & wxSIZE_AUTO_WIDTH )
  497.             nWidth = nTotWidth;
  498.         else
  499.             nWidth = nWidthOld;
  500.     }
  501.  
  502.     if (nHeight == -1)
  503.     {
  504.         if (nSizeFlags & wxSIZE_AUTO_HEIGHT)
  505.             nHeight = nTotHeight;
  506.         else
  507.             nHeight = nHeightOld;
  508.     }
  509.  
  510.     wxWindowOS2*                    pParent = (wxWindowOS2*)GetParent();
  511.  
  512.     if (pParent)
  513.     {
  514.         int                         nOS2Height = GetOS2ParentHeight(pParent);
  515.  
  516.         nYy = nOS2Height - (nYy + nHeight);
  517.         nYOffset = nYy + nHeight;
  518.     }
  519.     else
  520.     {
  521.         RECTL                       vRect;
  522.  
  523.         ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
  524.         nYy = vRect.yTop - (nYy + nHeight);
  525.     }
  526.     ::WinSetWindowPos( GetHwnd()
  527.                       ,HWND_TOP
  528.                       ,(LONG)nXx
  529.                       ,(LONG)nYy
  530.                       ,(LONG)nWidth
  531.                       ,(LONG)nHeight
  532.                       ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
  533.                      );
  534.  
  535.     //
  536.     // Now position all the buttons: the current button will be put at
  537.     // wxPoint(x_offset, y_offset) and the new row/column will start at
  538.     // startX/startY. The size of all buttons will be the same wxSize(maxWidth,
  539.     // maxHeight) except for the buttons in the last column which should extend
  540.     // to the right border of radiobox and thus can be wider than this.
  541.     //
  542.     // Also, remember that wxRA_SPECIFY_COLS means that we arrange buttons in
  543.     // left to right order and m_majorDim is the number of columns while
  544.     // wxRA_SPECIFY_ROWS means that the buttons are arranged top to bottom and
  545.     // m_majorDim is the number of rows.
  546.     //
  547.     nXOffset += nCx1;
  548.     nYOffset -= (nMaxHeight + ((3*nCy1)/2));
  549.  
  550.     nStartX = nXOffset;
  551.     nStartY = nYOffset;
  552.  
  553.     for (int i = 0; i < m_nNoItems; i++)
  554.     {
  555.         //
  556.         // The last button in the row may be wider than the other ones as the
  557.         // radiobox may be wider than the sum of the button widths (as it
  558.         // happens, for example, when the radiobox label is very long)
  559.         //
  560.         bool                        bIsLastInTheRow;
  561.  
  562.         if (m_windowStyle & wxRA_SPECIFY_COLS)
  563.         {
  564.             //
  565.             // Item is the last in its row if it is a multiple of the number of
  566.             // columns or if it is just the last item
  567.             //
  568.             int                  n = i + 1;
  569.  
  570.             bIsLastInTheRow = ((n % m_nMajorDim) == 0) || (n == m_nNoItems);
  571.         }
  572.         else // winRA_SPECIFY_ROWS
  573.         {
  574.             //
  575.             // Item is the last in the row if it is in the last columns
  576.             //
  577.             bIsLastInTheRow = i >= (m_nNoItems/m_nMajorDim) * m_nMajorDim;
  578.         }
  579.  
  580.         //
  581.         // Is this the start of new row/column?
  582.         //
  583.         if (i && (i % m_nMajorDim == 0))
  584.         {
  585.             if (m_windowStyle & wxRA_SPECIFY_ROWS)
  586.             {
  587.  
  588.                 //
  589.                 // Start of new column
  590.                 //
  591.                 nYOffset = nStartY;
  592.                 nXOffset += nMaxWidth + nCx1;
  593.             }
  594.             else // start of new row
  595.             {
  596.                 nXOffset = nStartX;
  597.                 nYOffset -= nMaxHeight;
  598.                 if (m_pnRadioWidth[0] > 0L)
  599.                     nYOffset -= nCy1/2;
  600.             }
  601.         }
  602.  
  603.         int                      nWidthBtn;
  604.  
  605.         if (bIsLastInTheRow)
  606.         {
  607.             //
  608.             // Make the button go to the end of radio box
  609.             //
  610.             nWidthBtn = nStartX + nWidth - nXOffset - (2 * nCx1);
  611.             if (nWidthBtn < nMaxWidth)
  612.                 nWidthBtn = nMaxWidth;
  613.         }
  614.         else
  615.         {
  616.             //
  617.             // Normal button, always of the same size
  618.             //
  619.             nWidthBtn = nMaxWidth;
  620.         }
  621.  
  622.         //
  623.         // Make all buttons of the same, maximal size - like this they
  624.         // cover the radiobox entirely and the radiobox tooltips are always
  625.         // shown (otherwise they are not when the mouse pointer is in the
  626.         // radiobox part not beinting to any radiobutton)
  627.         //
  628.         ::WinSetWindowPos( (HWND)m_ahRadioButtons[i]
  629.                           ,HWND_TOP
  630.                           ,(LONG)nXOffset
  631.                           ,(LONG)nYOffset
  632.                           ,(LONG)nWidthBtn
  633.                           ,(LONG)nMaxHeight
  634.                           ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
  635.                          );
  636.         GetParent()->Refresh();
  637.         //
  638.         // Where do we put the next button?
  639.         //
  640.         if (m_windowStyle & wxRA_SPECIFY_ROWS)
  641.         {
  642.             //
  643.             // Below this one
  644.             //
  645.             nYOffset -= nMaxHeight;
  646.             if (m_pnRadioWidth[0] > 0)
  647.                 nYOffset -= nCy1/2;
  648.         }
  649.         else
  650.         {
  651.             //
  652.             // To the right of this one
  653.             //
  654.             nXOffset += nWidthBtn + nCx1;
  655.         }
  656.     }
  657. } // end of wxRadioBox::DoSetSize
  658.  
  659. void wxRadioBox::Enable(
  660.   int                               nItem
  661. , bool                              bEnable
  662. )
  663. {
  664.     wxCHECK_RET( nItem >= 0 && nItem < m_nNoItems,
  665.                  wxT("invalid item in wxRadioBox::Enable()") );
  666.  
  667.     ::WinEnableWindow((HWND) m_ahRadioButtons[nItem], bEnable);
  668. } // end of wxRadioBox::Enable
  669.  
  670. bool wxRadioBox::Enable(
  671.   bool                              bEnable
  672. )
  673. {
  674.     if ( !wxControl::Enable(bEnable) )
  675.         return FALSE;
  676.     for (int i = 0; i < m_nNoItems; i++)
  677.         ::WinEnableWindow((HWND)m_ahRadioButtons[i], bEnable);
  678.     return TRUE;
  679. } // end of wxRadioBox::Enable
  680.  
  681. int wxRadioBox::FindString(
  682.   const wxString&                   rsStr
  683. ) const
  684. {
  685.     for (int i = 0; i < m_nNoItems; i++)
  686.     {
  687.         if (rsStr == wxGetWindowText(m_ahRadioButtons[i]) )
  688.             return i;
  689.     }
  690.     return wxNOT_FOUND;
  691. } // end of wxRadioBox::FindString
  692.  
  693. int wxRadioBox::GetColumnCount() const
  694. {
  695.     return GetNumHor();
  696. } // end of wxRadioBox::GetColumnCount
  697.  
  698. int wxRadioBox::GetCount() const
  699. {
  700.     return m_nNoItems;
  701. } // end of wxRadioBox::GetCount
  702.  
  703. wxString wxRadioBox::GetLabel(
  704.   int                               nItem
  705. ) const
  706. {
  707.     wxCHECK_MSG(nItem >= 0 && nItem < m_nNoItems, wxT(""), wxT("invalid radiobox index") );
  708.  
  709.     return wxGetWindowText(m_ahRadioButtons[nItem]);
  710. } // end of wxRadioBox::GetLabel
  711.  
  712. wxSize wxRadioBox::GetMaxButtonSize() const
  713. {
  714.     int                             nWidthMax = 0;
  715.     int                             nHeightMax = 0;
  716.  
  717.     for (int i = 0 ; i < m_nNoItems; i++)
  718.     {
  719.         int                         nWidth;
  720.         int                         nHeight;
  721.  
  722.         if (m_pnRadioWidth[i] < 0L)
  723.         {
  724.             GetTextExtent( wxGetWindowText(m_ahRadioButtons[i])
  725.                           ,&nWidth
  726.                           ,&nHeight
  727.                          );
  728.  
  729.             //
  730.             // Adjust the size to take into account the radio box itself
  731.             // FIXME this is totally bogus!
  732.             //
  733.             nWidth  += RADIO_SIZE;
  734.             nHeight *= 3;
  735.             nHeight /= 2;
  736.         }
  737.         else
  738.         {
  739.             nWidth  = m_pnRadioWidth[i];
  740.             nHeight = m_pnRadioHeight[i];
  741.         }
  742.         if (nWidthMax < nWidth )
  743.             nWidthMax = nWidth;
  744.         if (nHeightMax < nHeight )
  745.             nHeightMax = nHeight;
  746.     }
  747.     return(wxSize( nWidthMax
  748.                   ,nHeightMax
  749.                  )
  750.           );
  751. } // end of wxRadioBox::GetMaxButtonSize
  752.  
  753. int wxRadioBox::GetNumHor() const
  754. {
  755.     if ( m_windowStyle & wxRA_SPECIFY_ROWS )
  756.     {
  757.         return (m_nNoItems + m_nMajorDim - 1)/m_nMajorDim;
  758.     }
  759.     else
  760.     {
  761.         return m_nMajorDim;
  762.     }
  763. } // end of wxRadioBox::GetNumHor
  764.  
  765. int wxRadioBox::GetNumVer() const
  766. {
  767.     if ( m_windowStyle & wxRA_SPECIFY_ROWS )
  768.     {
  769.         return m_nMajorDim;
  770.     }
  771.     else
  772.     {
  773.         return (m_nNoItems + m_nMajorDim - 1)/m_nMajorDim;
  774.     }
  775. } // end of wxRadioBox::GetNumVer
  776.  
  777. void wxRadioBox::GetPosition(
  778.   int*                              pnX
  779. , int*                              pnY
  780. ) const
  781. {
  782.     wxWindowOS2*                    pParent = GetParent();
  783.     RECT                            vRect = { -1, -1, -1, -1 };;
  784.     POINTL                          vPoint;
  785.     int                             i;
  786.  
  787.     for (i = 0; i < m_nNoItems; i++)
  788.         wxFindMaxSize( m_ahRadioButtons[i]
  789.                       ,&vRect
  790.                      );
  791.     if (m_hWnd)
  792.         wxFindMaxSize( m_hWnd
  793.                       ,&vRect
  794.                      );
  795.  
  796.     //
  797.     // Since we now have the absolute screen coords, if there's a parent we
  798.     // must subtract its top left corner
  799.     //
  800.     vPoint.x = vRect.xLeft;
  801.     vPoint.y = vRect.yTop;
  802.     if (pParent)
  803.     {
  804.         SWP                             vSwp;
  805.  
  806.         ::WinQueryWindowPos((HWND)pParent->GetHWND(), &vSwp);
  807.         vPoint.x = vSwp.x;
  808.         vPoint.y = vSwp.y;
  809.     }
  810.  
  811.     //
  812.     // We may be faking the client origin. So a window that's really at (0, 30)
  813.     // may appear (to wxWin apps) to be at (0, 0).
  814.     //
  815.     if (GetParent())
  816.     {
  817.         wxPoint                     vPt(GetParent()->GetClientAreaOrigin());
  818.  
  819.         vPoint.x = vPt.x;
  820.         vPoint.y = vPt.y;
  821.     }
  822.     *pnX = vPoint.x;
  823.     *pnX = vPoint.y;
  824. } // end of wxRadioBox::GetPosition
  825.  
  826. int wxRadioBox::GetRowCount() const
  827. {
  828.     return GetNumVer();
  829. } // end of wxRadioBox::GetRowCount
  830.  
  831. // Get single selection, for single choice list items
  832. int wxRadioBox::GetSelection() const
  833. {
  834.     return m_nSelectedButton;
  835. } // end of wxRadioBox::GetSelection
  836.  
  837. void wxRadioBox::GetSize(
  838.   int*                              pnWidth
  839. , int*                              pnHeight
  840. ) const
  841. {
  842.     RECT                            vRect;
  843.     int                             i;
  844.  
  845.     vRect.xLeft   = -1;
  846.     vRect.xRight  = -1;
  847.     vRect.yTop    = -1;
  848.     vRect.yBottom = -1;
  849.  
  850.     if (m_hWnd)
  851.         wxFindMaxSize( m_hWnd
  852.                       ,&vRect
  853.                      );
  854.  
  855.     for (i = 0; i < m_nNoItems; i++)
  856.         wxFindMaxSize( m_ahRadioButtons[i]
  857.                       ,&vRect
  858.                      );
  859.  
  860.     *pnWidth  = vRect.xRight - vRect.xLeft;
  861.     *pnHeight = vRect.yBottom - vRect.yTop;
  862. } // end of wxRadioBox::GetSize
  863.  
  864. // Find string for position
  865. wxString wxRadioBox::GetString(
  866.   int                               nNum
  867. ) const
  868. {
  869.     return wxGetWindowText(m_ahRadioButtons[nNum]);
  870. } // end of wxRadioBox::GetString
  871.  
  872. // For single selection items only
  873. wxString wxRadioBox::GetStringSelection() const
  874. {
  875.     wxString                        sResult;
  876.     int                             nSel = GetSelection();
  877.  
  878.     if (nSel > -1)
  879.         sResult = GetString(nSel);
  880.     return sResult;
  881. } // end of wxRadioBox::GetStringSelection
  882.  
  883. wxSize wxRadioBox::GetTotalButtonSize(
  884.   const wxSize&                     rSizeBtn
  885. ) const
  886. {
  887.     int                             nCx1;
  888.     int                             nCy1;
  889.     int                             nExtraHeight;
  890.     int                             nHeight;
  891.     int                             nWidth;
  892.     int                             nWidthLabel;
  893.  
  894.     wxGetCharSize( m_hWnd
  895.                   ,&nCx1
  896.                   ,&nCy1
  897.                   ,(wxFont*)&GetFont()
  898.                  );
  899.     nExtraHeight = nCy1;
  900.  
  901.     nHeight = GetNumVer() * rSizeBtn.y + (2 * nCy1);
  902.     nWidth  = GetNumHor() * (rSizeBtn.x + nCx1) + nCx1;
  903.  
  904.     //
  905.     // And also wide enough for its label
  906.     //
  907.     GetTextExtent( GetTitle()
  908.                   ,&nWidthLabel
  909.                   ,NULL
  910.                  );
  911.     nWidthLabel += RADIO_SIZE;
  912.     if (nWidthLabel > nWidth)
  913.         nWidth = nWidthLabel;
  914.  
  915.     return(wxSize( nWidth
  916.                   ,nHeight
  917.                  )
  918.           );
  919. } // end of wxRadioBox::GetTotalButtonSize
  920.  
  921. WXHBRUSH wxRadioBox::OnCtlColor(
  922.   WXHDC                             hwinDC
  923. , WXHWND                            hWnd
  924. , WXUINT                            uCtlColor
  925. , WXUINT                            uMessage
  926. , WXWPARAM                          wParam
  927. , WXLPARAM                          lParam
  928. )
  929. {
  930.     HPS                             hPS = (HPS)hwinDC; // pass in a PS handle in OS/2
  931.  
  932.     if (GetParent()->GetTransparentBackground())
  933.         ::GpiSetBackMix(hPS, BM_LEAVEALONE);
  934.     else
  935.         ::GpiSetBackMix(hPS, BM_OVERPAINT);
  936.  
  937.     wxColour                        vColBack = GetBackgroundColour();
  938.  
  939.     ::GpiSetBackColor(hPS, vColBack.GetPixel());
  940.     ::GpiSetColor(hPS, vColBack.GetPixel());
  941.  
  942.  
  943.     wxBrush*                        pBrush = wxTheBrushList->FindOrCreateBrush( vColBack
  944.                                                                                ,wxSOLID
  945.                                                                               );
  946.     return ((WXHBRUSH)pBrush->GetResourceHandle());
  947. } // end of wxRadioBox::OnCtlColor
  948.  
  949. bool wxRadioBox::OS2Command(
  950.   WXUINT                            uCmd
  951. , WXWORD                            wId
  952. )
  953. {
  954.     int                             nSelectedButton = -1;
  955.  
  956.     if (uCmd == BN_CLICKED)
  957.     {
  958.         if (wId == GetId())
  959.             return TRUE;
  960.  
  961.  
  962.         for (int i = 0; i < m_nNoItems; i++)
  963.         {
  964.             if (wId == wxGetWindowId(m_ahRadioButtons[i]))
  965.             {
  966.                 nSelectedButton = i;
  967.                 break;
  968.             }
  969.         }
  970.         if (nSelectedButton == -1)
  971.         {
  972.             //
  973.             // Just ignore it
  974.             //
  975.             return FALSE;
  976.         }
  977.         if (nSelectedButton != m_nSelectedButton)
  978.         {
  979.             m_nSelectedButton = nSelectedButton;
  980.             SendNotificationEvent();
  981.         }
  982.         return TRUE;
  983.     }
  984.     else
  985.         return FALSE;
  986. } // end of wxRadioBox::OS2Command
  987.  
  988. void wxRadioBox::SendNotificationEvent()
  989. {
  990.     wxCommandEvent                  vEvent( wxEVT_COMMAND_RADIOBOX_SELECTED
  991.                                            ,m_windowId
  992.                                           );
  993.  
  994.     vEvent.SetInt( m_nSelectedButton );
  995.     vEvent.SetString( GetString(m_nSelectedButton) );
  996.     vEvent.SetEventObject(this);
  997.     ProcessCommand(vEvent);
  998. } // end of wxRadioBox::SendNotificationEvent
  999.  
  1000. void wxRadioBox::SetFocus()
  1001. {
  1002.     if (m_nNoItems > 0)
  1003.     {
  1004.         if (m_nSelectedButton == -1)
  1005.             ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[0]);
  1006.         else
  1007.             ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[m_nSelectedButton]);
  1008.     }
  1009. } // end of wxRadioBox::SetFocus
  1010.  
  1011. bool wxRadioBox::SetFont(
  1012.   const wxFont&                     rFont
  1013. )
  1014. {
  1015.     if (!wxControl::SetFont(rFont))
  1016.     {
  1017.         //
  1018.         // Nothing to do
  1019.         //
  1020.         return FALSE;
  1021.     }
  1022.     //
  1023.     // Also set the font of our radio buttons
  1024.     //
  1025.     WXHFONT                         hFont = wxFont(rFont).GetResourceHandle();
  1026.  
  1027.     for (int n = 0; n < (int)m_nNoItems; n++)
  1028.     {
  1029.         HWND                        hWndBtn = (HWND)m_ahRadioButtons[n];
  1030.  
  1031.         wxOS2SetFont( hWndBtn
  1032.                      ,rFont
  1033.                     );
  1034.         ::WinInvalidateRect(hWndBtn, NULL, FALSE);
  1035.     }
  1036.     return TRUE;
  1037. } // end of wxRadioBox::SetFont
  1038.  
  1039. void wxRadioBox::SetSelection(
  1040.   int                               nNum
  1041. )
  1042. {
  1043.     wxCHECK_RET( (nNum >= 0) && (nNum < m_nNoItems), wxT("invalid radiobox index") );
  1044.  
  1045.     if (m_nSelectedButton >= 0 && m_nSelectedButton < m_nNoItems)
  1046.         ::WinSendMsg((HWND)m_ahRadioButtons[m_nSelectedButton], BM_SETCHECK, (MPARAM)0, (MPARAM)0);
  1047.  
  1048.     ::WinSendMsg((HWND)m_ahRadioButtons[nNum], BM_SETCHECK, (MPARAM)1, (MPARAM)0);
  1049.     ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[nNum]);
  1050.     m_nSelectedButton = nNum;
  1051. } // end of wxRadioBox::SetSelection
  1052.  
  1053. void wxRadioBox::SetString(
  1054.   int                               nItem
  1055. , const wxString&                   rsLabel
  1056. )
  1057. {
  1058.     wxCHECK_RET( nItem >= 0 && nItem < m_nNoItems, wxT("invalid radiobox index") );
  1059.  
  1060.     m_pnRadioWidth[nItem] = m_pnRadioHeight[nItem] = -1;
  1061.     ::WinSetWindowText((HWND)m_ahRadioButtons[nItem], rsLabel.c_str());
  1062. } // end of wxRadioBox::SetString
  1063.  
  1064. bool wxRadioBox::SetStringSelection(
  1065.   const wxString&                   rsStr
  1066. )
  1067. {
  1068.     int                             nSel = FindString(rsStr);
  1069.  
  1070.     if (nSel > -1)
  1071.     {
  1072.         SetSelection(nSel);
  1073.         return TRUE;
  1074.     }
  1075.     else
  1076.         return FALSE;
  1077. } // end of wxRadioBox::SetStringSelection
  1078.  
  1079. bool wxRadioBox::Show(
  1080.   bool                              bShow
  1081. )
  1082. {
  1083.     int                             nCmdShow = 0;
  1084.  
  1085.     if (!wxControl::Show(bShow))
  1086.         return FALSE;
  1087.  
  1088.     for (int i = 0; i < m_nNoItems; i++)
  1089.     {
  1090.         ::WinShowWindow((HWND)m_ahRadioButtons[i], (BOOL)bShow);
  1091.     }
  1092.     return TRUE;
  1093. } // end of wxRadioBox::Show
  1094.  
  1095. // Show a specific button
  1096. void wxRadioBox::Show(
  1097.   int                               nItem
  1098. , bool                              bShow
  1099. )
  1100. {
  1101.     wxCHECK_RET( nItem >= 0 && nItem < m_nNoItems,
  1102.                  wxT("invalid item in wxRadioBox::Show()") );
  1103.  
  1104.     ::WinShowWindow((HWND)m_ahRadioButtons[nItem], bShow);
  1105. } // end of wxRadioBox::Show
  1106.  
  1107. void wxRadioBox::SubclassRadioButton(
  1108.   WXHWND                            hWndBtn
  1109. )
  1110. {
  1111.     HWND                            hwndBtn = (HWND)hWndBtn;
  1112.  
  1113.     fnWndProcRadioBtn = (WXFARPROC)::WinSubclassWindow(hWndBtn, (PFNWP)wxRadioBtnWndProc);
  1114. } // end of wxRadioBox::SubclassRadioButton
  1115.  
  1116. MRESULT wxRadioBox::WindowProc(
  1117.   WXUINT                            uMsg
  1118. , WXWPARAM                          wParam
  1119. , WXLPARAM                          lParam
  1120. )
  1121. {
  1122.     return (wxControl::OS2WindowProc( uMsg
  1123.                                      ,wParam
  1124.                                      ,lParam
  1125.                                     ));
  1126. } // end of wxRadioBox::WindowProc
  1127.  
  1128. // ---------------------------------------------------------------------------
  1129. // window proc for radio buttons
  1130. // ---------------------------------------------------------------------------
  1131.  
  1132. MRESULT wxRadioBtnWndProc(
  1133.   HWND                              hWnd
  1134. , UINT                              uMessage
  1135. , MPARAM                            wParam
  1136. , MPARAM                            lParam
  1137. )
  1138. {
  1139.     switch (uMessage)
  1140.     {
  1141.         case WM_CHAR:
  1142.             {
  1143.                 USHORT                  uKeyFlags = SHORT1FROMMP((MPARAM)wParam);
  1144.  
  1145.                 if (!(uKeyFlags & KC_KEYUP)) // Key Down event
  1146.                 {
  1147.                     if (uKeyFlags & KC_VIRTUALKEY)
  1148.                     {
  1149.                         wxRadioBox*             pRadiobox = (wxRadioBox *)::WinQueryWindowULong( hWnd
  1150.                                                                                                 ,QWL_USER
  1151.                                                                                                );
  1152.                         USHORT                  uVk = SHORT2FROMMP((MPARAM)lParam);
  1153.                         bool                    bProcessed = TRUE;
  1154.                         wxDirection             eDir;
  1155.  
  1156.                         switch(uVk)
  1157.                         {
  1158.                             case VK_LEFT:
  1159.                                 eDir = wxDOWN;
  1160.                                 break;
  1161.  
  1162.                             case VK_RIGHT:
  1163.                                 eDir = wxDOWN;
  1164.                                 break;
  1165.  
  1166.                             case VK_DOWN:
  1167.                                 eDir = wxDOWN;
  1168.                                 break;
  1169.  
  1170.                             case VK_UP:
  1171.                                 eDir = wxUP;
  1172.                                 break;
  1173.  
  1174.                             default:
  1175.                                 bProcessed = FALSE;
  1176.  
  1177.                                 //
  1178.                                 // Just to suppress the compiler warning
  1179.                                 //
  1180.                                 eDir = wxALL;
  1181.                         }
  1182.  
  1183.                         if (bProcessed)
  1184.                         {
  1185.                             int             nSelOld = pRadiobox->GetSelection();
  1186.                             int             nSelNew = pRadiobox->GetNextItem( nSelOld
  1187.                                                                              ,eDir
  1188.                                                                              ,pRadiobox->GetWindowStyleFlag()
  1189.                                                                             );
  1190.  
  1191.                             if (nSelNew != nSelOld)
  1192.                             {
  1193.                                 pRadiobox->SetSelection(nSelNew);
  1194.  
  1195.                                 //
  1196.                                 // Emulate the button click
  1197.                                 //
  1198.                                 pRadiobox->SendNotificationEvent();
  1199.                                 return 0;
  1200.                             }
  1201.                         }
  1202.                     }
  1203.                 }
  1204.             }
  1205.             break;
  1206.     }
  1207.  
  1208.     return fnWndProcRadioBtn( hWnd
  1209.                              ,(ULONG)uMessage
  1210.                              ,(MPARAM)wParam
  1211.                              ,(MPARAM)lParam
  1212.                             );
  1213. } // end of wxRadioBtnWndProc
  1214.  
  1215. MRESULT EXPENTRY wxRadioBoxWndProc(
  1216.   HWND                              hWnd
  1217. , UINT                              uMessage
  1218. , MPARAM                            wParam
  1219. , MPARAM                            lParam
  1220. )
  1221. {
  1222.     return (fnWndProcRadioBox( hWnd
  1223.                               ,(ULONG)uMessage
  1224.                               ,(MPARAM)wParam
  1225.                               ,(MPARAM)lParam
  1226.                              )
  1227.            );
  1228. } // end of wxRadioBoxWndProc
  1229.  
  1230.