]> git.saurik.com Git - wxWidgets.git/blob - src/msw/scrolbar.cpp
added some wxMSW stuff
[wxWidgets.git] / src / msw / scrolbar.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: scrolbar.cpp
3 // Purpose: wxScrollBar
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "scrolbar.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include "wx/defs.h"
25 #include "wx/utils.h"
26 #endif
27
28 #include "wx/scrolbar.h"
29 #include "wx/msw/private.h"
30
31 // extern wxList wxScrollBarList;
32 extern void wxFindMaxSize(HWND hwnd, RECT *rect);
33
34 #if !USE_SHARED_LIBRARY
35 IMPLEMENT_DYNAMIC_CLASS(wxScrollBar, wxControl)
36
37 #if WXWIN_COMPATIBILITY
38 BEGIN_EVENT_TABLE(wxScrollBar, wxControl)
39 EVT_SCROLL(wxScrollBar::OnScroll)
40 END_EVENT_TABLE()
41 #endif
42
43 #endif
44
45 // Scrollbar
46 bool wxScrollBar::Create(wxWindow *parent, const wxWindowID id,
47 const wxPoint& pos,
48 const wxSize& size, const long style,
49 const wxValidator& validator,
50 const wxString& name)
51 {
52 if (!parent)
53 return FALSE;
54 parent->AddChild(this);
55 SetName(name);
56 SetValidator(validator);
57
58 SetBackgroundColour(parent->GetDefaultBackgroundColour()) ;
59 SetForegroundColour(parent->GetDefaultForegroundColour()) ;
60 m_windowStyle = style;
61
62 if ( id == -1 )
63 m_windowId = (int)NewControlId();
64 else
65 m_windowId = id;
66
67 int x = pos.x;
68 int y = pos.y;
69 int width = size.x;
70 int height = size.y;
71
72 if (width == -1)
73 {
74 if (style & wxHORIZONTAL)
75 width = 140;
76 else
77 width = 14;
78 }
79 if (height == -1)
80 {
81 if (style & wxVERTICAL)
82 height = 140;
83 else
84 height = 14;
85 }
86
87 // Now create scrollbar
88 DWORD _direction = (style & wxHORIZONTAL) ?
89 SBS_HORZ: SBS_VERT;
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);
94
95 m_pageSize = 1;
96 m_viewSize = 1;
97 m_objectSize = 1;
98
99 ::SetScrollRange(scroll_bar, SB_CTL, 0, 1, FALSE);
100 ::SetScrollPos(scroll_bar, SB_CTL, 0, FALSE);
101 ShowWindow(scroll_bar, SW_SHOW);
102
103 m_hWnd = (WXHWND)scroll_bar;
104
105 // Subclass again for purposes of dialog editing mode
106 SubclassWin((WXHWND) scroll_bar);
107
108 SetSize(x, y, width, height);
109
110 return TRUE;
111 }
112
113 wxScrollBar::~wxScrollBar(void)
114 {
115 }
116
117 void wxScrollBar::MSWOnVScroll(const WXWORD wParam, const WXWORD pos, const WXHWND control)
118 {
119 int position = ::GetScrollPos((HWND) control, SB_CTL);
120 int minPos, maxPos;
121 ::GetScrollRange((HWND) control, SB_CTL, &minPos, &maxPos);
122 #if defined(__WIN95__)
123 // A page size greater than one has the effect of reducing the
124 // effective range, therefore the range has already been
125 // boosted artificially - so reduce it again.
126 if ( m_pageSize > 1 )
127 maxPos -= (m_pageSize - 1);
128 #endif
129
130 int scrollEvent = 0;
131
132 int nScrollInc;
133 switch ( wParam )
134 {
135 case SB_TOP:
136 nScrollInc = maxPos - position;
137 scrollEvent = wxEVT_SCROLL_TOP;
138 break;
139
140 case SB_BOTTOM:
141 nScrollInc = - position;
142 scrollEvent = wxEVT_SCROLL_BOTTOM;
143 break;
144
145 case SB_LINEUP:
146 nScrollInc = -1;
147 scrollEvent = wxEVT_SCROLL_LINEUP;
148 break;
149
150 case SB_LINEDOWN:
151 nScrollInc = 1;
152 scrollEvent = wxEVT_SCROLL_LINEDOWN;
153 break;
154
155 case SB_PAGEUP:
156 nScrollInc = -GetPageSize();
157 scrollEvent = wxEVT_SCROLL_PAGEUP;
158 break;
159
160 case SB_PAGEDOWN:
161 nScrollInc = GetPageSize();
162 scrollEvent = wxEVT_SCROLL_PAGEDOWN;
163 break;
164
165 case SB_THUMBTRACK:
166 case SB_THUMBPOSITION:
167 nScrollInc = pos - position;
168 scrollEvent = wxEVT_SCROLL_THUMBTRACK;
169 break;
170
171 default:
172 nScrollInc = 0;
173 }
174
175 if (nScrollInc != 0)
176 {
177 int new_pos = position + nScrollInc;
178
179 if (new_pos < 0)
180 new_pos = 0;
181 if (new_pos > maxPos)
182 new_pos = maxPos;
183
184 SetValue(new_pos);
185 wxScrollEvent event(scrollEvent, m_windowId);
186 event.SetPosition(new_pos);
187 event.SetEventObject( this );
188 GetEventHandler()->ProcessEvent(event);
189 }
190 }
191
192 void wxScrollBar::MSWOnHScroll(const WXWORD wParam, const WXWORD pos, const WXHWND control)
193 {
194 MSWOnVScroll(wParam, pos, control);
195 }
196
197 void wxScrollBar::SetPosition(const int viewStart)
198 {
199 #if defined(__WIN95__)
200 SCROLLINFO info;
201 info.cbSize = sizeof(SCROLLINFO);
202 info.nPage = 0;
203 info.nMin = 0;
204 info.nPos = viewStart;
205 info.fMask = SIF_POS ;
206
207 ::SetScrollInfo((HWND) GetHWND(), SB_CTL, &info, TRUE);
208 #else
209 ::SetScrollPos((HWND) GetHWND(), SB_CTL, viewStart, TRUE);
210 #endif
211 }
212
213 int wxScrollBar::GetPosition(void) const
214 {
215 return ::GetScrollPos((HWND)m_hWnd, SB_CTL);
216 }
217
218 void wxScrollBar::SetScrollbar(const int position, const int thumbSize, const int range, const int pageSize,
219 const bool refresh)
220 {
221 m_viewSize = pageSize;
222 m_pageSize = thumbSize;
223 m_objectSize = range;
224
225 // The range (number of scroll steps) is the
226 // object length minus the page size.
227 int range1 = wxMax((m_objectSize - m_pageSize), 0) ;
228
229 #if defined(__WIN95__)
230 // Try to adjust the range to cope with page size > 1
231 // (see comment for SetPageLength)
232 if ( m_pageSize > 1 )
233 {
234 range1 += (m_pageSize - 1);
235 }
236
237 SCROLLINFO info;
238 info.cbSize = sizeof(SCROLLINFO);
239 info.nPage = m_pageSize;
240 info.nMin = 0;
241 info.nMax = range1;
242 info.nPos = position;
243
244 info.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
245
246 ::SetScrollInfo((HWND) GetHWND(), SB_CTL, &info, refresh);
247 #else
248 ::SetScrollPos((HWND)m_hWnd, SB_CTL, position, TRUE);
249 ::SetScrollRange((HWND)m_hWnd, SB_CTL, 0, range1, TRUE);
250 #endif
251 }
252
253
254 /* From the WIN32 documentation:
255 In version 4.0 or later, the maximum value that a scroll bar can report
256 (that is, the maximum scrolling position) depends on the page size.
257 If the scroll bar has a page size greater than one, the maximum scrolling position
258 is less than the maximum range value. You can use the following formula to calculate
259 the maximum scrolling position:
260
261 MaxScrollPos = MaxRangeValue - (PageSize - 1)
262 */
263
264 #if WXWIN_COMPATIBILITY
265 void wxScrollBar::SetPageSize(const int pageLength)
266 {
267 m_pageSize = pageLength;
268
269 #if defined(__WIN95__)
270 SCROLLINFO info;
271 info.cbSize = sizeof(SCROLLINFO);
272 info.nPage = pageLength;
273 info.fMask = SIF_PAGE ;
274
275 ::SetScrollInfo((HWND) GetHWND(), SB_CTL, &info, TRUE);
276 #endif
277 }
278
279 void wxScrollBar::SetObjectLength(const int objectLength)
280 {
281 m_objectSize = objectLength;
282
283 // The range (number of scroll steps) is the
284 // object length minus the view size.
285 int range = wxMax((objectLength - m_viewSize), 0) ;
286
287 #if defined(__WIN95__)
288 // Try to adjust the range to cope with page size > 1
289 // (see comment for SetPageLength)
290 if ( m_pageSize > 1 )
291 {
292 range += (m_pageSize - 1);
293 }
294
295 SCROLLINFO info;
296 info.cbSize = sizeof(SCROLLINFO);
297 info.nPage = 0;
298 info.nMin = 0;
299 info.nMax = range;
300 info.nPos = 0;
301 info.fMask = SIF_RANGE ;
302
303 ::SetScrollInfo((HWND) GetHWND(), SB_CTL, &info, TRUE);
304 #else
305 ::SetScrollRange((HWND)m_hWnd, SB_CTL, 0, range, TRUE);
306 #endif
307 }
308
309 void wxScrollBar::SetViewLength(const int viewLength)
310 {
311 m_viewSize = viewLength;
312 }
313
314 void wxScrollBar::GetValues(int *viewStart, int *viewLength, int *objectLength,
315 int *pageLength) const
316 {
317 *viewStart = ::GetScrollPos((HWND)m_hWnd, SB_CTL);
318 *viewLength = m_viewSize;
319 *objectLength = m_objectSize;
320 *pageLength = m_pageSize;
321 }
322 #endif
323
324 WXHBRUSH wxScrollBar::OnCtlColor(const WXHDC pDC, const WXHWND pWnd, const WXUINT nCtlColor,
325 WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
326 {
327 return 0;
328 }
329
330 void wxScrollBar::Command(wxCommandEvent& event)
331 {
332 SetValue(event.m_commandInt);
333 ProcessCommand(event);
334 }
335
336 #if WXWIN_COMPATIBILITY
337 // Backward compatibility
338 void wxScrollBar::OnScroll(wxScrollEvent& event)
339 {
340 int oldEvent = event.GetEventType();
341 event.SetEventType( wxEVT_COMMAND_SCROLLBAR_UPDATED );
342 if ( !GetEventHandler()->ProcessEvent(event) )
343 {
344 event.SetEventType( oldEvent );
345 if (!GetParent()->GetEventHandler()->ProcessEvent(event))
346 event.Skip();
347 }
348 }
349 #endif