1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/msw/scrolbar.cpp 
   3 // Purpose:     wxScrollBar 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // For compilers that support precompilation, includes "wx.h". 
  13 #include "wx/wxprec.h" 
  21 #include "wx/scrolbar.h" 
  25     #include "wx/settings.h" 
  28 #include "wx/msw/private.h" 
  30 #if wxUSE_EXTENDED_RTTI 
  31 WX_DEFINE_FLAGS( wxScrollBarStyle 
) 
  33 wxBEGIN_FLAGS( wxScrollBarStyle 
) 
  34     // new style border flags, we put them first to 
  35     // use them for streaming out 
  36     wxFLAGS_MEMBER(wxBORDER_SIMPLE
) 
  37     wxFLAGS_MEMBER(wxBORDER_SUNKEN
) 
  38     wxFLAGS_MEMBER(wxBORDER_DOUBLE
) 
  39     wxFLAGS_MEMBER(wxBORDER_RAISED
) 
  40     wxFLAGS_MEMBER(wxBORDER_STATIC
) 
  41     wxFLAGS_MEMBER(wxBORDER_NONE
) 
  43     // old style border flags 
  44     wxFLAGS_MEMBER(wxSIMPLE_BORDER
) 
  45     wxFLAGS_MEMBER(wxSUNKEN_BORDER
) 
  46     wxFLAGS_MEMBER(wxDOUBLE_BORDER
) 
  47     wxFLAGS_MEMBER(wxRAISED_BORDER
) 
  48     wxFLAGS_MEMBER(wxSTATIC_BORDER
) 
  49     wxFLAGS_MEMBER(wxBORDER
) 
  51     // standard window styles 
  52     wxFLAGS_MEMBER(wxTAB_TRAVERSAL
) 
  53     wxFLAGS_MEMBER(wxCLIP_CHILDREN
) 
  54     wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW
) 
  55     wxFLAGS_MEMBER(wxWANTS_CHARS
) 
  56     wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE
) 
  57     wxFLAGS_MEMBER(wxALWAYS_SHOW_SB 
) 
  58     wxFLAGS_MEMBER(wxVSCROLL
) 
  59     wxFLAGS_MEMBER(wxHSCROLL
) 
  61     wxFLAGS_MEMBER(wxSB_HORIZONTAL
) 
  62     wxFLAGS_MEMBER(wxSB_VERTICAL
) 
  64 wxEND_FLAGS( wxScrollBarStyle 
) 
  66 IMPLEMENT_DYNAMIC_CLASS_XTI(wxScrollBar
, wxControl
,"wx/scrolbar.h") 
  68 wxBEGIN_PROPERTIES_TABLE(wxScrollBar
) 
  69     wxEVENT_RANGE_PROPERTY( Scroll 
, wxEVT_SCROLL_TOP 
, wxEVT_SCROLL_CHANGED 
, wxScrollEvent 
) 
  71     wxPROPERTY( ThumbPosition 
, int , SetThumbPosition
, GetThumbPosition
, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) 
  72     wxPROPERTY( Range 
, int , SetRange
, GetRange
, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) 
  73     wxPROPERTY( ThumbSize 
, int , SetThumbSize
, GetThumbSize
, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) 
  74     wxPROPERTY( PageSize 
, int , SetPageSize
, GetPageSize
, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) 
  75     wxPROPERTY_FLAGS( WindowStyle 
, wxScrollBarStyle 
, long , SetWindowStyleFlag 
, GetWindowStyleFlag 
, EMPTY_MACROVALUE 
, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style 
  76 wxEND_PROPERTIES_TABLE() 
  78 wxBEGIN_HANDLERS_TABLE(wxScrollBar
) 
  79 wxEND_HANDLERS_TABLE() 
  81 wxCONSTRUCTOR_5( wxScrollBar 
, wxWindow
* , Parent 
, wxWindowID 
, Id 
, wxPoint 
, Position 
, wxSize 
, Size 
, long , WindowStyle 
) 
  83 IMPLEMENT_DYNAMIC_CLASS(wxScrollBar
, wxControl
) 
  87 bool wxScrollBar::Create(wxWindow 
*parent
, wxWindowID id
, 
  89            const wxSize
& size
, long style
, 
  90            const wxValidator
& validator
, 
  93     if ( !CreateControl(parent
, id
, pos
, size
, style
, validator
, name
) ) 
  96     if (!MSWCreateControl(wxT("ScrollBar"), wxEmptyString
, pos
, size
)) 
  99     SetScrollbar(0, 1, 2, 1, false); 
 104 wxScrollBar::~wxScrollBar(void) 
 108 bool wxScrollBar::MSWOnScroll(int WXUNUSED(orientation
), WXWORD wParam
, 
 109                               WXWORD pos
, WXHWND 
WXUNUSED(control
)) 
 111     // current and max positions 
 113         maxPos
, trackPos 
= pos
; 
 115     wxUnusedVar(trackPos
); 
 117     // when we're dragging the scrollbar we can't use pos parameter because it 
 118     // is limited to 16 bits 
 119     // JACS: now always using GetScrollInfo, since there's no reason 
 121 //    if ( wParam == SB_THUMBPOSITION || wParam == SB_THUMBTRACK ) 
 123         SCROLLINFO scrollInfo
; 
 124         wxZeroMemory(scrollInfo
); 
 125         scrollInfo
.cbSize 
= sizeof(SCROLLINFO
); 
 127         // also get the range if we call GetScrollInfo() anyhow -- this is less 
 128         // expensive than call it once here and then call GetScrollRange() 
 130         scrollInfo
.fMask 
= SIF_RANGE 
| SIF_POS 
| SIF_TRACKPOS
; 
 132         if ( !::GetScrollInfo(GetHwnd(), SB_CTL
, &scrollInfo
) ) 
 134             wxLogLastError(_T("GetScrollInfo")); 
 137         trackPos 
= scrollInfo
.nTrackPos
; 
 138         position 
= scrollInfo
.nPos
; 
 139         maxPos 
= scrollInfo
.nMax
; 
 144         position 
= ::GetScrollPos((HWND
) control
, SB_CTL
); 
 146         ::GetScrollRange((HWND
) control
, SB_CTL
, &minPos
, &maxPos
); 
 150     // A page size greater than one has the effect of reducing the effective 
 151     // range, therefore the range has already been boosted artificially - so 
 153     if ( m_pageSize 
> 1 ) 
 154         maxPos 
-= (m_pageSize 
- 1); 
 156     wxEventType scrollEvent 
= wxEVT_NULL
; 
 162             nScrollInc 
= maxPos 
- position
; 
 163             scrollEvent 
= wxEVT_SCROLL_TOP
; 
 167             nScrollInc 
= -position
; 
 168             scrollEvent 
= wxEVT_SCROLL_BOTTOM
; 
 173             scrollEvent 
= wxEVT_SCROLL_LINEUP
; 
 178             scrollEvent 
= wxEVT_SCROLL_LINEDOWN
; 
 182             nScrollInc 
= -GetPageSize(); 
 183             scrollEvent 
= wxEVT_SCROLL_PAGEUP
; 
 187             nScrollInc 
= GetPageSize(); 
 188             scrollEvent 
= wxEVT_SCROLL_PAGEDOWN
; 
 191         case SB_THUMBPOSITION
: 
 192             nScrollInc 
= trackPos 
- position
; 
 193             scrollEvent 
= wxEVT_SCROLL_THUMBRELEASE
; 
 197             nScrollInc 
= trackPos 
- position
; 
 198             scrollEvent 
= wxEVT_SCROLL_THUMBTRACK
; 
 203             scrollEvent 
= wxEVT_SCROLL_CHANGED
; 
 212         position 
+= nScrollInc
; 
 216         if ( position 
> maxPos 
) 
 219         SetThumbPosition(position
); 
 221     else if ( scrollEvent 
!= wxEVT_SCROLL_THUMBRELEASE 
&& 
 222                 scrollEvent 
!= wxEVT_SCROLL_CHANGED 
) 
 224         // don't process the event if there is no displacement, 
 225         // unless this is a thumb release or end scroll event. 
 229     wxScrollEvent 
event(scrollEvent
, m_windowId
); 
 230     event
.SetOrientation(IsVertical() ? wxVERTICAL 
: wxHORIZONTAL
); 
 231     event
.SetPosition(position
); 
 232     event
.SetEventObject( this ); 
 234     return GetEventHandler()->ProcessEvent(event
); 
 237 void wxScrollBar::SetThumbPosition(int viewStart
) 
 240     info
.cbSize 
= sizeof(SCROLLINFO
); 
 243     info
.nPos 
= viewStart
; 
 244     info
.fMask 
= SIF_POS 
; 
 246     ::SetScrollInfo((HWND
) GetHWND(), SB_CTL
, &info
, TRUE
); 
 249 int wxScrollBar::GetThumbPosition(void) const 
 251     SCROLLINFO scrollInfo
; 
 252     wxZeroMemory(scrollInfo
); 
 253     scrollInfo
.cbSize 
= sizeof(SCROLLINFO
); 
 254     scrollInfo
.fMask 
= SIF_POS
; 
 256     if ( !::GetScrollInfo(GetHwnd(), SB_CTL
, &scrollInfo
) ) 
 258         wxLogLastError(_T("GetScrollInfo")); 
 260     return scrollInfo
.nPos
; 
 261 //    return ::GetScrollPos((HWND)m_hWnd, SB_CTL); 
 264 void wxScrollBar::SetScrollbar(int position
, int thumbSize
, int range
, int pageSize
, 
 267     m_viewSize 
= pageSize
; 
 268     m_pageSize 
= thumbSize
; 
 269     m_objectSize 
= range
; 
 271     // The range (number of scroll steps) is the 
 272     // object length minus the page size. 
 273     int range1 
= wxMax((m_objectSize 
- m_pageSize
), 0) ; 
 275     // Try to adjust the range to cope with page size > 1 
 276     // (see comment for SetPageLength) 
 277     if ( m_pageSize 
> 1 ) 
 279         range1 
+= (m_pageSize 
- 1); 
 283     info
.cbSize 
= sizeof(SCROLLINFO
); 
 284     info
.nPage 
= m_pageSize
; 
 287     info
.nPos 
= position
; 
 289     info
.fMask 
= SIF_PAGE 
| SIF_RANGE 
| SIF_POS
; 
 291     ::SetScrollInfo((HWND
) GetHWND(), SB_CTL
, &info
, refresh
); 
 294 void wxScrollBar::Command(wxCommandEvent
& event
) 
 296     SetThumbPosition(event
.GetInt()); 
 297     ProcessCommand(event
); 
 300 wxSize 
wxScrollBar::DoGetBestSize() const 
 307         w 
= wxSystemSettings::GetMetric(wxSYS_VSCROLL_X
); 
 311         h 
= wxSystemSettings::GetMetric(wxSYS_HSCROLL_Y
); 
 319 WXDWORD 
wxScrollBar::MSWGetStyle(long style
, WXDWORD 
*exstyle
) const 
 321     // we never have an external border 
 322     WXDWORD msStyle 
= wxControl::MSWGetStyle
 
 324                         (style 
& ~wxBORDER_MASK
) | wxBORDER_NONE
, exstyle
 
 327     // SBS_HORZ is 0 anyhow, but do mention it explicitly for clarity 
 328     msStyle 
|= style 
& wxSB_HORIZONTAL 
? SBS_HORZ 
: SBS_VERT
; 
 333 WXHBRUSH 
wxScrollBar::MSWControlColor(WXHDC pDC
, WXHWND hWnd
) 
 335     // unless we have an explicitly set bg colour, use default (gradient under 
 336     // XP) brush instead of GetBackgroundColour() one as the base class would 
 338     // note that fg colour isn't used for a scrollbar 
 339     return UseBgCol() ? wxControl::MSWControlColor(pDC
, hWnd
) : NULL
; 
 342 #endif // wxUSE_SCROLLBAR