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