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

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        msw/spinctrl.cpp
  3. // Purpose:     wxSpinCtrl class implementation for Win32
  4. // Author:      David Webster
  5. // Modified by:
  6. // Created:     10/15/99
  7. // RCS-ID:      $Id: SPINCTRL.CPP,v 1.14 2002/08/30 21:54:47 DW Exp $
  8. // Copyright:   (c) David Webster
  9. // Licence:     wxWindows licence
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. // ============================================================================
  13. // declarations
  14. // ============================================================================
  15.  
  16.  
  17. #ifdef __GNUG__
  18.     #pragma implementation "spinctrlbase.h"
  19.     #pragma implementation "spinctrl.h"
  20. #endif
  21.  
  22. // ----------------------------------------------------------------------------
  23. // headers
  24. // ----------------------------------------------------------------------------
  25.  
  26. // for compilers that support precompilation, includes "wx.h".
  27. #include "wx/wxprec.h"
  28.  
  29.  
  30. #ifndef WX_PRECOMP
  31.     #include "wx/wx.h"
  32. #endif
  33.  
  34. #if wxUSE_SPINBTN
  35.  
  36. #include "wx/spinctrl.h"
  37. #include "wx/os2/private.h"
  38.  
  39. // ----------------------------------------------------------------------------
  40. // macros
  41. // ----------------------------------------------------------------------------
  42.  
  43. extern void  wxAssociateWinWithHandle( HWND         hWnd
  44.                                       ,wxWindowOS2* pWin
  45.                                      );
  46. static WXFARPROC fnWndProcSpinCtrl = (WXFARPROC)NULL;
  47. wxArraySpins                        wxSpinCtrl::m_svAllSpins;
  48.  
  49. IMPLEMENT_DYNAMIC_CLASS(wxSpinCtrl, wxControl)
  50.  
  51. BEGIN_EVENT_TABLE(wxSpinCtrl, wxSpinButton)
  52.     EVT_SPIN(-1, wxSpinCtrl::OnSpinChange)
  53. END_EVENT_TABLE()
  54. // ----------------------------------------------------------------------------
  55. // constants
  56. // ----------------------------------------------------------------------------
  57.  
  58. // the margin between the up-down control and its buddy
  59. static const int MARGIN_BETWEEN = 5;
  60.  
  61. // ============================================================================
  62. // implementation
  63. // ============================================================================
  64. MRESULT EXPENTRY wxSpinCtrlWndProc(
  65.   HWND                              hWnd
  66. , UINT                              uMessage
  67. , MPARAM                            wParam
  68. , MPARAM                            lParam
  69. )
  70. {
  71.     wxSpinCtrl*                    pSpin = (wxSpinCtrl *)::WinQueryWindowULong( hWnd
  72.                                                                                ,QWL_USER
  73.                                                                               );
  74.     bool                            bProccesed = FALSE;
  75.     MRESULT                         rc = (MRESULT)0;
  76.     //
  77.     // Forward some messages (the key ones only so far) to the spin ctrl
  78.     //
  79.     switch (uMessage )
  80.     {
  81.         case WM_CHAR:
  82.             pSpin->OS2WindowProc( uMessage
  83.                                  ,wParam
  84.                                  ,lParam
  85.                                 );
  86.  
  87.             //
  88.             // The control may have been deleted at this point, so check.
  89.             //
  90.             if (!(::WinIsWindow(vHabmain, hWnd) && ((wxSpinCtrl *)::WinQueryWindowULong( hWnd
  91.                                                                                         ,QWL_USER
  92.                                                                                        )
  93.                                                    ) == pSpin))
  94.                 return 0;
  95.             break;
  96.  
  97.     }
  98.     return (fnWndProcSpinCtrl( hWnd
  99.                               ,(ULONG)uMessage
  100.                               ,(MPARAM)wParam
  101.                               ,(MPARAM)lParam
  102.                              )
  103.            );
  104. } // end of wxSpinCtrlWndProc
  105.  
  106. wxSpinCtrl::~wxSpinCtrl()
  107. {
  108.     m_svAllSpins.Remove(this);
  109.  
  110.     // This removes spurious memory leak reporting
  111.     if (m_svAllSpins.GetCount() == 0)
  112.         m_svAllSpins.Clear();
  113. } // end of wxSpinCtrl::~wxSpinCtrl
  114.  
  115. // ----------------------------------------------------------------------------
  116. // construction
  117. // ----------------------------------------------------------------------------
  118.  
  119. bool wxSpinCtrl::Create(
  120.   wxWindow*                         pParent
  121. , wxWindowID                        vId
  122. , const wxString&                   rsValue
  123. , const wxPoint&                    rPos
  124. , const wxSize&                     rSize
  125. , long                              lStyle
  126. , int                               nMin
  127. , int                               nMax
  128. , int                               nInitial
  129. , const wxString&                   rsName
  130. )
  131. {
  132.     SWP                             vSwp;
  133.  
  134.     if (vId == -1)
  135.         m_windowId = NewControlId();
  136.     else
  137.         m_windowId = vId;
  138.     m_backgroundColour = pParent->GetBackgroundColour();
  139.     m_foregroundColour = pParent->GetForegroundColour();
  140.     SetName(rsName);
  141.     SetParent(pParent);
  142.     m_windowStyle      = lStyle;
  143.  
  144.     int                             lSstyle = 0L;
  145.  
  146.     lSstyle = WS_VISIBLE      |
  147.               WS_TABSTOP      |
  148.               SPBS_MASTER     | // We use only single field spin buttons
  149.               SPBS_NUMERICONLY; // We default to numeric data
  150.  
  151.     if (m_windowStyle & wxCLIP_SIBLINGS )
  152.         lSstyle |= WS_CLIPSIBLINGS;
  153.  
  154.     SPBCDATA                        vCtrlData;
  155.  
  156.     vCtrlData.cbSize = sizeof(SPBCDATA);
  157.     vCtrlData.ulTextLimit = 10L;
  158.     vCtrlData.lLowerLimit = 0L;
  159.     vCtrlData.lUpperLimit = 100L;
  160.     vCtrlData.idMasterSpb = vId;
  161.     vCtrlData.pHWXCtlData = NULL;
  162.  
  163.     m_hWnd = (WXHWND)::WinCreateWindow( GetWinHwnd(pParent)
  164.                                        ,WC_SPINBUTTON
  165.                                        ,(PSZ)NULL
  166.                                        ,lSstyle
  167.                                        ,0L, 0L, 0L, 0L
  168.                                        ,GetWinHwnd(pParent)
  169.                                        ,HWND_TOP
  170.                                        ,(HMENU)vId
  171.                                        ,(PVOID)&vCtrlData
  172.                                        ,NULL
  173.                                       );
  174.     if (m_hWnd == 0)
  175.     {
  176.         return FALSE;
  177.     }
  178.     m_hWndBuddy = m_hWnd; // One in the same for OS/2
  179.     if(pParent)
  180.         pParent->AddChild((wxSpinButton *)this);
  181.     wxFont*                          pTextFont = new wxFont( 10
  182.                                                             ,wxMODERN
  183.                                                             ,wxNORMAL
  184.                                                             ,wxNORMAL
  185.                                                            );
  186.     SetFont(*pTextFont);
  187.     ::WinQueryWindowPos(m_hWnd, &vSwp);
  188.     SetXComp(vSwp.x);
  189.     SetYComp(vSwp.y);
  190.     SetSize( rPos.x
  191.             ,rPos.y
  192.             ,rSize.x
  193.             ,rSize.y
  194.            );
  195.  
  196.     SetRange(nMin, nMax);
  197.     SetValue(nInitial);
  198.  
  199.     //
  200.     // For OS/2 we'll just set our handle into our long data
  201.     //
  202.     wxAssociateWinWithHandle( m_hWnd
  203.                              ,(wxWindowOS2*)this
  204.                             );
  205.     ::WinSetWindowULong(GetHwnd(), QWL_USER, (LONG)this);
  206.     fnWndProcSpinCtrl = (WXFARPROC)::WinSubclassWindow(m_hWnd, (PFNWP)wxSpinCtrlWndProc);
  207.     m_svAllSpins.Add(this);
  208.     delete pTextFont;
  209.     return TRUE;
  210. } // end of wxSpinCtrl::Create
  211.  
  212. wxSize wxSpinCtrl::DoGetBestSize() const
  213. {
  214.     wxSize                          vSizeBtn = wxSpinButton::DoGetBestSize();
  215.     int                             nHeight;
  216.  
  217.     vSizeBtn.x += DEFAULT_ITEM_WIDTH + MARGIN_BETWEEN;
  218.  
  219.     wxGetCharSize( GetHWND()
  220.                   ,NULL
  221.                   ,&nHeight
  222.                   ,(wxFont*)&GetFont()
  223.                  );
  224.     nHeight = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nHeight);
  225.  
  226.     if (vSizeBtn.y < nHeight)
  227.     {
  228.         //
  229.         // Make the text tall enough
  230.         //
  231.         vSizeBtn.y = nHeight;
  232.     }
  233.     return vSizeBtn;
  234. } // end of wxSpinCtrl::DoGetBestSize
  235.  
  236. void wxSpinCtrl::DoGetPosition(
  237.   int*                              pnX
  238. , int*                              pnY
  239. ) const
  240. {
  241.     WXHWND                          hWnd = GetHWND();
  242.  
  243.     wxConstCast(this, wxSpinCtrl)->m_hWnd = m_hWndBuddy;
  244.     wxSpinButton::DoGetPosition( pnX
  245.                                 ,pnY
  246.                                );
  247.     wxConstCast(this, wxSpinCtrl)->m_hWnd = hWnd;
  248. } // end of wxpinCtrl::DoGetPosition
  249.  
  250. void wxSpinCtrl::DoGetSize(
  251.   int*                              pnWidth
  252. , int*                              pnHeight
  253. ) const
  254. {
  255.     RECTL                           vSpinrect;
  256.  
  257.     ::WinQueryWindowRect(GetHwnd(), &vSpinrect);
  258.  
  259.     if (pnWidth)
  260.         *pnWidth = vSpinrect.xRight - vSpinrect.xLeft;
  261.     if (pnHeight)
  262.         *pnHeight = vSpinrect.yTop - vSpinrect.yBottom;
  263. } // end of wxSpinCtrl::DoGetSize
  264.  
  265. void wxSpinCtrl::DoMoveWindow(
  266.   int                               nX
  267. , int                               nY
  268. , int                               nWidth
  269. , int                               nHeight
  270. )
  271. {
  272.     wxWindowOS2*                    pParent = (wxWindowOS2*)GetParent();
  273.  
  274.     if (pParent)
  275.     {
  276.         int                         nOS2Height = GetOS2ParentHeight(pParent);
  277.  
  278.         nY = nOS2Height - (nY + nHeight);
  279.     }
  280.     else
  281.     {
  282.         RECTL                       vRect;
  283.  
  284.         ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
  285.         nY = vRect.yTop - (nY + nHeight);
  286.     }
  287.     ::WinSetWindowPos( GetHwnd()
  288.                       ,HWND_TOP
  289.                       ,nX
  290.                       ,nY
  291.                       ,nWidth
  292.                       ,nHeight
  293.                       ,SWP_SIZE | SWP_MOVE | SWP_ZORDER | SWP_SHOW
  294.                      );
  295. } // end of wxSpinCtrl::DoMoveWindow
  296.  
  297. bool wxSpinCtrl::Enable(
  298.   bool                              bEnable
  299. )
  300. {
  301.     if (!wxControl::Enable(bEnable))
  302.     {
  303.         return FALSE;
  304.     }
  305.     ::WinEnableWindow(GetHwnd(), bEnable);
  306.     return TRUE;
  307. } // end of wxSpinCtrl::Enable
  308.  
  309. wxSpinCtrl* wxSpinCtrl::GetSpinForTextCtrl(
  310.   WXHWND                            hWndBuddy
  311. )
  312. {
  313.     wxSpinCtrl*                     pSpin = (wxSpinCtrl *)::WinQueryWindowULong( (HWND)hWndBuddy
  314.                                                                                 ,QWL_USER
  315.                                                                                );
  316.     int                             i = m_svAllSpins.Index(pSpin);
  317.  
  318.     if (i == wxNOT_FOUND)
  319.         return NULL;
  320.  
  321.     // sanity check
  322.     wxASSERT_MSG( pSpin->m_hWndBuddy == hWndBuddy,
  323.                   _T("wxSpinCtrl has incorrect buddy HWND!") );
  324.  
  325.     return pSpin;
  326. } // end of wxSpinCtrl::GetSpinForTextCtrl
  327.  
  328. int wxSpinCtrl::GetValue() const
  329. {
  330.     long                            lVal = 0L;
  331.     char                            zVal[10];
  332.  
  333.     ::WinSendMsg( GetHwnd()
  334.                  ,SPBM_QUERYVALUE
  335.                  ,MPFROMP(zVal)
  336.                  ,MPFROM2SHORT( (USHORT)10
  337.                                ,SPBQ_UPDATEIFVALID
  338.                               )
  339.                 );
  340.     lVal = atol(zVal);
  341.     return (int)lVal;
  342. } // end of wxSpinCtrl::GetValue
  343.  
  344. void wxSpinCtrl::OnChar (
  345.   wxKeyEvent&                       rEvent
  346. )
  347. {
  348.     switch (rEvent.KeyCode())
  349.     {
  350.         case WXK_RETURN:
  351.             {
  352.                 wxCommandEvent              vEvent( wxEVT_COMMAND_TEXT_ENTER
  353.                                                    ,m_windowId
  354.                                                   );
  355.                 wxString                    sVal = wxGetWindowText(m_hWndBuddy);
  356.  
  357.                 InitCommandEvent(vEvent);
  358.                 vEvent.SetString((char*)sVal.c_str());
  359.                 vEvent.SetInt(GetValue());
  360.                 if (GetEventHandler()->ProcessEvent(vEvent))
  361.                     return;
  362.                 break;
  363.             }
  364.  
  365.         case WXK_TAB:
  366.             //
  367.             // Always produce navigation event - even if we process TAB
  368.             // ourselves the fact that we got here means that the user code
  369.             // decided to skip processing of this TAB - probably to let it
  370.             // do its default job.
  371.             //
  372.             {
  373.                 wxNavigationKeyEvent        vEventNav;
  374.  
  375.                 vEventNav.SetDirection(!rEvent.ShiftDown());
  376.                 vEventNav.SetWindowChange(rEvent.ControlDown());
  377.                 vEventNav.SetEventObject(this);
  378.                 if (GetParent()->GetEventHandler()->ProcessEvent(vEventNav))
  379.                     return;
  380.             }
  381.             break;
  382.     }
  383.  
  384.     //
  385.     // No, we didn't process it
  386.     //
  387.     rEvent.Skip();
  388. } // end of wxSpinCtrl::OnChar
  389.  
  390. void wxSpinCtrl::OnSpinChange(
  391.   wxSpinEvent&                      rEventSpin
  392. )
  393. {
  394.     wxCommandEvent                  vEvent( wxEVT_COMMAND_SPINCTRL_UPDATED
  395.                                            ,GetId()
  396.                                           );
  397.  
  398.     vEvent.SetEventObject(this);
  399.     vEvent.SetInt(rEventSpin.GetPosition());
  400.     (void)GetEventHandler()->ProcessEvent(vEvent);
  401.     if (rEventSpin.GetSkipped())
  402.     {
  403.         vEvent.Skip();
  404.     }
  405. } // end of wxSpinCtrl::OnSpinChange
  406.  
  407. bool wxSpinCtrl::ProcessTextCommand(
  408.   WXWORD                            wCmd
  409. , WXWORD                            wId
  410. )
  411. {
  412.     switch (wCmd)
  413.     {
  414.         case SPBN_CHANGE:
  415.         {
  416.             wxCommandEvent          vEvent( wxEVT_COMMAND_TEXT_UPDATED
  417.                                            ,GetId()
  418.                                           );
  419.             vEvent.SetEventObject(this);
  420.  
  421.             wxString                sVal = wxGetWindowText(m_hWndBuddy);
  422.  
  423.             vEvent.SetString((char*)sVal.c_str());
  424.             vEvent.SetInt(GetValue());
  425.             return (GetEventHandler()->ProcessEvent(vEvent));
  426.         }
  427.  
  428.         case SPBN_SETFOCUS:
  429.         case SPBN_KILLFOCUS:
  430.         {
  431.             wxFocusEvent                vEvent( wCmd == EN_KILLFOCUS ? wxEVT_KILL_FOCUS : wxEVT_SET_FOCUS
  432.                                                ,m_windowId
  433.                                               );
  434.  
  435.             vEvent.SetEventObject(this);
  436.             return(GetEventHandler()->ProcessEvent(vEvent));
  437.         }
  438.         default:
  439.             break;
  440.     }
  441.  
  442.     //
  443.     // Not processed
  444.     //
  445.     return FALSE;
  446. } // end of wxSpinCtrl::ProcessTextCommand
  447.  
  448. void wxSpinCtrl::SetFocus()
  449. {
  450.     ::WinSetFocus(HWND_DESKTOP, GetHwnd());
  451. } // end of wxSpinCtrl::SetFocus
  452.  
  453. bool wxSpinCtrl::SetFont(
  454.   const wxFont&                     rFont
  455. )
  456. {
  457.     if (!wxWindowBase::SetFont(rFont))
  458.     {
  459.         // nothing to do
  460.         return FALSE;
  461.     }
  462.  
  463.     WXHANDLE                        hFont = GetFont().GetResourceHandle();
  464.     wxOS2SetFont( m_hWnd
  465.                  ,rFont
  466.                 );
  467.     return TRUE;
  468. } // end of wxSpinCtrl::SetFont
  469.  
  470. void wxSpinCtrl::SetValue(
  471.   const wxString&                   rsText
  472. )
  473. {
  474.     long                            lVal;
  475.  
  476.     lVal = atol(rsText.c_str());
  477.     wxSpinButton::SetValue(lVal);
  478. } // end of wxSpinCtrl::SetValue
  479.  
  480. bool wxSpinCtrl::Show(
  481.   bool                              bShow
  482. )
  483. {
  484.     if (!wxControl::Show(bShow))
  485.     {
  486.         return FALSE;
  487.     }
  488.     return TRUE;
  489. } // end of wxSpinCtrl::Show
  490.  
  491. void wxSpinCtrl::SetSelection (
  492.   long                              lFrom
  493. , long                              lTo
  494. )
  495. {
  496.     //
  497.     // If from and to are both -1, it means (in wxWindows) that all text should
  498.     // be selected - translate into Windows convention
  499.     //
  500.     if ((lFrom == -1) && (lTo == -1))
  501.     {
  502.         lFrom = 0;
  503.     }
  504.     ::WinSendMsg(m_hWnd, EM_SETSEL, MPFROM2SHORT((USHORT)lFrom, (USHORT)lTo), (MPARAM)0);
  505. } // end of wxSpinCtrl::SetSelection
  506.  
  507. #endif //wxUSE_SPINBTN
  508.