1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxScrollBar
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "scrolbar.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
28 #include "wx/scrolbar.h"
29 #include "wx/msw/private.h"
31 IMPLEMENT_DYNAMIC_CLASS(wxScrollBar
, wxControl
)
33 BEGIN_EVENT_TABLE(wxScrollBar
, wxControl
)
34 #if WXWIN_COMPATIBILITY
35 EVT_SCROLL(wxScrollBar::OnScroll
)
41 bool wxScrollBar::Create(wxWindow
*parent
, wxWindowID id
,
43 const wxSize
& size
, long style
,
44 const wxValidator
& validator
,
49 parent
->AddChild(this);
51 SetValidator(validator
);
53 SetBackgroundColour(parent
->GetBackgroundColour()) ;
54 SetForegroundColour(parent
->GetForegroundColour()) ;
55 m_windowStyle
= style
;
58 m_windowId
= (int)NewControlId();
69 if (style
& wxHORIZONTAL
)
76 if (style
& wxVERTICAL
)
82 // Now create scrollbar
83 DWORD _direction
= (style
& wxHORIZONTAL
) ?
85 HWND scroll_bar
= CreateWindowEx(MakeExtendedStyle(style
), wxT("SCROLLBAR"), wxT("scrollbar"),
86 _direction
| WS_CHILD
| WS_VISIBLE
,
87 0, 0, 0, 0, (HWND
) parent
->GetHWND(), (HMENU
)m_windowId
,
88 wxGetInstance(), NULL
);
94 ::SetScrollRange(scroll_bar
, SB_CTL
, 0, 1, FALSE
);
95 ::SetScrollPos(scroll_bar
, SB_CTL
, 0, FALSE
);
96 ShowWindow(scroll_bar
, SW_SHOW
);
98 SetFont(parent
->GetFont());
100 m_hWnd
= (WXHWND
)scroll_bar
;
102 // Subclass again for purposes of dialog editing mode
103 SubclassWin((WXHWND
) scroll_bar
);
105 SetSize(x
, y
, width
, height
);
110 wxScrollBar::~wxScrollBar(void)
114 bool wxScrollBar::MSWOnScroll(int WXUNUSED(orientation
), WXWORD wParam
,
115 WXWORD pos
, WXHWND control
)
117 int position
= ::GetScrollPos((HWND
) control
, SB_CTL
);
119 ::GetScrollRange((HWND
) control
, SB_CTL
, &minPos
, &maxPos
);
121 #if defined(__WIN95__)
122 // A page size greater than one has the effect of reducing the effective
123 // range, therefore the range has already been boosted artificially - so
125 if ( m_pageSize
> 1 )
126 maxPos
-= (m_pageSize
- 1);
129 wxEventType scrollEvent
= wxEVT_NULL
;
135 nScrollInc
= maxPos
- position
;
136 scrollEvent
= wxEVT_SCROLL_TOP
;
140 nScrollInc
= - position
;
141 scrollEvent
= wxEVT_SCROLL_BOTTOM
;
146 scrollEvent
= wxEVT_SCROLL_LINEUP
;
151 scrollEvent
= wxEVT_SCROLL_LINEDOWN
;
155 nScrollInc
= -GetPageSize();
156 scrollEvent
= wxEVT_SCROLL_PAGEUP
;
160 nScrollInc
= GetPageSize();
161 scrollEvent
= wxEVT_SCROLL_PAGEDOWN
;
165 case SB_THUMBPOSITION
:
166 nScrollInc
= pos
- position
;
167 scrollEvent
= wxEVT_SCROLL_THUMBTRACK
;
174 if ( nScrollInc
== 0 )
176 // no event to process, so don't process it
180 int new_pos
= position
+ nScrollInc
;
184 if (new_pos
> maxPos
)
187 SetThumbPosition(new_pos
);
188 wxScrollEvent
event(scrollEvent
, m_windowId
);
189 event
.SetPosition(new_pos
);
190 event
.SetEventObject( this );
192 return GetEventHandler()->ProcessEvent(event
);
195 void wxScrollBar::SetThumbPosition(int viewStart
)
197 #if defined(__WIN95__)
199 info
.cbSize
= sizeof(SCROLLINFO
);
202 info
.nPos
= viewStart
;
203 info
.fMask
= SIF_POS
;
205 ::SetScrollInfo((HWND
) GetHWND(), SB_CTL
, &info
, TRUE
);
207 ::SetScrollPos((HWND
) GetHWND(), SB_CTL
, viewStart
, TRUE
);
211 int wxScrollBar::GetThumbPosition(void) const
213 return ::GetScrollPos((HWND
)m_hWnd
, SB_CTL
);
216 void wxScrollBar::SetScrollbar(int position
, int thumbSize
, int range
, int pageSize
,
219 m_viewSize
= pageSize
;
220 m_pageSize
= thumbSize
;
221 m_objectSize
= range
;
223 // The range (number of scroll steps) is the
224 // object length minus the page size.
225 int range1
= wxMax((m_objectSize
- m_pageSize
), 0) ;
227 #if defined(__WIN95__)
228 // Try to adjust the range to cope with page size > 1
229 // (see comment for SetPageLength)
230 if ( m_pageSize
> 1 )
232 range1
+= (m_pageSize
- 1);
236 info
.cbSize
= sizeof(SCROLLINFO
);
237 info
.nPage
= m_pageSize
;
240 info
.nPos
= position
;
242 info
.fMask
= SIF_PAGE
| SIF_RANGE
| SIF_POS
;
244 ::SetScrollInfo((HWND
) GetHWND(), SB_CTL
, &info
, refresh
);
246 ::SetScrollPos((HWND
)m_hWnd
, SB_CTL
, position
, TRUE
);
247 ::SetScrollRange((HWND
)m_hWnd
, SB_CTL
, 0, range1
, TRUE
);
252 /* From the WIN32 documentation:
253 In version 4.0 or later, the maximum value that a scroll bar can report
254 (that is, the maximum scrolling position) depends on the page size.
255 If the scroll bar has a page size greater than one, the maximum scrolling position
256 is less than the maximum range value. You can use the following formula to calculate
257 the maximum scrolling position:
259 MaxScrollPos = MaxRangeValue - (PageSize - 1)
262 #if WXWIN_COMPATIBILITY
263 void wxScrollBar::SetPageSize(int pageLength
)
265 m_pageSize
= pageLength
;
267 #if defined(__WIN95__)
269 info
.cbSize
= sizeof(SCROLLINFO
);
270 info
.nPage
= pageLength
;
271 info
.fMask
= SIF_PAGE
;
273 ::SetScrollInfo((HWND
) GetHWND(), SB_CTL
, &info
, TRUE
);
277 void wxScrollBar::SetObjectLength(int objectLength
)
279 m_objectSize
= objectLength
;
281 // The range (number of scroll steps) is the
282 // object length minus the view size.
283 int range
= wxMax((objectLength
- m_viewSize
), 0) ;
285 #if defined(__WIN95__)
286 // Try to adjust the range to cope with page size > 1
287 // (see comment for SetPageLength)
288 if ( m_pageSize
> 1 )
290 range
+= (m_pageSize
- 1);
294 info
.cbSize
= sizeof(SCROLLINFO
);
299 info
.fMask
= SIF_RANGE
;
301 ::SetScrollInfo((HWND
) GetHWND(), SB_CTL
, &info
, TRUE
);
303 ::SetScrollRange((HWND
)m_hWnd
, SB_CTL
, 0, range
, TRUE
);
307 void wxScrollBar::SetViewLength(int viewLength
)
309 m_viewSize
= viewLength
;
312 void wxScrollBar::GetValues(int *viewStart
, int *viewLength
, int *objectLength
,
313 int *pageLength
) const
315 *viewStart
= ::GetScrollPos((HWND
)m_hWnd
, SB_CTL
);
316 *viewLength
= m_viewSize
;
317 *objectLength
= m_objectSize
;
318 *pageLength
= m_pageSize
;
322 WXHBRUSH
wxScrollBar::OnCtlColor(WXHDC pDC
, WXHWND pWnd
, WXUINT nCtlColor
,
323 WXUINT message
, WXWPARAM wParam
, WXLPARAM lParam
)
328 void wxScrollBar::Command(wxCommandEvent
& event
)
330 SetThumbPosition(event
.m_commandInt
);
331 ProcessCommand(event
);
334 #if WXWIN_COMPATIBILITY
335 // Backward compatibility
336 void wxScrollBar::OnScroll(wxScrollEvent
& event
)
338 wxEventType oldEvent
= event
.GetEventType();
339 event
.SetEventType( wxEVT_COMMAND_SCROLLBAR_UPDATED
);
340 if ( !GetEventHandler()->ProcessEvent(event
) )
342 event
.SetEventType( oldEvent
);
343 if (!GetParent()->GetEventHandler()->ProcessEvent(event
))