1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        msw/scrolbar.cpp 
   3 // Purpose:     wxScrollBar 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  13     #pragma implementation "scrolbar.h" 
  16 // For compilers that support precompilation, includes "wx.h". 
  17 #include "wx/wxprec.h" 
  29 #include "wx/scrolbar.h" 
  30 #include "wx/msw/private.h" 
  31 #include "wx/settings.h" 
  33 #if wxUSE_EXTENDED_RTTI 
  34 WX_DEFINE_FLAGS( wxScrollBarStyle 
) 
  36 wxBEGIN_FLAGS( wxScrollBarStyle 
) 
  37     // new style border flags, we put them first to 
  38     // use them for streaming out 
  39     wxFLAGS_MEMBER(wxBORDER_SIMPLE
) 
  40     wxFLAGS_MEMBER(wxBORDER_SUNKEN
) 
  41     wxFLAGS_MEMBER(wxBORDER_DOUBLE
) 
  42     wxFLAGS_MEMBER(wxBORDER_RAISED
) 
  43     wxFLAGS_MEMBER(wxBORDER_STATIC
) 
  44     wxFLAGS_MEMBER(wxBORDER_NONE
) 
  46     // old style border flags 
  47     wxFLAGS_MEMBER(wxSIMPLE_BORDER
) 
  48     wxFLAGS_MEMBER(wxSUNKEN_BORDER
) 
  49     wxFLAGS_MEMBER(wxDOUBLE_BORDER
) 
  50     wxFLAGS_MEMBER(wxRAISED_BORDER
) 
  51     wxFLAGS_MEMBER(wxSTATIC_BORDER
) 
  52     wxFLAGS_MEMBER(wxBORDER
) 
  54     // standard window styles 
  55     wxFLAGS_MEMBER(wxTAB_TRAVERSAL
) 
  56     wxFLAGS_MEMBER(wxCLIP_CHILDREN
) 
  57     wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW
) 
  58     wxFLAGS_MEMBER(wxWANTS_CHARS
) 
  59     wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE
) 
  60     wxFLAGS_MEMBER(wxALWAYS_SHOW_SB 
) 
  61     wxFLAGS_MEMBER(wxVSCROLL
) 
  62     wxFLAGS_MEMBER(wxHSCROLL
) 
  64     wxFLAGS_MEMBER(wxSB_HORIZONTAL
) 
  65     wxFLAGS_MEMBER(wxSB_VERTICAL
) 
  67 wxEND_FLAGS( wxScrollBarStyle 
) 
  69 IMPLEMENT_DYNAMIC_CLASS_XTI(wxScrollBar
, wxControl
,"wx/scrolbar.h") 
  71 wxBEGIN_PROPERTIES_TABLE(wxScrollBar
) 
  72     wxEVENT_RANGE_PROPERTY( Scroll 
, wxEVT_SCROLL_TOP 
, wxEVT_SCROLL_ENDSCROLL 
, wxScrollEvent 
) 
  74     wxPROPERTY( ThumbPosition 
, int , SetThumbPosition
, GetThumbPosition
, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) 
  75         wxPROPERTY( Range 
, int , SetRange
, GetRange
, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) 
  76         wxPROPERTY( ThumbSize 
, int , SetThumbSize
, GetThumbSize
, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) 
  77         wxPROPERTY( PageSize 
, int , SetPageSize
, GetPageSize
, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) 
  78     wxPROPERTY_FLAGS( WindowStyle 
, wxScrollBarStyle 
, long , SetWindowStyleFlag 
, GetWindowStyleFlag 
, , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style 
  79 wxEND_PROPERTIES_TABLE() 
  81 wxBEGIN_HANDLERS_TABLE(wxScrollBar
) 
  82 wxEND_HANDLERS_TABLE() 
  84 wxCONSTRUCTOR_5( wxScrollBar 
, wxWindow
* , Parent 
, wxWindowID 
, Id 
, wxPoint 
, Position 
, wxSize 
, Size 
, long , WindowStyle 
) 
  86 IMPLEMENT_DYNAMIC_CLASS(wxScrollBar
, wxControl
) 
  90 bool wxScrollBar::Create(wxWindow 
*parent
, wxWindowID id
, 
  92            const wxSize
& size
, long style
, 
  93            const wxValidator
& wxVALIDATOR_PARAM(validator
), 
  98     parent
->AddChild(this); 
 101     SetValidator(validator
); 
 102 #endif // wxUSE_VALIDATORS 
 104     if ((style 
& wxBORDER_MASK
) == wxBORDER_DEFAULT
) 
 105         style 
|= wxNO_BORDER
; 
 107     SetBackgroundColour(parent
->GetBackgroundColour()) ; 
 108     SetForegroundColour(parent
->GetForegroundColour()) ; 
 109     m_windowStyle 
= style
; 
 112       m_windowId 
= (int)NewControlId(); 
 123       if (style 
& wxHORIZONTAL
) 
 130       if (style 
& wxVERTICAL
) 
 137     WXDWORD wstyle 
= MSWGetStyle(style
, & exStyle
) ; 
 139     // Now create scrollbar 
 140     DWORD _direction 
= (style 
& wxHORIZONTAL
) ? 
 142     HWND scroll_bar 
= CreateWindowEx(exStyle
, wxT("SCROLLBAR"), wxT("scrollbar"), 
 144                          0, 0, 0, 0, (HWND
) parent
->GetHWND(), (HMENU
)m_windowId
, 
 145                          wxGetInstance(), NULL
); 
 151     ::SetScrollRange(scroll_bar
, SB_CTL
, 0, 1, FALSE
); 
 152     ::SetScrollPos(scroll_bar
, SB_CTL
, 0, FALSE
); 
 153     ShowWindow(scroll_bar
, SW_SHOW
); 
 155     SetFont(parent
->GetFont()); 
 157     m_hWnd 
= (WXHWND
)scroll_bar
; 
 159     // Subclass again for purposes of dialog editing mode 
 160     SubclassWin((WXHWND
) scroll_bar
); 
 162     SetSize(x
, y
, width
, height
); 
 167 wxScrollBar::~wxScrollBar(void) 
 171 bool wxScrollBar::MSWOnScroll(int WXUNUSED(orientation
), WXWORD wParam
, 
 172                               WXWORD pos
, WXHWND 
WXUNUSED(control
)) 
 174     // current and max positions 
 176         maxPos
, trackPos 
= pos
; 
 178     // when we're dragging the scrollbar we can't use pos parameter because it 
 179     // is limited to 16 bits 
 180     // JACS: now always using GetScrollInfo, since there's no reason 
 182 //    if ( wParam == SB_THUMBPOSITION || wParam == SB_THUMBTRACK ) 
 184         SCROLLINFO scrollInfo
; 
 185         wxZeroMemory(scrollInfo
); 
 186         scrollInfo
.cbSize 
= sizeof(SCROLLINFO
); 
 188         // also get the range if we call GetScrollInfo() anyhow -- this is less 
 189         // expensive than call it once here and then call GetScrollRange() 
 191         scrollInfo
.fMask 
= SIF_RANGE 
| SIF_POS 
| SIF_TRACKPOS
; 
 193         if ( !::GetScrollInfo(GetHwnd(), SB_CTL
, &scrollInfo
) ) 
 195             wxLogLastError(_T("GetScrollInfo")); 
 198         trackPos 
= scrollInfo
.nTrackPos
; 
 199         position 
= scrollInfo
.nPos
; 
 200         maxPos 
= scrollInfo
.nMax
; 
 205         position 
= ::GetScrollPos((HWND
) control
, SB_CTL
); 
 207         ::GetScrollRange((HWND
) control
, SB_CTL
, &minPos
, &maxPos
); 
 211 #if defined(__WIN95__) 
 212     // A page size greater than one has the effect of reducing the effective 
 213     // range, therefore the range has already been boosted artificially - so 
 215     if ( m_pageSize 
> 1 ) 
 216         maxPos 
-= (m_pageSize 
- 1); 
 219     wxEventType scrollEvent 
= wxEVT_NULL
; 
 225             nScrollInc 
= maxPos 
- position
; 
 226             scrollEvent 
= wxEVT_SCROLL_TOP
; 
 230             nScrollInc 
= -position
; 
 231             scrollEvent 
= wxEVT_SCROLL_BOTTOM
; 
 236             scrollEvent 
= wxEVT_SCROLL_LINEUP
; 
 241             scrollEvent 
= wxEVT_SCROLL_LINEDOWN
; 
 245             nScrollInc 
= -GetPageSize(); 
 246             scrollEvent 
= wxEVT_SCROLL_PAGEUP
; 
 250             nScrollInc 
= GetPageSize(); 
 251             scrollEvent 
= wxEVT_SCROLL_PAGEDOWN
; 
 254         case SB_THUMBPOSITION
: 
 255             nScrollInc 
= trackPos 
- position
; 
 256             scrollEvent 
= wxEVT_SCROLL_THUMBRELEASE
; 
 260             nScrollInc 
= trackPos 
- position
; 
 261             scrollEvent 
= wxEVT_SCROLL_THUMBTRACK
; 
 266             scrollEvent 
= wxEVT_SCROLL_ENDSCROLL
; 
 275         position 
+= nScrollInc
; 
 279         if ( position 
> maxPos 
) 
 282         SetThumbPosition(position
); 
 284     else if ( scrollEvent 
!= wxEVT_SCROLL_THUMBRELEASE 
&& 
 285                 scrollEvent 
!= wxEVT_SCROLL_ENDSCROLL 
) 
 287         // don't process the event if there is no displacement, 
 288         // unless this is a thumb release or end scroll event. 
 292     wxScrollEvent 
event(scrollEvent
, m_windowId
); 
 293     event
.SetOrientation(IsVertical() ? wxVERTICAL 
: wxHORIZONTAL
); 
 294     event
.SetPosition(position
); 
 295     event
.SetEventObject( this ); 
 297     return GetEventHandler()->ProcessEvent(event
); 
 300 void wxScrollBar::SetThumbPosition(int viewStart
) 
 302 #if defined(__WIN95__) 
 304     info
.cbSize 
= sizeof(SCROLLINFO
); 
 307     info
.nPos 
= viewStart
; 
 308     info
.fMask 
= SIF_POS 
; 
 310     ::SetScrollInfo((HWND
) GetHWND(), SB_CTL
, &info
, TRUE
); 
 312     ::SetScrollPos((HWND
) GetHWND(), SB_CTL
, viewStart
, TRUE
); 
 316 int wxScrollBar::GetThumbPosition(void) const 
 318     SCROLLINFO scrollInfo
; 
 319     wxZeroMemory(scrollInfo
); 
 320     scrollInfo
.cbSize 
= sizeof(SCROLLINFO
); 
 321     scrollInfo
.fMask 
= SIF_POS
; 
 323     if ( !::GetScrollInfo(GetHwnd(), SB_CTL
, &scrollInfo
) ) 
 325         wxLogLastError(_T("GetScrollInfo")); 
 327     return scrollInfo
.nPos
; 
 328 //    return ::GetScrollPos((HWND)m_hWnd, SB_CTL); 
 331 void wxScrollBar::SetScrollbar(int position
, int thumbSize
, int range
, int pageSize
, 
 334   m_viewSize 
= pageSize
; 
 335   m_pageSize 
= thumbSize
; 
 336   m_objectSize 
= range
; 
 338   // The range (number of scroll steps) is the 
 339   // object length minus the page size. 
 340   int range1 
= wxMax((m_objectSize 
- m_pageSize
), 0) ; 
 342 #if defined(__WIN95__) 
 343   // Try to adjust the range to cope with page size > 1 
 344   // (see comment for SetPageLength) 
 345   if ( m_pageSize 
> 1 ) 
 347     range1 
+= (m_pageSize 
- 1); 
 351   info
.cbSize 
= sizeof(SCROLLINFO
); 
 352   info
.nPage 
= m_pageSize
; 
 355   info
.nPos 
= position
; 
 357   info
.fMask 
= SIF_PAGE 
| SIF_RANGE 
| SIF_POS
; 
 359   ::SetScrollInfo((HWND
) GetHWND(), SB_CTL
, &info
, refresh
); 
 361   ::SetScrollPos((HWND
)m_hWnd
, SB_CTL
, position
, TRUE
); 
 362   ::SetScrollRange((HWND
)m_hWnd
, SB_CTL
, 0, range1
, TRUE
); 
 367 WXHBRUSH 
wxScrollBar::OnCtlColor(WXHDC 
WXUNUSED(pDC
), WXHWND 
WXUNUSED(pWnd
), WXUINT 
WXUNUSED(nCtlColor
), 
 368             WXUINT 
WXUNUSED(message
), WXWPARAM 
WXUNUSED(wParam
), WXLPARAM 
WXUNUSED(lParam
)) 
 373 void wxScrollBar::Command(wxCommandEvent
& event
) 
 375     SetThumbPosition(event
.m_commandInt
); 
 376     ProcessCommand(event
); 
 379 wxSize 
wxScrollBar::DoGetBestSize() const 
 386         w 
= wxSystemSettings::GetMetric(wxSYS_VSCROLL_X
); 
 390         h 
= wxSystemSettings::GetMetric(wxSYS_HSCROLL_Y
); 
 396 #endif // wxUSE_SCROLLBAR