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

Last change on this file since 3585 was 3585, checked in by cbratschi, 25 years ago

merged with Corel WINE 20000513, added new DPA_* functions

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