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