source: trunk/src/comctl32/trackbar.cpp@ 5416

Last change on this file since 5416 was 5416, checked in by sandervl, 24 years ago

Resync with Wine + previous merge fixes

File size: 67.3 KB
Line 
1/* $Id: trackbar.cpp,v 1.6 2001-03-31 13:25:27 sandervl Exp $ */
2/*
3 * Trackbar control
4 *
5 * Copyright 1998, 1999 Eric Kohl <ekohl@abo.rhein-zeitung.de>
6 * Copyright 1998,1999 Alex Priem <alexp@sci.kun.nl>
7 * Copyright 1999 Achim Hasenmueller
8 * Copyright 1999 Christoph Bratschi <cbratschi@datacomm.ch>
9 *
10 *
11 * Status: complete
12 * Version: 5.80
13 *
14 * Note: TBM_SETTHUMBLENGTH implemented, COMCTL32 5.00 ignores it
15 * Microsoft(TM) should fix this bug :)
16 */
17
18#include "winbase.h"
19#include "commctrl.h"
20#include "ccbase.h"
21#include "trackbar.h"
22#include "comctl32.h"
23#include <stdio.h>
24
25#define TRACKBAR_GetInfoPtr(hwnd) ((TRACKBAR_INFO*)getInfoPtr(hwnd))
26
27
28/* Used by TRACKBAR_Draw to find out which parts of the control
29 need to be recalculated */
30
31#define TB_THUMBPOSCHANGED 1
32#define TB_THUMBSIZECHANGED 2
33#define TB_THUMBCHANGED (TB_THUMBPOSCHANGED | TB_THUMBPOSCHANGED)
34#define TB_SELECTIONCHANGED 4
35#define TB_DRAG_MODE 16 /* we're dragging the slider */
36#define TB_DRAGPOSVALID 32 /* current Position is in dragPos */
37#define TB_SCROLL_MODE 64 /* WM_TIMER scroll mode */
38#define TB_SHOW_TOOLTIP 128 /* tooltip-style enabled and tooltip on */
39
40/* helper defines for TRACKBAR_DrawTic */
41#define TIC_LEFTEDGE 0x20
42#define TIC_RIGHTEDGE 0x40
43#define TIC_EDGE (TIC_LEFTEDGE | TIC_RIGHTEDGE)
44#define TIC_SELECTIONMARKMAX 0x80
45#define TIC_SELECTIONMARKMIN 0x100
46#define TIC_SELECTIONMARK (TIC_SELECTIONMARKMAX | TIC_SELECTIONMARKMIN)
47
48/* size calculation */
49
50#define BORDER_SIZE 2
51
52#define SCALE_SIZE 4
53#define SCALE_SPACE 1
54
55#define THUMB_LEN_SEL 23
56#define THUMB_LEN 21
57#define THUMB_MINLEN 4
58
59#define CHANNEL_NOSEL_HEIGHT 4 //min no sel height
60#define CHANNEL_MIN_HEIGHT 6 //min sel height
61#define CHANNEL_THUMB_DIFF 8 //sel thumb, channel difference
62#define CHANNEL_SPACE 8
63#define CHANNEL_SCALE_SPACE SCALE_SIZE+SCALE_SPACE+BORDER_SIZE
64#define CHANNEL_THUMB_SPACE BORDER_SIZE
65
66#define TOOLTIP_SPACE 5
67
68/* scroll mode */
69
70#define SCROLL_TIME 500 //ms
71#define SCROLL_TIMER_ID 1
72
73/* Tooltips */
74
75#define TOOLTIP_XSPACE 5
76#define TOOLTIP_YSPACE 5
77
78static const WORD pattern[8] =
79 {0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA};
80
81static BOOL TRACKBAR_SendNotify(TRACKBAR_INFO *infoPtr,UINT code);
82
83static void TRACKBAR_RecalculateTics(TRACKBAR_INFO *infoPtr,BOOL restoreOld)
84{
85 INT i,tic,nrTics;
86
87 if (infoPtr->dwStyle & TBS_NOTICKS) //no ticks
88 {
89 COMCTL32_Free(infoPtr->tics);
90 infoPtr->tics = NULL;
91
92 infoPtr->uNumTics = 0;
93 return;
94 }
95
96 if (restoreOld && !(infoPtr->dwStyle & TBS_AUTOTICKS) && infoPtr->tics)
97 { //check old ticks
98 LPLONG oldTics = (LONG*)COMCTL32_Alloc(infoPtr->uNumTics*sizeof(DWORD));
99 INT count = 0;
100
101 for (i = 0;i < infoPtr->uNumTics;i++)
102 {
103 if ((infoPtr->tics[i] >= infoPtr->nRangeMin) && (infoPtr->tics[i] <= infoPtr->nRangeMax))
104 {
105 oldTics[count] = infoPtr->tics[i];
106 count++;
107 }
108 }
109
110 COMCTL32_Free(infoPtr->tics);
111 infoPtr->tics = (LONG*)COMCTL32_ReAlloc(oldTics,count*sizeof(DWORD));
112 infoPtr->uNumTics = count;
113
114 return;
115 }
116
117 if (infoPtr->uTicFreq && (infoPtr->nRangeMax > infoPtr->nRangeMin) && (infoPtr->dwStyle & TBS_AUTOTICKS))
118 {
119 //Tics without start and end tic
120 nrTics = (infoPtr->nRangeMax-infoPtr->nRangeMin)/infoPtr->uTicFreq-1;
121 if (nrTics <= 0)
122 {
123 COMCTL32_Free(infoPtr->tics);
124 infoPtr->tics = NULL;
125 infoPtr->uNumTics = 0;
126 return;
127 }
128 } else
129 {
130 COMCTL32_Free(infoPtr->tics);
131 infoPtr->tics = NULL;
132 infoPtr->uNumTics = 0;
133 return;
134 }
135
136 if (nrTics != infoPtr->uNumTics)
137 {
138 COMCTL32_Free(infoPtr->tics);
139 infoPtr->tics = (LONG*)COMCTL32_Alloc(nrTics*sizeof(DWORD));
140 infoPtr->uNumTics = nrTics;
141 }
142
143 tic = infoPtr->nRangeMin+infoPtr->uTicFreq; //start not included
144 for (i = 0;i < nrTics;i++)
145 {
146 infoPtr->tics[i] = tic;
147 tic += infoPtr->uTicFreq;
148 }
149}
150
151
152/* converts from physical (mouse) position to logical position
153 (in range of trackbar) */
154
155static DOUBLE
156TRACKBAR_ConvertPlaceToPosition(TRACKBAR_INFO *infoPtr,int place,int vertical)
157{
158 double range,width,pos;
159
160 range = infoPtr->nRangeMax-infoPtr->nRangeMin;
161 if (vertical)
162 {
163 width = infoPtr->rcChannel.bottom-infoPtr->rcChannel.top;
164 pos = infoPtr->nRangeMin+(range*(place-infoPtr->rcChannel.top))/width;
165 } else
166 {
167 width = infoPtr->rcChannel.right-infoPtr->rcChannel.left;
168 pos = infoPtr->nRangeMin+(range*(place-infoPtr->rcChannel.left))/width;
169 }
170
171 if (pos > infoPtr->nRangeMax) pos = infoPtr->nRangeMax;
172 else if (pos < infoPtr->nRangeMin) pos = infoPtr->nRangeMin;
173
174 return pos;
175}
176
177
178static VOID
179TRACKBAR_CalcChannel(TRACKBAR_INFO *infoPtr)
180{
181 INT channelSize;
182 RECT lpRect,*channel = &infoPtr->rcChannel;
183 INT thumbDiff;
184
185 GetClientRect(infoPtr->hwnd,&lpRect);
186
187 if (infoPtr->dwStyle & TBS_ENABLESELRANGE) channelSize = MAX(infoPtr->uThumbLen-CHANNEL_THUMB_DIFF,CHANNEL_MIN_HEIGHT);
188 else channelSize = CHANNEL_NOSEL_HEIGHT;
189
190 thumbDiff = (infoPtr->uThumbLen-channelSize)/2;
191
192 if (infoPtr->dwStyle & TBS_VERT)
193 {
194 channel->top = lpRect.top+CHANNEL_SPACE;
195 channel->bottom = lpRect.bottom-CHANNEL_SPACE;
196
197 if ((infoPtr->dwStyle & TBS_BOTH) || (infoPtr->dwStyle & TBS_NOTICKS))
198 { //center
199 channel->left = (lpRect.right-channelSize)/2;
200 channel->right = (lpRect.right+channelSize)/2;
201 } else if (infoPtr->dwStyle & TBS_LEFT)
202 {
203 channel->left = lpRect.left+thumbDiff+CHANNEL_SCALE_SPACE;
204 channel->right = channel->left+channelSize;
205 } else
206 { //Right, align left
207 channel->left = lpRect.left+thumbDiff+CHANNEL_THUMB_SPACE;
208 channel->right = channel->left+channelSize;
209 }
210 } else
211 {
212 channel->left = lpRect.left+CHANNEL_SPACE;
213 channel->right = lpRect.right-CHANNEL_SPACE;
214 if ((infoPtr->dwStyle & TBS_BOTH) || (infoPtr->dwStyle & TBS_NOTICKS))
215 { //center
216 channel->top = (lpRect.bottom-channelSize)/2;
217 channel->bottom = (lpRect.bottom+channelSize)/2;
218 } else if (infoPtr->dwStyle & TBS_TOP)
219 {
220 channel->top = lpRect.top+thumbDiff+CHANNEL_SCALE_SPACE;
221 channel->bottom = channel->top+channelSize;
222 } else
223 { //Bottom, align top
224 channel->top = lpRect.top+thumbDiff+CHANNEL_THUMB_SPACE;
225 channel->bottom = channel->top+channelSize;
226 }
227 }
228}
229
230static VOID
231TRACKBAR_CalcThumb(TRACKBAR_INFO *infoPtr)
232{
233 RECT *thumb;
234 RECT *fullThumb;
235 int range, width;
236 int x,y;
237 int thumbFactor = 2;
238
239 thumb = &infoPtr->rcThumb;
240 fullThumb = &infoPtr->rcFullThumb;
241 range = infoPtr->nRangeMax-infoPtr->nRangeMin;
242 if (infoPtr->dwStyle & TBS_VERT)
243 {
244 width = infoPtr->rcChannel.bottom-infoPtr->rcChannel.top;
245 y = infoPtr->uThumbLen/thumbFactor; //thumb height
246 if (y%2 == 1) y++; //for real arrow
247 thumb->top = infoPtr->rcChannel.top+(width*(infoPtr->nPos-infoPtr->nRangeMin))/range-y/2; //centered
248 thumb->bottom = thumb->top+y;
249 //centered, no arrows
250 thumb->left = infoPtr->rcChannel.left-(infoPtr->uThumbLen-(infoPtr->rcChannel.right-infoPtr->rcChannel.left))/2;
251 thumb->right = thumb->left+infoPtr->uThumbLen;
252 CopyRect(fullThumb,thumb);
253 if (infoPtr->dwStyle & TBS_BOTH) return;
254 x = y/2; //arrow width
255 if (infoPtr->dwStyle & TBS_LEFT) thumb->left += x; else thumb->right -= x;
256 } else
257 {
258 width = infoPtr->rcChannel.right-infoPtr->rcChannel.left;
259 x = infoPtr->uThumbLen/thumbFactor; //thumb width
260 if (x%2 == 1) x++; //for real arrow
261 thumb->left = infoPtr->rcChannel.left+(width*(infoPtr->nPos-infoPtr->nRangeMin))/range-x/2; //centered
262 thumb->right = thumb->left+x;
263 //centered, no arrows
264 thumb->top = infoPtr->rcChannel.top-(infoPtr->uThumbLen-(infoPtr->rcChannel.bottom-infoPtr->rcChannel.top))/2;
265 thumb->bottom = thumb->top+infoPtr->uThumbLen;
266 CopyRect(fullThumb,thumb);
267 if (infoPtr->dwStyle & TBS_BOTH) return;
268 y = x/2; //arrow height
269 if (infoPtr->dwStyle & TBS_TOP) thumb->top += y; else thumb->bottom -= y;
270 }
271}
272
273static VOID
274TRACKBAR_CalcSelection(TRACKBAR_INFO *infoPtr)
275{
276 RECT *selection;
277 int range,width,height;
278 int selMin = infoPtr->nSelMin-infoPtr->nRangeMin; //relative to nRangeMin
279 int selMax = infoPtr->nSelMax-infoPtr->nRangeMin; //dito
280
281 selection = &infoPtr->rcSelection;
282 range = infoPtr->nRangeMax-infoPtr->nRangeMin;
283
284 if ((range <= 0) || (selMin == selMax)) SetRectEmpty(selection);
285 else
286 if (!(infoPtr->dwStyle & TBS_VERT))
287 { //Horizontal
288 width = infoPtr->rcChannel.right-infoPtr->rcChannel.left;
289 selection->left = infoPtr->rcChannel.left+(width*selMin)/range;
290 selection->right = infoPtr->rcChannel.left+(width*selMax)/range;
291 selection->top = infoPtr->rcChannel.top+2;
292 selection->bottom = infoPtr->rcChannel.bottom-2;
293 } else
294 { //Vertical
295 height = infoPtr->rcChannel.bottom-infoPtr->rcChannel.top;
296 selection->top = infoPtr->rcChannel.top+(height*selMin)/range;
297 selection->bottom = infoPtr->rcChannel.top+(height*selMax)/range;
298 selection->left = infoPtr->rcChannel.left+2;
299 selection->right = infoPtr->rcChannel.right-2;
300 }
301}
302
303/* Trackbar drawing code */
304
305/* ticPos is in tic-units, not in pixels */
306
307static VOID
308TRACKBAR_DrawHorizTic(TRACKBAR_INFO *infoPtr,HDC hdc,LONG ticPos,int flags,COLORREF clrTic)
309{
310 RECT rcChannel = infoPtr->rcChannel;
311 int x,y,width,range,side;
312
313 range = infoPtr->nRangeMax-infoPtr->nRangeMin;
314 width = rcChannel.right-rcChannel.left;
315
316 if (flags & TBS_TOP)
317 {
318 y = infoPtr->rcFullThumb.top-SCALE_SPACE-1;
319 side = -1;
320 } else
321 {
322 y = infoPtr->rcFullThumb.bottom+SCALE_SPACE+1;
323 side = 1;
324 }
325 if (flags & TIC_SELECTIONMARK)
326 {
327 ticPos -= infoPtr->nRangeMin; //relative to nRangeMin
328 if (flags & TIC_SELECTIONMARKMIN) x = rcChannel.left+(width*ticPos)/range - 1;
329 else x = rcChannel.left+(width*ticPos)/range+1;
330
331 //first line
332 SetPixel(hdc,x,y+1*side,clrTic);
333 SetPixel(hdc,x,y+2*side,clrTic);
334 //point
335 if (flags & TIC_SELECTIONMARKMIN) x--; else x++;
336 SetPixel(hdc,x,y+2*side,clrTic);
337
338 return;
339 }
340
341 if ((ticPos > infoPtr->nRangeMin) && (ticPos < infoPtr->nRangeMax))
342 {
343 ticPos -= infoPtr->nRangeMin; //relative to nRangeMin
344 x = rcChannel.left+(width*ticPos)/range;
345 SetPixel(hdc,x,y,clrTic); //base
346 SetPixel(hdc,x,y+1*side,clrTic);
347 SetPixel(hdc,x,y+2*side,clrTic);
348 }
349
350 if (flags & TIC_EDGE)
351 {
352 if (flags & TIC_LEFTEDGE) x = rcChannel.left;
353 else x = rcChannel.right;
354
355 SetPixel(hdc,x,y,clrTic); //base
356 SetPixel(hdc,x,y+1*side,clrTic);
357 SetPixel(hdc,x,y+2*side,clrTic);
358 SetPixel(hdc,x,y+3*side,clrTic);
359 }
360}
361
362static VOID TRACKBAR_FillHorzTics(TRACKBAR_INFO *infoPtr,HDC hdc,int flags,COLORREF clrTic)
363{
364 RECT rect;
365 INT range = infoPtr->nRangeMax-infoPtr->nRangeMin;
366 INT width = infoPtr->rcChannel.right-infoPtr->rcChannel.left;
367 HBRUSH hbr = CreateSolidBrush(clrTic);
368
369 if (flags & TBS_TOP)
370 {
371 rect.bottom = infoPtr->rcFullThumb.top-SCALE_SPACE-1+1;
372 rect.top = rect.bottom-3;
373 } else
374 {
375 rect.top = infoPtr->rcFullThumb.bottom+SCALE_SPACE+1;
376 rect.bottom = rect.top+3;
377 }
378 rect.left = infoPtr->rcChannel.left+(width*(infoPtr->tics[0]-infoPtr->nRangeMin))/range;
379 rect.right = infoPtr->rcChannel.left+(width*(infoPtr->tics[infoPtr->uNumTics-1]-infoPtr->nRangeMin))/range+1;
380
381 FillRect(hdc,&rect,hbr);
382 DeleteObject(hbr);
383}
384
385static VOID
386TRACKBAR_DrawVertTic(TRACKBAR_INFO *infoPtr,HDC hdc,LONG ticPos,int flags,COLORREF clrTic)
387{
388 RECT rcChannel = infoPtr->rcChannel;
389 int x,y,width,range,side;
390
391 range = infoPtr->nRangeMax-infoPtr->nRangeMin;
392 width = rcChannel.bottom-rcChannel.top;
393
394 if (flags & TBS_LEFT)
395 {
396 x = infoPtr->rcFullThumb.left-SCALE_SPACE-1;
397 side = -1;
398 } else
399 {
400 x = infoPtr->rcFullThumb.right+SCALE_SPACE+1;
401 side = 1;
402 }
403
404
405 if (flags & TIC_SELECTIONMARK)
406 {
407 ticPos -= infoPtr->nRangeMin;
408 if (flags & TIC_SELECTIONMARKMIN) y = rcChannel.top+(width*ticPos)/range-1;
409 else y = rcChannel.top+(width*ticPos)/range+1;
410
411 //first line
412 SetPixel(hdc,x+1*side,y,clrTic);
413 SetPixel(hdc,x+2*side,y,clrTic);
414 //point
415 if (flags & TIC_SELECTIONMARKMIN) y--; else y++;
416 SetPixel(hdc,x+2*side,y,clrTic);
417
418 return;
419 }
420
421 if ((ticPos>infoPtr->nRangeMin) && (ticPos<infoPtr->nRangeMax))
422 {
423 ticPos -= infoPtr->nRangeMin;
424 y = rcChannel.top+(width*ticPos)/range;
425 SetPixel (hdc,x, y,clrTic); //base
426 SetPixel (hdc,x+1*side,y,clrTic);
427 SetPixel (hdc,x+2*side,y,clrTic);
428 }
429
430 if (flags & TIC_EDGE)
431 {
432 if (flags & TIC_LEFTEDGE) y = rcChannel.top;
433 else y = rcChannel.bottom;
434
435 SetPixel (hdc,x,y,clrTic); //base
436 SetPixel (hdc,x+1*side,y,clrTic);
437 SetPixel (hdc,x+2*side,y,clrTic);
438 SetPixel (hdc,x+3*side,y,clrTic);
439 }
440}
441
442static VOID TRACKBAR_FillVertTics(TRACKBAR_INFO *infoPtr,HDC hdc,int flags,COLORREF clrTic)
443{
444 RECT rect;
445 INT range = infoPtr->nRangeMax-infoPtr->nRangeMin;
446 INT width = infoPtr->rcChannel.bottom-infoPtr->rcChannel.top;
447 HBRUSH hbr = CreateSolidBrush(clrTic);
448
449 if (flags & TBS_TOP)
450 {
451 rect.right = infoPtr->rcFullThumb.left-SCALE_SPACE-1+1;
452 rect.left = rect.right-3;
453 } else
454 {
455 rect.left = infoPtr->rcFullThumb.right+SCALE_SPACE+1;
456 rect.right = rect.left+3;
457 }
458 rect.top = infoPtr->rcChannel.top+(width*(infoPtr->tics[0]-infoPtr->nRangeMin))/range;
459 rect.bottom = infoPtr->rcChannel.top+(width*(infoPtr->tics[infoPtr->uNumTics-1]-infoPtr->nRangeMin))/range+1;
460
461 FillRect(hdc,&rect,hbr);
462 DeleteObject(hbr);
463}
464
465static VOID
466TRACKBAR_DrawTics(TRACKBAR_INFO *infoPtr,HDC hdc,LONG ticPos,int flags,COLORREF clrTic)
467{
468 if (flags & TBS_VERT)
469 {
470 if ((flags & TBS_LEFT) || (flags & TBS_BOTH))
471 TRACKBAR_DrawVertTic (infoPtr,hdc,ticPos,flags | TBS_LEFT ,clrTic);
472 //TBS_RIGHT == default
473 if (!(flags & TBS_LEFT) || (flags & TBS_BOTH))
474 TRACKBAR_DrawVertTic(infoPtr,hdc,ticPos,flags & ~TBS_LEFT,clrTic);
475 } else
476 {
477 if ((flags & TBS_TOP) || (flags & TBS_BOTH))
478 TRACKBAR_DrawHorizTic(infoPtr,hdc,ticPos,flags | TBS_TOP,clrTic);
479 //TBS_BOTTOM == default
480 if (!(flags & TBS_TOP) || (flags & TBS_BOTH))
481 TRACKBAR_DrawHorizTic(infoPtr,hdc,ticPos,flags & ~TBS_TOP,clrTic);
482 }
483}
484
485//draw thumb, call only from draw!
486
487static VOID TRACKBAR_DrawThumb(TRACKBAR_INFO *infoPtr,HDC hdc)
488{
489 if (!(infoPtr->dwStyle & TBS_NOTHUMB))
490 {
491 HBRUSH hbr,hbrOld;
492 RECT thumb = infoPtr->rcThumb;
493
494 if ((infoPtr->flags & TB_DRAG_MODE) || !IsWindowEnabled(infoPtr->hwnd)) hbr = CreateSolidBrush(infoPtr->clrHighlightedThumb);
495 else hbr = infoPtr->hbrThumb;
496 hbrOld = SelectObject(hdc,hbr);
497
498 if (infoPtr->dwStyle & TBS_BOTH)
499 {
500 DrawEdge(hdc,&thumb,EDGE_RAISED,BF_RECT | BF_ADJUST);
501 FillRect(hdc,&thumb,hbr);
502 } else
503 {
504 POINT points[6];
505 RECT triangle; /* for correct shadows of thumb */
506
507 if (infoPtr->dwStyle & TBS_VERT)
508 { //Vertical
509
510 if (infoPtr->dwStyle & TBS_LEFT)
511 {
512 HPEN oldPen,pen;
513
514 //Outline
515
516 SetPolyFillMode(hdc,WINDING);
517 points[0].x = thumb.left;
518 points[0].y = thumb.top;
519 points[1].x = thumb.left-(thumb.bottom-thumb.top)/2;
520 points[1].y = thumb.top+(thumb.bottom-thumb.top)/2;
521 points[2].x = thumb.left;
522 points[2].y = thumb.bottom;
523 points[3].x = thumb.right;
524 points[3].y = thumb.bottom;
525 points[4].x = thumb.right;
526 points[4].y = thumb.top;
527 points[5].x = points[0].x;
528 points[5].y = points[0].y;
529 Polygon(hdc,points,6);
530
531 //Edge
532
533 thumb.bottom++;
534 thumb.right++;
535 DrawEdge(hdc,&thumb,EDGE_RAISED,BF_BOTTOM | BF_TOP | BF_RIGHT);
536
537 //Draw notch
538
539 triangle.right = points[0].x;
540 triangle.top = points[0].y;
541 triangle.left = points[1].x;
542 triangle.bottom = points[1].y;
543 DrawEdge(hdc,&triangle,EDGE_RAISED,BF_DIAGONAL | BF_DIAGONAL_ENDTOPRIGHT);
544
545 //draw this line direct, DrawEdge not useful
546 pen = GetSysColorPen(COLOR_3DDKSHADOW);
547 oldPen = SelectObject(hdc,pen);
548 MoveToEx(hdc,points[1].x,points[1].y,NULL);
549 LineTo(hdc,points[2].x-1,points[2].y-1);
550 pen = GetSysColorPen(COLOR_BTNSHADOW);
551 SelectObject(hdc,pen);
552 MoveToEx(hdc,points[1].x+1,points[1].y,NULL);
553 LineTo(hdc,points[2].x,points[2].y-1);
554 SelectObject(hdc,oldPen);
555
556 } else //Right
557 {
558 HPEN oldPen,pen;
559
560 //Outline
561
562 SetPolyFillMode(hdc,WINDING);
563 points[0].x = thumb.left;
564 points[0].y = thumb.top;
565 points[1].x = thumb.left;
566 points[1].y = thumb.bottom;
567 points[2].x = thumb.right;
568 points[2].y = thumb.bottom;
569 points[3].x = thumb.right+(thumb.bottom-thumb.top)/2;
570 points[3].y = thumb.bottom-(thumb.bottom-thumb.top)/2;
571 points[4].x = thumb.right;
572 points[4].y = thumb.top;
573 points[5].x = points[0].x;
574 points[5].y = points[0].y;
575 Polygon(hdc,points,6);
576
577 //Edge
578
579 thumb.bottom++;
580 DrawEdge(hdc,&thumb,EDGE_RAISED,BF_BOTTOM | BF_TOP | BF_LEFT);
581
582 //Draw notch
583
584 //draw this line direct, DrawEdge not useful
585 pen = GetSysColorPen(COLOR_3DLIGHT);
586 oldPen = SelectObject(hdc,pen);
587 MoveToEx(hdc,points[4].x,points[4].y,NULL);
588 LineTo(hdc,points[3].x,points[3].y);
589 pen = GetSysColorPen(COLOR_BTNHIGHLIGHT);
590 SelectObject(hdc,pen);
591 MoveToEx(hdc,points[4].x,points[4].y+1,NULL);
592 LineTo(hdc,points[3].x-1,points[3].y);
593 SelectObject(hdc,oldPen);
594
595 triangle.right = points[3].x;
596 triangle.top = points[3].y;
597 triangle.left = points[2].x;
598 triangle.bottom = points[2].y;
599 DrawEdge(hdc,&triangle,EDGE_RAISED,BF_DIAGONAL | BF_DIAGONAL_ENDBOTTOMLEFT);
600 }
601 } else
602 { //Horizontal
603
604 if (infoPtr->dwStyle & TBS_TOP)
605 {
606 //Outline
607
608 SetPolyFillMode(hdc,WINDING);
609 points[0].x = thumb.left;
610 points[0].y = thumb.top;
611 points[1].x = thumb.left+(thumb.right-thumb.left)/2;
612 points[1].y = thumb.top-(thumb.right-thumb.left)/2;
613 points[2].x = thumb.right;
614 points[2].y = thumb.top;
615 points[3].x = thumb.right;
616 points[3].y = thumb.bottom;
617 points[4].x = thumb.left;
618 points[4].y = thumb.bottom;
619 points[5].x = points[0].x;
620 points[5].y = points[0].y;
621 Polygon(hdc,points,6);
622
623 //Edge
624
625 thumb.right++;
626 thumb.bottom++;
627 DrawEdge(hdc,&thumb,EDGE_RAISED,BF_BOTTOM | BF_LEFT | BF_RIGHT);
628
629 //Draw notch
630
631 triangle.left = points[0].x;
632 triangle.bottom = points[0].y;
633 triangle.right = points[1].x;
634 triangle.top = points[1].y;
635 DrawEdge(hdc,&triangle,EDGE_RAISED,BF_DIAGONAL | BF_DIAGONAL_ENDTOPRIGHT);
636
637
638 triangle.left = points[1].x;
639 triangle.top = points[1].y;
640 triangle.right = points[2].x;
641 triangle.bottom = points[2].y;
642 DrawEdge(hdc,&triangle,EDGE_RAISED,BF_DIAGONAL | BF_DIAGONAL_ENDBOTTOMRIGHT);
643
644 } else //Bottom
645 {
646
647 //Outline
648
649 SetPolyFillMode(hdc,WINDING);
650 points[0].x = thumb.left;
651 points[0].y = thumb.top;
652 points[1].x = thumb.right;
653 points[1].y = thumb.top;
654 points[2].x = thumb.right;
655 points[2].y = thumb.bottom;
656 points[3].x = thumb.right-(thumb.right-thumb.left)/2;
657 points[3].y = thumb.bottom+(thumb.right-thumb.left)/2;
658 points[4].x = thumb.left;
659 points[4].y = thumb.bottom;
660 points[5].x = points[0].x;
661 points[5].y = points[0].y;
662 Polygon(hdc,points,6);
663
664 //Edge
665
666 thumb.right++;
667 thumb.bottom++;
668 DrawEdge(hdc,&thumb,EDGE_RAISED,BF_TOP | BF_LEFT | BF_RIGHT);
669
670 //Draw notch
671
672 triangle.right = points[2].x;
673 triangle.top = points[2].y;
674 triangle.left = points[3].x;
675 triangle.bottom = points[3].y;
676 DrawEdge(hdc,&triangle,EDGE_RAISED,BF_DIAGONAL | BF_DIAGONAL_ENDBOTTOMLEFT);
677 triangle.right = points[3].x;
678 triangle.bottom = points[3].y;
679 triangle.left = points[4].x;
680 triangle.top = points[4].y;
681 DrawEdge(hdc,&triangle,EDGE_RAISED,BF_DIAGONAL | BF_DIAGONAL_ENDTOPLEFT);
682
683 }
684 }
685 }
686 SelectObject(hdc,hbrOld);
687 if (hbr != infoPtr->hbrThumb) DeleteObject(hbr);
688 }
689}
690
691//draw the trackbar
692
693static VOID TRACKBAR_Draw(TRACKBAR_INFO *infoPtr,HDC hdc)
694{
695 RECT rcClient,rcChannel,rcSelection;
696 HBRUSH hBrush;
697 int i;
698 NMCUSTOMDRAW cdraw;
699 LRESULT cdctlres,cdres;
700
701 GetClientRect(infoPtr->hwnd,&rcClient);
702
703 //Custom draw
704 cdraw.dwDrawStage = CDDS_PREPAINT;
705 cdraw.hdc = hdc;
706 cdraw.dwItemSpec = 0;
707 cdraw.uItemState = infoPtr->bFocus ? CDIS_FOCUS:CDIS_DEFAULT;
708 cdraw.rc = rcClient;
709 cdraw.lItemlParam = 0;
710
711 cdctlres = sendNotify(infoPtr->hwnd,NM_CUSTOMDRAW,&cdraw.hdr);
712
713 if (cdctlres & CDRF_SKIPDEFAULT) return;
714
715 //Background
716 hBrush = CreateSolidBrush(infoPtr->clrBk);
717 FillRect(hdc,&rcClient,hBrush);
718 DeleteObject(hBrush);
719
720 if (infoPtr->flags & TB_DRAGPOSVALID)
721 {
722 infoPtr->nPos = infoPtr->dragPos;
723 infoPtr->flags |= TB_THUMBPOSCHANGED;
724 }
725
726 if (infoPtr->flags & TB_THUMBCHANGED)
727 {
728 if (infoPtr->flags & TB_THUMBSIZECHANGED)
729 {
730 TRACKBAR_CalcChannel(infoPtr);
731 TRACKBAR_CalcSelection(infoPtr);
732 }
733 TRACKBAR_CalcThumb(infoPtr);
734 }
735 if (infoPtr->flags & TB_SELECTIONCHANGED) TRACKBAR_CalcSelection(infoPtr);
736 infoPtr->flags &= ~ (TB_THUMBCHANGED | TB_SELECTIONCHANGED | TB_DRAGPOSVALID);
737
738 /* draw channel */
739
740 if (cdctlres & CDRF_NOTIFYITEMDRAW)
741 {
742 cdraw.dwDrawStage = CDDS_ITEMPREPAINT;
743 cdraw.dwItemSpec = TBCD_CHANNEL;
744 cdraw.rc = infoPtr->rcChannel;
745
746 cdres = sendNotify(infoPtr->hwnd,NM_CUSTOMDRAW,&cdraw.hdr);
747 } else cdres = 0;
748
749 if (!(cdres & CDRF_SKIPDEFAULT))
750 {
751 rcChannel = infoPtr->rcChannel;
752 rcSelection = infoPtr->rcSelection;
753 DrawEdge(hdc,&rcChannel,EDGE_SUNKEN,BF_RECT | BF_ADJUST);
754
755 if (infoPtr->dwStyle & TBS_ENABLESELRANGE) /* fill the channel */
756 {
757 HBRUSH hbr = CreateSolidBrush(RGB(255,255,255));
758 FillRect(hdc,&rcChannel,hbr);
759 DeleteObject(hbr);
760 if (((infoPtr->dwStyle & TBS_VERT) && (rcSelection.top != rcSelection.bottom)) ||
761 ((!(infoPtr->dwStyle & TBS_VERT)) && (rcSelection.left != rcSelection.right)))
762 {
763 hbr = CreateSolidBrush (COLOR_HIGHLIGHT);
764 FillRect (hdc,&rcSelection,hbr);
765 DeleteObject(hbr);
766 }
767 }
768
769 if (cdctlres & CDRF_NOTIFYITEMDRAW)
770 {
771 cdraw.dwDrawStage = CDDS_ITEMPOSTPAINT;
772
773 sendNotify(infoPtr->hwnd,NM_CUSTOMDRAW,&cdraw.hdr);
774 }
775 }
776
777 /* draw tics */
778
779 if (cdctlres & CDRF_NOTIFYITEMDRAW)
780 {
781 cdraw.dwDrawStage = CDDS_ITEMPREPAINT;
782 cdraw.dwItemSpec = TBCD_TICS;
783 SetRectEmpty(&cdraw.rc);
784
785 cdres = sendNotify(infoPtr->hwnd,NM_CUSTOMDRAW,&cdraw.hdr);
786 } else cdres = 0;
787
788 if (!(cdres & CDRF_SKIPDEFAULT))
789 {
790 if (!(infoPtr->dwStyle & TBS_NOTICKS))
791 {
792 int ticFlags = infoPtr->dwStyle & 0x0f;
793 COLORREF clrTic = GetSysColor(COLOR_3DDKSHADOW);
794 INT range = infoPtr->nRangeMax-infoPtr->nRangeMin;
795 INT width = (infoPtr->dwStyle & TBS_VERT) ? rcChannel.bottom-rcChannel.top:rcChannel.right-rcChannel.left;
796
797 //check if maximum of visible marks is reached
798 if ((infoPtr->dwStyle & TBS_AUTOTICKS) && (infoPtr->uNumTics > 1) && ((INT)(width*infoPtr->tics[0]/range) == (INT)(width*infoPtr->tics[1]/range)))
799 {
800 //draw all pixels at once -> much faster
801 if (infoPtr->dwStyle & TBS_VERT)
802 {
803 if ((ticFlags & TBS_LEFT) || (ticFlags & TBS_BOTH))
804 TRACKBAR_FillVertTics(infoPtr,hdc,ticFlags | TBS_LEFT,clrTic);
805 if (!(ticFlags & TBS_LEFT) || (ticFlags & TBS_BOTH))
806 TRACKBAR_FillVertTics(infoPtr,hdc,ticFlags & ~TBS_LEFT,clrTic);
807 } else
808 {
809 if ((ticFlags & TBS_TOP) || (ticFlags & TBS_BOTH))
810 TRACKBAR_FillHorzTics(infoPtr,hdc,ticFlags | TBS_TOP,clrTic);
811 if (!(ticFlags & TBS_TOP) || (ticFlags & TBS_BOTH))
812 TRACKBAR_FillHorzTics(infoPtr,hdc,ticFlags & ~TBS_TOP,clrTic);
813 }
814 } else
815 {
816 for (i = 0;i < infoPtr->uNumTics;i++)
817 TRACKBAR_DrawTics(infoPtr,hdc,infoPtr->tics[i],ticFlags,clrTic);
818 }
819
820 TRACKBAR_DrawTics(infoPtr,hdc,0,ticFlags | TIC_LEFTEDGE,clrTic);
821 TRACKBAR_DrawTics(infoPtr,hdc,0,ticFlags | TIC_RIGHTEDGE,clrTic);
822
823 if ((infoPtr->dwStyle & TBS_ENABLESELRANGE) &&
824 ((infoPtr->dwStyle & TBS_VERT && rcSelection.bottom != rcSelection.top) ||
825 (!(infoPtr->dwStyle & TBS_VERT) && rcSelection.left != rcSelection.right)))
826 {
827 TRACKBAR_DrawTics(infoPtr,hdc,infoPtr->nSelMin,ticFlags | TIC_SELECTIONMARKMIN,clrTic);
828 TRACKBAR_DrawTics(infoPtr,hdc,infoPtr->nSelMax,ticFlags | TIC_SELECTIONMARKMAX,clrTic);
829 }
830 }
831
832 if (cdctlres & CDRF_NOTIFYITEMDRAW)
833 {
834 cdraw.dwDrawStage = CDDS_ITEMPOSTPAINT;
835
836 sendNotify(infoPtr->hwnd,NM_CUSTOMDRAW,&cdraw.hdr);
837 }
838 }
839
840 /* draw thumb */
841
842 if (cdctlres & CDRF_NOTIFYITEMDRAW)
843 {
844 cdraw.dwDrawStage = CDDS_ITEMPREPAINT;
845 cdraw.dwItemSpec = TBCD_THUMB;
846 cdraw.rc = infoPtr->rcFullThumb;
847
848 cdres = sendNotify(infoPtr->hwnd,NM_CUSTOMDRAW,&cdraw.hdr);
849 } else cdres = 0;
850
851 if (!(cdres & CDRF_SKIPDEFAULT))
852 {
853 TRACKBAR_DrawThumb(infoPtr,hdc);
854
855 if (cdctlres & CDRF_NOTIFYITEMDRAW)
856 {
857 cdraw.dwDrawStage = CDDS_ITEMPOSTPAINT;
858
859 sendNotify(infoPtr->hwnd,NM_CUSTOMDRAW,&cdraw.hdr);
860 }
861
862 }
863
864 if (infoPtr->bFocus && IsWindowEnabled(infoPtr->hwnd)) DrawFocusRect(hdc,&rcClient);
865
866 if (cdctlres & CDRF_NOTIFYPOSTPAINT)
867 {
868 cdraw.dwDrawStage = CDDS_POSTPAINT;
869 cdraw.dwItemSpec = 0;
870 GetClientRect(infoPtr->hwnd,&cdraw.rc);
871
872 sendNotify(infoPtr->hwnd,NM_CUSTOMDRAW,&cdraw.hdr);
873 }
874
875}
876
877//update thumb position
878
879static VOID TRACKBAR_UpdateThumbPosition(TRACKBAR_INFO *infoPtr,INT lastPos,BOOL mustRedraw)
880{
881 HDC hdc;
882 RECT lastRect,newRect,updateRect;
883 HDC hdcCompatible;
884 HBITMAP bitmap,oldbmp;
885
886 //last
887 lastRect = infoPtr->rcFullThumb;
888
889 //new
890 if (infoPtr->flags & TB_DRAGPOSVALID)
891 {
892 infoPtr->nPos = infoPtr->dragPos;
893 infoPtr->flags &= ~TB_DRAGPOSVALID;
894 }
895 if (!mustRedraw && (infoPtr->nPos == lastPos)) return;
896
897 if (infoPtr->dwStyle & TBS_NOTHUMB) return;
898
899 TRACKBAR_CalcThumb(infoPtr);
900 infoPtr->flags &= ~TB_THUMBCHANGED;
901 newRect = infoPtr->rcFullThumb;
902
903 //same rect?
904 if (!mustRedraw && EqualRect(&lastRect,&newRect)) return;
905
906 //3D frame adjustation
907 lastRect.right++;
908 lastRect.bottom++;
909 newRect.right++;
910 newRect.bottom++;
911
912 //BitBlt from memory -> no flickering
913 updateRect.left = MIN(lastRect.left,newRect.left);
914 updateRect.right = MAX(lastRect.right,newRect.right);
915 updateRect.top = MIN(lastRect.top,newRect.top);
916 updateRect.bottom = MAX(lastRect.bottom,newRect.bottom);
917 hdc = GetDC(infoPtr->hwnd);
918 hdcCompatible = CreateCompatibleDC(hdc);
919 bitmap = CreateCompatibleBitmap(hdc,updateRect.right,updateRect.bottom);
920 oldbmp = SelectObject(hdcCompatible,bitmap);
921 TRACKBAR_Draw(infoPtr,hdcCompatible);
922 if (infoPtr->dwStyle & TBS_VERT)
923 {
924 if ((lastRect.top > newRect.top) && (lastRect.top < newRect.bottom))
925 BitBlt(hdc,newRect.left,newRect.top,newRect.right-newRect.left,lastRect.bottom-newRect.top,hdcCompatible,newRect.left,newRect.top,SRCCOPY);
926 else if ((lastRect.bottom < newRect.bottom) && (lastRect.bottom > newRect.top))
927 BitBlt(hdc,lastRect.left,lastRect.top,lastRect.right-lastRect.left,newRect.bottom-lastRect.top,hdcCompatible,lastRect.left,lastRect.top,SRCCOPY);
928 else
929 {
930 BitBlt(hdc,lastRect.left,lastRect.top,lastRect.right-lastRect.left,lastRect.bottom-lastRect.top,hdcCompatible,lastRect.left,lastRect.top,SRCCOPY);
931 BitBlt(hdc,newRect.left,newRect.top,newRect.right-newRect.left,newRect.bottom-newRect.top,hdcCompatible,newRect.left,newRect.top,SRCCOPY);
932 }
933 } else
934 {
935 if ((lastRect.right > newRect.left) && (lastRect.right < newRect.right))
936 BitBlt(hdc,lastRect.left,lastRect.top,newRect.right-lastRect.left,lastRect.bottom-lastRect.top,hdcCompatible,lastRect.left,lastRect.top,SRCCOPY);
937 else if ((lastRect.left < newRect.right) && (lastRect.left > newRect.left))
938 BitBlt(hdc,newRect.left,newRect.top,lastRect.right-newRect.left,newRect.bottom-newRect.top,hdcCompatible,newRect.left,newRect.top,SRCCOPY);
939 else
940 {
941 BitBlt(hdc,lastRect.left,lastRect.top,lastRect.right-lastRect.left,lastRect.bottom-lastRect.top,hdcCompatible,lastRect.left,lastRect.top,SRCCOPY);
942 BitBlt(hdc,newRect.left,newRect.top,newRect.right-newRect.left,newRect.bottom-newRect.top,hdcCompatible,newRect.left,newRect.top,SRCCOPY);
943 }
944 }
945 SelectObject(hdcCompatible,oldbmp);
946 DeleteObject(bitmap);
947 DeleteDC(hdcCompatible);
948 ReleaseDC(infoPtr->hwnd,hdc);
949}
950
951//redraw everything
952
953static VOID TRACKBAR_Refresh(TRACKBAR_INFO *infoPtr)
954{
955 HDC hdc;
956
957 hdc = GetDC(infoPtr->hwnd);
958 TRACKBAR_Draw(infoPtr,hdc);
959 ReleaseDC(infoPtr->hwnd,hdc);
960}
961
962static VOID
963TRACKBAR_AlignBuddies(TRACKBAR_INFO *infoPtr)
964{
965 HWND hwndParent = GetParent(infoPtr->hwnd);
966 RECT rcSelf,rcBuddy;
967 INT x, y;
968
969 GetWindowRect(infoPtr->hwnd,&rcSelf);
970 MapWindowPoints(HWND_DESKTOP,hwndParent,(LPPOINT)&rcSelf,2);
971
972 /* align buddy left or above */
973 if (infoPtr->hwndBuddyLA)
974 {
975 GetWindowRect(infoPtr->hwndBuddyLA,&rcBuddy);
976
977 if (infoPtr->dwStyle & TBS_VERT)
978 { //above
979 x = (infoPtr->rcChannel.right+infoPtr->rcChannel.left)/2-(rcBuddy.right-rcBuddy.left)/2+rcSelf.left;
980 y = rcSelf.top-(rcBuddy.bottom-rcBuddy.top);
981 } else
982 { //left
983 x = rcSelf.left-(rcBuddy.right-rcBuddy.left);
984 y = (infoPtr->rcChannel.bottom+infoPtr->rcChannel.top)/2-(rcBuddy.bottom-rcBuddy.top)/2+rcSelf.top;
985 }
986
987 SetWindowPos(infoPtr->hwndBuddyLA,0,x,y,0,0,SWP_NOZORDER | SWP_NOSIZE);
988 }
989
990
991 /* align buddy right or below */
992 if (infoPtr->hwndBuddyRB)
993 {
994 GetWindowRect(infoPtr->hwndBuddyRB,&rcBuddy);
995
996 if (infoPtr->dwStyle & TBS_VERT)
997 { //below
998 x = (infoPtr->rcChannel.right+infoPtr->rcChannel.left)/2-(rcBuddy.right-rcBuddy.left)/2+rcSelf.left;
999 y = rcSelf.bottom;
1000 } else
1001 { //right
1002 x = rcSelf.right;
1003 y = (infoPtr->rcChannel.bottom+infoPtr->rcChannel.top)/2-(rcBuddy.bottom-rcBuddy.top)/2+rcSelf.top;
1004 }
1005
1006 SetWindowPos(infoPtr->hwndBuddyRB,0,x,y,0,0,SWP_NOZORDER | SWP_NOSIZE);
1007 }
1008}
1009
1010static LRESULT
1011TRACKBAR_ClearSel(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1012{
1013 if (infoPtr->nSelMin != infoPtr->nSelMax)
1014 {
1015 infoPtr->nSelMin = 0;
1016 infoPtr->nSelMax = 0;
1017 infoPtr->flags |= TB_SELECTIONCHANGED;
1018
1019 if ((BOOL)wParam) TRACKBAR_Refresh(infoPtr);
1020 }
1021
1022 return 0;
1023}
1024
1025static LRESULT
1026TRACKBAR_ClearTics(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1027{
1028 if (!(infoPtr->dwStyle & (TBS_AUTOTICKS | TBS_NOTICKS))) return 0;
1029
1030 if (infoPtr->tics)
1031 {
1032 COMCTL32_Free(infoPtr->tics);
1033 infoPtr->tics = NULL;
1034 infoPtr->uNumTics = 0;
1035
1036 if (wParam) TRACKBAR_Refresh(infoPtr);
1037 }
1038
1039 return 0;
1040}
1041
1042
1043static LRESULT
1044TRACKBAR_GetBuddy(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1045{
1046 if (wParam)
1047 return (LRESULT)infoPtr->hwndBuddyLA; //left or above
1048 else
1049 return (LRESULT)infoPtr->hwndBuddyRB; //right or below
1050}
1051
1052static LRESULT
1053TRACKBAR_GetChannelRect(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1054{
1055 LPRECT lprc = (LPRECT)lParam;
1056
1057 if (lprc == NULL) return 0;
1058
1059 CopyRect(lprc,&infoPtr->rcChannel);
1060
1061 return 0;
1062}
1063
1064static LRESULT
1065TRACKBAR_GetLineSize(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1066{
1067 return infoPtr->nLineSize;
1068}
1069
1070
1071static LRESULT
1072TRACKBAR_GetNumTics(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1073{
1074 if (infoPtr->dwStyle & TBS_NOTICKS) return 0;
1075
1076 return infoPtr->uNumTics+2; //includes last and first tick
1077}
1078
1079static LRESULT
1080TRACKBAR_GetPageSize(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1081{
1082 return infoPtr->nPageSize;
1083}
1084
1085
1086static LRESULT
1087TRACKBAR_GetPos(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1088{
1089 return infoPtr->nPos;
1090}
1091
1092
1093static LRESULT
1094TRACKBAR_GetRangeMax(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1095{
1096 return infoPtr->nRangeMax;
1097}
1098
1099
1100static LRESULT
1101TRACKBAR_GetRangeMin(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1102{
1103 return infoPtr->nRangeMin;
1104}
1105
1106
1107static LRESULT
1108TRACKBAR_GetSelEnd(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1109{
1110 return infoPtr->nSelMax;
1111}
1112
1113
1114static LRESULT
1115TRACKBAR_GetSelStart(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1116{
1117 return infoPtr->nSelMin;
1118}
1119
1120
1121static LRESULT
1122TRACKBAR_GetThumbLength(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1123{
1124 return infoPtr->uThumbLen;
1125}
1126
1127static LRESULT
1128TRACKBAR_GetPTics(TRACKBAR_INFO *infoPtr)
1129{
1130 return (LRESULT)infoPtr->tics;
1131}
1132
1133static LRESULT
1134TRACKBAR_GetThumbRect(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1135{
1136 LPRECT lprc = (LPRECT)lParam;
1137
1138 if (lprc == NULL) return 0;
1139
1140 CopyRect(lprc,&infoPtr->rcFullThumb);
1141
1142 return 0;
1143}
1144
1145
1146static LRESULT
1147TRACKBAR_GetTic(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1148{
1149 INT iTic;
1150
1151 iTic = (INT)wParam;
1152 if ((iTic < 0) || (iTic > infoPtr->uNumTics)) return -1;
1153
1154 return (LRESULT)infoPtr->tics[iTic];
1155
1156}
1157
1158
1159static LRESULT
1160TRACKBAR_GetTicPos(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1161{
1162 INT iTic, range, width, pos;
1163
1164
1165 iTic = (INT)wParam;
1166 if ((iTic < 0) || (iTic > infoPtr->uNumTics)) return -1;
1167
1168 range = infoPtr->nRangeMax-infoPtr->nRangeMin;
1169 width = infoPtr->rcChannel.right-infoPtr->rcChannel.left;
1170 pos = infoPtr->rcChannel.left+(width*(infoPtr->tics[iTic]-infoPtr->nRangeMin))/range;
1171
1172 return (LRESULT) pos;
1173}
1174
1175
1176static LRESULT
1177TRACKBAR_GetToolTips(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1178{
1179 if (infoPtr->dwStyle & TBS_TOOLTIPS)
1180 return (LRESULT)infoPtr->hwndToolTip;
1181 return 0;
1182}
1183
1184
1185static LRESULT
1186TRACKBAR_SetBuddy(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1187{
1188 HWND hwndTemp;
1189
1190 if (!(GetParent(lParam) == GetParent(infoPtr->hwnd))) return wParam ? infoPtr->hwndBuddyLA:infoPtr->hwndBuddyRB;
1191
1192 if (wParam)
1193 {
1194 /* buddy is left or above */
1195 hwndTemp = infoPtr->hwndBuddyLA;
1196 infoPtr->hwndBuddyLA = (HWND)lParam;
1197 } else
1198 {
1199 /* buddy is right or below */
1200 hwndTemp = infoPtr->hwndBuddyRB;
1201 infoPtr->hwndBuddyRB = (HWND)lParam;
1202 }
1203
1204 TRACKBAR_AlignBuddies(infoPtr);
1205
1206 return (LRESULT)hwndTemp;
1207}
1208
1209
1210static LRESULT
1211TRACKBAR_SetLineSize(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1212{
1213 INT nTemp = infoPtr->nLineSize;
1214
1215 infoPtr->nLineSize = (INT)lParam;
1216
1217 return nTemp;
1218}
1219
1220
1221static LRESULT
1222TRACKBAR_SetPageSize(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1223{
1224 INT nTemp = infoPtr->nPageSize;
1225
1226 infoPtr->nPageSize = (INT)lParam;
1227
1228 return nTemp;
1229}
1230
1231
1232static LRESULT
1233TRACKBAR_SetPos(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1234{
1235 INT lastPos = infoPtr->nPos;
1236
1237 infoPtr->nPos = (INT)LOWORD(lParam);
1238
1239 if (lastPos == infoPtr->nPos) return 0; //nothing changed
1240
1241 if (infoPtr->nPos < infoPtr->nRangeMin)
1242 infoPtr->nPos = infoPtr->nRangeMin;
1243
1244 if (infoPtr->nPos > infoPtr->nRangeMax)
1245 infoPtr->nPos = infoPtr->nRangeMax;
1246 infoPtr->flags |= TB_THUMBPOSCHANGED;
1247
1248 if (wParam) TRACKBAR_UpdateThumbPosition(infoPtr,lastPos,FALSE);
1249
1250 return 0;
1251}
1252
1253
1254static LRESULT
1255TRACKBAR_SetRange(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1256{
1257 int newMin,newMax;
1258
1259 newMin = (INT)LOWORD(lParam);
1260 newMax = (INT)HIWORD(lParam);
1261
1262 if (newMin == newMax) return 0;
1263 if (newMin > newMax)
1264 { //exchange
1265 int x;
1266
1267 x = newMin;
1268 newMin = newMax;
1269 newMax = x;
1270 }
1271 if ((newMin == infoPtr->nRangeMin) && (newMax == infoPtr->nRangeMax)) return 0;
1272
1273 infoPtr->nRangeMin = newMin;
1274 infoPtr->nRangeMax = newMax;
1275
1276 if (infoPtr->nPos < infoPtr->nRangeMin)
1277 {
1278 infoPtr->nPos = infoPtr->nRangeMin;
1279 infoPtr->flags |= TB_THUMBPOSCHANGED;
1280 }
1281 if (infoPtr->nPos > infoPtr->nRangeMax)
1282 {
1283 infoPtr->nPos = infoPtr->nRangeMax;
1284 infoPtr->flags |= TB_THUMBPOSCHANGED;
1285 }
1286
1287 if (infoPtr->nSelMin < infoPtr->nRangeMin)
1288 {
1289 infoPtr->nSelMin = infoPtr->nRangeMin;
1290 infoPtr->flags |= TB_SELECTIONCHANGED;
1291 }
1292 if (infoPtr->nSelMin > infoPtr->nRangeMax)
1293 {
1294 infoPtr->nSelMin = infoPtr->nRangeMax;
1295 infoPtr->flags |= TB_SELECTIONCHANGED;
1296 }
1297 if (infoPtr->nSelMax < infoPtr->nRangeMin)
1298 {
1299 infoPtr->nSelMax = infoPtr->nRangeMin;
1300 infoPtr->flags |= TB_SELECTIONCHANGED;
1301 }
1302 if (infoPtr->nSelMax > infoPtr->nRangeMax)
1303 {
1304 infoPtr->nSelMax = infoPtr->nRangeMax;
1305 infoPtr->flags |= TB_SELECTIONCHANGED;
1306 }
1307
1308 infoPtr->nPageSize = (infoPtr->nRangeMax-infoPtr->nRangeMin)/5;
1309 if (infoPtr->nPageSize == 0) infoPtr->nPageSize = 1;
1310 TRACKBAR_RecalculateTics(infoPtr,TRUE);
1311
1312 if (wParam) TRACKBAR_Refresh(infoPtr);
1313
1314 return 0;
1315}
1316
1317
1318static LRESULT
1319TRACKBAR_SetRangeMax(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1320{
1321 if ((INT)lParam <= infoPtr->nRangeMin) return 0;
1322 if (infoPtr->nRangeMax == (INT)lParam) return 0;
1323
1324 infoPtr->nRangeMax = (INT)lParam;
1325 if (infoPtr->nPos > infoPtr->nRangeMax)
1326 {
1327 infoPtr->nPos = infoPtr->nRangeMax;
1328 infoPtr->flags |=TB_THUMBPOSCHANGED;
1329 }
1330
1331 infoPtr->nPageSize = (infoPtr->nRangeMax-infoPtr->nRangeMin)/5;
1332 if (infoPtr->nPageSize == 0) infoPtr->nPageSize = 1;
1333 TRACKBAR_RecalculateTics(infoPtr,TRUE);
1334
1335 if (wParam) TRACKBAR_Refresh(infoPtr);
1336
1337 return 0;
1338}
1339
1340
1341static LRESULT
1342TRACKBAR_SetRangeMin(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1343{
1344 if ((INT)lParam >= infoPtr->nRangeMax) return 0;
1345 if (infoPtr->nRangeMin == (INT)lParam) return 0;
1346
1347 infoPtr->nRangeMin = (INT)lParam;
1348 if (infoPtr->nPos < infoPtr->nRangeMin)
1349 {
1350 infoPtr->nPos = infoPtr->nRangeMin;
1351 infoPtr->flags |=TB_THUMBPOSCHANGED;
1352 }
1353
1354 infoPtr->nPageSize = (infoPtr->nRangeMax-infoPtr->nRangeMin)/5;
1355 if (infoPtr->nPageSize == 0) infoPtr->nPageSize = 1;
1356 TRACKBAR_RecalculateTics(infoPtr,TRUE);
1357
1358 if (wParam) TRACKBAR_Refresh(infoPtr);
1359
1360 return 0;
1361}
1362
1363
1364static LRESULT
1365TRACKBAR_SetTicFreq(TRACKBAR_INFO *infoPtr,WPARAM wParam)
1366{
1367 if (infoPtr->uTicFreq == (UINT)wParam) return 0;
1368
1369 if (!(infoPtr->dwStyle & TBS_AUTOTICKS)) return 0;
1370
1371 infoPtr->uTicFreq = (UINT)wParam;
1372
1373 TRACKBAR_RecalculateTics(infoPtr,FALSE);
1374
1375 TRACKBAR_Refresh(infoPtr);
1376
1377 return 0;
1378}
1379
1380static LRESULT
1381TRACKBAR_SetSel(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1382{
1383 INT newMin,newMax,oldMin,oldMax;
1384
1385 oldMin = infoPtr->nSelMin;
1386 oldMax = infoPtr->nSelMax;
1387 newMin = (INT)LOWORD(lParam);
1388 newMax = (INT)HIWORD(lParam);
1389
1390 if ((infoPtr->nSelMin == newMin) && (infoPtr->nSelMax == newMax)) return 0;
1391 infoPtr->nSelMin = newMin;
1392 infoPtr->nSelMax = newMax;
1393
1394 if (infoPtr->nSelMin < infoPtr->nRangeMin) infoPtr->nSelMin = infoPtr->nRangeMin;
1395 if (infoPtr->nSelMin > infoPtr->nRangeMax) infoPtr->nSelMin = infoPtr->nRangeMax;
1396 if (infoPtr->nSelMax > infoPtr->nRangeMax) infoPtr->nSelMax = infoPtr->nRangeMax;
1397 if (infoPtr->nSelMax < infoPtr->nRangeMin) infoPtr->nSelMax = infoPtr->nRangeMin;
1398
1399 if (infoPtr->nSelMin > infoPtr->nSelMax) infoPtr->nSelMin = infoPtr->nSelMax;
1400
1401 if (!(infoPtr->dwStyle & TBS_ENABLESELRANGE)) return 0;
1402
1403 if ((oldMin != newMin) || (oldMax != newMax))
1404 {
1405 infoPtr->flags |= TB_SELECTIONCHANGED;
1406 if (wParam) TRACKBAR_Refresh(infoPtr);
1407 }
1408
1409 return 0;
1410}
1411
1412static LRESULT
1413TRACKBAR_SetSelEnd(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1414{
1415 INT oldMax;
1416
1417 if (infoPtr->nSelMax == (INT)lParam) return 0;
1418
1419 oldMax = infoPtr->nSelMax;
1420 infoPtr->nSelMax = (INT)lParam;
1421
1422 if (infoPtr->nSelMax > infoPtr->nRangeMax) infoPtr->nSelMax = infoPtr->nRangeMax;
1423 if (infoPtr->nSelMax < infoPtr->nRangeMin) infoPtr->nSelMax = infoPtr->nRangeMin;
1424
1425 if (infoPtr->nSelMin > infoPtr->nSelMax) infoPtr->nSelMin = infoPtr->nSelMax;
1426
1427 if (!(infoPtr->dwStyle & TBS_ENABLESELRANGE)) return 0;
1428
1429 if (oldMax != infoPtr->nSelMax)
1430 {
1431 infoPtr->flags |= TB_SELECTIONCHANGED;
1432 if (wParam) TRACKBAR_Refresh(infoPtr);
1433 }
1434
1435 return 0;
1436}
1437
1438static LRESULT
1439TRACKBAR_SetSelStart(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1440{
1441 INT oldMin;
1442
1443 if (infoPtr->nSelMin == (INT)lParam) return 0;
1444
1445 oldMin = infoPtr->nSelMin;
1446 infoPtr->nSelMin = (INT)lParam;
1447
1448 if (infoPtr->nSelMin < infoPtr->nRangeMin) infoPtr->nSelMin = infoPtr->nRangeMin;
1449 if (infoPtr->nSelMin > infoPtr->nRangeMax) infoPtr->nSelMin = infoPtr->nRangeMax;
1450
1451 if (infoPtr->nSelMin > infoPtr->nSelMax) infoPtr->nSelMin = infoPtr->nSelMax;
1452
1453 if (!(infoPtr->dwStyle & TBS_ENABLESELRANGE)) return 0;
1454
1455 if (oldMin != infoPtr->nSelMin)
1456 {
1457 infoPtr->flags |= TB_SELECTIONCHANGED;
1458 if (wParam) TRACKBAR_Refresh(infoPtr);
1459 }
1460
1461 return 0;
1462}
1463
1464static LRESULT
1465TRACKBAR_SetThumbLength(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1466{
1467 if (infoPtr->uThumbLen == (UINT)wParam) return 0;
1468
1469 if (infoPtr->dwStyle & TBS_FIXEDLENGTH) return 0;
1470
1471 infoPtr->uThumbLen = MAX((UINT)wParam,THUMB_MINLEN);
1472 infoPtr->flags |= TB_THUMBSIZECHANGED | TB_THUMBCHANGED;
1473
1474 TRACKBAR_Refresh(infoPtr);
1475
1476 return 0;
1477}
1478
1479static void TRACKBAR_QuickSort(LPLONG list,INT lo,INT hi)
1480{
1481 INT i,j,x,y;
1482
1483 i = lo;
1484 j = hi;
1485 x = list[(lo+hi)/2];
1486 do
1487 {
1488 while (list[i] < x) i++;
1489 while (x < list[j]) j--;
1490 if (i <= j)
1491 {
1492 y = list[i];
1493 list[i] = list[j];
1494 list[j] = y;
1495 i++;
1496 j--;
1497 }
1498 } while (i <= j);
1499 if (lo < j) TRACKBAR_QuickSort(list,lo,j);
1500 if (i < hi) TRACKBAR_QuickSort(list,i,hi);
1501}
1502
1503static LRESULT
1504TRACKBAR_SetTic(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1505{
1506 INT nPos = (INT)lParam;
1507 INT x;
1508
1509 if (!(infoPtr->dwStyle & (TBS_AUTOTICKS | TBS_NOTICKS))) return 0;
1510
1511 if ((nPos < infoPtr->nRangeMin) || (nPos > infoPtr->nRangeMax)) return FALSE;
1512
1513 //Check if tick exists
1514 for (x = 0;x < infoPtr->uNumTics;x++)
1515 {
1516 if (infoPtr->tics[x] == nPos) return TRUE; //value is ok
1517 }
1518
1519 infoPtr->uNumTics++;
1520 infoPtr->tics = (LONG*)COMCTL32_ReAlloc(infoPtr->tics,infoPtr->uNumTics*sizeof(DWORD));
1521 infoPtr->tics[infoPtr->uNumTics-1] = nPos;
1522
1523 //Quicksort the list
1524 TRACKBAR_QuickSort(infoPtr->tics,0,infoPtr->uNumTics-1);
1525
1526 TRACKBAR_Refresh(infoPtr);
1527
1528 return TRUE;
1529}
1530
1531static LRESULT
1532TRACKBAR_SetTipSide(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1533{
1534 INT fTemp = infoPtr->fLocation;
1535
1536 if (infoPtr->dwStyle & TBS_VERT)
1537 {
1538 if ((wParam == TBTS_LEFT) || (wParam == TBTS_RIGHT)) infoPtr->fLocation = (INT)wParam;
1539 } else
1540 {
1541 if ((wParam == TBTS_TOP) || (wParam == TBTS_BOTTOM)) infoPtr->fLocation = (INT)wParam;
1542 }
1543
1544 return fTemp;
1545}
1546
1547static LRESULT
1548TRACKBAR_SetToolTips(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1549{
1550 infoPtr->hwndToolTip = (HWND)wParam;
1551
1552 return 0;
1553}
1554
1555static LRESULT
1556TRACKBAR_InitializeThumb(TRACKBAR_INFO *infoPtr)
1557{
1558 RECT clientRect;
1559 INT scaleSize;
1560
1561 GetClientRect(infoPtr->hwnd,&clientRect);
1562 infoPtr->uThumbLen = (infoPtr->dwStyle & TBS_ENABLESELRANGE) ? THUMB_LEN_SEL:THUMB_LEN; /* initial thumb length */
1563
1564 scaleSize = 2*BORDER_SIZE;
1565 if (infoPtr->dwStyle & TBS_NOTICKS) scaleSize += 0;
1566 else if (infoPtr->dwStyle & TBS_BOTH) scaleSize += 2*(SCALE_SIZE+SCALE_SPACE);
1567 else scaleSize += SCALE_SIZE+SCALE_SPACE;
1568
1569 if (infoPtr->dwStyle & TBS_VERT)
1570 {
1571 INT width = clientRect.right-clientRect.left;
1572
1573 if (infoPtr->uThumbLen+scaleSize > width) infoPtr->uThumbLen = MAX(width-scaleSize,THUMB_MINLEN);
1574 } else
1575 {
1576 INT height = clientRect.bottom-clientRect.top;
1577
1578 if (infoPtr->uThumbLen+scaleSize > height) infoPtr->uThumbLen = MAX(height-scaleSize,THUMB_MINLEN);
1579 }
1580
1581 TRACKBAR_CalcChannel(infoPtr);
1582 TRACKBAR_CalcThumb(infoPtr);
1583
1584 infoPtr->flags &= ~TB_SELECTIONCHANGED;
1585
1586 return 0;
1587}
1588
1589static LRESULT
1590TRACKBAR_InitColors(TRACKBAR_INFO *infoPtr,BOOL redraw)
1591{
1592 infoPtr->clrBk = GetSysColor(COLOR_3DFACE);
1593 infoPtr->clrHighlightedThumb = GetSysColor(COLOR_3DHILIGHT);
1594
1595 if (redraw) TRACKBAR_Refresh(infoPtr);
1596
1597 return 0;
1598}
1599
1600static LRESULT
1601TRACKBAR_Create(HWND hwnd,WPARAM wParam,LPARAM lParam)
1602{
1603 TRACKBAR_INFO *infoPtr;
1604 LOGBRUSH lb;
1605
1606 infoPtr = (TRACKBAR_INFO*)initControl(hwnd,sizeof(TRACKBAR_INFO));
1607
1608 /* set default values */
1609 infoPtr->hwnd = hwnd;
1610 infoPtr->dwStyle = GetWindowLongA(hwnd,GWL_STYLE);;
1611
1612 infoPtr->nRangeMin = 0;
1613 infoPtr->nRangeMax = 100;
1614 infoPtr->nLineSize = 1;
1615 infoPtr->nPageSize = 20;
1616 infoPtr->nSelMin = 0;
1617 infoPtr->nSelMax = 0;
1618 infoPtr->nPos = 0;
1619
1620 infoPtr->uNumTics = 0; /* start and end tic are not included in count*/
1621 infoPtr->uTicFreq = 1;
1622 infoPtr->tics = NULL;
1623
1624 /* Create dotted brush */
1625 lb.lbStyle = BS_PATTERN;
1626 lb.lbHatch = (INT)CreateBitmap(8, 8, 1, 1, pattern);
1627 infoPtr->hbrThumb = CreateBrushIndirect(&lb);
1628 DeleteObject((HGDIOBJ)lb.lbHatch);
1629
1630 TRACKBAR_InitColors(infoPtr,FALSE);
1631
1632 infoPtr->hwndBuddyLA = 0;
1633 infoPtr->hwndBuddyRB = 0;
1634 infoPtr->flags = 0;
1635 infoPtr->bFocus = FALSE;
1636
1637 if (infoPtr->dwStyle & TBS_VERT)
1638 {
1639 infoPtr->fLocation = (infoPtr->dwStyle & TBS_LEFT) ? TBTS_RIGHT : TBTS_LEFT;
1640 } else
1641 {
1642 infoPtr->fLocation = (infoPtr->dwStyle & TBS_TOP) ? TBTS_BOTTOM : TBTS_TOP;
1643 }
1644
1645 TRACKBAR_InitializeThumb(infoPtr);
1646
1647 /* Create tooltip control */
1648 if (infoPtr->dwStyle & TBS_TOOLTIPS)
1649 {
1650 UINT uFlags = TTF_TRACK | TTF_ABSOLUTE;
1651
1652 if (infoPtr->dwStyle & TBS_VERT)
1653 if (infoPtr->fLocation == TBTS_RIGHT)
1654 uFlags |= TTF_ALIGNRIGHT | TTF_VCENTER;
1655 else
1656 uFlags |= TTF_ALIGNLEFT | TTF_VCENTER;
1657 else
1658 if (infoPtr->fLocation == TBTS_TOP)
1659 uFlags |= TTF_ALIGNTOP | TTF_HCENTER;
1660 else
1661 uFlags |= TTF_ALIGNBOTTOM | TTF_HCENTER;
1662
1663 infoPtr->hwndToolTip = createToolTip(hwnd,uFlags,TRUE);
1664 }
1665
1666 return 0;
1667}
1668
1669static LRESULT
1670TRACKBAR_Destroy(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1671{
1672 if (infoPtr->hbrThumb)
1673 DeleteObject((HGDIOBJ)infoPtr->hbrThumb);
1674
1675 /* delete tooltip control */
1676 destroyToolTip(infoPtr->hwndToolTip);
1677
1678 COMCTL32_Free(infoPtr->tics);
1679 doneControl(infoPtr->hwnd);
1680
1681 return 0;
1682}
1683
1684static VOID TRACKBAR_CalcToolTipPos(TRACKBAR_INFO *infoPtr,POINT *pt)
1685{
1686 if (infoPtr->dwStyle & TBS_VERT)
1687 {
1688 if (infoPtr->fLocation == TBTS_RIGHT)
1689 {
1690 pt->x = infoPtr->rcFullThumb.right+TOOLTIP_SPACE;
1691 pt->y = infoPtr->rcFullThumb.top+(infoPtr->rcFullThumb.bottom-infoPtr->rcFullThumb.top)/2;
1692 } else
1693 {
1694 pt->x = infoPtr->rcFullThumb.left-TOOLTIP_SPACE;
1695 pt->y = infoPtr->rcFullThumb.top+(infoPtr->rcFullThumb.bottom-infoPtr->rcFullThumb.top)/2;
1696 }
1697
1698 } else
1699 {
1700 if (infoPtr->fLocation == TBTS_TOP)
1701 {
1702 pt->x = infoPtr->rcFullThumb.left+(infoPtr->rcFullThumb.right-infoPtr->rcFullThumb.left)/2;
1703 pt->y = infoPtr->rcFullThumb.top-TOOLTIP_SPACE;
1704 } else
1705 {
1706 pt->x = infoPtr->rcFullThumb.left+(infoPtr->rcFullThumb.right-infoPtr->rcFullThumb.left)/2;
1707 pt->y = infoPtr->rcFullThumb.bottom+TOOLTIP_SPACE;
1708 }
1709 }
1710 ClientToScreen(infoPtr->hwnd,pt);
1711}
1712
1713static LRESULT
1714TRACKBAR_LButtonDown(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1715{
1716 int clickPlace,prevPos,vertical;
1717 DOUBLE clickPos;
1718 RECT thumb,fullThumb;
1719 POINT clickPoint;
1720
1721 SetFocus(infoPtr->hwnd);
1722
1723 vertical = infoPtr->dwStyle & TBS_VERT;
1724 clickPoint.x = (INT)LOWORD(lParam);
1725 clickPoint.y = (INT)HIWORD(lParam);
1726
1727
1728 if (vertical) clickPlace = clickPoint.y;
1729 else clickPlace = clickPoint.x;
1730
1731 //Button down on thumb?
1732 thumb = infoPtr->rcThumb;
1733 fullThumb = infoPtr->rcFullThumb;
1734 if ((vertical &&
1735 (clickPoint.y >= thumb.top) &&
1736 (clickPoint.y <= thumb.bottom) &&
1737 (((infoPtr->dwStyle & TBS_BOTH) &&
1738 (clickPoint.x >= thumb.left) &&
1739 (clickPoint.x <= thumb.right)
1740 ) ||
1741 ((infoPtr->dwStyle & TBS_LEFT) &&
1742 (clickPoint.x <= thumb.right) &&
1743 ((clickPoint.x >= thumb.left) ||
1744 ((clickPoint.x >= fullThumb.left) &&
1745 ((thumb.left-clickPoint.x <= clickPoint.y-thumb.top) &&
1746 (thumb.left-clickPoint.x <= thumb.bottom-clickPoint.y)
1747 )
1748 )
1749 )
1750 ) ||
1751 (!(infoPtr->dwStyle & (TBS_BOTH | TBS_LEFT)) &&
1752 (clickPoint.x >= thumb.left) &&
1753 ((clickPoint.x <= thumb.right) ||
1754 ((clickPoint.x <= fullThumb.right) &&
1755 ((clickPoint.x-thumb.right <= clickPoint.y-thumb.top) &&
1756 (clickPoint.x-thumb.right <= thumb.bottom-clickPoint.y)
1757 )
1758 )
1759 )
1760 ))
1761 ) ||
1762 (!vertical &&
1763 (clickPoint.x >= thumb.left) &&
1764 (clickPoint.x <= thumb.right) &&
1765 (((infoPtr->dwStyle & TBS_BOTH) &&
1766 (clickPoint.y >= thumb.top) &&
1767 (clickPoint.y <= thumb.bottom)
1768 ) ||
1769 ((infoPtr->dwStyle & TBS_TOP) &&
1770 (clickPoint.y <= thumb.bottom) &&
1771 ((clickPoint.y >= thumb.top) ||
1772 ((clickPoint.y >= fullThumb.top) &&
1773 ((thumb.top-clickPoint.y <= clickPoint.x-thumb.left) &&
1774 (thumb.top-clickPoint.y <= thumb.right-clickPoint.x)
1775 )
1776 )
1777 )
1778 ) ||
1779 (!(infoPtr->dwStyle & (TBS_BOTH | TBS_TOP)) &&
1780 (clickPoint.y >= thumb.top) &&
1781 ((clickPoint.y <= thumb.bottom) ||
1782 ((clickPoint.y <= fullThumb.bottom) &&
1783 ((clickPoint.y-thumb.bottom <= clickPoint.x-thumb.left) &&
1784 (clickPoint.y-thumb.bottom <= thumb.right-clickPoint.x)
1785 )
1786 )
1787 )
1788 ))
1789 ))
1790 {
1791 infoPtr->flags |= TB_DRAG_MODE;
1792 if (infoPtr->dwStyle & TBS_TOOLTIPS)
1793 { /* enable tooltip */
1794 TTTOOLINFOA ti;
1795 POINT pt;
1796 char buf[80];
1797
1798 ti.cbSize = sizeof(TTTOOLINFOA);
1799 ti.uId = 0;
1800 ti.hwnd = (UINT)infoPtr->hwnd;
1801 ti.hinst = 0;
1802 sprintf (buf,"%ld",infoPtr->nPos);
1803 ti.lpszText = (LPSTR)buf;
1804
1805 infoPtr->flags |= TB_SHOW_TOOLTIP;
1806 SetCapture(infoPtr->hwnd);
1807
1808 SendMessageA(infoPtr->hwndToolTip,TTM_UPDATETIPTEXTA,0,(LPARAM)&ti);
1809 TRACKBAR_CalcToolTipPos(infoPtr,&pt);
1810 SendMessageA(infoPtr->hwndToolTip,TTM_TRACKPOSITION,0,(LPARAM)MAKELPARAM(pt.x,pt.y));
1811
1812 SendMessageA(infoPtr->hwndToolTip,TTM_TRACKACTIVATE,(WPARAM)TRUE,(LPARAM)&ti);
1813 }
1814
1815 SetCapture(infoPtr->hwnd);
1816 TRACKBAR_UpdateThumbPosition(infoPtr,infoPtr->nPos,TRUE); //change arrow color
1817 return 0;
1818 }
1819 else if ((vertical &&
1820 (clickPoint.y >= thumb.top) &&
1821 (clickPoint.y <= thumb.bottom)) ||
1822 (!vertical &&
1823 (clickPoint.x >= thumb.left) &&
1824 (clickPoint.x <= thumb.right)))
1825 {
1826 //ScrollMode
1827 infoPtr->flags |= TB_SCROLL_MODE;
1828 SetCapture(infoPtr->hwnd);
1829 SetTimer(infoPtr->hwnd,SCROLL_TIMER_ID,SCROLL_TIME,NULL);
1830
1831 return 0;
1832 }
1833
1834 clickPos = TRACKBAR_ConvertPlaceToPosition(infoPtr,clickPlace,vertical);
1835 prevPos = infoPtr->nPos;
1836
1837 if (clickPos > prevPos)
1838 { /* similar to VK_NEXT */
1839 infoPtr->nPos += infoPtr->nPageSize;
1840 if (infoPtr->nPos > infoPtr->nRangeMax) infoPtr->nPos = infoPtr->nRangeMax;
1841 if (prevPos != infoPtr->nPos) TRACKBAR_SendNotify(infoPtr,TB_PAGEUP);
1842 } else
1843 { /* similar to VK_PRIOR */
1844 infoPtr->nPos -= infoPtr->nPageSize;
1845 if (infoPtr->nPos < infoPtr->nRangeMin) infoPtr->nPos = infoPtr->nRangeMin;
1846 if (prevPos != infoPtr->nPos) TRACKBAR_SendNotify(infoPtr,TB_PAGEDOWN);
1847 }
1848
1849 if (prevPos != infoPtr->nPos)
1850 {
1851 infoPtr->flags |= TB_THUMBPOSCHANGED;
1852 TRACKBAR_UpdateThumbPosition(infoPtr,prevPos,TRUE);
1853 }
1854
1855 //ScrollMode
1856 infoPtr->flags |= TB_SCROLL_MODE;
1857 SetCapture(infoPtr->hwnd);
1858 SetTimer(infoPtr->hwnd,SCROLL_TIMER_ID,SCROLL_TIME,NULL);
1859
1860 return 0;
1861}
1862
1863
1864static LRESULT
1865TRACKBAR_LButtonUp(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1866{
1867 if (infoPtr->flags & TB_DRAG_MODE)
1868 {
1869 TRACKBAR_SendNotify(infoPtr,TB_ENDTRACK);
1870
1871 infoPtr->flags &= ~TB_DRAG_MODE;
1872
1873 if (GetCapture() == infoPtr->hwnd)
1874 {
1875 sendNotify(infoPtr->hwnd,NM_RELEASEDCAPTURE);
1876
1877 ReleaseCapture();
1878 }
1879
1880 TRACKBAR_UpdateThumbPosition(infoPtr,infoPtr->nPos,TRUE); //change arrow color
1881 }
1882
1883 if (infoPtr->flags & TB_SCROLL_MODE)
1884 {
1885 infoPtr->flags &= ~TB_SCROLL_MODE;
1886
1887 if (GetCapture() == infoPtr->hwnd)
1888 {
1889 sendNotify(infoPtr->hwnd,NM_RELEASEDCAPTURE);
1890
1891 ReleaseCapture();
1892 }
1893
1894 KillTimer(infoPtr->hwnd,SCROLL_TIMER_ID);
1895 }
1896
1897 if (infoPtr->dwStyle & TBS_TOOLTIPS)
1898 { /* disable tooltip */
1899 TTTOOLINFOA ti;
1900
1901 ti.cbSize = sizeof(TTTOOLINFOA);
1902 ti.uId = 0;
1903 ti.hwnd = (UINT)infoPtr->hwnd;
1904
1905 infoPtr->flags &= ~TB_SHOW_TOOLTIP;
1906 SendMessageA(infoPtr->hwndToolTip,TTM_TRACKACTIVATE,(WPARAM)FALSE,(LPARAM)&ti);
1907 }
1908
1909 return 0;
1910}
1911
1912static LRESULT TRACKBAR_Timer(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1913{
1914 POINT mousePoint;
1915 INT mousePlace,prevPos,newPos,vertical;
1916 DOUBLE mousePos;
1917
1918 GetCursorPos(&mousePoint);
1919 ScreenToClient(infoPtr->hwnd,&mousePoint);
1920
1921 vertical = infoPtr->dwStyle & TBS_VERT;
1922 if (vertical) mousePlace = mousePoint.y;
1923 else mousePlace = mousePoint.x;
1924
1925 mousePos = TRACKBAR_ConvertPlaceToPosition(infoPtr,mousePlace,vertical);
1926 prevPos = infoPtr->nPos;
1927
1928 if (mousePos > (INT)mousePos+0.5) newPos = mousePos+1;
1929 else newPos = mousePos;
1930 if (newPos == prevPos) return 0;
1931
1932 if (newPos > prevPos)
1933 { /* similar to VK_NEXT */
1934 infoPtr->nPos += infoPtr->nPageSize;
1935 if (infoPtr->nPos > infoPtr->nRangeMax) infoPtr->nPos = infoPtr->nRangeMax;
1936 if (prevPos != infoPtr->nPos) TRACKBAR_SendNotify(infoPtr,TB_PAGEUP);
1937 } else
1938 { /* similar to VK_PRIOR */
1939 infoPtr->nPos -= infoPtr->nPageSize;
1940 if (infoPtr->nPos < infoPtr->nRangeMin) infoPtr->nPos = infoPtr->nRangeMin;
1941 if (prevPos != infoPtr->nPos) TRACKBAR_SendNotify(infoPtr,TB_PAGEDOWN);
1942 }
1943
1944 if (prevPos != infoPtr->nPos)
1945 {
1946 infoPtr->flags |= TB_THUMBPOSCHANGED;
1947 TRACKBAR_UpdateThumbPosition(infoPtr,prevPos,FALSE);
1948 }
1949
1950 return 0;
1951}
1952
1953static LRESULT
1954TRACKBAR_CaptureChanged(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1955{
1956 sendNotify(infoPtr->hwnd,NM_RELEASEDCAPTURE);
1957
1958 if (infoPtr->flags & TB_DRAGPOSVALID)
1959 {
1960 int lastPos = infoPtr->nPos;
1961 infoPtr->nPos = infoPtr->dragPos;
1962 if (lastPos != infoPtr->nPos) TRACKBAR_UpdateThumbPosition(infoPtr,lastPos,TRUE);
1963 }
1964
1965 infoPtr->flags &= ~TB_DRAGPOSVALID;
1966
1967 if (infoPtr->flags & TB_SCROLL_MODE)
1968 {
1969 infoPtr->flags &= ~TB_SCROLL_MODE;
1970 KillTimer(infoPtr->hwnd,SCROLL_TIMER_ID);
1971 }
1972
1973 if (infoPtr->flags & TB_DRAG_MODE)
1974 {
1975 TRACKBAR_SendNotify(infoPtr,TB_ENDTRACK);
1976
1977 infoPtr->flags &= ~TB_DRAG_MODE;
1978 }
1979
1980 return 0;
1981}
1982
1983
1984static LRESULT
1985TRACKBAR_Paint(TRACKBAR_INFO *infoPtr,WPARAM wParam)
1986{
1987 HDC hdc;
1988 PAINTSTRUCT ps;
1989
1990 hdc = wParam == 0 ? BeginPaint(infoPtr->hwnd,&ps):(HDC)wParam;
1991 TRACKBAR_Draw(infoPtr,hdc);
1992 if (!wParam) EndPaint(infoPtr->hwnd,&ps);
1993 return 0;
1994}
1995
1996
1997static LRESULT
1998TRACKBAR_SetFocus(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
1999{
2000 HDC hdc;
2001 RECT rcClient;
2002
2003 if (!infoPtr->bFocus && IsWindowEnabled(infoPtr->hwnd))
2004 {
2005 infoPtr->bFocus = TRUE;
2006
2007 GetClientRect(infoPtr->hwnd,&rcClient);
2008 hdc = GetDC (infoPtr->hwnd);
2009 DrawFocusRect(hdc,&rcClient);
2010 ReleaseDC(infoPtr->hwnd,hdc);
2011 }
2012 return 0;
2013}
2014
2015static LRESULT
2016TRACKBAR_KillFocus(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
2017{
2018 HDC hdc;
2019 RECT rcClient;
2020
2021
2022 infoPtr->flags &= ~TB_DRAG_MODE;
2023 if (infoPtr->bFocus && IsWindowEnabled(infoPtr->hwnd))
2024 {
2025 infoPtr->bFocus = FALSE;
2026
2027 GetClientRect(infoPtr->hwnd,&rcClient);
2028 hdc = GetDC(infoPtr->hwnd);
2029 DrawFocusRect(hdc,&rcClient); //XOR removes
2030 ReleaseDC(infoPtr->hwnd,hdc);
2031 }
2032
2033 return 0;
2034}
2035
2036static LRESULT
2037TRACKBAR_Size(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
2038{
2039 if (!(infoPtr->dwStyle & TBS_FIXEDLENGTH))
2040 {
2041 /* If trackbar doesn't have TBS_FIXEDLENGTH style
2042 * it sets thumb length according to new width / height.
2043 */
2044 LONG h;
2045 LONG hmin = (infoPtr->dwStyle & TBS_ENABLESELRANGE) ? THUMB_LEN_SEL:THUMB_LEN;
2046
2047 if (infoPtr->dwStyle & TBS_VERT)
2048 h = (LONG)(INT16)LOWORD(lParam); /* width */
2049 else
2050 h = (LONG)(INT16)HIWORD(lParam); /* height */
2051
2052 if (h < hmin)
2053 {
2054 /* focus rect + tic size + thumb offset */
2055
2056 h -= (BORDER_SIZE+SCALE_SPACE)*2;
2057 }
2058
2059 h = MAX(h,THUMB_MINLEN);
2060 h = MIN(h,hmin);
2061
2062 infoPtr->uThumbLen = h;
2063 }
2064
2065 TRACKBAR_CalcChannel(infoPtr);
2066 TRACKBAR_AlignBuddies(infoPtr);
2067
2068 return 0;
2069}
2070
2071static BOOL TRACKBAR_SendNotify(TRACKBAR_INFO *infoPtr,UINT code)
2072{
2073 if (infoPtr->dwStyle & TBS_VERT)
2074 return sendVScroll(infoPtr->hwnd,code);
2075 else
2076 return sendHScroll(infoPtr->hwnd,code);
2077}
2078
2079static LRESULT
2080TRACKBAR_MouseMove(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
2081{
2082 SHORT clickPlace;
2083 DOUBLE dragPos;
2084
2085 if (!(infoPtr->flags & TB_DRAG_MODE)) return TRUE;
2086
2087 if (infoPtr->dwStyle & TBS_VERT) clickPlace = (SHORT)HIWORD(lParam);
2088 else clickPlace = (SHORT)LOWORD(lParam);
2089
2090 dragPos = TRACKBAR_ConvertPlaceToPosition(infoPtr,clickPlace,infoPtr->dwStyle & TBS_VERT);
2091 if (dragPos > ((INT)dragPos)+0.5) infoPtr->dragPos = dragPos + 1;
2092 else infoPtr->dragPos = dragPos;
2093
2094 if (infoPtr->nPos == infoPtr->dragPos) return TRUE; //nothing changed
2095
2096 infoPtr->flags |= TB_DRAGPOSVALID;
2097
2098 TRACKBAR_UpdateThumbPosition(infoPtr,infoPtr->nPos,FALSE); //infoPtr->nPos now set
2099
2100 TRACKBAR_SendNotify(infoPtr,TB_THUMBTRACK | (infoPtr->nPos << 16));
2101
2102 if (infoPtr->flags & TB_SHOW_TOOLTIP)
2103 {
2104 POINT pt;
2105 TTTOOLINFOA ti;
2106 char buf[80];
2107
2108 ti.cbSize = sizeof(TTTOOLINFOA);
2109 ti.hwnd = infoPtr->hwnd;
2110 ti.uId = 0;
2111 ti.hinst = 0;
2112 sprintf(buf,"%d",infoPtr->nPos);
2113 ti.lpszText = (LPSTR)buf;
2114
2115 SendMessageA(infoPtr->hwndToolTip,TTM_UPDATETIPTEXTA,0,(LPARAM)&ti);
2116 TRACKBAR_CalcToolTipPos(infoPtr,&pt);
2117 SendMessageA(infoPtr->hwndToolTip,TTM_TRACKPOSITION,0,(LPARAM)MAKELPARAM(pt.x,pt.y));
2118 }
2119
2120 return 0;
2121}
2122
2123static LRESULT
2124TRACKBAR_Enable(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
2125{
2126 BOOL oldFocus = infoPtr->bFocus;
2127
2128 if (wParam) infoPtr->bFocus = (GetFocus() == infoPtr->hwnd);
2129 else infoPtr->bFocus = FALSE;
2130
2131 if (oldFocus != infoPtr->bFocus) TRACKBAR_Refresh(infoPtr);
2132 else TRACKBAR_UpdateThumbPosition(infoPtr,infoPtr->nPos,TRUE);
2133
2134 return 0;
2135}
2136
2137static LRESULT
2138TRACKBAR_KeyDown(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPARAM lParam)
2139{
2140 INT pos;
2141
2142 if (infoPtr->flags & TB_DRAG_MODE) return TRUE;
2143
2144 pos = infoPtr->nPos;
2145 switch (wParam) {
2146 case VK_LEFT:
2147 case VK_UP:
2148 if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
2149 infoPtr->nPos -= infoPtr->nLineSize;
2150 if (infoPtr->nPos < infoPtr->nRangeMin)
2151 infoPtr->nPos = infoPtr->nRangeMin;
2152 TRACKBAR_SendNotify(infoPtr,TB_LINEUP);
2153 break;
2154 case VK_RIGHT:
2155 case VK_DOWN:
2156 if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
2157 infoPtr->nPos += infoPtr->nLineSize;
2158 if (infoPtr->nPos > infoPtr->nRangeMax)
2159 infoPtr->nPos = infoPtr->nRangeMax;
2160 TRACKBAR_SendNotify(infoPtr,TB_LINEDOWN);
2161 break;
2162 case VK_NEXT:
2163 if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
2164 infoPtr->nPos += infoPtr->nPageSize;
2165 if (infoPtr->nPos > infoPtr->nRangeMax)
2166 infoPtr->nPos = infoPtr->nRangeMax;
2167 TRACKBAR_SendNotify(infoPtr,TB_PAGEUP);
2168 break;
2169 case VK_PRIOR:
2170 if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
2171 infoPtr->nPos -= infoPtr->nPageSize;
2172 if (infoPtr->nPos < infoPtr->nRangeMin)
2173 infoPtr->nPos = infoPtr->nRangeMin;
2174 TRACKBAR_SendNotify(infoPtr,TB_PAGEDOWN);
2175 break;
2176 case VK_HOME:
2177 if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
2178 infoPtr->nPos = infoPtr->nRangeMin;
2179 TRACKBAR_SendNotify(infoPtr,TB_TOP);
2180 break;
2181 case VK_END:
2182 if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
2183 infoPtr->nPos = infoPtr->nRangeMax;
2184 TRACKBAR_SendNotify(infoPtr,TB_BOTTOM);
2185 break;
2186
2187 default:
2188 return FALSE;
2189 }
2190
2191 if (pos != infoPtr->nPos)
2192 {
2193 infoPtr->flags |= TB_THUMBPOSCHANGED;
2194 TRACKBAR_UpdateThumbPosition(infoPtr,pos,FALSE);
2195 }
2196
2197 return TRUE;
2198}
2199
2200
2201static LRESULT
2202TRACKBAR_KeyUp(TRACKBAR_INFO *infoPtr,WPARAM wParam)
2203{
2204 if (infoPtr->flags & TB_DRAG_MODE) return TRUE;
2205
2206 switch (wParam) {
2207 case VK_LEFT:
2208 case VK_UP:
2209 case VK_RIGHT:
2210 case VK_DOWN:
2211 case VK_NEXT:
2212 case VK_PRIOR:
2213 case VK_HOME:
2214 case VK_END:
2215 TRACKBAR_SendNotify(infoPtr,TB_ENDTRACK);
2216 }
2217 return TRUE;
2218}
2219
2220static LRESULT
2221TRACKBAR_StyleChanged(TRACKBAR_INFO *infoPtr,WPARAM wParam,LPSTYLESTRUCT lParam)
2222{
2223 TRACKBAR_CalcChannel(infoPtr);
2224
2225 return 0;
2226}
2227
2228static LRESULT WINAPI
2229TRACKBAR_WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
2230{
2231 TRACKBAR_INFO *infoPtr;
2232
2233 if (uMsg == WM_CREATE)
2234 return TRACKBAR_Create(hwnd,wParam,lParam);
2235
2236 infoPtr = TRACKBAR_GetInfoPtr(hwnd);
2237
2238 if (!infoPtr)
2239 goto defproc;
2240
2241 switch (uMsg)
2242 {
2243 case TBM_CLEARSEL:
2244 return TRACKBAR_ClearSel(infoPtr,wParam,lParam);
2245
2246 case TBM_CLEARTICS:
2247 return TRACKBAR_ClearTics(infoPtr,wParam,lParam);
2248
2249 case TBM_GETBUDDY:
2250 return TRACKBAR_GetBuddy(infoPtr,wParam,lParam);
2251
2252 case TBM_GETCHANNELRECT:
2253 return TRACKBAR_GetChannelRect(infoPtr,wParam,lParam);
2254
2255 case TBM_GETLINESIZE:
2256 return TRACKBAR_GetLineSize(infoPtr,wParam,lParam);
2257
2258 case TBM_GETNUMTICS:
2259 return TRACKBAR_GetNumTics(infoPtr,wParam,lParam);
2260
2261 case TBM_GETPAGESIZE:
2262 return TRACKBAR_GetPageSize(infoPtr,wParam,lParam);
2263
2264 case TBM_GETPOS:
2265 return TRACKBAR_GetPos(infoPtr,wParam,lParam);
2266
2267 case TBM_GETPTICS:
2268 return TRACKBAR_GetPTics(infoPtr);
2269
2270 case TBM_GETRANGEMAX:
2271 return TRACKBAR_GetRangeMax(infoPtr,wParam,lParam);
2272
2273 case TBM_GETRANGEMIN:
2274 return TRACKBAR_GetRangeMin(infoPtr,wParam,lParam);
2275
2276 case TBM_GETSELEND:
2277 return TRACKBAR_GetSelEnd(infoPtr,wParam,lParam);
2278
2279 case TBM_GETSELSTART:
2280 return TRACKBAR_GetSelStart(infoPtr,wParam,lParam);
2281
2282 case TBM_GETTHUMBLENGTH:
2283 return TRACKBAR_GetThumbLength(infoPtr,wParam,lParam);
2284
2285 case TBM_GETTHUMBRECT:
2286 return TRACKBAR_GetThumbRect(infoPtr,wParam,lParam);
2287
2288 case TBM_GETTIC:
2289 return TRACKBAR_GetTic(infoPtr,wParam,lParam);
2290
2291 case TBM_GETTICPOS:
2292 return TRACKBAR_GetTicPos(infoPtr,wParam,lParam);
2293
2294 case TBM_GETTOOLTIPS:
2295 return TRACKBAR_GetToolTips(infoPtr,wParam,lParam);
2296
2297 case TBM_SETBUDDY:
2298 return TRACKBAR_SetBuddy(infoPtr,wParam,lParam);
2299
2300 case TBM_SETLINESIZE:
2301 return TRACKBAR_SetLineSize(infoPtr,wParam,lParam);
2302
2303 case TBM_SETPAGESIZE:
2304 return TRACKBAR_SetPageSize(infoPtr,wParam,lParam);
2305
2306 case TBM_SETPOS:
2307 return TRACKBAR_SetPos(infoPtr,wParam,lParam);
2308
2309 case TBM_SETRANGE:
2310 return TRACKBAR_SetRange(infoPtr,wParam,lParam);
2311
2312 case TBM_SETRANGEMAX:
2313 return TRACKBAR_SetRangeMax(infoPtr,wParam,lParam);
2314
2315 case TBM_SETRANGEMIN:
2316 return TRACKBAR_SetRangeMin(infoPtr,wParam,lParam);
2317
2318 case TBM_SETSEL:
2319 return TRACKBAR_SetSel(infoPtr,wParam,lParam);
2320
2321 case TBM_SETSELEND:
2322 return TRACKBAR_SetSelEnd(infoPtr,wParam,lParam);
2323
2324 case TBM_SETSELSTART:
2325 return TRACKBAR_SetSelStart(infoPtr,wParam,lParam);
2326
2327 case TBM_SETTHUMBLENGTH:
2328 return TRACKBAR_SetThumbLength(infoPtr,wParam,lParam);
2329
2330 case TBM_SETTIC:
2331 return TRACKBAR_SetTic(infoPtr,wParam,lParam);
2332
2333 case TBM_SETTICFREQ:
2334 return TRACKBAR_SetTicFreq(infoPtr,wParam);
2335
2336 case TBM_SETTIPSIDE:
2337 return TRACKBAR_SetTipSide(infoPtr,wParam,lParam);
2338
2339 case TBM_SETTOOLTIPS:
2340 return TRACKBAR_SetToolTips(infoPtr,wParam,lParam);
2341
2342 case WM_CAPTURECHANGED:
2343 return TRACKBAR_CaptureChanged(infoPtr,wParam,lParam);
2344
2345 case WM_DESTROY:
2346 return TRACKBAR_Destroy(infoPtr,wParam,lParam);
2347
2348 case WM_ENABLE:
2349 return TRACKBAR_Enable(infoPtr,wParam,lParam);
2350
2351 case WM_ERASEBKGND:
2352 return 1;
2353
2354 case WM_GETDLGCODE:
2355 return DLGC_WANTARROWS;
2356
2357 case WM_KEYDOWN:
2358 return TRACKBAR_KeyDown(infoPtr,wParam,lParam);
2359
2360 case WM_KEYUP:
2361 return TRACKBAR_KeyUp(infoPtr,wParam);
2362
2363 case WM_LBUTTONDOWN:
2364 return TRACKBAR_LButtonDown(infoPtr,wParam,lParam);
2365
2366 case WM_LBUTTONUP:
2367 return TRACKBAR_LButtonUp(infoPtr,wParam,lParam);
2368
2369 case WM_TIMER:
2370 return TRACKBAR_Timer(infoPtr,wParam,lParam);
2371
2372 case WM_MOUSEMOVE:
2373 return TRACKBAR_MouseMove(infoPtr,wParam,lParam);
2374
2375 case WM_PAINT:
2376 return TRACKBAR_Paint(infoPtr,wParam);
2377
2378 case WM_SETFOCUS:
2379 return TRACKBAR_SetFocus(infoPtr,wParam,lParam);
2380
2381 case WM_KILLFOCUS:
2382 return TRACKBAR_KillFocus(infoPtr,wParam,lParam);
2383
2384 case WM_STYLECHANGED:
2385 return TRACKBAR_StyleChanged(infoPtr,wParam,(LPSTYLESTRUCT)lParam);
2386
2387 case WM_SIZE:
2388 return TRACKBAR_Size(infoPtr,wParam,lParam);
2389
2390 case WM_WININICHANGE:
2391 return TRACKBAR_InitializeThumb(infoPtr);
2392
2393 case WM_SYSCOLORCHANGE:
2394 return TRACKBAR_InitColors(infoPtr,TRUE);
2395
2396 default:
2397 //if (uMsg >= WM_USER)
2398 // ERR (trackbar, "unknown msg %04x wp=%08x lp=%08lx\n",
2399 // uMsg, wParam, lParam);
2400 defproc:
2401 return defComCtl32ProcA(hwnd,uMsg,wParam,lParam);
2402 }
2403 return 0;
2404}
2405
2406
2407VOID
2408TRACKBAR_Register (VOID)
2409{
2410 WNDCLASSA wndClass;
2411
2412 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
2413 wndClass.style = CS_GLOBALCLASS;
2414 wndClass.lpfnWndProc = (WNDPROC)TRACKBAR_WindowProc;
2415 wndClass.cbClsExtra = 0;
2416 wndClass.cbWndExtra = sizeof(TRACKBAR_INFO *);
2417 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
2418 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
2419 wndClass.lpszClassName = TRACKBAR_CLASSA;
2420
2421 RegisterClassA(&wndClass);
2422}
2423
2424
2425VOID
2426TRACKBAR_Unregister (VOID)
2427{
2428 UnregisterClassA (TRACKBAR_CLASSA, (HINSTANCE)NULL);
2429}
2430
Note: See TracBrowser for help on using the repository browser.