]> git.saurik.com Git - wxWidgets.git/blob - src/msw/slider95.cpp
35380bd868ae503f2e426cbd1d4412d2cf5ac6af
[wxWidgets.git] / src / msw / slider95.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: msw/slider.cpp
3 // Purpose: wxSlider, using the Win95 (and later) trackbar control
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart 1998
9 // Vadim Zeitlin 2004
10 // Licence: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
12
13 // ============================================================================
14 // declarations
15 // ============================================================================
16
17 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
18 #pragma implementation "slider95.h"
19 #endif
20
21 // ----------------------------------------------------------------------------
22 // headers
23 // ----------------------------------------------------------------------------
24
25 // For compilers that support precompilation, includes "wx.h".
26 #include "wx/wxprec.h"
27
28 #ifdef __BORLANDC__
29 #pragma hdrstop
30 #endif
31
32 #if wxUSE_SLIDER
33
34 #ifndef WX_PRECOMP
35 #include "wx/brush.h"
36 #endif
37
38 #include "wx/slider.h"
39 #include "wx/msw/subwin.h"
40
41 #if !(defined(__GNUWIN32_OLD__) && !defined(__CYGWIN10__))
42 #include <commctrl.h>
43 #endif
44
45 #define USE_DEFERRED_SIZING 1
46 #define USE_DEFER_BUG_WORKAROUND 0
47
48 // ----------------------------------------------------------------------------
49 // constants
50 // ----------------------------------------------------------------------------
51
52 // indices of labels in wxSlider::m_labels
53 enum
54 {
55 SliderLabel_Min,
56 SliderLabel_Max,
57 SliderLabel_Value,
58 SliderLabel_Last
59 };
60
61 // the gap between the slider and the labels, in pixels
62 static const int HGAP = 5;
63
64 // ----------------------------------------------------------------------------
65 // XTI
66 // ----------------------------------------------------------------------------
67
68 #if wxUSE_EXTENDED_RTTI
69 WX_DEFINE_FLAGS( wxSliderStyle )
70
71 wxBEGIN_FLAGS( wxSliderStyle )
72 // new style border flags, we put them first to
73 // use them for streaming out
74 wxFLAGS_MEMBER(wxBORDER_SIMPLE)
75 wxFLAGS_MEMBER(wxBORDER_SUNKEN)
76 wxFLAGS_MEMBER(wxBORDER_DOUBLE)
77 wxFLAGS_MEMBER(wxBORDER_RAISED)
78 wxFLAGS_MEMBER(wxBORDER_STATIC)
79 wxFLAGS_MEMBER(wxBORDER_NONE)
80
81 // old style border flags
82 wxFLAGS_MEMBER(wxSIMPLE_BORDER)
83 wxFLAGS_MEMBER(wxSUNKEN_BORDER)
84 wxFLAGS_MEMBER(wxDOUBLE_BORDER)
85 wxFLAGS_MEMBER(wxRAISED_BORDER)
86 wxFLAGS_MEMBER(wxSTATIC_BORDER)
87 wxFLAGS_MEMBER(wxBORDER)
88
89 // standard window styles
90 wxFLAGS_MEMBER(wxTAB_TRAVERSAL)
91 wxFLAGS_MEMBER(wxCLIP_CHILDREN)
92 wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW)
93 wxFLAGS_MEMBER(wxWANTS_CHARS)
94 wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE)
95 wxFLAGS_MEMBER(wxALWAYS_SHOW_SB )
96 wxFLAGS_MEMBER(wxVSCROLL)
97 wxFLAGS_MEMBER(wxHSCROLL)
98
99 wxFLAGS_MEMBER(wxSL_HORIZONTAL)
100 wxFLAGS_MEMBER(wxSL_VERTICAL)
101 wxFLAGS_MEMBER(wxSL_AUTOTICKS)
102 wxFLAGS_MEMBER(wxSL_LABELS)
103 wxFLAGS_MEMBER(wxSL_LEFT)
104 wxFLAGS_MEMBER(wxSL_TOP)
105 wxFLAGS_MEMBER(wxSL_RIGHT)
106 wxFLAGS_MEMBER(wxSL_BOTTOM)
107 wxFLAGS_MEMBER(wxSL_BOTH)
108 wxFLAGS_MEMBER(wxSL_SELRANGE)
109 wxFLAGS_MEMBER(wxSL_INVERSE)
110
111 wxEND_FLAGS( wxSliderStyle )
112
113 IMPLEMENT_DYNAMIC_CLASS_XTI(wxSlider, wxControl,"wx/scrolbar.h")
114
115 wxBEGIN_PROPERTIES_TABLE(wxSlider)
116 wxEVENT_RANGE_PROPERTY( Scroll , wxEVT_SCROLL_TOP , wxEVT_SCROLL_ENDSCROLL , wxScrollEvent )
117 wxEVENT_PROPERTY( Updated , wxEVT_COMMAND_SLIDER_UPDATED , wxCommandEvent )
118
119 wxPROPERTY( Value , int , SetValue, GetValue , 0, 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
120 wxPROPERTY( Minimum , int , SetMin, GetMin, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
121 wxPROPERTY( Maximum , int , SetMax, GetMax, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
122 wxPROPERTY( PageSize , int , SetPageSize, GetLineSize, 1 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
123 wxPROPERTY( LineSize , int , SetLineSize, GetLineSize, 1 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
124 wxPROPERTY( ThumbLength , int , SetThumbLength, GetThumbLength, 1 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
125 wxPROPERTY_FLAGS( WindowStyle , wxSliderStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style
126 wxEND_PROPERTIES_TABLE()
127
128 wxBEGIN_HANDLERS_TABLE(wxSlider)
129 wxEND_HANDLERS_TABLE()
130
131 wxCONSTRUCTOR_8( wxSlider , wxWindow* , Parent , wxWindowID , Id , int , Value , int , Minimum , int , Maximum , wxPoint , Position , wxSize , Size , long , WindowStyle )
132 #else
133 IMPLEMENT_DYNAMIC_CLASS(wxSlider, wxControl)
134 #endif
135
136 // ============================================================================
137 // wxSlider implementation
138 // ============================================================================
139
140 // ----------------------------------------------------------------------------
141 // construction
142 // ----------------------------------------------------------------------------
143
144 void wxSlider::Init()
145 {
146 m_labels = NULL;
147
148 m_pageSize = 1;
149 m_lineSize = 1;
150 m_rangeMax = 0;
151 m_rangeMin = 0;
152 m_tickFreq = 0;
153 }
154
155 bool
156 wxSlider::Create(wxWindow *parent,
157 wxWindowID id,
158 int value,
159 int minValue,
160 int maxValue,
161 const wxPoint& pos,
162 const wxSize& size,
163 long style,
164 const wxValidator& validator,
165 const wxString& name)
166 {
167 // our styles are redundant: wxSL_LEFT/RIGHT imply wxSL_VERTICAL and
168 // wxSL_TOP/BOTTOM imply wxSL_HORIZONTAL, but for backwards compatibility
169 // reasons we can't really change it, instead try to infer the orientation
170 // from the flags given to us here
171 switch ( style & (wxSL_LEFT | wxSL_RIGHT | wxSL_TOP | wxSL_BOTTOM) )
172 {
173 case wxSL_LEFT:
174 case wxSL_RIGHT:
175 style |= wxSL_VERTICAL;
176 break;
177
178 case wxSL_TOP:
179 case wxSL_BOTTOM:
180 style |= wxSL_HORIZONTAL;
181 break;
182
183 case 0:
184 // no specific direction, do we have at least the orientation?
185 if ( !(style & (wxSL_HORIZONTAL | wxSL_VERTICAL)) )
186 {
187 // no, choose default
188 style |= wxSL_BOTTOM | wxSL_HORIZONTAL;
189 }
190 };
191
192 wxASSERT_MSG( !(style & wxSL_VERTICAL) | !(style & wxSL_HORIZONTAL),
193 _T("incompatible slider direction and orientation") );
194
195
196 // initialize everything
197 if ( !CreateControl(parent, id, pos, size, style, validator, name) )
198 return false;
199
200 // ensure that we have correct values for GetLabelsSize()
201 m_rangeMin = minValue;
202 m_rangeMax = maxValue;
203
204 // create the labels first, so that our DoGetBestSize() could take them
205 // into account
206 //
207 // note that we could simply create 3 wxStaticTexts here but it could
208 // result in some observable side effects at wx level (e.g. the parent of
209 // wxSlider would have 3 more children than expected) and so we prefer not
210 // to do it like this
211 if ( m_windowStyle & wxSL_LABELS )
212 {
213 m_labels = new wxSubwindows(SliderLabel_Last);
214
215 HWND hwndParent = GetHwndOf(parent);
216 for ( size_t n = 0; n < SliderLabel_Last; n++ )
217 {
218 (*m_labels)[n] = ::CreateWindow
219 (
220 wxT("STATIC"),
221 NULL,
222 WS_CHILD | WS_VISIBLE | SS_CENTER,
223 0, 0, 0, 0,
224 hwndParent,
225 (HMENU)NewControlId(),
226 wxGetInstance(),
227 NULL
228 );
229 }
230
231 m_labels->SetFont(GetFont());
232 }
233
234 // now create the main control too
235 if ( !MSWCreateControl(TRACKBAR_CLASS, wxEmptyString, pos, size) )
236 return false;
237
238 // and initialize everything
239 SetRange(minValue, maxValue);
240 SetValue(value);
241 SetPageSize((maxValue - minValue)/10);
242
243 // we need to position the labels correctly if we have them and if
244 // SetSize() hadn't been called before (when best size was determined by
245 // MSWCreateControl()) as in this case they haven't been put in place yet
246 if ( m_labels && size.x != wxDefaultCoord && size.y != wxDefaultCoord )
247 {
248 SetSize(size);
249 }
250
251 return true;
252 }
253
254 WXDWORD wxSlider::MSWGetStyle(long style, WXDWORD *exstyle) const
255 {
256 WXDWORD msStyle = wxControl::MSWGetStyle(style, exstyle);
257
258 // TBS_HORZ, TBS_RIGHT and TBS_BOTTOM are 0 but do include them for clarity
259 msStyle |= style & wxSL_VERTICAL ? TBS_VERT : TBS_HORZ;
260
261 if ( style & wxSL_BOTH )
262 {
263 // this fully specifies the style combined with TBS_VERT/HORZ above
264 msStyle |= TBS_BOTH;
265 }
266 else // choose one direction
267 {
268 if ( style & wxSL_LEFT )
269 msStyle |= TBS_LEFT;
270 else if ( style & wxSL_RIGHT )
271 msStyle |= TBS_RIGHT;
272 else if ( style & wxSL_TOP )
273 msStyle |= TBS_TOP;
274 else if ( style & wxSL_BOTTOM )
275 msStyle |= TBS_BOTTOM;
276 }
277
278 if ( style & wxSL_AUTOTICKS )
279 msStyle |= TBS_AUTOTICKS;
280 else
281 msStyle |= TBS_NOTICKS;
282
283 if ( style & wxSL_SELRANGE )
284 msStyle |= TBS_ENABLESELRANGE;
285
286 return msStyle;
287 }
288
289 wxSlider::~wxSlider()
290 {
291 delete m_labels;
292 }
293
294 // ----------------------------------------------------------------------------
295 // event handling
296 // ----------------------------------------------------------------------------
297
298 bool wxSlider::MSWOnScroll(int WXUNUSED(orientation),
299 WXWORD wParam,
300 WXWORD WXUNUSED(pos),
301 WXHWND control)
302 {
303 wxEventType scrollEvent;
304 switch ( wParam )
305 {
306 case SB_TOP:
307 scrollEvent = wxEVT_SCROLL_TOP;
308 break;
309
310 case SB_BOTTOM:
311 scrollEvent = wxEVT_SCROLL_BOTTOM;
312 break;
313
314 case SB_LINEUP:
315 scrollEvent = wxEVT_SCROLL_LINEUP;
316 break;
317
318 case SB_LINEDOWN:
319 scrollEvent = wxEVT_SCROLL_LINEDOWN;
320 break;
321
322 case SB_PAGEUP:
323 scrollEvent = wxEVT_SCROLL_PAGEUP;
324 break;
325
326 case SB_PAGEDOWN:
327 scrollEvent = wxEVT_SCROLL_PAGEDOWN;
328 break;
329
330 case SB_THUMBTRACK:
331 scrollEvent = wxEVT_SCROLL_THUMBTRACK;
332 break;
333
334 case SB_THUMBPOSITION:
335 scrollEvent = wxEVT_SCROLL_THUMBRELEASE;
336 break;
337
338 case SB_ENDSCROLL:
339 scrollEvent = wxEVT_SCROLL_ENDSCROLL;
340 break;
341
342 default:
343 // unknown scroll event?
344 return false;
345 }
346
347 int newPos = ValueInvertOrNot((int) ::SendMessage((HWND) control, TBM_GETPOS, 0, 0));
348 if ( (newPos < GetMin()) || (newPos > GetMax()) )
349 {
350 // out of range - but we did process it
351 return true;
352 }
353
354 SetValue(newPos);
355
356 wxScrollEvent event(scrollEvent, m_windowId);
357 event.SetPosition(newPos);
358 event.SetEventObject( this );
359 GetEventHandler()->ProcessEvent(event);
360
361 wxCommandEvent cevent( wxEVT_COMMAND_SLIDER_UPDATED, GetId() );
362 cevent.SetInt( newPos );
363 cevent.SetEventObject( this );
364
365 return GetEventHandler()->ProcessEvent( cevent );
366 }
367
368 void wxSlider::Command (wxCommandEvent & event)
369 {
370 SetValue (event.GetInt());
371 ProcessCommand (event);
372 }
373
374 // ----------------------------------------------------------------------------
375 // geometry stuff
376 // ----------------------------------------------------------------------------
377
378 wxRect wxSlider::GetBoundingBox() const
379 {
380 // take care not to call our own functions which would call us recursively
381 int x, y, w, h;
382 wxSliderBase::DoGetPosition(&x, &y);
383 wxSliderBase::DoGetSize(&w, &h);
384
385 wxRect rect(x, y, w, h);
386 if ( m_labels )
387 {
388 wxRect lrect = m_labels->GetBoundingBox();
389 GetParent()->ScreenToClient(&lrect.x, &lrect.y);
390 rect.Union(lrect);
391 }
392
393 return rect;
394 }
395
396 void wxSlider::DoGetSize(int *width, int *height) const
397 {
398 wxRect rect = GetBoundingBox();
399
400 if ( width )
401 *width = rect.width;
402 if ( height )
403 *height = rect.height;
404 }
405
406 void wxSlider::DoGetPosition(int *x, int *y) const
407 {
408 wxRect rect = GetBoundingBox();
409
410 if ( x )
411 *x = rect.x;
412 if ( y )
413 *y = rect.y;
414 }
415
416 int wxSlider::GetLabelsSize(int *width) const
417 {
418 int cy;
419
420 if ( width )
421 {
422 // find the max label width
423 int wLabelMin, wLabelMax;
424 GetTextExtent(Format(m_rangeMin), &wLabelMin, &cy);
425 GetTextExtent(Format(m_rangeMax), &wLabelMax, &cy);
426
427 *width = wxMax(wLabelMin, wLabelMax);
428 }
429 else
430 {
431 cy = GetCharHeight();
432 }
433
434 return EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
435 }
436
437 void wxSlider::DoMoveWindow(int x, int y, int width, int height)
438 {
439 // all complications below are because we need to position the labels,
440 // without them everything is easy
441 if ( !m_labels )
442 {
443 wxSliderBase::DoMoveWindow(x, y, width, height);
444 return;
445 }
446
447 // if our parent had prepared a defer window handle for us, use it (unless
448 // we are a top level window)
449 wxWindowMSW *parent = GetParent();
450
451 #if USE_DEFERRED_SIZING
452 HDWP hdwp = parent && !IsTopLevel() ? (HDWP)parent->m_hDWP : NULL;
453 #else
454 HDWP hdwp = 0;
455 #endif
456
457 // be careful to position the slider itself after moving the labels as
458 // otherwise our GetBoundingBox(), which is called from WM_SIZE handler,
459 // would return a wrong result and wrong size would be cached internally
460 if ( HasFlag(wxSL_VERTICAL) )
461 {
462 int wLabel;
463 int hLabel = GetLabelsSize(&wLabel);
464
465 int xLabel = HasFlag(wxSL_LEFT) ? x + width - wLabel : x;
466
467 // position all labels: min at the top, value in the middle and max at
468 // the bottom
469 wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Min],
470 xLabel, y, wLabel, hLabel);
471
472 wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Value],
473 xLabel, y + (height - hLabel)/2, wLabel, hLabel);
474
475 wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Max],
476 xLabel, y + height - hLabel, wLabel, hLabel);
477
478 // position the slider itself along the left/right edge
479 wxMoveWindowDeferred(hdwp, this, GetHwnd(),
480 HasFlag(wxSL_LEFT) ? x : x + wLabel + HGAP,
481 y + hLabel/2,
482 width - wLabel - HGAP,
483 height - hLabel);
484 }
485 else // horizontal
486 {
487 int wLabel;
488 int hLabel = GetLabelsSize(&wLabel);
489
490 int yLabel = HasFlag(wxSL_TOP) ? y + height - hLabel : y;
491
492 // position all labels: min on the left, value in the middle and max to
493 // the right
494 wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Min],
495 x, yLabel, wLabel, hLabel);
496
497 wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Value],
498 x + (width - wLabel)/2, yLabel, wLabel, hLabel);
499
500 wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Max],
501 x + width - wLabel, yLabel, wLabel, hLabel);
502
503 // position the slider itself along the top/bottom edge
504 wxMoveWindowDeferred(hdwp, this, GetHwnd(),
505 x,
506 HasFlag(wxSL_TOP) ? y : y + hLabel,
507 width,
508 height - hLabel);
509 }
510 if ( hdwp )
511 {
512 // Store the size so we can report it accurately
513 wxExtraWindowData* extraData = (wxExtraWindowData*) m_windowReserved;
514 if (!extraData)
515 {
516 extraData = new wxExtraWindowData;
517 m_windowReserved = (void*) extraData;
518 }
519 extraData->m_pos = wxPoint(x, y);
520 extraData->m_size = wxSize(width, height);
521 extraData->m_deferring = true;
522
523 // hdwp must be updated as it may have been changed
524 parent->m_hDWP = (WXHANDLE)hdwp;
525 }
526 }
527
528 wxSize wxSlider::DoGetBestSize() const
529 {
530 // these values are arbitrary
531 static const int length = 100;
532 static const int thumb = 24;
533 static const int ticks = 8;
534
535 int *width;
536 wxSize size;
537 if ( HasFlag(wxSL_VERTICAL) )
538 {
539 size.x = thumb;
540 size.y = length;
541 width = &size.x;
542
543 if ( m_labels )
544 {
545 int wLabel;
546 int hLabel = GetLabelsSize(&wLabel);
547
548 // account for the labels
549 size.x += HGAP + wLabel;
550
551 // labels are indented relative to the slider itself
552 size.y += hLabel;
553 }
554 }
555 else // horizontal
556 {
557 size.x = length;
558 size.y = thumb;
559 width = &size.y;
560
561 if ( m_labels )
562 {
563 // labels add extra height
564 size.y += GetLabelsSize();
565 }
566 }
567
568 // need extra space to show ticks
569 if ( HasFlag(wxSL_TICKS) )
570 {
571 *width += ticks;
572
573 // and maybe twice as much if we show them on both sides
574 if ( HasFlag(wxSL_BOTH) )
575 *width += ticks;
576 }
577
578 return size;
579 }
580
581 // ----------------------------------------------------------------------------
582 // slider-specific methods
583 // ----------------------------------------------------------------------------
584
585 int wxSlider::GetValue() const
586 {
587 return ValueInvertOrNot(::SendMessage(GetHwnd(), TBM_GETPOS, 0, 0));
588 }
589
590 void wxSlider::SetValue(int value)
591 {
592 ::SendMessage(GetHwnd(), TBM_SETPOS, (WPARAM)TRUE, (LPARAM)ValueInvertOrNot(value));
593
594 if ( m_labels )
595 {
596 ::SetWindowText((*m_labels)[SliderLabel_Value], Format(value));
597 }
598 }
599
600 void wxSlider::SetRange(int minValue, int maxValue)
601 {
602 m_rangeMin = minValue;
603 m_rangeMax = maxValue;
604
605 ::SendMessage(GetHwnd(), TBM_SETRANGEMIN, TRUE, m_rangeMin);
606 ::SendMessage(GetHwnd(), TBM_SETRANGEMAX, TRUE, m_rangeMax);
607
608 if ( m_labels )
609 {
610 ::SetWindowText((*m_labels)[SliderLabel_Min], Format(ValueInvertOrNot(m_rangeMin)));
611 ::SetWindowText((*m_labels)[SliderLabel_Max], Format(ValueInvertOrNot(m_rangeMax)));
612 }
613 }
614
615 void wxSlider::SetTickFreq(int n, int pos)
616 {
617 m_tickFreq = n;
618 ::SendMessage( GetHwnd(), TBM_SETTICFREQ, (WPARAM) n, (LPARAM) pos );
619 }
620
621 void wxSlider::SetPageSize(int pageSize)
622 {
623 ::SendMessage( GetHwnd(), TBM_SETPAGESIZE, (WPARAM) 0, (LPARAM) pageSize );
624 m_pageSize = pageSize;
625 }
626
627 int wxSlider::GetPageSize() const
628 {
629 return m_pageSize;
630 }
631
632 void wxSlider::ClearSel()
633 {
634 ::SendMessage(GetHwnd(), TBM_CLEARSEL, (WPARAM) TRUE, (LPARAM) 0);
635 }
636
637 void wxSlider::ClearTicks()
638 {
639 ::SendMessage(GetHwnd(), TBM_CLEARTICS, (WPARAM) TRUE, (LPARAM) 0);
640 }
641
642 void wxSlider::SetLineSize(int lineSize)
643 {
644 m_lineSize = lineSize;
645 ::SendMessage(GetHwnd(), TBM_SETLINESIZE, (WPARAM) 0, (LPARAM) lineSize);
646 }
647
648 int wxSlider::GetLineSize() const
649 {
650 return (int)::SendMessage(GetHwnd(), TBM_GETLINESIZE, 0, 0);
651 }
652
653 int wxSlider::GetSelEnd() const
654 {
655 return (int)::SendMessage(GetHwnd(), TBM_SETSELEND, 0, 0);
656 }
657
658 int wxSlider::GetSelStart() const
659 {
660 return (int)::SendMessage(GetHwnd(), TBM_GETSELSTART, 0, 0);
661 }
662
663 void wxSlider::SetSelection(int minPos, int maxPos)
664 {
665 ::SendMessage(GetHwnd(), TBM_SETSEL,
666 (WPARAM) TRUE /* redraw */,
667 (LPARAM) MAKELONG( minPos, maxPos) );
668 }
669
670 void wxSlider::SetThumbLength(int len)
671 {
672 ::SendMessage(GetHwnd(), TBM_SETTHUMBLENGTH, (WPARAM) len, (LPARAM) 0);
673 }
674
675 int wxSlider::GetThumbLength() const
676 {
677 return (int)::SendMessage( GetHwnd(), TBM_GETTHUMBLENGTH, 0, 0);
678 }
679
680 void wxSlider::SetTick(int tickPos)
681 {
682 ::SendMessage( GetHwnd(), TBM_SETTIC, (WPARAM) 0, (LPARAM) tickPos );
683 }
684
685 // ----------------------------------------------------------------------------
686 // composite control methods
687 // ----------------------------------------------------------------------------
688
689 WXHWND wxSlider::GetStaticMin() const
690 {
691 return m_labels ? (WXHWND)(*m_labels)[SliderLabel_Min] : NULL;
692 }
693
694 WXHWND wxSlider::GetStaticMax() const
695 {
696 return m_labels ? (WXHWND)(*m_labels)[SliderLabel_Max] : NULL;
697 }
698
699 WXHWND wxSlider::GetEditValue() const
700 {
701 return m_labels ? (WXHWND)(*m_labels)[SliderLabel_Value] : NULL;
702 }
703
704 WX_FORWARD_STD_METHODS_TO_SUBWINDOWS(wxSlider, wxSliderBase, m_labels)
705
706 #endif // wxUSE_SLIDER