1 /////////////////////////////////////////////////////////////////////////////
2 // Name: msw/scrolbar.cpp
3 // Purpose: wxScrollBar
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 #pragma implementation "scrolbar.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
29 #include "wx/scrolbar.h"
30 #include "wx/msw/private.h"
32 IMPLEMENT_DYNAMIC_CLASS(wxScrollBar
, wxControl
)
44 bool wxScrollBar::Create(wxWindow
*parent
, wxWindowID id
,
46 const wxSize
& size
, long style
,
47 const wxValidator
& validator
,
52 parent
->AddChild(this);
55 SetValidator(validator
);
56 #endif // wxUSE_VALIDATORS
58 if ((style
& wxBORDER_MASK
) == wxBORDER_DEFAULT
)
61 SetBackgroundColour(parent
->GetBackgroundColour()) ;
62 SetForegroundColour(parent
->GetForegroundColour()) ;
63 m_windowStyle
= style
;
66 m_windowId
= (int)NewControlId();
77 if (style
& wxHORIZONTAL
)
84 if (style
& wxVERTICAL
)
91 WXDWORD wstyle
= MSWGetStyle(style
, & exStyle
) ;
93 // Now create scrollbar
94 DWORD _direction
= (style
& wxHORIZONTAL
) ?
96 HWND scroll_bar
= CreateWindowEx(exStyle
, wxT("SCROLLBAR"), wxT("scrollbar"),
98 0, 0, 0, 0, (HWND
) parent
->GetHWND(), (HMENU
)m_windowId
,
99 wxGetInstance(), NULL
);
105 ::SetScrollRange(scroll_bar
, SB_CTL
, 0, 1, FALSE
);
106 ::SetScrollPos(scroll_bar
, SB_CTL
, 0, FALSE
);
107 ShowWindow(scroll_bar
, SW_SHOW
);
109 SetFont(parent
->GetFont());
111 m_hWnd
= (WXHWND
)scroll_bar
;
113 // Subclass again for purposes of dialog editing mode
114 SubclassWin((WXHWND
) scroll_bar
);
116 SetSize(x
, y
, width
, height
);
121 wxScrollBar::~wxScrollBar(void)
125 bool wxScrollBar::MSWOnScroll(int WXUNUSED(orientation
), WXWORD wParam
,
126 WXWORD pos
, WXHWND
WXUNUSED(control
))
128 // current and max positions
130 maxPos
, trackPos
= pos
;
132 // when we're dragging the scrollbar we can't use pos parameter because it
133 // is limited to 16 bits
134 // JACS: now always using GetScrollInfo, since there's no reason
136 // if ( wParam == SB_THUMBPOSITION || wParam == SB_THUMBTRACK )
138 SCROLLINFO scrollInfo
;
139 wxZeroMemory(scrollInfo
);
140 scrollInfo
.cbSize
= sizeof(SCROLLINFO
);
142 // also get the range if we call GetScrollInfo() anyhow -- this is less
143 // expensive than call it once here and then call GetScrollRange()
145 scrollInfo
.fMask
= SIF_RANGE
| SIF_POS
| SIF_TRACKPOS
;
147 if ( !::GetScrollInfo(GetHwnd(), SB_CTL
, &scrollInfo
) )
149 wxLogLastError(_T("GetScrollInfo"));
152 trackPos
= scrollInfo
.nTrackPos
;
153 position
= scrollInfo
.nPos
;
154 maxPos
= scrollInfo
.nMax
;
159 position
= ::GetScrollPos((HWND
) control
, SB_CTL
);
161 ::GetScrollRange((HWND
) control
, SB_CTL
, &minPos
, &maxPos
);
165 #if defined(__WIN95__)
166 // A page size greater than one has the effect of reducing the effective
167 // range, therefore the range has already been boosted artificially - so
169 if ( m_pageSize
> 1 )
170 maxPos
-= (m_pageSize
- 1);
173 wxEventType scrollEvent
= wxEVT_NULL
;
179 nScrollInc
= maxPos
- position
;
180 scrollEvent
= wxEVT_SCROLL_TOP
;
184 nScrollInc
= -position
;
185 scrollEvent
= wxEVT_SCROLL_BOTTOM
;
190 scrollEvent
= wxEVT_SCROLL_LINEUP
;
195 scrollEvent
= wxEVT_SCROLL_LINEDOWN
;
199 nScrollInc
= -GetPageSize();
200 scrollEvent
= wxEVT_SCROLL_PAGEUP
;
204 nScrollInc
= GetPageSize();
205 scrollEvent
= wxEVT_SCROLL_PAGEDOWN
;
208 case SB_THUMBPOSITION
:
209 nScrollInc
= trackPos
- position
;
210 scrollEvent
= wxEVT_SCROLL_THUMBRELEASE
;
214 nScrollInc
= trackPos
- position
;
215 scrollEvent
= wxEVT_SCROLL_THUMBTRACK
;
220 scrollEvent
= wxEVT_SCROLL_ENDSCROLL
;
229 position
+= nScrollInc
;
233 if ( position
> maxPos
)
236 SetThumbPosition(position
);
238 else if ( scrollEvent
!= wxEVT_SCROLL_THUMBRELEASE
&&
239 scrollEvent
!= wxEVT_SCROLL_ENDSCROLL
)
241 // don't process the event if there is no displacement,
242 // unless this is a thumb release or end scroll event.
246 wxScrollEvent
event(scrollEvent
, m_windowId
);
247 event
.SetOrientation(IsVertical() ? wxVERTICAL
: wxHORIZONTAL
);
248 event
.SetPosition(position
);
249 event
.SetEventObject( this );
251 return GetEventHandler()->ProcessEvent(event
);
254 void wxScrollBar::SetThumbPosition(int viewStart
)
256 #if defined(__WIN95__)
258 info
.cbSize
= sizeof(SCROLLINFO
);
261 info
.nPos
= viewStart
;
262 info
.fMask
= SIF_POS
;
264 ::SetScrollInfo((HWND
) GetHWND(), SB_CTL
, &info
, TRUE
);
266 ::SetScrollPos((HWND
) GetHWND(), SB_CTL
, viewStart
, TRUE
);
270 int wxScrollBar::GetThumbPosition(void) const
272 SCROLLINFO scrollInfo
;
273 wxZeroMemory(scrollInfo
);
274 scrollInfo
.cbSize
= sizeof(SCROLLINFO
);
275 scrollInfo
.fMask
= SIF_POS
;
277 if ( !::GetScrollInfo(GetHwnd(), SB_CTL
, &scrollInfo
) )
279 wxLogLastError(_T("GetScrollInfo"));
281 return scrollInfo
.nPos
;
282 // return ::GetScrollPos((HWND)m_hWnd, SB_CTL);
285 void wxScrollBar::SetScrollbar(int position
, int thumbSize
, int range
, int pageSize
,
288 m_viewSize
= pageSize
;
289 m_pageSize
= thumbSize
;
290 m_objectSize
= range
;
292 // The range (number of scroll steps) is the
293 // object length minus the page size.
294 int range1
= wxMax((m_objectSize
- m_pageSize
), 0) ;
296 #if defined(__WIN95__)
297 // Try to adjust the range to cope with page size > 1
298 // (see comment for SetPageLength)
299 if ( m_pageSize
> 1 )
301 range1
+= (m_pageSize
- 1);
305 info
.cbSize
= sizeof(SCROLLINFO
);
306 info
.nPage
= m_pageSize
;
309 info
.nPos
= position
;
311 info
.fMask
= SIF_PAGE
| SIF_RANGE
| SIF_POS
;
313 ::SetScrollInfo((HWND
) GetHWND(), SB_CTL
, &info
, refresh
);
315 ::SetScrollPos((HWND
)m_hWnd
, SB_CTL
, position
, TRUE
);
316 ::SetScrollRange((HWND
)m_hWnd
, SB_CTL
, 0, range1
, TRUE
);
321 WXHBRUSH
wxScrollBar::OnCtlColor(WXHDC
WXUNUSED(pDC
), WXHWND
WXUNUSED(pWnd
), WXUINT
WXUNUSED(nCtlColor
),
322 WXUINT
WXUNUSED(message
), WXWPARAM
WXUNUSED(wParam
), WXLPARAM
WXUNUSED(lParam
))
327 void wxScrollBar::Command(wxCommandEvent
& event
)
329 SetThumbPosition(event
.m_commandInt
);
330 ProcessCommand(event
);
333 #endif // wxUSE_SCROLLBAR