4 * Copyright 1998, 1999 Eric Kohl
5 * Copyright 1998, 1999 Alex Priem
6 * Copyright 2002 Dimitrie O. Paun
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 * This code was audited for completeness against the documented features
25 * of Comctl32.dll version 6.0 on Sep. 12, 2002, by Dimitrie O. Paun.
27 * Unless otherwise noted, we believe this code to be complete, as per
28 * the specification mentioned above.
29 * If you discover missing features, or bugs, please note them below.
47 #include "wine/debug.h"
51 WINE_DEFAULT_DEBUG_CHANNEL(trackbar
);
81 #define TB_REFRESH_TIMER 1
82 #define TB_REFRESH_DELAY 500
84 #define TOOLTIP_OFFSET 2 /* distance from ctrl edge to tooltip */
86 #define TB_DEFAULTPAGESIZE 20
88 /* Used by TRACKBAR_Refresh to find out which parts of the control
89 need to be recalculated */
91 #define TB_THUMBPOSCHANGED 1
92 #define TB_THUMBSIZECHANGED 2
93 #define TB_THUMBCHANGED (TB_THUMBPOSCHANGED | TB_THUMBSIZECHANGED)
94 #define TB_SELECTIONCHANGED 4
95 #define TB_DRAG_MODE 8 /* we're dragging the slider */
96 #define TB_AUTO_PAGE_LEFT 16
97 #define TB_AUTO_PAGE_RIGHT 32
98 #define TB_AUTO_PAGE (TB_AUTO_PAGE_LEFT | TB_AUTO_PAGE_RIGHT)
99 #define TB_THUMB_HOT 64 /* mouse hovers above thumb */
101 /* helper defines for TRACKBAR_DrawTic */
102 #define TIC_EDGE 0x20
103 #define TIC_SELECTIONMARKMAX 0x80
104 #define TIC_SELECTIONMARKMIN 0x100
105 #define TIC_SELECTIONMARK (TIC_SELECTIONMARKMAX | TIC_SELECTIONMARKMIN)
107 static const WCHAR themeClass
[] = { 'T','r','a','c','k','b','a','r',0 };
110 notify_customdraw (const TRACKBAR_INFO
*infoPtr
, NMCUSTOMDRAW
*pnmcd
, int stage
)
112 pnmcd
->dwDrawStage
= stage
;
113 return SendMessageW (infoPtr
->hwndNotify
, WM_NOTIFY
,
114 pnmcd
->hdr
.idFrom
, (LPARAM
)pnmcd
);
117 static LRESULT
notify_hdr (const TRACKBAR_INFO
*infoPtr
, INT code
, LPNMHDR pnmh
)
121 TRACE("(code=%d)\n", code
);
123 pnmh
->hwndFrom
= infoPtr
->hwndSelf
;
124 pnmh
->idFrom
= GetWindowLongPtrW(infoPtr
->hwndSelf
, GWLP_ID
);
126 result
= SendMessageW(infoPtr
->hwndNotify
, WM_NOTIFY
, pnmh
->idFrom
, (LPARAM
)pnmh
);
128 TRACE(" <= %ld\n", result
);
133 static inline int notify (const TRACKBAR_INFO
*infoPtr
, INT code
)
136 return notify_hdr(infoPtr
, code
, &nmh
);
139 static void notify_with_scroll (const TRACKBAR_INFO
*infoPtr
, UINT code
)
141 UINT scroll
= infoPtr
->dwStyle
& TBS_VERT
? WM_VSCROLL
: WM_HSCROLL
;
145 SendMessageW (infoPtr
->hwndNotify
, scroll
, code
, (LPARAM
)infoPtr
->hwndSelf
);
148 static void TRACKBAR_RecalculateTics (TRACKBAR_INFO
*infoPtr
)
153 if (infoPtr
->uTicFreq
&& infoPtr
->lRangeMax
>= infoPtr
->lRangeMin
) {
154 nrTics
=(infoPtr
->lRangeMax
- infoPtr
->lRangeMin
)/infoPtr
->uTicFreq
;
155 /* don't add extra tic if there's no remainder */
156 if (nrTics
&& ((infoPtr
->lRangeMax
- infoPtr
->lRangeMin
) % infoPtr
->uTicFreq
== 0))
160 Free (infoPtr
->tics
);
161 infoPtr
->tics
= NULL
;
162 infoPtr
->uNumTics
= 0;
166 if (nrTics
!= infoPtr
->uNumTics
) {
167 infoPtr
->tics
=ReAlloc (infoPtr
->tics
,
168 (nrTics
+1)*sizeof (DWORD
));
169 if (!infoPtr
->tics
) {
170 infoPtr
->uNumTics
= 0;
171 notify(infoPtr
, NM_OUTOFMEMORY
);
174 infoPtr
->uNumTics
= nrTics
;
177 tic
= infoPtr
->lRangeMin
+ infoPtr
->uTicFreq
;
178 for (i
= 0; i
< nrTics
; i
++, tic
+= infoPtr
->uTicFreq
)
179 infoPtr
->tics
[i
] = tic
;
182 /* converts from physical (mouse) position to logical position
183 (in range of trackbar) */
186 TRACKBAR_ConvertPlaceToPosition (const TRACKBAR_INFO
*infoPtr
, int place
)
188 double range
, width
, pos
, offsetthumb
;
190 range
= infoPtr
->lRangeMax
- infoPtr
->lRangeMin
;
191 if (infoPtr
->dwStyle
& TBS_VERT
) {
192 offsetthumb
= (infoPtr
->rcThumb
.bottom
- infoPtr
->rcThumb
.top
)/2;
193 width
= infoPtr
->rcChannel
.bottom
- infoPtr
->rcChannel
.top
- (offsetthumb
* 2) - 1;
194 pos
= (range
*(place
- infoPtr
->rcChannel
.top
- offsetthumb
)) / width
;
196 offsetthumb
= (infoPtr
->rcThumb
.right
- infoPtr
->rcThumb
.left
)/2;
197 width
= infoPtr
->rcChannel
.right
- infoPtr
->rcChannel
.left
- (offsetthumb
* 2) - 1;
198 pos
= (range
*(place
- infoPtr
->rcChannel
.left
- offsetthumb
)) / width
;
200 pos
+= infoPtr
->lRangeMin
;
201 if (pos
> infoPtr
->lRangeMax
)
202 pos
= infoPtr
->lRangeMax
;
203 else if (pos
< infoPtr
->lRangeMin
)
204 pos
= infoPtr
->lRangeMin
;
206 TRACE("%.2f\n", pos
);
207 return (LONG
)floor(pos
+ 0.5);
211 /* return: 0> prev, 0 none, >0 next */
213 TRACKBAR_GetAutoPageDirection (const TRACKBAR_INFO
*infoPtr
, POINT clickPoint
)
217 if (infoPtr
->dwStyle
& TBS_VERT
) {
218 pageRect
.top
= infoPtr
->rcChannel
.top
;
219 pageRect
.bottom
= infoPtr
->rcChannel
.bottom
;
220 pageRect
.left
= infoPtr
->rcThumb
.left
;
221 pageRect
.right
= infoPtr
->rcThumb
.right
;
223 pageRect
.top
= infoPtr
->rcThumb
.top
;
224 pageRect
.bottom
= infoPtr
->rcThumb
.bottom
;
225 pageRect
.left
= infoPtr
->rcChannel
.left
;
226 pageRect
.right
= infoPtr
->rcChannel
.right
;
230 if (PtInRect(&pageRect
, clickPoint
))
232 int clickPlace
= (infoPtr
->dwStyle
& TBS_VERT
) ? clickPoint
.y
: clickPoint
.x
;
234 LONG clickPos
= TRACKBAR_ConvertPlaceToPosition(infoPtr
, clickPlace
);
236 return clickPos
- infoPtr
->lPos
;
243 TRACKBAR_PageDown (TRACKBAR_INFO
*infoPtr
)
245 if (infoPtr
->lPos
== infoPtr
->lRangeMax
) return;
247 infoPtr
->lPos
+= infoPtr
->lPageSize
;
248 if (infoPtr
->lPos
> infoPtr
->lRangeMax
)
249 infoPtr
->lPos
= infoPtr
->lRangeMax
;
250 notify_with_scroll (infoPtr
, TB_PAGEDOWN
);
255 TRACKBAR_PageUp (TRACKBAR_INFO
*infoPtr
)
257 if (infoPtr
->lPos
== infoPtr
->lRangeMin
) return;
259 infoPtr
->lPos
-= infoPtr
->lPageSize
;
260 if (infoPtr
->lPos
< infoPtr
->lRangeMin
)
261 infoPtr
->lPos
= infoPtr
->lRangeMin
;
262 notify_with_scroll (infoPtr
, TB_PAGEUP
);
265 static inline void TRACKBAR_LineUp(TRACKBAR_INFO
*infoPtr
)
267 if (infoPtr
->lPos
== infoPtr
->lRangeMin
) return;
268 infoPtr
->lPos
-= infoPtr
->lLineSize
;
269 if (infoPtr
->lPos
< infoPtr
->lRangeMin
)
270 infoPtr
->lPos
= infoPtr
->lRangeMin
;
271 notify_with_scroll (infoPtr
, TB_LINEUP
);
274 static inline void TRACKBAR_LineDown(TRACKBAR_INFO
*infoPtr
)
276 if (infoPtr
->lPos
== infoPtr
->lRangeMax
) return;
277 infoPtr
->lPos
+= infoPtr
->lLineSize
;
278 if (infoPtr
->lPos
> infoPtr
->lRangeMax
)
279 infoPtr
->lPos
= infoPtr
->lRangeMax
;
280 notify_with_scroll (infoPtr
, TB_LINEDOWN
);
284 TRACKBAR_CalcChannel (TRACKBAR_INFO
*infoPtr
)
286 INT cyChannel
, offsetthumb
, offsetedge
;
287 RECT lpRect
, *channel
= & infoPtr
->rcChannel
;
289 GetClientRect (infoPtr
->hwndSelf
, &lpRect
);
291 offsetthumb
= infoPtr
->uThumbLen
/ 4;
292 offsetedge
= offsetthumb
+ 3;
293 cyChannel
= (infoPtr
->dwStyle
& TBS_ENABLESELRANGE
) ? offsetthumb
*3 : 4;
294 if (infoPtr
->dwStyle
& TBS_VERT
) {
295 channel
->top
= lpRect
.top
+ offsetedge
;
296 channel
->bottom
= lpRect
.bottom
- offsetedge
;
297 if (infoPtr
->dwStyle
& TBS_ENABLESELRANGE
)
298 channel
->left
= lpRect
.left
+ ((infoPtr
->uThumbLen
- cyChannel
+ 2) / 2);
300 channel
->left
= lpRect
.left
+ (infoPtr
->uThumbLen
/ 2) - 1;
301 if (infoPtr
->dwStyle
& TBS_BOTH
) {
302 if (infoPtr
->dwStyle
& TBS_NOTICKS
)
307 else if (infoPtr
->dwStyle
& TBS_TOP
) {
308 if (infoPtr
->dwStyle
& TBS_NOTICKS
)
313 channel
->right
= channel
->left
+ cyChannel
;
315 channel
->left
= lpRect
.left
+ offsetedge
;
316 channel
->right
= lpRect
.right
- offsetedge
;
317 if (infoPtr
->dwStyle
& TBS_ENABLESELRANGE
)
318 channel
->top
= lpRect
.top
+ ((infoPtr
->uThumbLen
- cyChannel
+ 2) / 2);
320 channel
->top
= lpRect
.top
+ (infoPtr
->uThumbLen
/ 2) - 1;
321 if (infoPtr
->dwStyle
& TBS_BOTH
) {
322 if (infoPtr
->dwStyle
& TBS_NOTICKS
)
327 else if (infoPtr
->dwStyle
& TBS_TOP
) {
328 if (infoPtr
->dwStyle
& TBS_NOTICKS
)
333 channel
->bottom
= channel
->top
+ cyChannel
;
338 TRACKBAR_CalcThumb (const TRACKBAR_INFO
*infoPtr
, LONG lPos
, RECT
*thumb
)
340 int range
, width
, height
, thumbwidth
;
343 range
= infoPtr
->lRangeMax
- infoPtr
->lRangeMin
;
344 thumbwidth
= (infoPtr
->uThumbLen
/ 2) | 1;
346 if (!range
) range
= 1;
348 GetClientRect(infoPtr
->hwndSelf
, &lpRect
);
349 if (infoPtr
->dwStyle
& TBS_VERT
)
351 height
= infoPtr
->rcChannel
.bottom
- infoPtr
->rcChannel
.top
- thumbwidth
;
353 if ((infoPtr
->dwStyle
& (TBS_BOTH
| TBS_LEFT
)) && !(infoPtr
->dwStyle
& TBS_NOTICKS
))
357 thumb
->right
= thumb
->left
+ infoPtr
->uThumbLen
;
358 thumb
->top
= infoPtr
->rcChannel
.top
+
359 (height
*(lPos
- infoPtr
->lRangeMin
))/range
;
360 thumb
->bottom
= thumb
->top
+ thumbwidth
;
364 width
= infoPtr
->rcChannel
.right
- infoPtr
->rcChannel
.left
- thumbwidth
;
366 thumb
->left
= infoPtr
->rcChannel
.left
+
367 (width
*(lPos
- infoPtr
->lRangeMin
))/range
;
368 thumb
->right
= thumb
->left
+ thumbwidth
;
369 if ((infoPtr
->dwStyle
& (TBS_BOTH
| TBS_TOP
)) && !(infoPtr
->dwStyle
& TBS_NOTICKS
))
373 thumb
->bottom
= thumb
->top
+ infoPtr
->uThumbLen
;
378 TRACKBAR_UpdateThumb (TRACKBAR_INFO
*infoPtr
)
380 TRACKBAR_CalcThumb(infoPtr
, infoPtr
->lPos
, &infoPtr
->rcThumb
);
384 TRACKBAR_InvalidateAll (const TRACKBAR_INFO
*infoPtr
)
386 InvalidateRect(infoPtr
->hwndSelf
, NULL
, FALSE
);
390 TRACKBAR_InvalidateThumb (const TRACKBAR_INFO
*infoPtr
, LONG thumbPos
)
394 TRACKBAR_CalcThumb(infoPtr
, thumbPos
, &rcThumb
);
395 InflateRect(&rcThumb
, 1, 1);
396 InvalidateRect(infoPtr
->hwndSelf
, &rcThumb
, FALSE
);
400 TRACKBAR_InvalidateThumbMove (const TRACKBAR_INFO
*infoPtr
, LONG oldPos
, LONG newPos
)
402 TRACKBAR_InvalidateThumb (infoPtr
, oldPos
);
403 if (newPos
!= oldPos
)
404 TRACKBAR_InvalidateThumb (infoPtr
, newPos
);
408 TRACKBAR_HasSelection (const TRACKBAR_INFO
*infoPtr
)
410 return infoPtr
->lSelMin
!= infoPtr
->lSelMax
;
414 TRACKBAR_CalcSelection (TRACKBAR_INFO
*infoPtr
)
416 RECT
*selection
= &infoPtr
->rcSelection
;
417 int range
= infoPtr
->lRangeMax
- infoPtr
->lRangeMin
;
418 int offsetthumb
, height
, width
;
421 SetRectEmpty (selection
);
423 if (infoPtr
->dwStyle
& TBS_VERT
) {
424 offsetthumb
= (infoPtr
->rcThumb
.bottom
- infoPtr
->rcThumb
.top
)/2;
425 height
= infoPtr
->rcChannel
.bottom
- infoPtr
->rcChannel
.top
- offsetthumb
*2;
426 selection
->top
= infoPtr
->rcChannel
.top
+ offsetthumb
+
427 (height
*infoPtr
->lSelMin
)/range
;
428 selection
->bottom
= infoPtr
->rcChannel
.top
+ offsetthumb
+
429 (height
*infoPtr
->lSelMax
)/range
;
430 selection
->left
= infoPtr
->rcChannel
.left
+ 3;
431 selection
->right
= infoPtr
->rcChannel
.right
- 3;
433 offsetthumb
= (infoPtr
->rcThumb
.right
- infoPtr
->rcThumb
.left
)/2;
434 width
= infoPtr
->rcChannel
.right
- infoPtr
->rcChannel
.left
- offsetthumb
*2;
435 selection
->left
= infoPtr
->rcChannel
.left
+ offsetthumb
+
436 (width
*infoPtr
->lSelMin
)/range
;
437 selection
->right
= infoPtr
->rcChannel
.left
+ offsetthumb
+
438 (width
*infoPtr
->lSelMax
)/range
;
439 selection
->top
= infoPtr
->rcChannel
.top
+ 3;
440 selection
->bottom
= infoPtr
->rcChannel
.bottom
- 3;
444 TRACE("selection[%s]\n", wine_dbgstr_rect(selection
));
448 TRACKBAR_AutoPage (TRACKBAR_INFO
*infoPtr
, POINT clickPoint
)
450 LONG dir
= TRACKBAR_GetAutoPageDirection(infoPtr
, clickPoint
);
451 LONG prevPos
= infoPtr
->lPos
;
453 TRACE("clickPoint=%s, dir=%d\n", wine_dbgstr_point(&clickPoint
), dir
);
455 if (dir
> 0 && (infoPtr
->flags
& TB_AUTO_PAGE_RIGHT
))
456 TRACKBAR_PageDown(infoPtr
);
457 else if (dir
< 0 && (infoPtr
->flags
& TB_AUTO_PAGE_LEFT
))
458 TRACKBAR_PageUp(infoPtr
);
461 TRACKBAR_UpdateThumb (infoPtr
);
462 TRACKBAR_InvalidateThumbMove (infoPtr
, prevPos
, infoPtr
->lPos
);
467 /* Trackbar drawing code. I like my spaghetti done milanese. */
470 TRACKBAR_DrawChannel (const TRACKBAR_INFO
*infoPtr
, HDC hdc
)
472 RECT rcChannel
= infoPtr
->rcChannel
;
473 HTHEME theme
= GetWindowTheme (infoPtr
->hwndSelf
);
477 DrawThemeBackground (theme
, hdc
,
478 (infoPtr
->dwStyle
& TBS_VERT
) ?
479 TKP_TRACKVERT
: TKP_TRACK
, TKS_NORMAL
, &rcChannel
, 0);
483 DrawEdge (hdc
, &rcChannel
, EDGE_SUNKEN
, BF_RECT
| BF_ADJUST
);
484 if (infoPtr
->dwStyle
& TBS_ENABLESELRANGE
) { /* fill the channel */
485 FillRect (hdc
, &rcChannel
, GetStockObject(WHITE_BRUSH
));
486 if (TRACKBAR_HasSelection(infoPtr
))
487 FillRect (hdc
, &infoPtr
->rcSelection
, GetSysColorBrush(COLOR_HIGHLIGHT
));
493 TRACKBAR_DrawOneTic (const TRACKBAR_INFO
*infoPtr
, HDC hdc
, LONG ticPos
, int flags
)
495 int x
, y
, ox
, oy
, range
, side
, indent
= 0, len
= 3;
499 if (flags
& TBS_VERT
) {
500 offsetthumb
= (infoPtr
->rcThumb
.bottom
- infoPtr
->rcThumb
.top
)/2;
501 SetRect(&rcTics
, infoPtr
->rcThumb
.left
- 2, infoPtr
->rcChannel
.top
+ offsetthumb
,
502 infoPtr
->rcThumb
.right
+ 2, infoPtr
->rcChannel
.bottom
- offsetthumb
- 1);
504 offsetthumb
= (infoPtr
->rcThumb
.right
- infoPtr
->rcThumb
.left
)/2;
505 SetRect(&rcTics
, infoPtr
->rcChannel
.left
+ offsetthumb
, infoPtr
->rcThumb
.top
- 2,
506 infoPtr
->rcChannel
.right
- offsetthumb
- 1, infoPtr
->rcThumb
.bottom
+ 2);
509 if (flags
& (TBS_TOP
| TBS_LEFT
)) {
519 range
= infoPtr
->lRangeMax
- infoPtr
->lRangeMin
;
521 range
= 1; /* to avoid division by zero */
523 if (flags
& TIC_SELECTIONMARK
) {
524 indent
= (flags
& TIC_SELECTIONMARKMIN
) ? -1 : 1;
525 } else if (flags
& TIC_EDGE
) {
529 if (flags
& TBS_VERT
) {
530 int height
= rcTics
.bottom
- rcTics
.top
;
531 y
= rcTics
.top
+ (height
*(ticPos
- infoPtr
->lRangeMin
))/range
;
533 int width
= rcTics
.right
- rcTics
.left
;
534 x
= rcTics
.left
+ (width
*(ticPos
- infoPtr
->lRangeMin
))/range
;
539 MoveToEx(hdc
, x
, y
, 0);
540 if (flags
& TBS_VERT
) x
+= len
* side
;
541 else y
+= len
* side
;
544 if (flags
& TIC_SELECTIONMARK
) {
545 if (flags
& TBS_VERT
) {
550 MoveToEx(hdc
, x
, y
, 0);
551 if (flags
& TBS_VERT
) {
564 TRACKBAR_DrawTic (const TRACKBAR_INFO
*infoPtr
, HDC hdc
, LONG ticPos
, int flags
)
566 if ((flags
& (TBS_LEFT
| TBS_TOP
)) || (flags
& TBS_BOTH
))
567 TRACKBAR_DrawOneTic (infoPtr
, hdc
, ticPos
, flags
| TBS_LEFT
);
569 if (!(flags
& (TBS_LEFT
| TBS_TOP
)) || (flags
& TBS_BOTH
))
570 TRACKBAR_DrawOneTic (infoPtr
, hdc
, ticPos
, flags
& ~TBS_LEFT
);
574 TRACKBAR_DrawTics (const TRACKBAR_INFO
*infoPtr
, HDC hdc
)
577 int ticFlags
= infoPtr
->dwStyle
& 0x0f;
578 LOGPEN ticPen
= { PS_SOLID
, {1, 0}, GetSysColor (COLOR_3DDKSHADOW
) };
579 HPEN hOldPen
, hTicPen
;
580 HTHEME theme
= GetWindowTheme (infoPtr
->hwndSelf
);
584 int part
= (infoPtr
->dwStyle
& TBS_VERT
) ? TKP_TICSVERT
: TKP_TICS
;
585 GetThemeColor (theme
, part
, TSS_NORMAL
, TMT_COLOR
, &ticPen
.lopnColor
);
587 /* create the pen to draw the tics with */
588 hTicPen
= CreatePenIndirect(&ticPen
);
589 hOldPen
= hTicPen
? SelectObject(hdc
, hTicPen
) : 0;
591 /* actually draw the tics */
592 for (i
=0; i
<infoPtr
->uNumTics
; i
++)
593 TRACKBAR_DrawTic (infoPtr
, hdc
, infoPtr
->tics
[i
], ticFlags
);
595 TRACKBAR_DrawTic (infoPtr
, hdc
, infoPtr
->lRangeMin
, ticFlags
| TIC_EDGE
);
596 TRACKBAR_DrawTic (infoPtr
, hdc
, infoPtr
->lRangeMax
, ticFlags
| TIC_EDGE
);
598 if ((infoPtr
->dwStyle
& TBS_ENABLESELRANGE
) && TRACKBAR_HasSelection(infoPtr
)) {
599 TRACKBAR_DrawTic (infoPtr
, hdc
, infoPtr
->lSelMin
,
600 ticFlags
| TIC_SELECTIONMARKMIN
);
601 TRACKBAR_DrawTic (infoPtr
, hdc
, infoPtr
->lSelMax
,
602 ticFlags
| TIC_SELECTIONMARKMAX
);
605 /* clean up the pen, if we created one */
607 SelectObject(hdc
, hOldPen
);
608 DeleteObject(hTicPen
);
613 TRACKBAR_FillThumb (const TRACKBAR_INFO
*infoPtr
, HDC hdc
, HBRUSH hbrush
)
615 const RECT
*thumb
= &infoPtr
->rcThumb
;
620 if (infoPtr
->dwStyle
& TBS_BOTH
)
622 FillRect(hdc
, thumb
, hbrush
);
626 if (infoPtr
->dwStyle
& TBS_VERT
)
628 PointDepth
= (thumb
->bottom
- thumb
->top
) / 2;
629 if (infoPtr
->dwStyle
& TBS_LEFT
)
631 points
[0].x
= thumb
->right
-1;
632 points
[0].y
= thumb
->top
;
633 points
[1].x
= thumb
->right
-1;
634 points
[1].y
= thumb
->bottom
-1;
635 points
[2].x
= thumb
->left
+ PointDepth
;
636 points
[2].y
= thumb
->bottom
-1;
637 points
[3].x
= thumb
->left
;
638 points
[3].y
= thumb
->top
+ PointDepth
;
639 points
[4].x
= thumb
->left
+ PointDepth
;
640 points
[4].y
= thumb
->top
;
641 points
[5].x
= points
[0].x
;
642 points
[5].y
= points
[0].y
;
646 points
[0].x
= thumb
->right
;
647 points
[0].y
= thumb
->top
+ PointDepth
;
648 points
[1].x
= thumb
->right
- PointDepth
;
649 points
[1].y
= thumb
->bottom
-1;
650 points
[2].x
= thumb
->left
;
651 points
[2].y
= thumb
->bottom
-1;
652 points
[3].x
= thumb
->left
;
653 points
[3].y
= thumb
->top
;
654 points
[4].x
= thumb
->right
- PointDepth
;
655 points
[4].y
= thumb
->top
;
656 points
[5].x
= points
[0].x
;
657 points
[5].y
= points
[0].y
;
662 PointDepth
= (thumb
->right
- thumb
->left
) / 2;
663 if (infoPtr
->dwStyle
& TBS_TOP
)
665 points
[0].x
= thumb
->left
+ PointDepth
;
666 points
[0].y
= thumb
->top
+1;
667 points
[1].x
= thumb
->right
-1;
668 points
[1].y
= thumb
->top
+ PointDepth
+ 1;
669 points
[2].x
= thumb
->right
-1;
670 points
[2].y
= thumb
->bottom
-1;
671 points
[3].x
= thumb
->left
;
672 points
[3].y
= thumb
->bottom
-1;
673 points
[4].x
= thumb
->left
;
674 points
[4].y
= thumb
->top
+ PointDepth
+ 1;
675 points
[5].x
= points
[0].x
;
676 points
[5].y
= points
[0].y
;
680 points
[0].x
= thumb
->right
-1;
681 points
[0].y
= thumb
->top
;
682 points
[1].x
= thumb
->right
-1;
683 points
[1].y
= thumb
->bottom
- PointDepth
- 1;
684 points
[2].x
= thumb
->left
+ PointDepth
;
685 points
[2].y
= thumb
->bottom
-1;
686 points
[3].x
= thumb
->left
;
687 points
[3].y
= thumb
->bottom
- PointDepth
- 1;
688 points
[4].x
= thumb
->left
;
689 points
[4].y
= thumb
->top
;
690 points
[5].x
= points
[0].x
;
691 points
[5].y
= points
[0].y
;
695 oldbr
= SelectObject(hdc
, hbrush
);
696 SetPolyFillMode(hdc
, WINDING
);
697 Polygon(hdc
, points
, sizeof(points
) / sizeof(points
[0]));
698 SelectObject(hdc
, oldbr
);
704 TRACKBAR_DrawThumb (TRACKBAR_INFO
*infoPtr
, HDC hdc
)
706 HTHEME theme
= GetWindowTheme (infoPtr
->hwndSelf
);
714 if (infoPtr
->dwStyle
& TBS_BOTH
)
715 partId
= (infoPtr
->dwStyle
& TBS_VERT
) ? TKP_THUMBVERT
: TKP_THUMB
;
716 else if (infoPtr
->dwStyle
& TBS_LEFT
)
717 partId
= (infoPtr
->dwStyle
& TBS_VERT
) ? TKP_THUMBLEFT
: TKP_THUMBTOP
;
719 partId
= (infoPtr
->dwStyle
& TBS_VERT
) ? TKP_THUMBRIGHT
: TKP_THUMBBOTTOM
;
721 if (infoPtr
->dwStyle
& WS_DISABLED
)
722 stateId
= TUS_DISABLED
;
723 else if (infoPtr
->flags
& TB_DRAG_MODE
)
724 stateId
= TUS_PRESSED
;
725 else if (infoPtr
->flags
& TB_THUMB_HOT
)
728 stateId
= TUS_NORMAL
;
730 DrawThemeBackground (theme
, hdc
, partId
, stateId
, &infoPtr
->rcThumb
, NULL
);
735 if (infoPtr
->dwStyle
& WS_DISABLED
|| infoPtr
->flags
& TB_DRAG_MODE
)
737 if (comctl32_color
.clr3dHilight
== comctl32_color
.clrWindow
)
738 brush
= COMCTL32_hPattern55AABrush
;
740 brush
= GetSysColorBrush(COLOR_SCROLLBAR
);
742 SetTextColor(hdc
, comctl32_color
.clr3dFace
);
743 SetBkColor(hdc
, comctl32_color
.clr3dHilight
);
746 brush
= GetSysColorBrush(COLOR_BTNFACE
);
748 PointDepth
= TRACKBAR_FillThumb(infoPtr
, hdc
, brush
);
750 if (infoPtr
->dwStyle
& TBS_BOTH
)
752 DrawEdge(hdc
, &infoPtr
->rcThumb
, EDGE_RAISED
, BF_RECT
| BF_SOFT
);
757 RECT thumb
= infoPtr
->rcThumb
;
759 if (infoPtr
->dwStyle
& TBS_VERT
)
761 if (infoPtr
->dwStyle
& TBS_LEFT
)
763 /* rectangular part */
764 thumb
.left
+= PointDepth
;
765 DrawEdge(hdc
, &thumb
, EDGE_RAISED
, BF_TOP
| BF_RIGHT
| BF_BOTTOM
| BF_SOFT
);
768 thumb
.left
-= PointDepth
;
769 thumb
.right
= thumb
.left
+ PointDepth
;
770 thumb
.bottom
= infoPtr
->rcThumb
.top
+ PointDepth
+ 1;
771 thumb
.top
= infoPtr
->rcThumb
.top
;
772 DrawEdge(hdc
, &thumb
, EDGE_RAISED
, BF_DIAGONAL_ENDTOPRIGHT
| BF_SOFT
);
775 thumb
.top
+= PointDepth
;
776 thumb
.bottom
+= PointDepth
;
777 DrawEdge(hdc
, &thumb
, EDGE_SUNKEN
, BF_DIAGONAL_ENDTOPLEFT
| BF_SOFT
);
782 /* rectangular part */
783 thumb
.right
-= PointDepth
;
784 DrawEdge(hdc
, &thumb
, EDGE_RAISED
, BF_TOP
| BF_LEFT
| BF_BOTTOM
| BF_SOFT
);
787 thumb
.left
= thumb
.right
;
788 thumb
.right
+= PointDepth
+ 1;
789 thumb
.bottom
= infoPtr
->rcThumb
.top
+ PointDepth
+ 1;
790 thumb
.top
= infoPtr
->rcThumb
.top
;
791 DrawEdge(hdc
, &thumb
, EDGE_RAISED
, BF_DIAGONAL_ENDTOPLEFT
| BF_SOFT
);
794 thumb
.top
+= PointDepth
;
795 thumb
.bottom
+= PointDepth
;
796 DrawEdge(hdc
, &thumb
, EDGE_RAISED
, BF_DIAGONAL_ENDBOTTOMLEFT
| BF_SOFT
);
801 if (infoPtr
->dwStyle
& TBS_TOP
)
803 /* rectangular part */
804 thumb
.top
+= PointDepth
;
805 DrawEdge(hdc
, &thumb
, EDGE_RAISED
, BF_LEFT
| BF_BOTTOM
| BF_RIGHT
| BF_SOFT
);
808 thumb
.left
= infoPtr
->rcThumb
.left
;
809 thumb
.right
= thumb
.left
+ PointDepth
;
810 thumb
.bottom
= infoPtr
->rcThumb
.top
+ PointDepth
+ 1;
811 thumb
.top
-= PointDepth
;
812 DrawEdge(hdc
, &thumb
, EDGE_RAISED
, BF_DIAGONAL_ENDTOPRIGHT
| BF_SOFT
);
815 thumb
.left
+= PointDepth
;
816 thumb
.right
+= PointDepth
;
817 DrawEdge(hdc
, &thumb
, EDGE_RAISED
, BF_DIAGONAL_ENDBOTTOMRIGHT
| BF_SOFT
);
821 /* rectangular part */
822 thumb
.bottom
-= PointDepth
;
823 DrawEdge(hdc
, &thumb
, EDGE_RAISED
, BF_LEFT
| BF_TOP
| BF_RIGHT
| BF_SOFT
);
826 thumb
.left
= infoPtr
->rcThumb
.left
;
827 thumb
.right
= thumb
.left
+ PointDepth
;
828 thumb
.top
= infoPtr
->rcThumb
.bottom
- PointDepth
- 1;
829 thumb
.bottom
+= PointDepth
;
830 DrawEdge(hdc
, &thumb
, EDGE_RAISED
, BF_DIAGONAL_ENDTOPLEFT
| BF_SOFT
);
833 thumb
.left
+= PointDepth
;
834 thumb
.right
+= PointDepth
;
835 DrawEdge(hdc
, &thumb
, EDGE_RAISED
, BF_DIAGONAL_ENDBOTTOMLEFT
| BF_SOFT
);
843 TRACKBAR_ActivateToolTip (const TRACKBAR_INFO
*infoPtr
, BOOL fShow
)
847 if (!infoPtr
->hwndToolTip
) return;
849 ZeroMemory(&ti
, sizeof(ti
));
850 ti
.cbSize
= sizeof(ti
);
851 ti
.hwnd
= infoPtr
->hwndSelf
;
853 SendMessageW (infoPtr
->hwndToolTip
, TTM_TRACKACTIVATE
, fShow
, (LPARAM
)&ti
);
858 TRACKBAR_UpdateToolTip (const TRACKBAR_INFO
*infoPtr
)
861 static const WCHAR fmt
[] = { '%', 'l', 'd', 0 };
867 if (!infoPtr
->hwndToolTip
) return;
869 ZeroMemory(&ti
, sizeof(ti
));
870 ti
.cbSize
= sizeof(ti
);
871 ti
.hwnd
= infoPtr
->hwndSelf
;
872 ti
.uFlags
= TTF_IDISHWND
| TTF_TRACK
| TTF_ABSOLUTE
;
874 wsprintfW (buf
, fmt
, infoPtr
->lPos
);
876 SendMessageW (infoPtr
->hwndToolTip
, TTM_UPDATETIPTEXTW
, 0, (LPARAM
)&ti
);
878 GetClientRect (infoPtr
->hwndSelf
, &rcClient
);
879 size
= SendMessageW (infoPtr
->hwndToolTip
, TTM_GETBUBBLESIZE
, 0, (LPARAM
)&ti
);
880 if (infoPtr
->dwStyle
& TBS_VERT
) {
881 if (infoPtr
->fLocation
== TBTS_LEFT
)
882 pt
.x
= 0 - LOWORD(size
) - TOOLTIP_OFFSET
;
884 pt
.x
= rcClient
.right
+ TOOLTIP_OFFSET
;
885 pt
.y
= (infoPtr
->rcThumb
.top
+ infoPtr
->rcThumb
.bottom
- HIWORD(size
))/2;
887 if (infoPtr
->fLocation
== TBTS_TOP
)
888 pt
.y
= 0 - HIWORD(size
) - TOOLTIP_OFFSET
;
890 pt
.y
= rcClient
.bottom
+ TOOLTIP_OFFSET
;
891 pt
.x
= (infoPtr
->rcThumb
.left
+ infoPtr
->rcThumb
.right
- LOWORD(size
))/2;
893 ClientToScreen(infoPtr
->hwndSelf
, &pt
);
895 SendMessageW (infoPtr
->hwndToolTip
, TTM_TRACKPOSITION
,
896 0, MAKELPARAM(pt
.x
, pt
.y
));
901 TRACKBAR_Refresh (TRACKBAR_INFO
*infoPtr
, HDC hdcDst
)
905 HBITMAP hOldBmp
= 0, hOffScreenBmp
= 0;
909 if (infoPtr
->flags
& TB_THUMBCHANGED
) {
910 TRACKBAR_UpdateThumb (infoPtr
);
911 if (infoPtr
->flags
& TB_THUMBSIZECHANGED
)
912 TRACKBAR_CalcChannel (infoPtr
);
914 if (infoPtr
->flags
& TB_SELECTIONCHANGED
)
915 TRACKBAR_CalcSelection (infoPtr
);
917 if (infoPtr
->flags
& TB_DRAG_MODE
)
918 TRACKBAR_UpdateToolTip (infoPtr
);
920 infoPtr
->flags
&= ~ (TB_THUMBCHANGED
| TB_SELECTIONCHANGED
);
922 GetClientRect (infoPtr
->hwndSelf
, &rcClient
);
924 /* try to render offscreen, if we fail, carrry onscreen */
925 hdc
= CreateCompatibleDC(hdcDst
);
927 hOffScreenBmp
= CreateCompatibleBitmap(hdcDst
, rcClient
.right
, rcClient
.bottom
);
929 hOldBmp
= SelectObject(hdc
, hOffScreenBmp
);
938 ZeroMemory(&nmcd
, sizeof(nmcd
));
939 nmcd
.hdr
.hwndFrom
= infoPtr
->hwndSelf
;
940 nmcd
.hdr
.idFrom
= GetWindowLongPtrW (infoPtr
->hwndSelf
, GWLP_ID
);
941 nmcd
.hdr
.code
= NM_CUSTOMDRAW
;
944 /* start the paint cycle */
946 gcdrf
= notify_customdraw(infoPtr
, &nmcd
, CDDS_PREPAINT
);
947 if (gcdrf
& CDRF_SKIPDEFAULT
) goto cleanup
;
949 /* Erase background */
950 if (gcdrf
== CDRF_DODEFAULT
||
951 notify_customdraw(infoPtr
, &nmcd
, CDDS_PREERASE
) != CDRF_SKIPDEFAULT
) {
952 if (GetWindowTheme (infoPtr
->hwndSelf
)) {
953 DrawThemeParentBackground (infoPtr
->hwndSelf
, hdc
, 0);
956 HBRUSH brush
= (HBRUSH
)SendMessageW(infoPtr
->hwndNotify
, WM_CTLCOLORSTATIC
,
957 (WPARAM
)hdc
, (LPARAM
)infoPtr
->hwndSelf
);
958 FillRect (hdc
, &rcClient
, brush
? brush
: GetSysColorBrush(COLOR_BTNFACE
));
960 if (gcdrf
!= CDRF_DODEFAULT
)
961 notify_customdraw(infoPtr
, &nmcd
, CDDS_POSTERASE
);
965 if (gcdrf
& CDRF_NOTIFYITEMDRAW
) {
966 nmcd
.dwItemSpec
= TBCD_CHANNEL
;
967 nmcd
.uItemState
= CDIS_DEFAULT
;
968 nmcd
.rc
= infoPtr
->rcChannel
;
969 icdrf
= notify_customdraw(infoPtr
, &nmcd
, CDDS_ITEMPREPAINT
);
970 } else icdrf
= CDRF_DODEFAULT
;
971 if ( !(icdrf
& CDRF_SKIPDEFAULT
) ) {
972 TRACKBAR_DrawChannel (infoPtr
, hdc
);
973 if (icdrf
& CDRF_NOTIFYPOSTPAINT
)
974 notify_customdraw(infoPtr
, &nmcd
, CDDS_ITEMPOSTPAINT
);
979 if (!(infoPtr
->dwStyle
& TBS_NOTICKS
)) {
980 if (gcdrf
& CDRF_NOTIFYITEMDRAW
) {
981 nmcd
.dwItemSpec
= TBCD_TICS
;
982 nmcd
.uItemState
= CDIS_DEFAULT
;
984 icdrf
= notify_customdraw(infoPtr
, &nmcd
, CDDS_ITEMPREPAINT
);
985 } else icdrf
= CDRF_DODEFAULT
;
986 if ( !(icdrf
& CDRF_SKIPDEFAULT
) ) {
987 TRACKBAR_DrawTics (infoPtr
, hdc
);
988 if (icdrf
& CDRF_NOTIFYPOSTPAINT
)
989 notify_customdraw(infoPtr
, &nmcd
, CDDS_ITEMPOSTPAINT
);
994 if (!(infoPtr
->dwStyle
& TBS_NOTHUMB
)) {
995 if (gcdrf
& CDRF_NOTIFYITEMDRAW
) {
996 nmcd
.dwItemSpec
= TBCD_THUMB
;
997 nmcd
.uItemState
= infoPtr
->flags
& TB_DRAG_MODE
? CDIS_HOT
: CDIS_DEFAULT
;
998 nmcd
.rc
= infoPtr
->rcThumb
;
999 icdrf
= notify_customdraw(infoPtr
, &nmcd
, CDDS_ITEMPREPAINT
);
1000 } else icdrf
= CDRF_DODEFAULT
;
1001 if ( !(icdrf
& CDRF_SKIPDEFAULT
) ) {
1002 TRACKBAR_DrawThumb(infoPtr
, hdc
);
1003 if (icdrf
& CDRF_NOTIFYPOSTPAINT
)
1004 notify_customdraw(infoPtr
, &nmcd
, CDDS_ITEMPOSTPAINT
);
1008 /* draw focus rectangle */
1009 if (infoPtr
->bFocussed
) {
1010 DrawFocusRect(hdc
, &rcClient
);
1013 /* finish up the painting */
1014 if (gcdrf
& CDRF_NOTIFYPOSTPAINT
)
1015 notify_customdraw(infoPtr
, &nmcd
, CDDS_POSTPAINT
);
1018 /* cleanup, if we rendered offscreen */
1019 if (hdc
!= hdcDst
) {
1020 BitBlt(hdcDst
, 0, 0, rcClient
.right
, rcClient
.bottom
, hdc
, 0, 0, SRCCOPY
);
1021 SelectObject(hdc
, hOldBmp
);
1022 DeleteObject(hOffScreenBmp
);
1029 TRACKBAR_AlignBuddies (const TRACKBAR_INFO
*infoPtr
)
1031 HWND hwndParent
= GetParent (infoPtr
->hwndSelf
);
1032 RECT rcSelf
, rcBuddy
;
1035 GetWindowRect (infoPtr
->hwndSelf
, &rcSelf
);
1036 MapWindowPoints (HWND_DESKTOP
, hwndParent
, (LPPOINT
)&rcSelf
, 2);
1038 /* align buddy left or above */
1039 if (infoPtr
->hwndBuddyLA
) {
1040 GetWindowRect (infoPtr
->hwndBuddyLA
, &rcBuddy
);
1041 MapWindowPoints (HWND_DESKTOP
, hwndParent
, (LPPOINT
)&rcBuddy
, 2);
1043 if (infoPtr
->dwStyle
& TBS_VERT
) {
1044 x
= (infoPtr
->rcChannel
.right
+ infoPtr
->rcChannel
.left
) / 2 -
1045 (rcBuddy
.right
- rcBuddy
.left
) / 2 + rcSelf
.left
;
1046 y
= rcSelf
.top
- (rcBuddy
.bottom
- rcBuddy
.top
);
1049 x
= rcSelf
.left
- (rcBuddy
.right
- rcBuddy
.left
);
1050 y
= (infoPtr
->rcChannel
.bottom
+ infoPtr
->rcChannel
.top
) / 2 -
1051 (rcBuddy
.bottom
- rcBuddy
.top
) / 2 + rcSelf
.top
;
1054 SetWindowPos (infoPtr
->hwndBuddyLA
, 0, x
, y
, 0, 0,
1055 SWP_NOZORDER
| SWP_NOSIZE
);
1059 /* align buddy right or below */
1060 if (infoPtr
->hwndBuddyRB
) {
1061 GetWindowRect (infoPtr
->hwndBuddyRB
, &rcBuddy
);
1062 MapWindowPoints (HWND_DESKTOP
, hwndParent
, (LPPOINT
)&rcBuddy
, 2);
1064 if (infoPtr
->dwStyle
& TBS_VERT
) {
1065 x
= (infoPtr
->rcChannel
.right
+ infoPtr
->rcChannel
.left
) / 2 -
1066 (rcBuddy
.right
- rcBuddy
.left
) / 2 + rcSelf
.left
;
1071 y
= (infoPtr
->rcChannel
.bottom
+ infoPtr
->rcChannel
.top
) / 2 -
1072 (rcBuddy
.bottom
- rcBuddy
.top
) / 2 + rcSelf
.top
;
1074 SetWindowPos (infoPtr
->hwndBuddyRB
, 0, x
, y
, 0, 0,
1075 SWP_NOZORDER
| SWP_NOSIZE
);
1081 TRACKBAR_ClearSel (TRACKBAR_INFO
*infoPtr
, BOOL fRedraw
)
1083 infoPtr
->lSelMin
= 0;
1084 infoPtr
->lSelMax
= 0;
1085 infoPtr
->flags
|= TB_SELECTIONCHANGED
;
1087 if (fRedraw
) TRACKBAR_InvalidateAll(infoPtr
);
1094 TRACKBAR_ClearTics (TRACKBAR_INFO
*infoPtr
, BOOL fRedraw
)
1096 if (infoPtr
->tics
) {
1097 Free (infoPtr
->tics
);
1098 infoPtr
->tics
= NULL
;
1099 infoPtr
->uNumTics
= 0;
1102 if (fRedraw
) TRACKBAR_InvalidateAll(infoPtr
);
1108 static inline LRESULT
1109 TRACKBAR_GetChannelRect (const TRACKBAR_INFO
*infoPtr
, LPRECT lprc
)
1111 if (lprc
== NULL
) return 0;
1113 lprc
->left
= infoPtr
->rcChannel
.left
;
1114 lprc
->right
= infoPtr
->rcChannel
.right
;
1115 lprc
->bottom
= infoPtr
->rcChannel
.bottom
;
1116 lprc
->top
= infoPtr
->rcChannel
.top
;
1123 TRACKBAR_GetNumTics (const TRACKBAR_INFO
*infoPtr
)
1125 if (infoPtr
->dwStyle
& TBS_NOTICKS
) return 0;
1127 return infoPtr
->uNumTics
+ 2;
1131 static int comp_tics (const void *ap
, const void *bp
)
1133 const DWORD a
= *(const DWORD
*)ap
;
1134 const DWORD b
= *(const DWORD
*)bp
;
1136 TRACE("(a=%d, b=%d)\n", a
, b
);
1137 if (a
< b
) return -1;
1138 if (a
> b
) return 1;
1144 TRACKBAR_GetTic (const TRACKBAR_INFO
*infoPtr
, INT iTic
)
1146 if ((iTic
< 0) || (iTic
>= infoPtr
->uNumTics
) || !infoPtr
->tics
)
1149 qsort(infoPtr
->tics
, infoPtr
->uNumTics
, sizeof(DWORD
), comp_tics
);
1150 return infoPtr
->tics
[iTic
];
1155 TRACKBAR_GetTicPos (const TRACKBAR_INFO
*infoPtr
, INT iTic
)
1157 LONG range
, width
, pos
, tic
;
1160 if ((iTic
< 0) || (iTic
>= infoPtr
->uNumTics
) || !infoPtr
->tics
)
1163 tic
= TRACKBAR_GetTic (infoPtr
, iTic
);
1164 range
= infoPtr
->lRangeMax
- infoPtr
->lRangeMin
;
1165 if (range
<= 0) range
= 1;
1166 offsetthumb
= (infoPtr
->rcThumb
.right
- infoPtr
->rcThumb
.left
)/2;
1167 width
= infoPtr
->rcChannel
.right
- infoPtr
->rcChannel
.left
- offsetthumb
*2;
1168 pos
= infoPtr
->rcChannel
.left
+ offsetthumb
+ (width
* tic
) / range
;
1175 TRACKBAR_SetBuddy (TRACKBAR_INFO
*infoPtr
, BOOL fLocation
, HWND hwndBuddy
)
1180 /* buddy is left or above */
1181 hwndTemp
= infoPtr
->hwndBuddyLA
;
1182 infoPtr
->hwndBuddyLA
= hwndBuddy
;
1185 /* buddy is right or below */
1186 hwndTemp
= infoPtr
->hwndBuddyRB
;
1187 infoPtr
->hwndBuddyRB
= hwndBuddy
;
1190 TRACKBAR_AlignBuddies (infoPtr
);
1197 TRACKBAR_SetLineSize (TRACKBAR_INFO
*infoPtr
, LONG lLineSize
)
1199 LONG lTemp
= infoPtr
->lLineSize
;
1201 infoPtr
->lLineSize
= lLineSize
;
1208 TRACKBAR_SetPageSize (TRACKBAR_INFO
*infoPtr
, LONG lPageSize
)
1210 LONG lTemp
= infoPtr
->lPageSize
;
1212 if (lPageSize
!= -1)
1213 infoPtr
->lPageSize
= lPageSize
;
1215 infoPtr
->lPageSize
= TB_DEFAULTPAGESIZE
;
1221 static inline LRESULT
1222 TRACKBAR_SetPos (TRACKBAR_INFO
*infoPtr
, BOOL fPosition
, LONG lPosition
)
1224 LONG oldPos
= infoPtr
->lPos
;
1225 infoPtr
->lPos
= lPosition
;
1227 if (infoPtr
->lPos
< infoPtr
->lRangeMin
)
1228 infoPtr
->lPos
= infoPtr
->lRangeMin
;
1230 if (infoPtr
->lPos
> infoPtr
->lRangeMax
)
1231 infoPtr
->lPos
= infoPtr
->lRangeMax
;
1233 if (fPosition
&& oldPos
!= lPosition
)
1235 TRACKBAR_UpdateThumb(infoPtr
);
1236 TRACKBAR_InvalidateThumbMove(infoPtr
, oldPos
, lPosition
);
1243 static inline LRESULT
1244 TRACKBAR_SetRange (TRACKBAR_INFO
*infoPtr
, BOOL redraw
, LONG range
)
1246 BOOL changed
= infoPtr
->lRangeMin
!= (SHORT
)LOWORD(range
) ||
1247 infoPtr
->lRangeMax
!= (SHORT
)HIWORD(range
);
1249 infoPtr
->lRangeMin
= (SHORT
)LOWORD(range
);
1250 infoPtr
->lRangeMax
= (SHORT
)HIWORD(range
);
1252 /* clip position to new min/max limit */
1253 if (infoPtr
->lPos
< infoPtr
->lRangeMin
)
1254 infoPtr
->lPos
= infoPtr
->lRangeMin
;
1256 if (infoPtr
->lPos
> infoPtr
->lRangeMax
)
1257 infoPtr
->lPos
= infoPtr
->lRangeMax
;
1259 infoPtr
->lPageSize
= (infoPtr
->lRangeMax
- infoPtr
->lRangeMin
) / 5;
1260 if (infoPtr
->lPageSize
== 0) infoPtr
->lPageSize
= 1;
1263 if (infoPtr
->dwStyle
& TBS_AUTOTICKS
)
1264 TRACKBAR_RecalculateTics (infoPtr
);
1265 infoPtr
->flags
|= TB_THUMBPOSCHANGED
;
1268 if (redraw
) TRACKBAR_InvalidateAll(infoPtr
);
1274 static inline LRESULT
1275 TRACKBAR_SetRangeMax (TRACKBAR_INFO
*infoPtr
, BOOL redraw
, LONG lMax
)
1277 BOOL changed
= infoPtr
->lRangeMax
!= lMax
;
1278 LONG rightmost
= max(lMax
, infoPtr
->lRangeMin
);
1280 infoPtr
->lRangeMax
= lMax
;
1281 if (infoPtr
->lPos
> rightmost
) {
1282 infoPtr
->lPos
= rightmost
;
1283 infoPtr
->flags
|= TB_THUMBPOSCHANGED
;
1286 infoPtr
->lPageSize
= (infoPtr
->lRangeMax
- infoPtr
->lRangeMin
) / 5;
1287 if (infoPtr
->lPageSize
== 0) infoPtr
->lPageSize
= 1;
1289 if (changed
&& (infoPtr
->dwStyle
& TBS_AUTOTICKS
))
1290 TRACKBAR_RecalculateTics (infoPtr
);
1292 if (redraw
) TRACKBAR_InvalidateAll(infoPtr
);
1298 static inline LRESULT
1299 TRACKBAR_SetRangeMin (TRACKBAR_INFO
*infoPtr
, BOOL redraw
, LONG lMin
)
1301 BOOL changed
= infoPtr
->lRangeMin
!= lMin
;
1303 infoPtr
->lRangeMin
= lMin
;
1304 if (infoPtr
->lPos
< infoPtr
->lRangeMin
) {
1305 infoPtr
->lPos
= infoPtr
->lRangeMin
;
1306 infoPtr
->flags
|= TB_THUMBPOSCHANGED
;
1309 infoPtr
->lPageSize
= (infoPtr
->lRangeMax
- infoPtr
->lRangeMin
) / 5;
1310 if (infoPtr
->lPageSize
== 0) infoPtr
->lPageSize
= 1;
1312 if (changed
&& (infoPtr
->dwStyle
& TBS_AUTOTICKS
))
1313 TRACKBAR_RecalculateTics (infoPtr
);
1315 if (redraw
) TRACKBAR_InvalidateAll(infoPtr
);
1321 static inline LRESULT
1322 TRACKBAR_SetSel (TRACKBAR_INFO
*infoPtr
, BOOL fRedraw
, LONG lSel
)
1324 if (!(infoPtr
->dwStyle
& TBS_ENABLESELRANGE
)){
1325 infoPtr
->lSelMin
= 0;
1326 infoPtr
->lSelMax
= 0;
1330 infoPtr
->lSelMin
= (SHORT
)LOWORD(lSel
);
1331 infoPtr
->lSelMax
= (SHORT
)HIWORD(lSel
);
1332 infoPtr
->flags
|= TB_SELECTIONCHANGED
;
1334 if (infoPtr
->lSelMin
< infoPtr
->lRangeMin
)
1335 infoPtr
->lSelMin
= infoPtr
->lRangeMin
;
1336 if (infoPtr
->lSelMax
> infoPtr
->lRangeMax
)
1337 infoPtr
->lSelMax
= infoPtr
->lRangeMax
;
1339 if (fRedraw
) TRACKBAR_InvalidateAll(infoPtr
);
1345 static inline LRESULT
1346 TRACKBAR_SetSelEnd (TRACKBAR_INFO
*infoPtr
, BOOL fRedraw
, LONG lEnd
)
1348 if (!(infoPtr
->dwStyle
& TBS_ENABLESELRANGE
)){
1349 infoPtr
->lSelMax
= 0;
1353 infoPtr
->lSelMax
= lEnd
;
1354 infoPtr
->flags
|= TB_SELECTIONCHANGED
;
1356 if (infoPtr
->lSelMax
> infoPtr
->lRangeMax
)
1357 infoPtr
->lSelMax
= infoPtr
->lRangeMax
;
1359 if (fRedraw
) TRACKBAR_InvalidateAll(infoPtr
);
1365 static inline LRESULT
1366 TRACKBAR_SetSelStart (TRACKBAR_INFO
*infoPtr
, BOOL fRedraw
, LONG lStart
)
1368 if (!(infoPtr
->dwStyle
& TBS_ENABLESELRANGE
)){
1369 infoPtr
->lSelMin
= 0;
1373 infoPtr
->lSelMin
= lStart
;
1374 infoPtr
->flags
|=TB_SELECTIONCHANGED
;
1376 if (infoPtr
->lSelMin
< infoPtr
->lRangeMin
)
1377 infoPtr
->lSelMin
= infoPtr
->lRangeMin
;
1379 if (fRedraw
) TRACKBAR_InvalidateAll(infoPtr
);
1385 static inline LRESULT
1386 TRACKBAR_SetThumbLength (TRACKBAR_INFO
*infoPtr
, UINT iLength
)
1388 if (infoPtr
->dwStyle
& TBS_FIXEDLENGTH
) {
1389 /* We're not supposed to check if it's really changed or not,
1390 just repaint in any case. */
1391 infoPtr
->uThumbLen
= iLength
;
1392 infoPtr
->flags
|= TB_THUMBSIZECHANGED
;
1393 TRACKBAR_InvalidateAll(infoPtr
);
1400 static inline LRESULT
1401 TRACKBAR_SetTic (TRACKBAR_INFO
*infoPtr
, LONG lPos
)
1403 if ((lPos
< infoPtr
->lRangeMin
) || (lPos
> infoPtr
->lRangeMax
))
1406 TRACE("lPos=%d\n", lPos
);
1408 infoPtr
->uNumTics
++;
1409 infoPtr
->tics
=ReAlloc( infoPtr
->tics
,
1410 (infoPtr
->uNumTics
)*sizeof (DWORD
));
1411 if (!infoPtr
->tics
) {
1412 infoPtr
->uNumTics
= 0;
1413 notify(infoPtr
, NM_OUTOFMEMORY
);
1416 infoPtr
->tics
[infoPtr
->uNumTics
-1] = lPos
;
1418 TRACKBAR_InvalidateAll(infoPtr
);
1424 static inline LRESULT
1425 TRACKBAR_SetTicFreq (TRACKBAR_INFO
*infoPtr
, WORD wFreq
)
1427 if (infoPtr
->dwStyle
& TBS_AUTOTICKS
) {
1428 infoPtr
->uTicFreq
= wFreq
;
1429 TRACKBAR_RecalculateTics (infoPtr
);
1430 TRACKBAR_InvalidateAll(infoPtr
);
1433 TRACKBAR_UpdateThumb (infoPtr
);
1439 TRACKBAR_SetTipSide (TRACKBAR_INFO
*infoPtr
, INT fLocation
)
1441 INT fTemp
= infoPtr
->fLocation
;
1443 infoPtr
->fLocation
= fLocation
;
1449 static inline LRESULT
1450 TRACKBAR_SetToolTips (TRACKBAR_INFO
*infoPtr
, HWND hwndTT
)
1452 infoPtr
->hwndToolTip
= hwndTT
;
1459 TRACKBAR_SetUnicodeFormat (TRACKBAR_INFO
*infoPtr
, BOOL fUnicode
)
1461 BOOL bTemp
= infoPtr
->bUnicode
;
1463 infoPtr
->bUnicode
= fUnicode
;
1470 TRACKBAR_InitializeThumb (TRACKBAR_INFO
*infoPtr
)
1473 int clientWidth
, clientMetric
;
1475 /* initial thumb length */
1476 clientMetric
= (infoPtr
->dwStyle
& TBS_ENABLESELRANGE
) ? 23 : 21;
1477 GetClientRect(infoPtr
->hwndSelf
,&rect
);
1478 if (infoPtr
->dwStyle
& TBS_VERT
) {
1479 clientWidth
= rect
.right
- rect
.left
;
1481 clientWidth
= rect
.bottom
- rect
.top
;
1483 if (clientWidth
>= clientMetric
)
1484 infoPtr
->uThumbLen
= clientMetric
;
1486 infoPtr
->uThumbLen
= clientWidth
> 9 ? clientWidth
- 6 : 4;
1488 TRACKBAR_CalcChannel (infoPtr
);
1489 TRACKBAR_UpdateThumb (infoPtr
);
1490 infoPtr
->flags
&= ~TB_SELECTIONCHANGED
;
1497 TRACKBAR_Create (HWND hwnd
, const CREATESTRUCTW
*lpcs
)
1499 TRACKBAR_INFO
*infoPtr
;
1501 infoPtr
= Alloc (sizeof(TRACKBAR_INFO
));
1502 if (!infoPtr
) return -1;
1503 SetWindowLongPtrW (hwnd
, 0, (DWORD_PTR
)infoPtr
);
1505 /* set default values */
1506 infoPtr
->hwndSelf
= hwnd
;
1507 infoPtr
->dwStyle
= lpcs
->style
;
1508 infoPtr
->lRangeMin
= 0;
1509 infoPtr
->lRangeMax
= 100;
1510 infoPtr
->lLineSize
= 1;
1511 infoPtr
->lPageSize
= TB_DEFAULTPAGESIZE
;
1512 infoPtr
->lSelMin
= 0;
1513 infoPtr
->lSelMax
= 0;
1515 infoPtr
->fLocation
= TBTS_TOP
;
1516 infoPtr
->uNumTics
= 0; /* start and end tic are not included in count*/
1517 infoPtr
->uTicFreq
= 1;
1518 infoPtr
->tics
= NULL
;
1519 infoPtr
->hwndNotify
= lpcs
->hwndParent
;
1521 TRACKBAR_InitializeThumb (infoPtr
);
1523 /* Create tooltip control */
1524 if (infoPtr
->dwStyle
& TBS_TOOLTIPS
) {
1526 infoPtr
->hwndToolTip
=
1527 CreateWindowExW (0, TOOLTIPS_CLASSW
, NULL
, WS_POPUP
,
1528 CW_USEDEFAULT
, CW_USEDEFAULT
,
1529 CW_USEDEFAULT
, CW_USEDEFAULT
,
1532 if (infoPtr
->hwndToolTip
) {
1535 ZeroMemory (&ti
, sizeof(ti
));
1536 ti
.cbSize
= sizeof(ti
);
1537 ti
.uFlags
= TTF_IDISHWND
| TTF_TRACK
| TTF_ABSOLUTE
;
1539 ti
.lpszText
= &wEmpty
;
1541 SendMessageW (infoPtr
->hwndToolTip
, TTM_ADDTOOLW
, 0, (LPARAM
)&ti
);
1545 OpenThemeData (hwnd
, themeClass
);
1552 TRACKBAR_Destroy (TRACKBAR_INFO
*infoPtr
)
1554 /* delete tooltip control */
1555 if (infoPtr
->hwndToolTip
)
1556 DestroyWindow (infoPtr
->hwndToolTip
);
1558 Free (infoPtr
->tics
);
1559 infoPtr
->tics
= NULL
;
1561 SetWindowLongPtrW (infoPtr
->hwndSelf
, 0, 0);
1562 CloseThemeData (GetWindowTheme (infoPtr
->hwndSelf
));
1570 TRACKBAR_KillFocus (TRACKBAR_INFO
*infoPtr
)
1573 infoPtr
->bFocussed
= FALSE
;
1574 TRACKBAR_InvalidateAll(infoPtr
);
1580 TRACKBAR_LButtonDown (TRACKBAR_INFO
*infoPtr
, INT x
, INT y
)
1587 SetFocus(infoPtr
->hwndSelf
);
1589 if (PtInRect(&infoPtr
->rcThumb
, clickPoint
)) {
1590 infoPtr
->flags
|= TB_DRAG_MODE
;
1591 SetCapture (infoPtr
->hwndSelf
);
1592 TRACKBAR_UpdateToolTip (infoPtr
);
1593 TRACKBAR_ActivateToolTip (infoPtr
, TRUE
);
1594 TRACKBAR_InvalidateThumb(infoPtr
, infoPtr
->lPos
);
1596 LONG dir
= TRACKBAR_GetAutoPageDirection(infoPtr
, clickPoint
);
1597 if (dir
== 0) return 0;
1598 infoPtr
->flags
|= (dir
< 0) ? TB_AUTO_PAGE_LEFT
: TB_AUTO_PAGE_RIGHT
;
1599 TRACKBAR_AutoPage (infoPtr
, clickPoint
);
1600 SetCapture (infoPtr
->hwndSelf
);
1601 SetTimer(infoPtr
->hwndSelf
, TB_REFRESH_TIMER
, TB_REFRESH_DELAY
, 0);
1609 TRACKBAR_LButtonUp (TRACKBAR_INFO
*infoPtr
)
1611 if (infoPtr
->flags
& TB_DRAG_MODE
) {
1612 notify_with_scroll (infoPtr
, TB_THUMBPOSITION
| (infoPtr
->lPos
<<16));
1613 notify_with_scroll (infoPtr
, TB_ENDTRACK
);
1614 infoPtr
->flags
&= ~TB_DRAG_MODE
;
1616 notify(infoPtr
, NM_RELEASEDCAPTURE
);
1617 TRACKBAR_ActivateToolTip(infoPtr
, FALSE
);
1618 TRACKBAR_InvalidateThumb(infoPtr
, infoPtr
->lPos
);
1620 if (infoPtr
->flags
& TB_AUTO_PAGE
) {
1621 KillTimer (infoPtr
->hwndSelf
, TB_REFRESH_TIMER
);
1622 infoPtr
->flags
&= ~TB_AUTO_PAGE
;
1623 notify_with_scroll (infoPtr
, TB_ENDTRACK
);
1625 notify(infoPtr
, NM_RELEASEDCAPTURE
);
1633 TRACKBAR_CaptureChanged (const TRACKBAR_INFO
*infoPtr
)
1635 notify_with_scroll (infoPtr
, TB_ENDTRACK
);
1641 TRACKBAR_Paint (TRACKBAR_INFO
*infoPtr
, HDC hdc
)
1644 TRACKBAR_Refresh(infoPtr
, hdc
);
1647 hdc
= BeginPaint (infoPtr
->hwndSelf
, &ps
);
1648 TRACKBAR_Refresh (infoPtr
, hdc
);
1649 EndPaint (infoPtr
->hwndSelf
, &ps
);
1657 TRACKBAR_SetFocus (TRACKBAR_INFO
*infoPtr
)
1660 infoPtr
->bFocussed
= TRUE
;
1661 TRACKBAR_InvalidateAll(infoPtr
);
1668 TRACKBAR_Size (TRACKBAR_INFO
*infoPtr
)
1670 if (infoPtr
->dwStyle
& TBS_FIXEDLENGTH
)
1672 TRACKBAR_CalcChannel(infoPtr
);
1673 TRACKBAR_UpdateThumb(infoPtr
);
1676 TRACKBAR_InitializeThumb(infoPtr
);
1677 TRACKBAR_AlignBuddies (infoPtr
);
1678 TRACKBAR_InvalidateAll(infoPtr
);
1684 TRACKBAR_StyleChanged (TRACKBAR_INFO
*infoPtr
, WPARAM wStyleType
,
1685 const STYLESTRUCT
*lpss
)
1687 if (wStyleType
!= GWL_STYLE
) return 0;
1689 infoPtr
->dwStyle
= lpss
->styleNew
;
1695 TRACKBAR_Timer (TRACKBAR_INFO
*infoPtr
)
1697 if (infoPtr
->flags
& TB_AUTO_PAGE
) {
1699 if (GetCursorPos(&pt
))
1700 if (ScreenToClient(infoPtr
->hwndSelf
, &pt
))
1701 TRACKBAR_AutoPage(infoPtr
, pt
);
1707 /* update theme after a WM_THEMECHANGED message */
1708 static LRESULT
theme_changed (const TRACKBAR_INFO
* infoPtr
)
1710 HTHEME theme
= GetWindowTheme (infoPtr
->hwndSelf
);
1711 CloseThemeData (theme
);
1712 OpenThemeData (infoPtr
->hwndSelf
, themeClass
);
1718 TRACKBAR_MouseMove (TRACKBAR_INFO
*infoPtr
, INT x
, INT y
)
1720 INT clickPlace
= (infoPtr
->dwStyle
& TBS_VERT
) ? y
: x
;
1721 LONG dragPos
, oldPos
= infoPtr
->lPos
;
1723 TRACE("(x=%d. y=%d)\n", x
, y
);
1725 if (infoPtr
->flags
& TB_AUTO_PAGE
) {
1729 TRACKBAR_AutoPage (infoPtr
, pt
);
1733 if (!(infoPtr
->flags
& TB_DRAG_MODE
))
1735 if (GetWindowTheme (infoPtr
->hwndSelf
))
1737 DWORD oldFlags
= infoPtr
->flags
;
1741 if (PtInRect (&infoPtr
->rcThumb
, pt
))
1743 TRACKMOUSEEVENT tme
;
1744 tme
.cbSize
= sizeof( tme
);
1745 tme
.dwFlags
= TME_LEAVE
;
1746 tme
.hwndTrack
= infoPtr
->hwndSelf
;
1747 TrackMouseEvent( &tme
);
1748 infoPtr
->flags
|= TB_THUMB_HOT
;
1752 TRACKMOUSEEVENT tme
;
1753 tme
.cbSize
= sizeof( tme
);
1754 tme
.dwFlags
= TME_CANCEL
;
1755 tme
.hwndTrack
= infoPtr
->hwndSelf
;
1756 TrackMouseEvent( &tme
);
1757 infoPtr
->flags
&= ~TB_THUMB_HOT
;
1759 if (oldFlags
!= infoPtr
->flags
) InvalidateRect (infoPtr
->hwndSelf
, &infoPtr
->rcThumb
, FALSE
);
1764 dragPos
= TRACKBAR_ConvertPlaceToPosition (infoPtr
, clickPlace
);
1766 if (dragPos
== oldPos
) return TRUE
;
1768 infoPtr
->lPos
= dragPos
;
1769 TRACKBAR_UpdateThumb (infoPtr
);
1771 notify_with_scroll (infoPtr
, TB_THUMBTRACK
| (infoPtr
->lPos
<<16));
1773 TRACKBAR_InvalidateThumbMove(infoPtr
, oldPos
, dragPos
);
1774 UpdateWindow (infoPtr
->hwndSelf
);
1780 TRACKBAR_KeyDown (TRACKBAR_INFO
*infoPtr
, INT nVirtKey
)
1782 BOOL downIsLeft
= infoPtr
->dwStyle
& TBS_DOWNISLEFT
;
1783 BOOL vert
= infoPtr
->dwStyle
& TBS_VERT
;
1784 LONG pos
= infoPtr
->lPos
;
1786 TRACE("%x\n", nVirtKey
);
1790 if (!vert
&& downIsLeft
) TRACKBAR_LineDown(infoPtr
);
1791 else TRACKBAR_LineUp(infoPtr
);
1794 if (vert
&& downIsLeft
) TRACKBAR_LineDown(infoPtr
);
1795 else TRACKBAR_LineUp(infoPtr
);
1798 if (!vert
&& downIsLeft
) TRACKBAR_LineUp(infoPtr
);
1799 else TRACKBAR_LineDown(infoPtr
);
1802 if (vert
&& downIsLeft
) TRACKBAR_LineUp(infoPtr
);
1803 else TRACKBAR_LineDown(infoPtr
);
1806 if (!vert
&& downIsLeft
) TRACKBAR_PageUp(infoPtr
);
1807 else TRACKBAR_PageDown(infoPtr
);
1810 if (!vert
&& downIsLeft
) TRACKBAR_PageDown(infoPtr
);
1811 else TRACKBAR_PageUp(infoPtr
);
1814 if (infoPtr
->lPos
== infoPtr
->lRangeMin
) return FALSE
;
1815 infoPtr
->lPos
= infoPtr
->lRangeMin
;
1816 notify_with_scroll (infoPtr
, TB_TOP
);
1819 if (infoPtr
->lPos
== infoPtr
->lRangeMax
) return FALSE
;
1820 infoPtr
->lPos
= infoPtr
->lRangeMax
;
1821 notify_with_scroll (infoPtr
, TB_BOTTOM
);
1825 if (pos
!= infoPtr
->lPos
) {
1826 TRACKBAR_UpdateThumb (infoPtr
);
1827 TRACKBAR_InvalidateThumbMove (infoPtr
, pos
, infoPtr
->lPos
);
1835 TRACKBAR_KeyUp (const TRACKBAR_INFO
*infoPtr
, INT nVirtKey
)
1846 notify_with_scroll (infoPtr
, TB_ENDTRACK
);
1853 TRACKBAR_Enable (TRACKBAR_INFO
*infoPtr
, BOOL enable
)
1856 infoPtr
->dwStyle
&= ~WS_DISABLED
;
1858 infoPtr
->dwStyle
|= WS_DISABLED
;
1860 InvalidateRect(infoPtr
->hwndSelf
, &infoPtr
->rcThumb
, TRUE
);
1865 static LRESULT WINAPI
1866 TRACKBAR_WindowProc (HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
1868 TRACKBAR_INFO
*infoPtr
= (TRACKBAR_INFO
*)GetWindowLongPtrW (hwnd
, 0);
1870 TRACE("hwnd=%p msg=%x wparam=%lx lparam=%lx\n", hwnd
, uMsg
, wParam
, lParam
);
1872 if (!infoPtr
&& (uMsg
!= WM_CREATE
))
1873 return DefWindowProcW (hwnd
, uMsg
, wParam
, lParam
);
1878 return TRACKBAR_ClearSel (infoPtr
, (BOOL
)wParam
);
1881 return TRACKBAR_ClearTics (infoPtr
, (BOOL
)wParam
);
1884 return (LRESULT
)(wParam
? infoPtr
->hwndBuddyLA
: infoPtr
->hwndBuddyRB
);
1886 case TBM_GETCHANNELRECT
:
1887 return TRACKBAR_GetChannelRect (infoPtr
, (LPRECT
)lParam
);
1889 case TBM_GETLINESIZE
:
1890 return infoPtr
->lLineSize
;
1892 case TBM_GETNUMTICS
:
1893 return TRACKBAR_GetNumTics (infoPtr
);
1895 case TBM_GETPAGESIZE
:
1896 return infoPtr
->lPageSize
;
1899 return infoPtr
->lPos
;
1902 return (LRESULT
)infoPtr
->tics
;
1904 case TBM_GETRANGEMAX
:
1905 return infoPtr
->lRangeMax
;
1907 case TBM_GETRANGEMIN
:
1908 return infoPtr
->lRangeMin
;
1911 return infoPtr
->lSelMax
;
1913 case TBM_GETSELSTART
:
1914 return infoPtr
->lSelMin
;
1916 case TBM_GETTHUMBLENGTH
:
1917 return infoPtr
->uThumbLen
;
1919 case TBM_GETTHUMBRECT
:
1920 return CopyRect((LPRECT
)lParam
, &infoPtr
->rcThumb
);
1923 return TRACKBAR_GetTic (infoPtr
, (INT
)wParam
);
1926 return TRACKBAR_GetTicPos (infoPtr
, (INT
)wParam
);
1928 case TBM_GETTOOLTIPS
:
1929 return (LRESULT
)infoPtr
->hwndToolTip
;
1931 case TBM_GETUNICODEFORMAT
:
1932 return infoPtr
->bUnicode
;
1935 return (LRESULT
) TRACKBAR_SetBuddy(infoPtr
, (BOOL
)wParam
, (HWND
)lParam
);
1937 case TBM_SETLINESIZE
:
1938 return TRACKBAR_SetLineSize (infoPtr
, (LONG
)lParam
);
1940 case TBM_SETPAGESIZE
:
1941 return TRACKBAR_SetPageSize (infoPtr
, (LONG
)lParam
);
1944 return TRACKBAR_SetPos (infoPtr
, (BOOL
)wParam
, (LONG
)lParam
);
1947 return TRACKBAR_SetRange (infoPtr
, (BOOL
)wParam
, (LONG
)lParam
);
1949 case TBM_SETRANGEMAX
:
1950 return TRACKBAR_SetRangeMax (infoPtr
, (BOOL
)wParam
, (LONG
)lParam
);
1952 case TBM_SETRANGEMIN
:
1953 return TRACKBAR_SetRangeMin (infoPtr
, (BOOL
)wParam
, (LONG
)lParam
);
1956 return TRACKBAR_SetSel (infoPtr
, (BOOL
)wParam
, (LONG
)lParam
);
1959 return TRACKBAR_SetSelEnd (infoPtr
, (BOOL
)wParam
, (LONG
)lParam
);
1961 case TBM_SETSELSTART
:
1962 return TRACKBAR_SetSelStart (infoPtr
, (BOOL
)wParam
, (LONG
)lParam
);
1964 case TBM_SETTHUMBLENGTH
:
1965 return TRACKBAR_SetThumbLength (infoPtr
, (UINT
)wParam
);
1968 return TRACKBAR_SetTic (infoPtr
, (LONG
)lParam
);
1970 case TBM_SETTICFREQ
:
1971 return TRACKBAR_SetTicFreq (infoPtr
, (WORD
)wParam
);
1973 case TBM_SETTIPSIDE
:
1974 return TRACKBAR_SetTipSide (infoPtr
, (INT
)wParam
);
1976 case TBM_SETTOOLTIPS
:
1977 return TRACKBAR_SetToolTips (infoPtr
, (HWND
)wParam
);
1979 case TBM_SETUNICODEFORMAT
:
1980 return TRACKBAR_SetUnicodeFormat (infoPtr
, (BOOL
)wParam
);
1983 case WM_CAPTURECHANGED
:
1984 if (hwnd
== (HWND
)lParam
) return 0;
1985 return TRACKBAR_CaptureChanged (infoPtr
);
1988 return TRACKBAR_Create (hwnd
, (LPCREATESTRUCTW
)lParam
);
1991 return TRACKBAR_Destroy (infoPtr
);
1994 return TRACKBAR_Enable (infoPtr
, (BOOL
)wParam
);
2000 return DLGC_WANTARROWS
;
2003 return TRACKBAR_KeyDown (infoPtr
, (INT
)wParam
);
2006 return TRACKBAR_KeyUp (infoPtr
, (INT
)wParam
);
2009 return TRACKBAR_KillFocus (infoPtr
);
2011 case WM_LBUTTONDOWN
:
2012 return TRACKBAR_LButtonDown (infoPtr
, (SHORT
)LOWORD(lParam
), (SHORT
)HIWORD(lParam
));
2015 return TRACKBAR_LButtonUp (infoPtr
);
2018 infoPtr
->flags
&= ~TB_THUMB_HOT
;
2019 InvalidateRect (infoPtr
->hwndSelf
, &infoPtr
->rcThumb
, FALSE
);
2023 return TRACKBAR_MouseMove (infoPtr
, (SHORT
)LOWORD(lParam
), (SHORT
)HIWORD(lParam
));
2025 case WM_PRINTCLIENT
:
2027 return TRACKBAR_Paint (infoPtr
, (HDC
)wParam
);
2030 return TRACKBAR_SetFocus (infoPtr
);
2033 return TRACKBAR_Size (infoPtr
);
2035 case WM_STYLECHANGED
:
2036 return TRACKBAR_StyleChanged (infoPtr
, wParam
, (LPSTYLESTRUCT
)lParam
);
2038 case WM_THEMECHANGED
:
2039 return theme_changed (infoPtr
);
2042 return TRACKBAR_Timer (infoPtr
);
2044 case WM_WININICHANGE
:
2045 return TRACKBAR_InitializeThumb (infoPtr
);
2048 if ((uMsg
>= WM_USER
) && (uMsg
< WM_APP
) && !COMCTL32_IsReflectedMessage(uMsg
))
2049 ERR("unknown msg %04x wp=%08lx lp=%08lx\n", uMsg
, wParam
, lParam
);
2050 return DefWindowProcW (hwnd
, uMsg
, wParam
, lParam
);
2055 void TRACKBAR_Register (void)
2059 ZeroMemory (&wndClass
, sizeof(WNDCLASSW
));
2060 wndClass
.style
= CS_GLOBALCLASS
;
2061 wndClass
.lpfnWndProc
= TRACKBAR_WindowProc
;
2062 wndClass
.cbClsExtra
= 0;
2063 wndClass
.cbWndExtra
= sizeof(TRACKBAR_INFO
*);
2064 wndClass
.hCursor
= LoadCursorW (0, (LPWSTR
)IDC_ARROW
);
2065 wndClass
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
2066 wndClass
.lpszClassName
= TRACKBAR_CLASSW
;
2068 RegisterClassW (&wndClass
);
2072 void TRACKBAR_Unregister (void)
2074 UnregisterClassW (TRACKBAR_CLASSW
, NULL
);