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"
31 bool wxScrollBar::Create(wxWindow
*parent
, wxWindowID id
,
33 const wxSize
& size
, long style
,
34 const wxValidator
& validator
,
37 if ( !CreateControl(parent
, id
, pos
, size
, style
, validator
, name
) )
40 if (!MSWCreateControl(wxT("ScrollBar"), wxEmptyString
, pos
, size
))
43 SetScrollbar(0, 1, 2, 1, false);
48 wxScrollBar::~wxScrollBar(void)
52 bool wxScrollBar::MSWOnScroll(int WXUNUSED(orientation
), WXWORD wParam
,
53 WXWORD
WXUNUSED(pos
), WXHWND
WXUNUSED(control
))
55 // don't use pos parameter because it is limited to 16 bits, get the full
56 // 32 bit position from the control itself instead
57 WinStruct
<SCROLLINFO
> scrollInfo
;
58 scrollInfo
.fMask
= SIF_RANGE
| SIF_POS
| SIF_TRACKPOS
;
60 if ( !::GetScrollInfo(GetHwnd(), SB_CTL
, &scrollInfo
) )
62 wxLogLastError(wxT("GetScrollInfo"));
66 int maxPos
= scrollInfo
.nMax
;
68 // A page size greater than one has the effect of reducing the effective
69 // range, therefore the range has already been boosted artificially - so
72 maxPos
-= (m_pageSize
- 1);
74 int position
= scrollInfo
.nPos
;
75 wxEventType scrollEvent
= wxEVT_NULL
;
80 scrollEvent
= wxEVT_SCROLL_TOP
;
85 scrollEvent
= wxEVT_SCROLL_BOTTOM
;
90 scrollEvent
= wxEVT_SCROLL_LINEUP
;
95 scrollEvent
= wxEVT_SCROLL_LINEDOWN
;
99 position
-= GetPageSize();
100 scrollEvent
= wxEVT_SCROLL_PAGEUP
;
104 position
+= GetPageSize();
105 scrollEvent
= wxEVT_SCROLL_PAGEDOWN
;
108 case SB_THUMBPOSITION
:
110 position
= scrollInfo
.nTrackPos
;
111 scrollEvent
= wParam
== SB_THUMBPOSITION
? wxEVT_SCROLL_THUMBRELEASE
112 : wxEVT_SCROLL_THUMBTRACK
;
116 scrollEvent
= wxEVT_SCROLL_CHANGED
;
120 if ( position
!= scrollInfo
.nPos
)
124 if ( position
> maxPos
)
127 SetThumbPosition(position
);
129 else if ( scrollEvent
!= wxEVT_SCROLL_THUMBRELEASE
&&
130 scrollEvent
!= wxEVT_SCROLL_CHANGED
)
132 // don't process the event if there is no displacement,
133 // unless this is a thumb release or end scroll event.
137 wxScrollEvent
event(scrollEvent
, m_windowId
);
138 event
.SetOrientation(IsVertical() ? wxVERTICAL
: wxHORIZONTAL
);
139 event
.SetPosition(position
);
140 event
.SetEventObject( this );
142 return HandleWindowEvent(event
);
145 void wxScrollBar::SetThumbPosition(int viewStart
)
148 info
.cbSize
= sizeof(SCROLLINFO
);
151 info
.nPos
= viewStart
;
152 info
.fMask
= SIF_POS
;
154 ::SetScrollInfo((HWND
) GetHWND(), SB_CTL
, &info
, TRUE
);
157 int wxScrollBar::GetThumbPosition(void) const
159 SCROLLINFO scrollInfo
;
160 wxZeroMemory(scrollInfo
);
161 scrollInfo
.cbSize
= sizeof(SCROLLINFO
);
162 scrollInfo
.fMask
= SIF_POS
;
164 if ( !::GetScrollInfo(GetHwnd(), SB_CTL
, &scrollInfo
) )
166 wxLogLastError(wxT("GetScrollInfo"));
168 return scrollInfo
.nPos
;
171 void wxScrollBar::SetScrollbar(int position
, int thumbSize
, int range
, int pageSize
,
174 m_viewSize
= pageSize
;
175 m_pageSize
= thumbSize
;
176 m_objectSize
= range
;
178 // The range (number of scroll steps) is the
179 // object length minus the page size.
180 int range1
= wxMax((m_objectSize
- m_pageSize
), 0) ;
182 // Try to adjust the range to cope with page size > 1
183 // (see comment for SetPageLength)
184 if ( m_pageSize
> 1 )
186 range1
+= (m_pageSize
- 1);
190 info
.cbSize
= sizeof(SCROLLINFO
);
191 info
.nPage
= m_pageSize
;
194 info
.nPos
= position
;
196 info
.fMask
= SIF_PAGE
| SIF_RANGE
| SIF_POS
;
198 ::SetScrollInfo((HWND
) GetHWND(), SB_CTL
, &info
, refresh
);
201 void wxScrollBar::Command(wxCommandEvent
& event
)
203 SetThumbPosition(event
.GetInt());
204 ProcessCommand(event
);
207 wxSize
wxScrollBar::DoGetBestSize() const
214 w
= wxSystemSettings::GetMetric(wxSYS_VSCROLL_X
);
218 h
= wxSystemSettings::GetMetric(wxSYS_HSCROLL_Y
);
226 WXDWORD
wxScrollBar::MSWGetStyle(long style
, WXDWORD
*exstyle
) const
228 // we never have an external border
229 WXDWORD msStyle
= wxControl::MSWGetStyle
231 (style
& ~wxBORDER_MASK
) | wxBORDER_NONE
, exstyle
234 // SBS_HORZ is 0 anyhow, but do mention it explicitly for clarity
235 msStyle
|= style
& wxSB_HORIZONTAL
? SBS_HORZ
: SBS_VERT
;
240 WXHBRUSH
wxScrollBar::MSWControlColor(WXHDC pDC
, WXHWND hWnd
)
242 // unless we have an explicitly set bg colour, use default (gradient under
243 // XP) brush instead of GetBackgroundColour() one as the base class would
245 // note that fg colour isn't used for a scrollbar
246 return UseBgCol() ? wxControl::MSWControlColor(pDC
, hWnd
) : NULL
;
249 #endif // wxUSE_SCROLLBAR