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"
31 #include "wx/settings.h"
33 #if wxUSE_EXTENDED_RTTI
34 WX_DEFINE_FLAGS( wxScrollBarStyle
)
36 wxBEGIN_FLAGS( wxScrollBarStyle
)
37 // new style border flags, we put them first to
38 // use them for streaming out
39 wxFLAGS_MEMBER(wxBORDER_SIMPLE
)
40 wxFLAGS_MEMBER(wxBORDER_SUNKEN
)
41 wxFLAGS_MEMBER(wxBORDER_DOUBLE
)
42 wxFLAGS_MEMBER(wxBORDER_RAISED
)
43 wxFLAGS_MEMBER(wxBORDER_STATIC
)
44 wxFLAGS_MEMBER(wxBORDER_NONE
)
46 // old style border flags
47 wxFLAGS_MEMBER(wxSIMPLE_BORDER
)
48 wxFLAGS_MEMBER(wxSUNKEN_BORDER
)
49 wxFLAGS_MEMBER(wxDOUBLE_BORDER
)
50 wxFLAGS_MEMBER(wxRAISED_BORDER
)
51 wxFLAGS_MEMBER(wxSTATIC_BORDER
)
52 wxFLAGS_MEMBER(wxBORDER
)
54 // standard window styles
55 wxFLAGS_MEMBER(wxTAB_TRAVERSAL
)
56 wxFLAGS_MEMBER(wxCLIP_CHILDREN
)
57 wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW
)
58 wxFLAGS_MEMBER(wxWANTS_CHARS
)
59 wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE
)
60 wxFLAGS_MEMBER(wxALWAYS_SHOW_SB
)
61 wxFLAGS_MEMBER(wxVSCROLL
)
62 wxFLAGS_MEMBER(wxHSCROLL
)
64 wxFLAGS_MEMBER(wxSB_HORIZONTAL
)
65 wxFLAGS_MEMBER(wxSB_VERTICAL
)
67 wxEND_FLAGS( wxScrollBarStyle
)
69 IMPLEMENT_DYNAMIC_CLASS_XTI(wxScrollBar
, wxControl
,"wx/scrolbar.h")
71 wxBEGIN_PROPERTIES_TABLE(wxScrollBar
)
72 wxEVENT_RANGE_PROPERTY( Scroll
, wxEVT_SCROLL_TOP
, wxEVT_SCROLL_ENDSCROLL
, wxScrollEvent
)
74 wxPROPERTY( ThumbPosition
, int , SetThumbPosition
, GetThumbPosition
, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
75 wxPROPERTY( Range
, int , SetRange
, GetRange
, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
76 wxPROPERTY( ThumbSize
, int , SetThumbSize
, GetThumbSize
, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
77 wxPROPERTY( PageSize
, int , SetPageSize
, GetPageSize
, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
78 wxPROPERTY_FLAGS( WindowStyle
, wxScrollBarStyle
, long , SetWindowStyleFlag
, GetWindowStyleFlag
, EMPTY_MACROVALUE
, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style
79 wxEND_PROPERTIES_TABLE()
81 wxBEGIN_HANDLERS_TABLE(wxScrollBar
)
82 wxEND_HANDLERS_TABLE()
84 wxCONSTRUCTOR_5( wxScrollBar
, wxWindow
* , Parent
, wxWindowID
, Id
, wxPoint
, Position
, wxSize
, Size
, long , WindowStyle
)
86 IMPLEMENT_DYNAMIC_CLASS(wxScrollBar
, wxControl
)
90 bool wxScrollBar::Create(wxWindow
*parent
, wxWindowID id
,
92 const wxSize
& size
, long style
,
93 const wxValidator
& wxVALIDATOR_PARAM(validator
),
98 parent
->AddChild(this);
101 SetValidator(validator
);
102 #endif // wxUSE_VALIDATORS
104 if ((style
& wxBORDER_MASK
) == wxBORDER_DEFAULT
)
105 style
|= wxNO_BORDER
;
107 SetBackgroundColour(parent
->GetBackgroundColour()) ;
108 SetForegroundColour(parent
->GetForegroundColour()) ;
109 m_windowStyle
= style
;
112 m_windowId
= (int)NewControlId();
123 if (style
& wxHORIZONTAL
)
130 if (style
& wxVERTICAL
)
137 WXDWORD wstyle
= MSWGetStyle(style
, & exStyle
) ;
139 // Now create scrollbar
140 DWORD _direction
= (style
& wxHORIZONTAL
) ?
142 HWND scroll_bar
= CreateWindowEx(exStyle
, wxT("SCROLLBAR"), wxT("scrollbar"),
144 0, 0, 0, 0, (HWND
) parent
->GetHWND(), (HMENU
)m_windowId
,
145 wxGetInstance(), NULL
);
151 ::SetScrollRange(scroll_bar
, SB_CTL
, 0, 1, FALSE
);
152 ::SetScrollPos(scroll_bar
, SB_CTL
, 0, FALSE
);
153 ShowWindow(scroll_bar
, SW_SHOW
);
155 m_hWnd
= (WXHWND
)scroll_bar
;
157 // Subclass again for purposes of dialog editing mode
158 SubclassWin((WXHWND
) scroll_bar
);
160 SetSize(x
, y
, width
, height
);
165 wxScrollBar::~wxScrollBar(void)
169 bool wxScrollBar::MSWOnScroll(int WXUNUSED(orientation
), WXWORD wParam
,
170 WXWORD pos
, WXHWND
WXUNUSED(control
))
172 // current and max positions
174 maxPos
, trackPos
= pos
;
176 // when we're dragging the scrollbar we can't use pos parameter because it
177 // is limited to 16 bits
178 // JACS: now always using GetScrollInfo, since there's no reason
180 // if ( wParam == SB_THUMBPOSITION || wParam == SB_THUMBTRACK )
182 SCROLLINFO scrollInfo
;
183 wxZeroMemory(scrollInfo
);
184 scrollInfo
.cbSize
= sizeof(SCROLLINFO
);
186 // also get the range if we call GetScrollInfo() anyhow -- this is less
187 // expensive than call it once here and then call GetScrollRange()
189 scrollInfo
.fMask
= SIF_RANGE
| SIF_POS
| SIF_TRACKPOS
;
191 if ( !::GetScrollInfo(GetHwnd(), SB_CTL
, &scrollInfo
) )
193 wxLogLastError(_T("GetScrollInfo"));
196 trackPos
= scrollInfo
.nTrackPos
;
197 position
= scrollInfo
.nPos
;
198 maxPos
= scrollInfo
.nMax
;
203 position
= ::GetScrollPos((HWND
) control
, SB_CTL
);
205 ::GetScrollRange((HWND
) control
, SB_CTL
, &minPos
, &maxPos
);
209 #if defined(__WIN95__)
210 // A page size greater than one has the effect of reducing the effective
211 // range, therefore the range has already been boosted artificially - so
213 if ( m_pageSize
> 1 )
214 maxPos
-= (m_pageSize
- 1);
217 wxEventType scrollEvent
= wxEVT_NULL
;
223 nScrollInc
= maxPos
- position
;
224 scrollEvent
= wxEVT_SCROLL_TOP
;
228 nScrollInc
= -position
;
229 scrollEvent
= wxEVT_SCROLL_BOTTOM
;
234 scrollEvent
= wxEVT_SCROLL_LINEUP
;
239 scrollEvent
= wxEVT_SCROLL_LINEDOWN
;
243 nScrollInc
= -GetPageSize();
244 scrollEvent
= wxEVT_SCROLL_PAGEUP
;
248 nScrollInc
= GetPageSize();
249 scrollEvent
= wxEVT_SCROLL_PAGEDOWN
;
252 case SB_THUMBPOSITION
:
253 nScrollInc
= trackPos
- position
;
254 scrollEvent
= wxEVT_SCROLL_THUMBRELEASE
;
258 nScrollInc
= trackPos
- position
;
259 scrollEvent
= wxEVT_SCROLL_THUMBTRACK
;
264 scrollEvent
= wxEVT_SCROLL_ENDSCROLL
;
273 position
+= nScrollInc
;
277 if ( position
> maxPos
)
280 SetThumbPosition(position
);
282 else if ( scrollEvent
!= wxEVT_SCROLL_THUMBRELEASE
&&
283 scrollEvent
!= wxEVT_SCROLL_ENDSCROLL
)
285 // don't process the event if there is no displacement,
286 // unless this is a thumb release or end scroll event.
290 wxScrollEvent
event(scrollEvent
, m_windowId
);
291 event
.SetOrientation(IsVertical() ? wxVERTICAL
: wxHORIZONTAL
);
292 event
.SetPosition(position
);
293 event
.SetEventObject( this );
295 return GetEventHandler()->ProcessEvent(event
);
298 void wxScrollBar::SetThumbPosition(int viewStart
)
300 #if defined(__WIN95__)
302 info
.cbSize
= sizeof(SCROLLINFO
);
305 info
.nPos
= viewStart
;
306 info
.fMask
= SIF_POS
;
308 ::SetScrollInfo((HWND
) GetHWND(), SB_CTL
, &info
, TRUE
);
310 ::SetScrollPos((HWND
) GetHWND(), SB_CTL
, viewStart
, TRUE
);
314 int wxScrollBar::GetThumbPosition(void) const
316 SCROLLINFO scrollInfo
;
317 wxZeroMemory(scrollInfo
);
318 scrollInfo
.cbSize
= sizeof(SCROLLINFO
);
319 scrollInfo
.fMask
= SIF_POS
;
321 if ( !::GetScrollInfo(GetHwnd(), SB_CTL
, &scrollInfo
) )
323 wxLogLastError(_T("GetScrollInfo"));
325 return scrollInfo
.nPos
;
326 // return ::GetScrollPos((HWND)m_hWnd, SB_CTL);
329 void wxScrollBar::SetScrollbar(int position
, int thumbSize
, int range
, int pageSize
,
332 m_viewSize
= pageSize
;
333 m_pageSize
= thumbSize
;
334 m_objectSize
= range
;
336 // The range (number of scroll steps) is the
337 // object length minus the page size.
338 int range1
= wxMax((m_objectSize
- m_pageSize
), 0) ;
340 #if defined(__WIN95__)
341 // Try to adjust the range to cope with page size > 1
342 // (see comment for SetPageLength)
343 if ( m_pageSize
> 1 )
345 range1
+= (m_pageSize
- 1);
349 info
.cbSize
= sizeof(SCROLLINFO
);
350 info
.nPage
= m_pageSize
;
353 info
.nPos
= position
;
355 info
.fMask
= SIF_PAGE
| SIF_RANGE
| SIF_POS
;
357 ::SetScrollInfo((HWND
) GetHWND(), SB_CTL
, &info
, refresh
);
359 ::SetScrollPos((HWND
)m_hWnd
, SB_CTL
, position
, TRUE
);
360 ::SetScrollRange((HWND
)m_hWnd
, SB_CTL
, 0, range1
, TRUE
);
365 WXHBRUSH
wxScrollBar::OnCtlColor(WXHDC
WXUNUSED(pDC
), WXHWND
WXUNUSED(pWnd
), WXUINT
WXUNUSED(nCtlColor
),
366 WXUINT
WXUNUSED(message
), WXWPARAM
WXUNUSED(wParam
), WXLPARAM
WXUNUSED(lParam
))
371 void wxScrollBar::Command(wxCommandEvent
& event
)
373 SetThumbPosition(event
.m_commandInt
);
374 ProcessCommand(event
);
377 wxSize
wxScrollBar::DoGetBestSize() const
384 w
= wxSystemSettings::GetMetric(wxSYS_VSCROLL_X
);
388 h
= wxSystemSettings::GetMetric(wxSYS_HSCROLL_Y
);
394 #endif // wxUSE_SCROLLBAR