source: trunk/src/comctl32/trackbar.c@ 180

Last change on this file since 180 was 180, checked in by cbratschi, 26 years ago

Several COMCTL32 changes

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