]> git.saurik.com Git - wxWidgets.git/blame - src/msw/scrolbar.cpp
workaround for blocking behaviour under carbon when running in classic
[wxWidgets.git] / src / msw / scrolbar.cpp
CommitLineData
2bda0e17 1/////////////////////////////////////////////////////////////////////////////
1e6feb95 2// Name: msw/scrolbar.cpp
2bda0e17
KB
3// Purpose: wxScrollBar
4// Author: Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
6c9a19aa
JS
8// Copyright: (c) Julian Smart
9// Licence: wxWindows licence
2bda0e17
KB
10/////////////////////////////////////////////////////////////////////////////
11
14f355c2 12#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
1e6feb95 13 #pragma implementation "scrolbar.h"
2bda0e17
KB
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
1e6feb95 20 #pragma hdrstop
2bda0e17
KB
21#endif
22
1e6feb95
VZ
23#if wxUSE_SCROLLBAR
24
2bda0e17 25#ifndef WX_PRECOMP
1e6feb95 26 #include "wx/utils.h"
2bda0e17
KB
27#endif
28
29#include "wx/scrolbar.h"
30#include "wx/msw/private.h"
31
f0a126fe 32#if wxUSE_EXTENDED_RTTI
bc9fb572
JS
33WX_DEFINE_FLAGS( wxScrollBarStyle )
34
3ff066a4 35wxBEGIN_FLAGS( wxScrollBarStyle )
bc9fb572
JS
36 // new style border flags, we put them first to
37 // use them for streaming out
3ff066a4
SC
38 wxFLAGS_MEMBER(wxBORDER_SIMPLE)
39 wxFLAGS_MEMBER(wxBORDER_SUNKEN)
40 wxFLAGS_MEMBER(wxBORDER_DOUBLE)
41 wxFLAGS_MEMBER(wxBORDER_RAISED)
42 wxFLAGS_MEMBER(wxBORDER_STATIC)
43 wxFLAGS_MEMBER(wxBORDER_NONE)
bc9fb572
JS
44
45 // old style border flags
3ff066a4
SC
46 wxFLAGS_MEMBER(wxSIMPLE_BORDER)
47 wxFLAGS_MEMBER(wxSUNKEN_BORDER)
48 wxFLAGS_MEMBER(wxDOUBLE_BORDER)
49 wxFLAGS_MEMBER(wxRAISED_BORDER)
50 wxFLAGS_MEMBER(wxSTATIC_BORDER)
cb0afb26 51 wxFLAGS_MEMBER(wxBORDER)
bc9fb572
JS
52
53 // standard window styles
3ff066a4
SC
54 wxFLAGS_MEMBER(wxTAB_TRAVERSAL)
55 wxFLAGS_MEMBER(wxCLIP_CHILDREN)
56 wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW)
57 wxFLAGS_MEMBER(wxWANTS_CHARS)
cb0afb26 58 wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE)
3ff066a4
SC
59 wxFLAGS_MEMBER(wxALWAYS_SHOW_SB )
60 wxFLAGS_MEMBER(wxVSCROLL)
61 wxFLAGS_MEMBER(wxHSCROLL)
bc9fb572 62
3ff066a4
SC
63 wxFLAGS_MEMBER(wxSB_HORIZONTAL)
64 wxFLAGS_MEMBER(wxSB_VERTICAL)
bc9fb572 65
3ff066a4 66wxEND_FLAGS( wxScrollBarStyle )
bc9fb572 67
f0a126fe
SC
68IMPLEMENT_DYNAMIC_CLASS_XTI(wxScrollBar, wxControl,"wx/scrolbar.h")
69
3ff066a4
SC
70wxBEGIN_PROPERTIES_TABLE(wxScrollBar)
71 wxEVENT_RANGE_PROPERTY( Scroll , wxEVT_SCROLL_TOP , wxEVT_SCROLL_ENDSCROLL , wxScrollEvent )
c5ca409b 72
3ff066a4
SC
73 wxPROPERTY( ThumbPosition , int , SetThumbPosition, GetThumbPosition, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
74 wxPROPERTY( Range , int , SetRange, GetRange, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
75 wxPROPERTY( ThumbSize , int , SetThumbSize, GetThumbSize, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
76 wxPROPERTY( PageSize , int , SetPageSize, GetPageSize, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
77 wxPROPERTY_FLAGS( WindowStyle , wxScrollBarStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style
78wxEND_PROPERTIES_TABLE()
2bda0e17 79
3ff066a4
SC
80wxBEGIN_HANDLERS_TABLE(wxScrollBar)
81wxEND_HANDLERS_TABLE()
066f1b7a 82
3ff066a4 83wxCONSTRUCTOR_5( wxScrollBar , wxWindow* , Parent , wxWindowID , Id , wxPoint , Position , wxSize , Size , long , WindowStyle )
f0a126fe
SC
84#else
85IMPLEMENT_DYNAMIC_CLASS(wxScrollBar, wxControl)
86#endif
2bda0e17
KB
87
88// Scrollbar
debe6624 89bool wxScrollBar::Create(wxWindow *parent, wxWindowID id,
2bda0e17 90 const wxPoint& pos,
debe6624 91 const wxSize& size, long style,
ac8d0c11 92 const wxValidator& wxVALIDATOR_PARAM(validator),
2bda0e17
KB
93 const wxString& name)
94{
95 if (!parent)
96 return FALSE;
97 parent->AddChild(this);
98 SetName(name);
11b6a93b 99#if wxUSE_VALIDATORS
a23fd0e1 100 SetValidator(validator);
11b6a93b 101#endif // wxUSE_VALIDATORS
33ac7e6f 102
7051e6c7
JS
103 if ((style & wxBORDER_MASK) == wxBORDER_DEFAULT)
104 style |= wxNO_BORDER;
105
fd71308f
JS
106 SetBackgroundColour(parent->GetBackgroundColour()) ;
107 SetForegroundColour(parent->GetForegroundColour()) ;
2bda0e17
KB
108 m_windowStyle = style;
109
110 if ( id == -1 )
a23fd0e1 111 m_windowId = (int)NewControlId();
2bda0e17 112 else
a23fd0e1 113 m_windowId = id;
2bda0e17
KB
114
115 int x = pos.x;
116 int y = pos.y;
117 int width = size.x;
118 int height = size.y;
119
120 if (width == -1)
121 {
122 if (style & wxHORIZONTAL)
123 width = 140;
124 else
125 width = 14;
126 }
127 if (height == -1)
128 {
129 if (style & wxVERTICAL)
130 height = 140;
131 else
132 height = 14;
133 }
134
fe3d9123
JS
135 WXDWORD exStyle = 0;
136 WXDWORD wstyle = MSWGetStyle(style, & exStyle) ;
b0766406 137
2bda0e17
KB
138 // Now create scrollbar
139 DWORD _direction = (style & wxHORIZONTAL) ?
140 SBS_HORZ: SBS_VERT;
fe3d9123 141 HWND scroll_bar = CreateWindowEx(exStyle, wxT("SCROLLBAR"), wxT("scrollbar"),
b0766406 142 _direction | wstyle,
2bda0e17
KB
143 0, 0, 0, 0, (HWND) parent->GetHWND(), (HMENU)m_windowId,
144 wxGetInstance(), NULL);
145
146 m_pageSize = 1;
147 m_viewSize = 1;
148 m_objectSize = 1;
149
150 ::SetScrollRange(scroll_bar, SB_CTL, 0, 1, FALSE);
151 ::SetScrollPos(scroll_bar, SB_CTL, 0, FALSE);
152 ShowWindow(scroll_bar, SW_SHOW);
153
c0ed460c 154 SetFont(parent->GetFont());
1c089c47 155
2bda0e17
KB
156 m_hWnd = (WXHWND)scroll_bar;
157
158 // Subclass again for purposes of dialog editing mode
159 SubclassWin((WXHWND) scroll_bar);
160
161 SetSize(x, y, width, height);
162
163 return TRUE;
164}
165
166wxScrollBar::~wxScrollBar(void)
167{
168}
169
a23fd0e1 170bool wxScrollBar::MSWOnScroll(int WXUNUSED(orientation), WXWORD wParam,
2eb10e2a 171 WXWORD pos, WXHWND WXUNUSED(control))
2bda0e17 172{
2b5f62a0
VZ
173 // current and max positions
174 int position,
175 maxPos, trackPos = pos;
176
2b5f62a0
VZ
177 // when we're dragging the scrollbar we can't use pos parameter because it
178 // is limited to 16 bits
4676948b
JS
179 // JACS: now always using GetScrollInfo, since there's no reason
180 // not to
181// if ( wParam == SB_THUMBPOSITION || wParam == SB_THUMBTRACK )
2b5f62a0
VZ
182 {
183 SCROLLINFO scrollInfo;
184 wxZeroMemory(scrollInfo);
185 scrollInfo.cbSize = sizeof(SCROLLINFO);
186
187 // also get the range if we call GetScrollInfo() anyhow -- this is less
188 // expensive than call it once here and then call GetScrollRange()
189 // below
190 scrollInfo.fMask = SIF_RANGE | SIF_POS | SIF_TRACKPOS;
191
192 if ( !::GetScrollInfo(GetHwnd(), SB_CTL, &scrollInfo) )
193 {
194 wxLogLastError(_T("GetScrollInfo"));
195 }
196
197 trackPos = scrollInfo.nTrackPos;
198 position = scrollInfo.nPos;
199 maxPos = scrollInfo.nMax;
200 }
4676948b 201#if 0
2b5f62a0 202 else
2b5f62a0
VZ
203 {
204 position = ::GetScrollPos((HWND) control, SB_CTL);
205 int minPos;
206 ::GetScrollRange((HWND) control, SB_CTL, &minPos, &maxPos);
207 }
4676948b 208#endif
a23fd0e1 209
2bda0e17 210#if defined(__WIN95__)
a23fd0e1
VZ
211 // A page size greater than one has the effect of reducing the effective
212 // range, therefore the range has already been boosted artificially - so
213 // reduce it again.
214 if ( m_pageSize > 1 )
215 maxPos -= (m_pageSize - 1);
216#endif // __WIN95__
2bda0e17 217
7798a18e 218 wxEventType scrollEvent = wxEVT_NULL;
2bda0e17
KB
219
220 int nScrollInc;
221 switch ( wParam )
222 {
a29ffc34 223 case SB_BOTTOM:
a23fd0e1
VZ
224 nScrollInc = maxPos - position;
225 scrollEvent = wxEVT_SCROLL_TOP;
226 break;
227
a29ffc34
VZ
228 case SB_TOP:
229 nScrollInc = -position;
a23fd0e1
VZ
230 scrollEvent = wxEVT_SCROLL_BOTTOM;
231 break;
232
233 case SB_LINEUP:
234 nScrollInc = -1;
235 scrollEvent = wxEVT_SCROLL_LINEUP;
236 break;
237
238 case SB_LINEDOWN:
239 nScrollInc = 1;
240 scrollEvent = wxEVT_SCROLL_LINEDOWN;
241 break;
242
243 case SB_PAGEUP:
244 nScrollInc = -GetPageSize();
245 scrollEvent = wxEVT_SCROLL_PAGEUP;
246 break;
247
248 case SB_PAGEDOWN:
249 nScrollInc = GetPageSize();
250 scrollEvent = wxEVT_SCROLL_PAGEDOWN;
251 break;
252
a23fd0e1 253 case SB_THUMBPOSITION:
2b5f62a0 254 nScrollInc = trackPos - position;
7d56fb8f
GRG
255 scrollEvent = wxEVT_SCROLL_THUMBRELEASE;
256 break;
feda3011
GRG
257
258 case SB_THUMBTRACK:
2b5f62a0 259 nScrollInc = trackPos - position;
a23fd0e1
VZ
260 scrollEvent = wxEVT_SCROLL_THUMBTRACK;
261 break;
262
e8b669d3
VZ
263 case SB_ENDSCROLL:
264 nScrollInc = 0;
265 scrollEvent = wxEVT_SCROLL_ENDSCROLL;
266 break;
267
a23fd0e1
VZ
268 default:
269 nScrollInc = 0;
2bda0e17
KB
270 }
271
e8b669d3 272 if ( nScrollInc )
2bda0e17 273 {
e8b669d3 274 position += nScrollInc;
2bda0e17 275
e8b669d3
VZ
276 if ( position < 0 )
277 position = 0;
278 if ( position > maxPos )
279 position = maxPos;
a23fd0e1 280
e8b669d3
VZ
281 SetThumbPosition(position);
282 }
283 else if ( scrollEvent != wxEVT_SCROLL_THUMBRELEASE &&
284 scrollEvent != wxEVT_SCROLL_ENDSCROLL )
285 {
286 // don't process the event if there is no displacement,
287 // unless this is a thumb release or end scroll event.
288 return FALSE;
289 }
a23fd0e1 290
a23fd0e1 291 wxScrollEvent event(scrollEvent, m_windowId);
27e229f5 292 event.SetOrientation(IsVertical() ? wxVERTICAL : wxHORIZONTAL);
e8b669d3 293 event.SetPosition(position);
a23fd0e1
VZ
294 event.SetEventObject( this );
295
296 return GetEventHandler()->ProcessEvent(event);
2bda0e17
KB
297}
298
4fabb575 299void wxScrollBar::SetThumbPosition(int viewStart)
2bda0e17
KB
300{
301#if defined(__WIN95__)
2b5f62a0
VZ
302 SCROLLINFO info;
303 info.cbSize = sizeof(SCROLLINFO);
304 info.nPage = 0;
305 info.nMin = 0;
306 info.nPos = viewStart;
307 info.fMask = SIF_POS ;
308
309 ::SetScrollInfo((HWND) GetHWND(), SB_CTL, &info, TRUE);
2bda0e17 310#else
2b5f62a0 311 ::SetScrollPos((HWND) GetHWND(), SB_CTL, viewStart, TRUE);
2bda0e17
KB
312#endif
313}
314
4fabb575 315int wxScrollBar::GetThumbPosition(void) const
2bda0e17 316{
4676948b
JS
317 SCROLLINFO scrollInfo;
318 wxZeroMemory(scrollInfo);
319 scrollInfo.cbSize = sizeof(SCROLLINFO);
320 scrollInfo.fMask = SIF_POS;
f0a126fe 321
4676948b
JS
322 if ( !::GetScrollInfo(GetHwnd(), SB_CTL, &scrollInfo) )
323 {
324 wxLogLastError(_T("GetScrollInfo"));
325 }
326 return scrollInfo.nPos;
327// return ::GetScrollPos((HWND)m_hWnd, SB_CTL);
2bda0e17
KB
328}
329
debe6624
JS
330void wxScrollBar::SetScrollbar(int position, int thumbSize, int range, int pageSize,
331 bool refresh)
2bda0e17
KB
332{
333 m_viewSize = pageSize;
334 m_pageSize = thumbSize;
335 m_objectSize = range;
336
337 // The range (number of scroll steps) is the
338 // object length minus the page size.
339 int range1 = wxMax((m_objectSize - m_pageSize), 0) ;
340
341#if defined(__WIN95__)
342 // Try to adjust the range to cope with page size > 1
343 // (see comment for SetPageLength)
344 if ( m_pageSize > 1 )
345 {
a23fd0e1 346 range1 += (m_pageSize - 1);
2bda0e17
KB
347 }
348
349 SCROLLINFO info;
350 info.cbSize = sizeof(SCROLLINFO);
351 info.nPage = m_pageSize;
352 info.nMin = 0;
353 info.nMax = range1;
354 info.nPos = position;
355
356 info.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
357
358 ::SetScrollInfo((HWND) GetHWND(), SB_CTL, &info, refresh);
359#else
360 ::SetScrollPos((HWND)m_hWnd, SB_CTL, position, TRUE);
361 ::SetScrollRange((HWND)m_hWnd, SB_CTL, 0, range1, TRUE);
362#endif
363}
364
365
33ac7e6f
KB
366WXHBRUSH wxScrollBar::OnCtlColor(WXHDC WXUNUSED(pDC), WXHWND WXUNUSED(pWnd), WXUINT WXUNUSED(nCtlColor),
367 WXUINT WXUNUSED(message), WXWPARAM WXUNUSED(wParam), WXLPARAM WXUNUSED(lParam))
2bda0e17
KB
368{
369 return 0;
370}
371
372void wxScrollBar::Command(wxCommandEvent& event)
373{
ca5e9f67 374 SetThumbPosition(event.m_commandInt);
2bda0e17
KB
375 ProcessCommand(event);
376}
377
1e6feb95 378#endif // wxUSE_SCROLLBAR