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 // extern wxList wxScrollBarList;
32 extern void wxFindMaxSize(HWND hwnd
, RECT
*rect
);
34 #if !USE_SHARED_LIBRARY
35 IMPLEMENT_DYNAMIC_CLASS(wxScrollBar
, wxControl
)
37 #if WXWIN_COMPATIBILITY
38 BEGIN_EVENT_TABLE(wxScrollBar
, wxControl
)
39 EVT_SCROLL(wxScrollBar::OnScroll
)
46 bool wxScrollBar::Create(wxWindow
*parent
, wxWindowID id
,
48 const wxSize
& size
, long style
,
49 const wxValidator
& validator
,
54 parent
->AddChild(this);
56 SetValidator(validator
);
58 SetBackgroundColour(parent
->GetDefaultBackgroundColour()) ;
59 SetForegroundColour(parent
->GetDefaultForegroundColour()) ;
60 m_windowStyle
= style
;
63 m_windowId
= (int)NewControlId();
74 if (style
& wxHORIZONTAL
)
81 if (style
& wxVERTICAL
)
87 // Now create scrollbar
88 DWORD _direction
= (style
& wxHORIZONTAL
) ?
90 HWND scroll_bar
= CreateWindowEx(MakeExtendedStyle(style
), "SCROLLBAR", "scrollbar",
91 _direction
| WS_CHILD
| WS_VISIBLE
,
92 0, 0, 0, 0, (HWND
) parent
->GetHWND(), (HMENU
)m_windowId
,
93 wxGetInstance(), NULL
);
99 ::SetScrollRange(scroll_bar
, SB_CTL
, 0, 1, FALSE
);
100 ::SetScrollPos(scroll_bar
, SB_CTL
, 0, FALSE
);
101 ShowWindow(scroll_bar
, SW_SHOW
);
103 SetFont(* parent
->GetFont());
105 m_hWnd
= (WXHWND
)scroll_bar
;
107 // Subclass again for purposes of dialog editing mode
108 SubclassWin((WXHWND
) scroll_bar
);
110 SetSize(x
, y
, width
, height
);
115 wxScrollBar::~wxScrollBar(void)
119 void wxScrollBar::MSWOnVScroll(WXWORD wParam
, WXWORD pos
, WXHWND control
)
121 int position
= ::GetScrollPos((HWND
) control
, SB_CTL
);
123 ::GetScrollRange((HWND
) control
, SB_CTL
, &minPos
, &maxPos
);
124 #if defined(__WIN95__)
125 // A page size greater than one has the effect of reducing the
126 // effective range, therefore the range has already been
127 // boosted artificially - so reduce it again.
128 if ( m_pageSize
> 1 )
129 maxPos
-= (m_pageSize
- 1);
132 wxEventType scrollEvent
= wxEVT_NULL
;
138 nScrollInc
= maxPos
- position
;
139 scrollEvent
= wxEVT_SCROLL_TOP
;
143 nScrollInc
= - position
;
144 scrollEvent
= wxEVT_SCROLL_BOTTOM
;
149 scrollEvent
= wxEVT_SCROLL_LINEUP
;
154 scrollEvent
= wxEVT_SCROLL_LINEDOWN
;
158 nScrollInc
= -GetPageSize();
159 scrollEvent
= wxEVT_SCROLL_PAGEUP
;
163 nScrollInc
= GetPageSize();
164 scrollEvent
= wxEVT_SCROLL_PAGEDOWN
;
168 case SB_THUMBPOSITION
:
169 nScrollInc
= pos
- position
;
170 scrollEvent
= wxEVT_SCROLL_THUMBTRACK
;
179 int new_pos
= position
+ nScrollInc
;
183 if (new_pos
> maxPos
)
187 wxScrollEvent
event(scrollEvent
, m_windowId
);
188 event
.SetPosition(new_pos
);
189 event
.SetEventObject( this );
190 GetEventHandler()->ProcessEvent(event
);
194 void wxScrollBar::MSWOnHScroll(WXWORD wParam
, WXWORD pos
, WXHWND control
)
196 MSWOnVScroll(wParam
, pos
, control
);
199 void wxScrollBar::SetPosition(int viewStart
)
201 #if defined(__WIN95__)
203 info
.cbSize
= sizeof(SCROLLINFO
);
206 info
.nPos
= viewStart
;
207 info
.fMask
= SIF_POS
;
209 ::SetScrollInfo((HWND
) GetHWND(), SB_CTL
, &info
, TRUE
);
211 ::SetScrollPos((HWND
) GetHWND(), SB_CTL
, viewStart
, TRUE
);
215 int wxScrollBar::GetPosition(void) const
217 return ::GetScrollPos((HWND
)m_hWnd
, SB_CTL
);
220 void wxScrollBar::SetScrollbar(int position
, int thumbSize
, int range
, int pageSize
,
223 m_viewSize
= pageSize
;
224 m_pageSize
= thumbSize
;
225 m_objectSize
= range
;
227 // The range (number of scroll steps) is the
228 // object length minus the page size.
229 int range1
= wxMax((m_objectSize
- m_pageSize
), 0) ;
231 #if defined(__WIN95__)
232 // Try to adjust the range to cope with page size > 1
233 // (see comment for SetPageLength)
234 if ( m_pageSize
> 1 )
236 range1
+= (m_pageSize
- 1);
240 info
.cbSize
= sizeof(SCROLLINFO
);
241 info
.nPage
= m_pageSize
;
244 info
.nPos
= position
;
246 info
.fMask
= SIF_PAGE
| SIF_RANGE
| SIF_POS
;
248 ::SetScrollInfo((HWND
) GetHWND(), SB_CTL
, &info
, refresh
);
250 ::SetScrollPos((HWND
)m_hWnd
, SB_CTL
, position
, TRUE
);
251 ::SetScrollRange((HWND
)m_hWnd
, SB_CTL
, 0, range1
, TRUE
);
256 /* From the WIN32 documentation:
257 In version 4.0 or later, the maximum value that a scroll bar can report
258 (that is, the maximum scrolling position) depends on the page size.
259 If the scroll bar has a page size greater than one, the maximum scrolling position
260 is less than the maximum range value. You can use the following formula to calculate
261 the maximum scrolling position:
263 MaxScrollPos = MaxRangeValue - (PageSize - 1)
266 #if WXWIN_COMPATIBILITY
267 void wxScrollBar::SetPageSize(int pageLength
)
269 m_pageSize
= pageLength
;
271 #if defined(__WIN95__)
273 info
.cbSize
= sizeof(SCROLLINFO
);
274 info
.nPage
= pageLength
;
275 info
.fMask
= SIF_PAGE
;
277 ::SetScrollInfo((HWND
) GetHWND(), SB_CTL
, &info
, TRUE
);
281 void wxScrollBar::SetObjectLength(int objectLength
)
283 m_objectSize
= objectLength
;
285 // The range (number of scroll steps) is the
286 // object length minus the view size.
287 int range
= wxMax((objectLength
- m_viewSize
), 0) ;
289 #if defined(__WIN95__)
290 // Try to adjust the range to cope with page size > 1
291 // (see comment for SetPageLength)
292 if ( m_pageSize
> 1 )
294 range
+= (m_pageSize
- 1);
298 info
.cbSize
= sizeof(SCROLLINFO
);
303 info
.fMask
= SIF_RANGE
;
305 ::SetScrollInfo((HWND
) GetHWND(), SB_CTL
, &info
, TRUE
);
307 ::SetScrollRange((HWND
)m_hWnd
, SB_CTL
, 0, range
, TRUE
);
311 void wxScrollBar::SetViewLength(int viewLength
)
313 m_viewSize
= viewLength
;
316 void wxScrollBar::GetValues(int *viewStart
, int *viewLength
, int *objectLength
,
317 int *pageLength
) const
319 *viewStart
= ::GetScrollPos((HWND
)m_hWnd
, SB_CTL
);
320 *viewLength
= m_viewSize
;
321 *objectLength
= m_objectSize
;
322 *pageLength
= m_pageSize
;
326 WXHBRUSH
wxScrollBar::OnCtlColor(WXHDC pDC
, WXHWND pWnd
, WXUINT nCtlColor
,
327 WXUINT message
, WXWPARAM wParam
, WXLPARAM lParam
)
332 void wxScrollBar::Command(wxCommandEvent
& event
)
334 SetValue(event
.m_commandInt
);
335 ProcessCommand(event
);
338 #if WXWIN_COMPATIBILITY
339 // Backward compatibility
340 void wxScrollBar::OnScroll(wxScrollEvent
& event
)
342 wxEventType oldEvent
= event
.GetEventType();
343 event
.SetEventType( wxEVT_COMMAND_SCROLLBAR_UPDATED
);
344 if ( !GetEventHandler()->ProcessEvent(event
) )
346 event
.SetEventType( oldEvent
);
347 if (!GetParent()->GetEventHandler()->ProcessEvent(event
))