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
WXUNUSED(pos
), WXHWND
WXUNUSED(control
))
111 // don't use pos parameter because it is limited to 16 bits, get the full
112 // 32 bit position from the control itself instead
113 WinStruct
<SCROLLINFO
> scrollInfo
;
114 scrollInfo
.fMask
= SIF_RANGE
| SIF_POS
| SIF_TRACKPOS
;
116 if ( !::GetScrollInfo(GetHwnd(), SB_CTL
, &scrollInfo
) )
118 wxLogLastError(wxT("GetScrollInfo"));
122 int position
= scrollInfo
.nPos
;
123 int maxPos
= scrollInfo
.nMax
;
125 // A page size greater than one has the effect of reducing the effective
126 // range, therefore the range has already been boosted artificially - so
128 if ( m_pageSize
> 1 )
129 maxPos
-= (m_pageSize
- 1);
131 wxEventType scrollEvent
= wxEVT_NULL
;
137 nScrollInc
= maxPos
- position
;
138 scrollEvent
= wxEVT_SCROLL_TOP
;
142 nScrollInc
= -position
;
143 scrollEvent
= wxEVT_SCROLL_BOTTOM
;
148 scrollEvent
= wxEVT_SCROLL_LINEUP
;
153 scrollEvent
= wxEVT_SCROLL_LINEDOWN
;
157 nScrollInc
= -GetPageSize();
158 scrollEvent
= wxEVT_SCROLL_PAGEUP
;
162 nScrollInc
= GetPageSize();
163 scrollEvent
= wxEVT_SCROLL_PAGEDOWN
;
166 case SB_THUMBPOSITION
:
168 nScrollInc
= scrollInfo
.nTrackPos
- position
;
169 scrollEvent
= wParam
== SB_THUMBPOSITION
? wxEVT_SCROLL_THUMBRELEASE
170 : wxEVT_SCROLL_THUMBTRACK
;
175 scrollEvent
= wxEVT_SCROLL_CHANGED
;
184 position
+= nScrollInc
;
188 if ( position
> maxPos
)
191 SetThumbPosition(position
);
193 else if ( scrollEvent
!= wxEVT_SCROLL_THUMBRELEASE
&&
194 scrollEvent
!= wxEVT_SCROLL_CHANGED
)
196 // don't process the event if there is no displacement,
197 // unless this is a thumb release or end scroll event.
201 wxScrollEvent
event(scrollEvent
, m_windowId
);
202 event
.SetOrientation(IsVertical() ? wxVERTICAL
: wxHORIZONTAL
);
203 event
.SetPosition(position
);
204 event
.SetEventObject( this );
206 return HandleWindowEvent(event
);
209 void wxScrollBar::SetThumbPosition(int viewStart
)
212 info
.cbSize
= sizeof(SCROLLINFO
);
215 info
.nPos
= viewStart
;
216 info
.fMask
= SIF_POS
;
218 ::SetScrollInfo((HWND
) GetHWND(), SB_CTL
, &info
, TRUE
);
221 int wxScrollBar::GetThumbPosition(void) const
223 SCROLLINFO scrollInfo
;
224 wxZeroMemory(scrollInfo
);
225 scrollInfo
.cbSize
= sizeof(SCROLLINFO
);
226 scrollInfo
.fMask
= SIF_POS
;
228 if ( !::GetScrollInfo(GetHwnd(), SB_CTL
, &scrollInfo
) )
230 wxLogLastError(wxT("GetScrollInfo"));
232 return scrollInfo
.nPos
;
235 void wxScrollBar::SetScrollbar(int position
, int thumbSize
, int range
, int pageSize
,
238 m_viewSize
= pageSize
;
239 m_pageSize
= thumbSize
;
240 m_objectSize
= range
;
242 // The range (number of scroll steps) is the
243 // object length minus the page size.
244 int range1
= wxMax((m_objectSize
- m_pageSize
), 0) ;
246 // Try to adjust the range to cope with page size > 1
247 // (see comment for SetPageLength)
248 if ( m_pageSize
> 1 )
250 range1
+= (m_pageSize
- 1);
254 info
.cbSize
= sizeof(SCROLLINFO
);
255 info
.nPage
= m_pageSize
;
258 info
.nPos
= position
;
260 info
.fMask
= SIF_PAGE
| SIF_RANGE
| SIF_POS
;
262 ::SetScrollInfo((HWND
) GetHWND(), SB_CTL
, &info
, refresh
);
265 void wxScrollBar::Command(wxCommandEvent
& event
)
267 SetThumbPosition(event
.GetInt());
268 ProcessCommand(event
);
271 wxSize
wxScrollBar::DoGetBestSize() const
278 w
= wxSystemSettings::GetMetric(wxSYS_VSCROLL_X
);
282 h
= wxSystemSettings::GetMetric(wxSYS_HSCROLL_Y
);
290 WXDWORD
wxScrollBar::MSWGetStyle(long style
, WXDWORD
*exstyle
) const
292 // we never have an external border
293 WXDWORD msStyle
= wxControl::MSWGetStyle
295 (style
& ~wxBORDER_MASK
) | wxBORDER_NONE
, exstyle
298 // SBS_HORZ is 0 anyhow, but do mention it explicitly for clarity
299 msStyle
|= style
& wxSB_HORIZONTAL
? SBS_HORZ
: SBS_VERT
;
304 WXHBRUSH
wxScrollBar::MSWControlColor(WXHDC pDC
, WXHWND hWnd
)
306 // unless we have an explicitly set bg colour, use default (gradient under
307 // XP) brush instead of GetBackgroundColour() one as the base class would
309 // note that fg colour isn't used for a scrollbar
310 return UseBgCol() ? wxControl::MSWControlColor(pDC
, hWnd
) : NULL
;
313 #endif // wxUSE_SCROLLBAR