]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/msw/scrolbar.cpp
fixed wxEVT_CONTEXT_MENU generation (it works differently under w2k/XP than under...
[wxWidgets.git] / src / msw / scrolbar.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: msw/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
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
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#if wxUSE_SCROLLBAR
24
25#ifndef WX_PRECOMP
26 #include "wx/utils.h"
27#endif
28
29#include "wx/scrolbar.h"
30#include "wx/msw/private.h"
31
32#if wxUSE_EXTENDED_RTTI
33WX_DEFINE_FLAGS( wxScrollBarStyle )
34
35wxBEGIN_FLAGS( wxScrollBarStyle )
36 // new style border flags, we put them first to
37 // use them for streaming out
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)
44
45 // old style border flags
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)
51 wxFLAGS_MEMBER(wxBORDER)
52
53 // standard window styles
54 wxFLAGS_MEMBER(wxTAB_TRAVERSAL)
55 wxFLAGS_MEMBER(wxCLIP_CHILDREN)
56 wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW)
57 wxFLAGS_MEMBER(wxWANTS_CHARS)
58 wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE)
59 wxFLAGS_MEMBER(wxALWAYS_SHOW_SB )
60 wxFLAGS_MEMBER(wxVSCROLL)
61 wxFLAGS_MEMBER(wxHSCROLL)
62
63 wxFLAGS_MEMBER(wxSB_HORIZONTAL)
64 wxFLAGS_MEMBER(wxSB_VERTICAL)
65
66wxEND_FLAGS( wxScrollBarStyle )
67
68IMPLEMENT_DYNAMIC_CLASS_XTI(wxScrollBar, wxControl,"wx/scrolbar.h")
69
70wxBEGIN_PROPERTIES_TABLE(wxScrollBar)
71 wxEVENT_RANGE_PROPERTY( Scroll , wxEVT_SCROLL_TOP , wxEVT_SCROLL_ENDSCROLL , wxScrollEvent )
72
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()
79
80wxBEGIN_HANDLERS_TABLE(wxScrollBar)
81wxEND_HANDLERS_TABLE()
82
83wxCONSTRUCTOR_5( wxScrollBar , wxWindow* , Parent , wxWindowID , Id , wxPoint , Position , wxSize , Size , long , WindowStyle )
84#else
85IMPLEMENT_DYNAMIC_CLASS(wxScrollBar, wxControl)
86#endif
87
88// Scrollbar
89bool wxScrollBar::Create(wxWindow *parent, wxWindowID id,
90 const wxPoint& pos,
91 const wxSize& size, long style,
92 const wxValidator& wxVALIDATOR_PARAM(validator),
93 const wxString& name)
94{
95 if (!parent)
96 return FALSE;
97 parent->AddChild(this);
98 SetName(name);
99#if wxUSE_VALIDATORS
100 SetValidator(validator);
101#endif // wxUSE_VALIDATORS
102
103 if ((style & wxBORDER_MASK) == wxBORDER_DEFAULT)
104 style |= wxNO_BORDER;
105
106 SetBackgroundColour(parent->GetBackgroundColour()) ;
107 SetForegroundColour(parent->GetForegroundColour()) ;
108 m_windowStyle = style;
109
110 if ( id == -1 )
111 m_windowId = (int)NewControlId();
112 else
113 m_windowId = id;
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
135 WXDWORD exStyle = 0;
136 WXDWORD wstyle = MSWGetStyle(style, & exStyle) ;
137
138 // Now create scrollbar
139 DWORD _direction = (style & wxHORIZONTAL) ?
140 SBS_HORZ: SBS_VERT;
141 HWND scroll_bar = CreateWindowEx(exStyle, wxT("SCROLLBAR"), wxT("scrollbar"),
142 _direction | wstyle,
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
154 SetFont(parent->GetFont());
155
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
170bool wxScrollBar::MSWOnScroll(int WXUNUSED(orientation), WXWORD wParam,
171 WXWORD pos, WXHWND WXUNUSED(control))
172{
173 // current and max positions
174 int position,
175 maxPos, trackPos = pos;
176
177 // when we're dragging the scrollbar we can't use pos parameter because it
178 // is limited to 16 bits
179 // JACS: now always using GetScrollInfo, since there's no reason
180 // not to
181// if ( wParam == SB_THUMBPOSITION || wParam == SB_THUMBTRACK )
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 }
201#if 0
202 else
203 {
204 position = ::GetScrollPos((HWND) control, SB_CTL);
205 int minPos;
206 ::GetScrollRange((HWND) control, SB_CTL, &minPos, &maxPos);
207 }
208#endif
209
210#if defined(__WIN95__)
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__
217
218 wxEventType scrollEvent = wxEVT_NULL;
219
220 int nScrollInc;
221 switch ( wParam )
222 {
223 case SB_BOTTOM:
224 nScrollInc = maxPos - position;
225 scrollEvent = wxEVT_SCROLL_TOP;
226 break;
227
228 case SB_TOP:
229 nScrollInc = -position;
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
253 case SB_THUMBPOSITION:
254 nScrollInc = trackPos - position;
255 scrollEvent = wxEVT_SCROLL_THUMBRELEASE;
256 break;
257
258 case SB_THUMBTRACK:
259 nScrollInc = trackPos - position;
260 scrollEvent = wxEVT_SCROLL_THUMBTRACK;
261 break;
262
263 case SB_ENDSCROLL:
264 nScrollInc = 0;
265 scrollEvent = wxEVT_SCROLL_ENDSCROLL;
266 break;
267
268 default:
269 nScrollInc = 0;
270 }
271
272 if ( nScrollInc )
273 {
274 position += nScrollInc;
275
276 if ( position < 0 )
277 position = 0;
278 if ( position > maxPos )
279 position = maxPos;
280
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 }
290
291 wxScrollEvent event(scrollEvent, m_windowId);
292 event.SetOrientation(IsVertical() ? wxVERTICAL : wxHORIZONTAL);
293 event.SetPosition(position);
294 event.SetEventObject( this );
295
296 return GetEventHandler()->ProcessEvent(event);
297}
298
299void wxScrollBar::SetThumbPosition(int viewStart)
300{
301#if defined(__WIN95__)
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);
310#else
311 ::SetScrollPos((HWND) GetHWND(), SB_CTL, viewStart, TRUE);
312#endif
313}
314
315int wxScrollBar::GetThumbPosition(void) const
316{
317 SCROLLINFO scrollInfo;
318 wxZeroMemory(scrollInfo);
319 scrollInfo.cbSize = sizeof(SCROLLINFO);
320 scrollInfo.fMask = SIF_POS;
321
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);
328}
329
330void wxScrollBar::SetScrollbar(int position, int thumbSize, int range, int pageSize,
331 bool refresh)
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 {
346 range1 += (m_pageSize - 1);
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
366WXHBRUSH wxScrollBar::OnCtlColor(WXHDC WXUNUSED(pDC), WXHWND WXUNUSED(pWnd), WXUINT WXUNUSED(nCtlColor),
367 WXUINT WXUNUSED(message), WXWPARAM WXUNUSED(wParam), WXLPARAM WXUNUSED(lParam))
368{
369 return 0;
370}
371
372void wxScrollBar::Command(wxCommandEvent& event)
373{
374 SetThumbPosition(event.m_commandInt);
375 ProcessCommand(event);
376}
377
378#endif // wxUSE_SCROLLBAR