]> git.saurik.com Git - wxWidgets.git/blobdiff - src/os2/spinbutt.cpp
delay setting the window shape until it is realized (slightly modified patch 1935497)
[wxWidgets.git] / src / os2 / spinbutt.cpp
index 554c1a692c611ecce9b15912b1c9529b29eef3db..a7b3237f2519668198a25eca7634feff970d63e0 100644 (file)
 #ifndef WX_PRECOMP
     #include "wx/wx.h"
 #endif
+#if wxUSE_SPINBTN
 
 // Can't resolve reference to CreateUpDownControl in
 // TWIN32, but could probably use normal CreateWindow instead.
 
 
 #include "wx/spinbutt.h"
+
+extern void  wxAssociateWinWithHandle( HWND         hWnd
+                                      ,wxWindowOS2* pWin
+                                     );
+
+IMPLEMENT_DYNAMIC_CLASS(wxSpinEvent, wxNotifyEvent)
+
 #include "wx/os2/private.h"
 
 // ============================================================================
 // wxWin macros
 // ----------------------------------------------------------------------------
 
-#if !USE_SHARED_LIBRARY
 IMPLEMENT_DYNAMIC_CLASS(wxSpinButton, wxControl)
-#endif
 
 bool wxSpinButton::Create(
-  wxWindow*                         parent
-, wxWindowID                        id
-, const wxPoint&                    pos
-, const wxSize&                     size
-, long                              style
-, const wxString&                   name
+  wxWindow*                         pParent
+, wxWindowID                        vId
+, const wxPoint&                    rPos
+, const wxSize&                     rSize
+, long                              lStyle
+, const wxString&                   rsName
 )
 {
-    SetName(name);
-
-    m_windowStyle = style;
-
-    SetParent(parent);
-
-    m_windowId = (id == -1) ? NewControlId() : id;
+    int                             nX      = rPos.x;
+    int                             nY      = rPos.y;
+    int                             nWidth  = rSize.x;
+    int                             nHeight = rSize.y;
+    SWP                             vSwp;
+
+    m_min = 0;
+    m_max = 100;
+    if (vId == -1)
+        m_windowId = NewControlId();
+    else
+        m_windowId = vId;
+    m_backgroundColour = pParent->GetBackgroundColour();
+    m_foregroundColour = pParent->GetForegroundColour();
+    SetName(rsName);
+    SetParent(pParent);
+    m_windowStyle      = lStyle;
+
+    //
+    // Get the right size for the control
+    //
+    if (nWidth <= 0 || nHeight <= 0 )
+    {
+        wxSize                      vSize = DoGetBestSize();
 
-    // TODO create spin button
-    return FALSE;
-}
+        if (nWidth <= 0 )
+            nWidth = vSize.x;
+        if (nHeight <= 0 )
+            nHeight = vSize.y;
+    }
+    if (nX < 0 )
+        nX = 0;
+    if (nY < 0 )
+        nY = 0;
+
+    long                            lSstyle = 0L;
+
+    lSstyle = WS_VISIBLE      |
+              WS_TABSTOP      |
+              SPBS_MASTER     | // We use only single field spin buttons
+              SPBS_NUMERICONLY; // We default to numeric data
+
+    if (m_windowStyle & wxCLIP_SIBLINGS )
+        lSstyle |= WS_CLIPSIBLINGS;
+
+    m_hWnd = (WXHWND)::WinCreateWindow( GetWinHwnd(pParent)
+                                       ,WC_SPINBUTTON
+                                       ,(PSZ)NULL
+                                       ,lSstyle
+                                       ,0L, 0L, 0L, 0L
+                                       ,GetWinHwnd(pParent)
+                                       ,HWND_TOP
+                                       ,(HMENU)vId
+                                       ,NULL
+                                       ,NULL
+                                      );
+    if (m_hWnd == 0)
+    {
+        return FALSE;
+    }
+    SetRange(m_min, m_max);
+    if(pParent)
+        pParent->AddChild((wxSpinButton *)this);
+
+    ::WinQueryWindowPos(m_hWnd, &vSwp);
+    SetXComp(vSwp.x);
+    SetYComp(vSwp.y-5); // compensate for the associated TextControl border
+
+    SetFont(*wxSMALL_FONT);
+    //
+    // For OS/2 we want to hide the text portion so we can substitute an
+    // independent text ctrl in its place.
+    // Therefore we must override any user given width with our best guess.
+    //
+    SetSize( nX - GetXComp()
+            ,nY - GetYComp()
+            ,nWidth
+            ,nHeight
+           );
+    wxAssociateWinWithHandle( m_hWnd
+                             ,(wxWindowOS2*)this
+                            );
+#if 0
+    // FIXME:
+    // Apparently, this does not work, as it crashes in setvalue/setrange calls
+    // What's it supposed to do anyway?
+    ::WinSetWindowULong(GetHwnd(), QWL_USER, (LONG)this);
+    fnWndProcSpinCtrl = (WXFARPROC)::WinSubclassWindow(m_hWnd, (PFNWP)wxSpinCtrlWndProc);
+#endif
+    return TRUE;
+} // end of wxSpinButton::Create
 
 wxSpinButton::~wxSpinButton()
 {
-}
+} // end of wxSpinButton::~wxSpinButton
 
 // ----------------------------------------------------------------------------
 // size calculation
 // ----------------------------------------------------------------------------
 
-wxSize wxSpinButton::DoGetBestSize()
+wxSize wxSpinButton::DoGetBestSize() const
 {
-    // TODO:
-/*
-    if ( (GetWindowStyle() & wxSP_VERTICAL) != 0 )
-    {
-        // vertical control
-        return wxSize(GetSystemMetrics(SM_CXVSCROLL),
-                      2*GetSystemMetrics(SM_CYVSCROLL));
-    }
-    else
-    {
-        // horizontal control
-        return wxSize(2*GetSystemMetrics(SM_CXHSCROLL),
-                      GetSystemMetrics(SM_CYHSCROLL));
-    }
-*/
-    return wxSize(0, 0);
-}
+    //
+    // OS/2 PM does not really have system metrics so we'll just set it to
+    // a square based on its height.
+    //
+    RECTL   vRect;
+    ::WinQueryWindowRect(GetHwnd(),&vRect);
+    return wxSize(vRect.yTop,vRect.yTop);
+} // end of wxSpinButton::DoGetBestSize
 
 // ----------------------------------------------------------------------------
 // Attributes
@@ -91,65 +168,61 @@ wxSize wxSpinButton::DoGetBestSize()
 
 int wxSpinButton::GetValue() const
 {
-    // TODO
-    return 0;
-}
-
-void wxSpinButton::SetValue(int val)
-{
-    // TODO
-}
-
-void wxSpinButton::SetRange(int minVal, int maxVal)
+    long                            lVal = 0L;
+    char                            zVal[10];
+
+    ::WinSendMsg( GetHwnd()
+                 ,SPBM_QUERYVALUE
+                 ,MPFROMP(zVal)
+                 ,MPFROM2SHORT( (USHORT)10
+                               ,SPBQ_UPDATEIFVALID
+                              )
+                );
+    lVal = atol(zVal);
+    return ((int)lVal);
+} // end of wxSpinButton::GetValue
+
+bool wxSpinButton::OS2OnScroll( int    WXUNUSED(nOrientation),
+                                WXWORD WXUNUSED(wParam),
+                                WXWORD wPos,
+                                WXHWND hControl )
 {
-    // TODO
-}
+    wxCHECK_MSG(hControl, false, wxT("scrolling what?") );
 
-bool wxSpinButton::OS2OnScroll(int orientation, WXWORD wParam,
-                               WXWORD pos, WXHWND control)
-{
-    wxCHECK_MSG( control, FALSE, wxT("scrolling what?") )
-// TODO:
-/*
-    if ( wParam != SB_THUMBPOSITION )
-    {
-        // probable SB_ENDSCROLL - we don't react to it
-        return FALSE;
-    }
+    wxSpinEvent vEvent( wxEVT_SCROLL_THUMBTRACK, m_windowId );
+    int nVal = (int)wPos;    // cast is important for negative values!
 
-    wxSpinEvent event(wxEVT_SCROLL_THUMBTRACK, m_windowId);
-    event.SetPosition((short)pos);    // cast is important for negative values!
-    event.SetEventObject(this);
+    vEvent.SetPosition(nVal);
+    vEvent.SetEventObject(this);
+    return(HandleWindowEvent(vEvent));
+} // end of wxSpinButton::OS2OnScroll
 
-    return GetEventHandler()->ProcessEvent(event);
-*/
-    return FALSE;
-}
-
-bool wxSpinButton::OS2OnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
+bool wxSpinButton::OS2Command( WXUINT WXUNUSED(uCmd),
+                               WXWORD WXUNUSED(wId) )
 {
-    // TODO:
-/*
-    LPNM_UPDOWN lpnmud = (LPNM_UPDOWN)lParam;
-
-    wxSpinEvent event(lpnmud->iDelta > 0 ? wxEVT_SCROLL_LINEUP
-                                         : wxEVT_SCROLL_LINEDOWN,
-                      m_windowId);
-    event.SetPosition(lpnmud->iPos + lpnmud->iDelta);
-    event.SetEventObject(this);
-
-    bool processed = GetEventHandler()->ProcessEvent(event);
-
-    *result = event.IsAllowed() ? 0 : 1;
+    return false;
+} // end of wxSpinButton::OS2Command
 
-    return processed;
-*/
-    return FALSE;
-}
-
-bool wxSpinButton::OS2Command(WXUINT cmd, WXWORD id)
+void wxSpinButton::SetRange(
+  int                               nMinVal
+, int                               nMaxVal
+)
+{
+    m_min = nMinVal;
+    m_max = nMaxVal;
+
+    ::WinSendMsg( GetHwnd()
+                 ,SPBM_SETLIMITS
+                 ,MPFROMLONG(nMaxVal)
+                 ,MPFROMLONG(nMinVal)
+                );
+} // end of wxSpinButton::SetRange
+
+void wxSpinButton::SetValue(
+  int                               nValue
+)
 {
-    // No command messages
-    return FALSE;
-}
+    ::WinSendMsg(GetHwnd(), SPBM_SETCURRENTVALUE, MPFROMLONG(nValue), MPARAM(0));
+} // end of wxSpinButton::SetValue
 
+#endif //wxUSE_SPINBTN