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

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

Trackbar optimized

File size: 56.8 KB
Line 
1/* $Id: trackbar.c,v 1.6 1999-06-21 15:28:44 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
57#define CHANNEL_MIN_HEIGHT 4
58#define CHANNEL_THUMB_DIFF 8
59#define CHANNEL_SPACE 8
60#define CHANNEL_SCALE_SPACE CHANNEL_THUMB_DIFF/2+SCALE_SIZE+SCALE_SPACE+BORDER_SIZE
61#define CHANNEL_THUMB_SPACE CHANNEL_THUMB_DIFF+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 (!(dwStyle & TBS_AUTOTICKS)) return;
105
106 if (infoPtr->uTicFreq == 0)
107 {
108 COMCTL32_Free(infoPtr->tics);
109 infoPtr->tics = NULL;
110 infoPtr->uNumTics = 0;
111 return;
112 }
113
114 if (infoPtr->uTicFreq && infoPtr->nRangeMax > infoPtr->nRangeMin && (dwStyle & TBS_AUTOTICKS))
115 {
116 //Tics without start and end tic
117 nrTics = (infoPtr->nRangeMax-infoPtr->nRangeMin)/infoPtr->uTicFreq-1;
118 } else
119 {
120 COMCTL32_Free(infoPtr->tics);
121 infoPtr->tics = NULL;
122 infoPtr->uNumTics = 0;
123 return;
124 }
125
126 if (nrTics != infoPtr->uNumTics)
127 {
128 COMCTL32_Free(infoPtr->tics);
129 infoPtr->tics = COMCTL32_Alloc(nrTics*sizeof(DWORD));
130 infoPtr->uNumTics = nrTics;
131 }
132
133 tic = infoPtr->nRangeMin+infoPtr->uTicFreq; //start not included
134 for (i = 0;i < nrTics;i++)
135 {
136 infoPtr->tics[i] = tic;
137 tic += infoPtr->uTicFreq;
138 }
139}
140
141
142/* converts from physical (mouse) position to logical position
143 (in range of trackbar) */
144
145static DOUBLE
146TRACKBAR_ConvertPlaceToPosition(TRACKBAR_INFO *infoPtr,int place,int vertical)
147{
148 double range,width,pos;
149
150 range = infoPtr->nRangeMax-infoPtr->nRangeMin;
151 if (vertical)
152 {
153 width = infoPtr->rcChannel.bottom-infoPtr->rcChannel.top;
154 pos = infoPtr->nRangeMin+(range*(place-infoPtr->rcChannel.top))/width;
155 } else
156 {
157 width = infoPtr->rcChannel.right-infoPtr->rcChannel.left;
158 pos = infoPtr->nRangeMin+(range*(place-infoPtr->rcChannel.left))/width;
159 }
160
161 if (pos > infoPtr->nRangeMax) pos = infoPtr->nRangeMax;
162 else if (pos < infoPtr->nRangeMin) pos = infoPtr->nRangeMin;
163
164// TRACE (trackbar,"%.2f\n",pos);
165 return pos;
166}
167
168
169static VOID
170TRACKBAR_CalcChannel (HWND hwnd,TRACKBAR_INFO *infoPtr)
171{
172 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
173 INT channelSize;
174 RECT lpRect,*channel = &infoPtr->rcChannel;
175
176 GetClientRect(hwnd,&lpRect);
177
178 if (dwStyle & TBS_ENABLESELRANGE) channelSize = MAX(infoPtr->uThumbLen-CHANNEL_THUMB_DIFF,CHANNEL_MIN_HEIGHT);
179 else channelSize = CHANNEL_NOSEL_HEIGHT;
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)
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+CHANNEL_SCALE_SPACE;
193 channel->right = channel->left+channelSize;
194 } else
195 { //Right, align left
196 channel->left = lpRect.left+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)
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+CHANNEL_SCALE_SPACE;
210 channel->bottom = channel->top+channelSize;
211 } else
212 { //Bottom, align top
213 channel->top = lpRect.top+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 = 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 if (dwStyle & TBS_NOTHUMB) return;
717
718 //last
719 lastRect = infoPtr->rcFullThumb;
720
721 //new
722 if (infoPtr->flags & TB_DRAGPOSVALID) infoPtr->nPos = infoPtr->dragPos;
723 if (infoPtr->nPos == lastPos) return;
724
725 TRACKBAR_CalcThumb(hwnd,infoPtr);
726 infoPtr->flags &= ~TB_THUMBCHANGED;
727 newRect = infoPtr->rcFullThumb;
728
729
730 //3D frame adjustation
731 lastRect.right++;
732 lastRect.bottom++;
733 newRect.right++;
734 newRect.bottom++;
735 //Odin32 pixel bugs
736 lastRect.top--;
737 lastRect.left--;
738 newRect.top--;
739 newRect.left--;
740
741 hdc = GetDC(hwnd);
742 hrgnLast = CreateRectRgnIndirect(&lastRect);
743 hrgnNew = CreateRectRgnIndirect(&newRect);
744 hrgn = CreateRectRgn(0,0,0,0);
745 CombineRgn(hrgn,hrgnLast,hrgnNew,RGN_OR);
746 SelectClipRgn(hdc,hrgn);
747 TRACKBAR_Draw(hwnd,hdc);
748 SelectClipRgn(hdc,0);
749 DeleteObject(hrgnLast);
750 DeleteObject(hrgnNew);
751 DeleteObject(hrgn);
752 ReleaseDC(hwnd,hdc);
753}
754
755//redraw thumb at same position
756
757static VOID TRACKBAR_UpdateThumb(HWND hwnd)
758{
759 HDC hdc;
760 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
761 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
762 HRGN hrgn;
763
764 if (dwStyle & TBS_NOTHUMB) return;
765
766 hdc = GetDC(hwnd);
767 hrgn = CreateRectRgnIndirect(&infoPtr->rcFullThumb);
768 SelectClipRgn(hdc,hrgn);
769 TRACKBAR_Draw(hwnd,hdc);
770 SelectClipRgn(hdc,0);
771 DeleteObject(hrgn);
772 ReleaseDC(hwnd,hdc);
773}
774
775//redraw everything
776
777static VOID TRACKBAR_Refresh (HWND hwnd)
778{
779 HDC hdc;
780
781 hdc = GetDC (hwnd);
782 TRACKBAR_Draw(hwnd,hdc);
783 ReleaseDC(hwnd,hdc);
784}
785
786static VOID
787TRACKBAR_AlignBuddies (HWND hwnd, TRACKBAR_INFO *infoPtr)
788{
789 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
790 HWND hwndParent = GetParent (hwnd);
791 RECT rcSelf, rcBuddy;
792 INT x, y;
793
794 GetWindowRect (hwnd, &rcSelf);
795 MapWindowPoints (HWND_DESKTOP, hwndParent, (LPPOINT)&rcSelf, 2);
796
797 /* align buddy left or above */
798 if (infoPtr->hwndBuddyLA) {
799 GetWindowRect (infoPtr->hwndBuddyLA, &rcBuddy);
800 MapWindowPoints (HWND_DESKTOP, hwndParent, (LPPOINT)&rcBuddy, 2);
801
802 if (dwStyle & TBS_VERT) {
803 x = (infoPtr->rcChannel.right + infoPtr->rcChannel.left) / 2 -
804 (rcBuddy.right - rcBuddy.left) / 2 + rcSelf.left;
805 y = rcSelf.top - (rcBuddy.bottom - rcBuddy.top);
806 }
807 else {
808 x = rcSelf.left - (rcBuddy.right - rcBuddy.left);
809 y = (infoPtr->rcChannel.bottom + infoPtr->rcChannel.top) / 2 -
810 (rcBuddy.bottom - rcBuddy.top) / 2 + rcSelf.top;
811 }
812
813 SetWindowPos (infoPtr->hwndBuddyLA, 0, x, y, 0, 0,
814 SWP_NOZORDER | SWP_NOSIZE);
815 }
816
817
818 /* align buddy right or below */
819 if (infoPtr->hwndBuddyRB) {
820 GetWindowRect (infoPtr->hwndBuddyRB, &rcBuddy);
821 MapWindowPoints (HWND_DESKTOP, hwndParent, (LPPOINT)&rcBuddy, 2);
822
823 if (dwStyle & TBS_VERT) {
824 x = (infoPtr->rcChannel.right + infoPtr->rcChannel.left) / 2 -
825 (rcBuddy.right - rcBuddy.left) / 2 + rcSelf.left;
826 y = rcSelf.bottom;
827 }
828 else {
829 x = rcSelf.right;
830 y = (infoPtr->rcChannel.bottom + infoPtr->rcChannel.top) / 2 -
831 (rcBuddy.bottom - rcBuddy.top) / 2 + rcSelf.top;
832 }
833 SetWindowPos (infoPtr->hwndBuddyRB, 0, x, y, 0, 0,
834 SWP_NOZORDER | SWP_NOSIZE);
835 }
836}
837
838
839static LRESULT
840TRACKBAR_ClearSel (HWND hwnd, WPARAM wParam, LPARAM lParam)
841{
842 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
843
844 if (infoPtr->nSelMin != infoPtr->nSelMax)
845 {
846 infoPtr->nSelMin = 0;
847 infoPtr->nSelMax = 0;
848 infoPtr->flags |= TB_SELECTIONCHANGED;
849
850 if ((BOOL)wParam) TRACKBAR_Refresh(hwnd);
851 }
852
853 return 0;
854}
855
856
857static LRESULT
858TRACKBAR_ClearTics (HWND hwnd, WPARAM wParam, LPARAM lParam)
859{
860 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
861
862 if (!(GetWindowLongA(hwnd, GWL_STYLE) & (TBS_AUTOTICKS | TBS_NOTICKS))) return 0;
863
864 if (infoPtr->tics)
865 {
866 COMCTL32_Free(infoPtr->tics);
867 infoPtr->tics = NULL;
868 infoPtr->uNumTics = 0;
869
870 if (wParam) TRACKBAR_Refresh(hwnd);
871 }
872
873 return 0;
874}
875
876
877static LRESULT
878TRACKBAR_GetBuddy (HWND hwnd, WPARAM wParam, LPARAM lParam)
879{
880 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
881
882 if (wParam) /* buddy is left or above */
883 return (LRESULT)infoPtr->hwndBuddyLA;
884
885 /* buddy is right or below */
886 return (LRESULT) infoPtr->hwndBuddyRB;
887}
888
889
890static LRESULT
891TRACKBAR_GetChannelRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
892{
893 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
894 LPRECT lprc = (LPRECT)lParam;
895
896 if (lprc == NULL) return 0;
897
898 CopyRect(lprc,&infoPtr->rcChannel);
899
900 return 0;
901}
902
903
904static LRESULT
905TRACKBAR_GetLineSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
906{
907 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
908
909 return infoPtr->nLineSize;
910}
911
912
913static LRESULT
914TRACKBAR_GetNumTics (HWND hwnd, WPARAM wParam, LPARAM lParam)
915{
916 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
917
918 if (GetWindowLongA(hwnd, GWL_STYLE) & TBS_NOTICKS) return 0;
919
920 return infoPtr->uNumTics+2; //includes last and first tick
921}
922
923
924static LRESULT
925TRACKBAR_GetPageSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
926{
927 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
928
929 return infoPtr->nPageSize;
930}
931
932
933static LRESULT
934TRACKBAR_GetPos (HWND hwnd, WPARAM wParam, LPARAM lParam)
935{
936 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
937
938 return infoPtr->nPos;
939}
940
941
942static LRESULT
943TRACKBAR_GetRangeMax (HWND hwnd, WPARAM wParam, LPARAM lParam)
944{
945 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
946
947 return infoPtr->nRangeMax;
948}
949
950
951static LRESULT
952TRACKBAR_GetRangeMin (HWND hwnd, WPARAM wParam, LPARAM lParam)
953{
954 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
955
956 return infoPtr->nRangeMin;
957}
958
959
960static LRESULT
961TRACKBAR_GetSelEnd (HWND hwnd, WPARAM wParam, LPARAM lParam)
962{
963 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
964
965 return infoPtr->nSelMax;
966}
967
968
969static LRESULT
970TRACKBAR_GetSelStart (HWND hwnd, WPARAM wParam, LPARAM lParam)
971{
972 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
973
974 return infoPtr->nSelMin;
975}
976
977
978static LRESULT
979TRACKBAR_GetThumbLength (HWND hwnd, WPARAM wParam, LPARAM lParam)
980{
981 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
982
983 return infoPtr->uThumbLen;
984}
985
986static LRESULT
987TRACKBAR_GetPTics (HWND hwnd)
988{
989 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
990
991 return (LRESULT)infoPtr->tics;
992}
993
994static LRESULT
995TRACKBAR_GetThumbRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
996{
997 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
998 LPRECT lprc = (LPRECT)lParam;
999
1000 if (lprc == NULL) return 0;
1001
1002 CopyRect(lprc,&infoPtr->rcFullThumb);
1003
1004 return 0;
1005}
1006
1007
1008static LRESULT
1009TRACKBAR_GetTic (HWND hwnd, WPARAM wParam, LPARAM lParam)
1010{
1011 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1012 INT iTic;
1013
1014 iTic = (INT)wParam;
1015 if ((iTic < 0) || (iTic > infoPtr->uNumTics)) return -1;
1016
1017 return (LRESULT)infoPtr->tics[iTic];
1018
1019}
1020
1021
1022static LRESULT
1023TRACKBAR_GetTicPos (HWND hwnd, WPARAM wParam, LPARAM lParam)
1024{
1025 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1026 INT iTic, range, width, pos;
1027
1028
1029 iTic = (INT)wParam;
1030 if ((iTic < 0) || (iTic > infoPtr->uNumTics)) return -1;
1031
1032 range = infoPtr->nRangeMax-infoPtr->nRangeMin;
1033 width = infoPtr->rcChannel.right-infoPtr->rcChannel.left;
1034 pos = infoPtr->rcChannel.left+(width*(infoPtr->tics[iTic]-infoPtr->nRangeMin))/range;
1035
1036 return (LRESULT) pos;
1037}
1038
1039
1040static LRESULT
1041TRACKBAR_GetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
1042{
1043 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1044
1045 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_TOOLTIPS)
1046 return (LRESULT)infoPtr->hwndToolTip;
1047 return 0;
1048}
1049
1050
1051/* case TBM_GETUNICODEFORMAT: */
1052
1053
1054static LRESULT
1055TRACKBAR_SetBuddy (HWND hwnd, WPARAM wParam, LPARAM lParam)
1056{
1057 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1058 HWND hwndTemp;
1059
1060 if (wParam) {
1061 /* buddy is left or above */
1062 hwndTemp = infoPtr->hwndBuddyLA;
1063 infoPtr->hwndBuddyLA = (HWND)lParam;
1064
1065// FIXME (trackbar, "move buddy!\n");
1066 }
1067 else {
1068 /* buddy is right or below */
1069 hwndTemp = infoPtr->hwndBuddyRB;
1070 infoPtr->hwndBuddyRB = (HWND)lParam;
1071
1072// FIXME (trackbar, "move buddy!\n");
1073 }
1074
1075 TRACKBAR_AlignBuddies (hwnd, infoPtr);
1076
1077 return (LRESULT)hwndTemp;
1078}
1079
1080
1081static LRESULT
1082TRACKBAR_SetLineSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
1083{
1084 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1085 INT nTemp = infoPtr->nLineSize;
1086
1087 infoPtr->nLineSize = (INT)lParam;
1088
1089 return nTemp;
1090}
1091
1092
1093static LRESULT
1094TRACKBAR_SetPageSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
1095{
1096 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1097 INT nTemp = infoPtr->nPageSize;
1098
1099 infoPtr->nPageSize = (INT)lParam;
1100
1101 return nTemp;
1102}
1103
1104
1105static LRESULT
1106TRACKBAR_SetPos (HWND hwnd, WPARAM wParam, LPARAM lParam)
1107{
1108 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1109 INT lastPos = infoPtr->nPos;
1110
1111 infoPtr->nPos = (INT)LOWORD(lParam);
1112
1113 if (lastPos == infoPtr->nPos) return 0; //nothing changed
1114
1115 if (infoPtr->nPos < infoPtr->nRangeMin)
1116 infoPtr->nPos = infoPtr->nRangeMin;
1117
1118 if (infoPtr->nPos > infoPtr->nRangeMax)
1119 infoPtr->nPos = infoPtr->nRangeMax;
1120 infoPtr->flags |= TB_THUMBPOSCHANGED;
1121
1122 if (wParam) TRACKBAR_UpdateThumbPosition(hwnd,lastPos);
1123
1124 return 0;
1125}
1126
1127
1128static LRESULT
1129TRACKBAR_SetRange (HWND hwnd, WPARAM wParam, LPARAM lParam)
1130{
1131 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1132 int newMin,newMax;
1133 newMin = (INT)LOWORD(lParam);
1134 newMax = (INT)HIWORD(lParam);
1135
1136 if (newMin == infoPtr->nRangeMin && newMax == infoPtr->nRangeMax) return 0;
1137
1138 infoPtr->nRangeMin = newMin;
1139 infoPtr->nRangeMax = newMax;
1140
1141 if (infoPtr->nPos < infoPtr->nRangeMin)
1142 {
1143 infoPtr->nPos = infoPtr->nRangeMin;
1144 infoPtr->flags |= TB_THUMBPOSCHANGED;
1145 }
1146
1147 if (infoPtr->nPos > infoPtr->nRangeMax)
1148 {
1149 infoPtr->nPos = infoPtr->nRangeMax;
1150 infoPtr->flags |= TB_THUMBPOSCHANGED;
1151 }
1152
1153 infoPtr->nPageSize = (infoPtr->nRangeMax-infoPtr->nRangeMin)/5;
1154 if (infoPtr->nPageSize == 0) infoPtr->nPageSize = 1;
1155 TRACKBAR_RecalculateTics(hwnd,infoPtr,TRUE);
1156
1157 if (wParam) TRACKBAR_Refresh(hwnd);
1158
1159 return 0;
1160}
1161
1162
1163static LRESULT
1164TRACKBAR_SetRangeMax (HWND hwnd, WPARAM wParam, LPARAM lParam)
1165{
1166 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1167
1168 if (infoPtr->nRangeMax == (INT)lParam) return 0;
1169
1170 infoPtr->nRangeMax = (INT)lParam;
1171 if (infoPtr->nPos > infoPtr->nRangeMax)
1172 {
1173 infoPtr->nPos = infoPtr->nRangeMax;
1174 infoPtr->flags |=TB_THUMBPOSCHANGED;
1175 }
1176
1177 infoPtr->nPageSize = (infoPtr->nRangeMax-infoPtr->nRangeMin)/5;
1178 if (infoPtr->nPageSize == 0) infoPtr->nPageSize = 1;
1179 TRACKBAR_RecalculateTics(hwnd,infoPtr,TRUE);
1180
1181 if (wParam) TRACKBAR_Refresh(hwnd);
1182
1183 return 0;
1184}
1185
1186
1187static LRESULT
1188TRACKBAR_SetRangeMin (HWND hwnd, WPARAM wParam, LPARAM lParam)
1189{
1190 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1191
1192 if (infoPtr->nRangeMin == (INT)lParam) return 0;
1193
1194 infoPtr->nRangeMin = (INT)lParam;
1195 if (infoPtr->nPos < infoPtr->nRangeMin)
1196 {
1197 infoPtr->nPos = infoPtr->nRangeMin;
1198 infoPtr->flags |=TB_THUMBPOSCHANGED;
1199 }
1200
1201 infoPtr->nPageSize = (infoPtr->nRangeMax-infoPtr->nRangeMin)/5;
1202 if (infoPtr->nPageSize == 0) infoPtr->nPageSize = 1;
1203 TRACKBAR_RecalculateTics(hwnd,infoPtr,TRUE);
1204
1205 if (wParam) TRACKBAR_Refresh(hwnd);
1206
1207 return 0;
1208}
1209
1210
1211static LRESULT
1212TRACKBAR_SetTicFreq (HWND hwnd, WPARAM wParam)
1213{
1214 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1215
1216 if (infoPtr->uTicFreq == (UINT)wParam) return 0;
1217
1218 if (!(GetWindowLongA (hwnd, GWL_STYLE) & TBS_AUTOTICKS)) return 0;
1219
1220 infoPtr->uTicFreq = (UINT)wParam;
1221
1222 TRACKBAR_RecalculateTics(hwnd,infoPtr,FALSE);
1223
1224 TRACKBAR_Refresh(hwnd);
1225
1226 return 0;
1227}
1228
1229
1230static LRESULT
1231TRACKBAR_SetSel (HWND hwnd, WPARAM wParam, LPARAM lParam)
1232{
1233 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1234 INT newMin,newMax;
1235
1236 newMin = (INT)LOWORD(lParam);
1237 newMax = (INT)HIWORD(lParam);
1238
1239 if (infoPtr->nSelMin == newMin && infoPtr->nSelMax == newMax) return 0;
1240 infoPtr->nSelMin = newMin;
1241 infoPtr->nSelMax = newMax;
1242
1243 infoPtr->flags |=TB_SELECTIONCHANGED;
1244
1245 if (!GetWindowLongA (hwnd, GWL_STYLE) & TBS_ENABLESELRANGE)
1246 return 0;
1247
1248 if (infoPtr->nSelMin < infoPtr->nRangeMin)
1249 infoPtr->nSelMin = infoPtr->nRangeMin;
1250 if (infoPtr->nSelMax > infoPtr->nRangeMax)
1251 infoPtr->nSelMax = infoPtr->nRangeMax;
1252
1253 if (wParam) TRACKBAR_Refresh(hwnd);
1254
1255 return 0;
1256}
1257
1258
1259static LRESULT
1260TRACKBAR_SetSelEnd (HWND hwnd, WPARAM wParam, LPARAM lParam)
1261{
1262 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1263
1264 if (infoPtr->nSelMax == (INT)lParam) return 0;
1265
1266 if (!GetWindowLongA (hwnd, GWL_STYLE) & TBS_ENABLESELRANGE)
1267 return 0;
1268
1269 infoPtr->nSelMax = (INT)lParam;
1270 infoPtr->flags |= TB_SELECTIONCHANGED;
1271
1272 if (infoPtr->nSelMax > infoPtr->nRangeMax)
1273 infoPtr->nSelMax = infoPtr->nRangeMax;
1274
1275 if (wParam) TRACKBAR_Refresh(hwnd);
1276
1277 return 0;
1278}
1279
1280
1281static LRESULT
1282TRACKBAR_SetSelStart (HWND hwnd, WPARAM wParam, LPARAM lParam)
1283{
1284 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1285
1286 if (infoPtr->nSelMin == (INT)lParam) return 0;
1287
1288 if (!GetWindowLongA (hwnd, GWL_STYLE) & TBS_ENABLESELRANGE)
1289 return 0;
1290
1291 infoPtr->nSelMin = (INT)lParam;
1292 infoPtr->flags |= TB_SELECTIONCHANGED;
1293
1294 if (infoPtr->nSelMin < infoPtr->nRangeMin)
1295 infoPtr->nSelMin = infoPtr->nRangeMin;
1296
1297 if (wParam) TRACKBAR_Refresh(hwnd);
1298
1299 return 0;
1300}
1301
1302
1303static LRESULT
1304TRACKBAR_SetThumbLength (HWND hwnd, WPARAM wParam, LPARAM lParam)
1305{
1306 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1307
1308 if (infoPtr->uThumbLen == (UINT)wParam) return 0;
1309
1310 if (!(GetWindowLongA (hwnd, GWL_STYLE) & TBS_FIXEDLENGTH)) return 0;
1311
1312 infoPtr->uThumbLen = (UINT)wParam;
1313 infoPtr->flags |= TB_THUMBSIZECHANGED;
1314
1315 TRACKBAR_Refresh(hwnd);
1316
1317 return 0;
1318}
1319
1320static void TRACKBAR_QuickSort(LPLONG list,INT lo,INT hi)
1321{
1322 INT i,j,x,y;
1323
1324 i = lo;
1325 j = hi;
1326 x = list[(lo+hi)/2];
1327 while (i <= j)
1328 {
1329 while (list[i] < x) i++;
1330 while (x < list[j]) j--;
1331 if (i <= j)
1332 {
1333 y = list[i];
1334 list[i] = list[j];
1335 list[j] = y;
1336 i++;
1337 j--;
1338 }
1339 }
1340 if (lo < j) TRACKBAR_QuickSort(list,lo,j);
1341 if (i < hi) TRACKBAR_QuickSort(list,i,hi);
1342}
1343
1344static LRESULT
1345TRACKBAR_SetTic (HWND hwnd, WPARAM wParam, LPARAM lParam)
1346{
1347 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1348 INT nPos = (INT)lParam;
1349 INT x;
1350
1351 if (!(GetWindowLongA(hwnd, GWL_STYLE) & (TBS_AUTOTICKS | TBS_NOTICKS))) return 0;
1352
1353 if ((nPos < infoPtr->nRangeMin) || (nPos > infoPtr->nRangeMax)) return FALSE;
1354
1355 //Check if tick exists
1356 for (x = 0;x < infoPtr->uNumTics;x++)
1357 {
1358 if (infoPtr->tics[x] == nPos) return TRUE; //value is ok
1359 }
1360
1361 infoPtr->uNumTics++;
1362 infoPtr->tics = COMCTL32_ReAlloc(infoPtr->tics,infoPtr->uNumTics*sizeof(DWORD));
1363 infoPtr->tics[infoPtr->uNumTics-1] = nPos;
1364
1365 //Quicksort the list
1366 TRACKBAR_QuickSort(infoPtr->tics,0,infoPtr->uNumTics-1);
1367
1368 TRACKBAR_Refresh(hwnd);
1369
1370 return TRUE;
1371}
1372
1373
1374static LRESULT
1375TRACKBAR_SetTipSide (HWND hwnd, WPARAM wParam, LPARAM lParam)
1376{
1377 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1378 INT fTemp = infoPtr->fLocation;
1379
1380 infoPtr->fLocation = (INT)wParam;
1381
1382 return fTemp;
1383}
1384
1385
1386static LRESULT
1387TRACKBAR_SetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
1388{
1389 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1390
1391 infoPtr->hwndToolTip = (HWND)wParam;
1392
1393 return 0;
1394}
1395
1396
1397/* case TBM_SETUNICODEFORMAT: */
1398
1399
1400static LRESULT
1401TRACKBAR_InitializeThumb (HWND hwnd)
1402{
1403 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1404 RECT clientRect;
1405 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
1406 INT scaleSize;
1407
1408 GetWindowRect(hwnd,&clientRect);
1409 infoPtr->uThumbLen = THUMB_LEN; /* initial thumb length */
1410
1411 scaleSize = 2*BORDER_SIZE;
1412 if (dwStyle & TBS_NOTICKS) scaleSize += 0;
1413 else if (dwStyle & TBS_BOTH) scaleSize += 2*(SCALE_SIZE+SCALE_SPACE);
1414 else scaleSize += SCALE_SIZE+SCALE_SPACE;
1415
1416 if (dwStyle & TBS_VERT)
1417 {
1418 INT width = clientRect.right-clientRect.left;
1419
1420 if (infoPtr->uThumbLen+scaleSize > width) infoPtr->uThumbLen = MAX(width-scaleSize,THUMB_MINLEN);
1421 } else
1422 {
1423 INT height = clientRect.bottom-clientRect.top;
1424
1425 if (infoPtr->uThumbLen+scaleSize > height) infoPtr->uThumbLen = MAX(height-scaleSize,THUMB_MINLEN);
1426 }
1427
1428 TRACKBAR_CalcChannel(hwnd,infoPtr);
1429 TRACKBAR_CalcThumb(hwnd,infoPtr);
1430
1431 infoPtr->flags &= ~TB_SELECTIONCHANGED;
1432
1433 return 0;
1434}
1435
1436
1437static LRESULT
1438TRACKBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
1439{
1440 TRACKBAR_INFO *infoPtr;
1441
1442 infoPtr = (TRACKBAR_INFO *)COMCTL32_Alloc (sizeof(TRACKBAR_INFO));
1443 SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
1444
1445 /* set default values */
1446 infoPtr->nRangeMin = 0;
1447 infoPtr->nRangeMax = 100;
1448 infoPtr->nLineSize = 1;
1449 infoPtr->nPageSize = 20;
1450 infoPtr->nSelMin = 0;
1451 infoPtr->nSelMax = 0;
1452 infoPtr->nPos = 0;
1453
1454 infoPtr->uNumTics = 0; /* start and end tic are not included in count*/
1455 infoPtr->uTicFreq = 1;
1456 infoPtr->tics = NULL;
1457 infoPtr->clrBk = GetSysColor (COLOR_3DFACE);
1458 infoPtr->hwndNotify = GetParent (hwnd);
1459
1460 TRACKBAR_InitializeThumb (hwnd);
1461
1462 /* Create tooltip control */
1463 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_TOOLTIPS) {
1464 TTTOOLINFOA ti;
1465
1466 infoPtr->hwndToolTip =
1467 CreateWindowExA (0, TOOLTIPS_CLASSA, NULL, 0,
1468 CW_USEDEFAULT, CW_USEDEFAULT,
1469 CW_USEDEFAULT, CW_USEDEFAULT,
1470 hwnd, 0, 0, 0);
1471
1472 /* Send NM_TOOLTIPSCREATED notification */
1473 if (infoPtr->hwndToolTip) {
1474 NMTOOLTIPSCREATED nmttc;
1475
1476 nmttc.hdr.hwndFrom = hwnd;
1477 nmttc.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1478 nmttc.hdr.code = NM_TOOLTIPSCREATED;
1479 nmttc.hwndToolTips = infoPtr->hwndToolTip;
1480
1481 SendMessageA (GetParent (hwnd), WM_NOTIFY,
1482 (WPARAM)nmttc.hdr.idFrom, (LPARAM)&nmttc);
1483 }
1484
1485 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
1486 ti.cbSize = sizeof(TTTOOLINFOA);
1487 ti.uFlags = TTF_IDISHWND | TTF_TRACK;
1488 ti.hwnd = hwnd;
1489 ti.uId = 0;
1490 ti.lpszText = "Test"; /* LPSTR_TEXTCALLBACK */
1491 SetRectEmpty (&ti.rect);
1492
1493 SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA, 0, (LPARAM)&ti);
1494 }
1495
1496 return 0;
1497}
1498
1499
1500static LRESULT
1501TRACKBAR_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
1502{
1503 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1504
1505 /* delete tooltip control */
1506 if (infoPtr->hwndToolTip)
1507 DestroyWindow (infoPtr->hwndToolTip);
1508
1509 COMCTL32_Free (infoPtr);
1510 return 0;
1511}
1512
1513static LRESULT
1514TRACKBAR_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
1515{
1516 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1517 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1518 int clickPlace,prevPos,vertical;
1519 DOUBLE clickPos;
1520 RECT thumb;
1521 POINT clickPoint;
1522
1523 SetFocus (hwnd);
1524
1525 vertical = dwStyle & TBS_VERT;
1526 clickPoint.x = (INT)LOWORD(lParam);
1527 clickPoint.y = (INT)HIWORD(lParam);
1528
1529
1530 if (vertical) clickPlace = clickPoint.y;
1531 else clickPlace = clickPoint.x;
1532
1533 //Button down on thumb?
1534 thumb = infoPtr->rcFullThumb; //approzimative
1535 if ((vertical &&
1536 (clickPoint.y >= thumb.top) &&
1537 (clickPoint.y <= thumb.bottom) &&
1538 (clickPoint.x >= thumb.left) &&
1539 (clickPoint.x <= thumb.right)) ||
1540 (!vertical &&
1541 (clickPoint.x >= thumb.left) &&
1542 (clickPoint.x <= thumb.right) &&
1543 (clickPoint.y >= thumb.top) &&
1544 (clickPoint.y <= thumb.bottom)))
1545 {
1546 infoPtr->flags |= TB_DRAG_MODE;
1547 if (dwStyle & TBS_TOOLTIPS)
1548 { /* enable tooltip */
1549 TTTOOLINFOA ti;
1550 POINT pt;
1551
1552 GetCursorPos (&pt);
1553 SendMessageA (infoPtr->hwndToolTip, TTM_TRACKPOSITION, 0,
1554 (LPARAM)MAKELPARAM(pt.x, pt.y));
1555
1556 ti.cbSize = sizeof(TTTOOLINFOA);
1557 ti.uId = 0;
1558 ti.hwnd = (UINT)hwnd;
1559
1560 infoPtr->flags |= TB_SHOW_TOOLTIP;
1561 SetCapture (hwnd);
1562 SendMessageA (infoPtr->hwndToolTip, TTM_TRACKACTIVATE,
1563 (WPARAM)TRUE, (LPARAM)&ti);
1564 }
1565 SetCapture(hwnd);
1566 TRACKBAR_UpdateThumb(hwnd); //change arrow color
1567 return 0;
1568 }
1569 else if ((vertical &&
1570 (clickPoint.y >= thumb.top) &&
1571 (clickPoint.y <= thumb.bottom)) ||
1572 (!vertical &&
1573 (clickPoint.x >= thumb.left) &&
1574 (clickPoint.x <= thumb.right)))
1575 {
1576 //ScrollMode
1577 infoPtr->flags |= TB_SCROLL_MODE;
1578 SetCapture(hwnd);
1579 SetTimer(hwnd,SCROLL_TIMER_ID,SCROLL_TIME,NULL);
1580
1581 return 0;
1582 }
1583
1584 clickPos = TRACKBAR_ConvertPlaceToPosition(infoPtr,clickPlace,vertical);
1585 prevPos = infoPtr->nPos;
1586
1587 if (clickPos > prevPos)
1588 { /* similar to VK_NEXT */
1589 infoPtr->nPos += infoPtr->nPageSize;
1590 if (infoPtr->nPos > infoPtr->nRangeMax) infoPtr->nPos = infoPtr->nRangeMax;
1591 if (prevPos != infoPtr->nPos) TRACKBAR_SendNotify(hwnd,TB_PAGEUP);
1592 } else
1593 { /* similar to VK_PRIOR */
1594 infoPtr->nPos -= infoPtr->nPageSize;
1595 if (infoPtr->nPos < infoPtr->nRangeMin) infoPtr->nPos = infoPtr->nRangeMin;
1596 if (prevPos != infoPtr->nPos) TRACKBAR_SendNotify(hwnd,TB_PAGEDOWN);
1597 }
1598
1599 if (prevPos != infoPtr->nPos)
1600 {
1601 infoPtr->flags |= TB_THUMBPOSCHANGED;
1602 TRACKBAR_UpdateThumbPosition(hwnd,prevPos);
1603 }
1604
1605 //ScrollMode
1606 infoPtr->flags |= TB_SCROLL_MODE;
1607 SetCapture(hwnd);
1608 SetTimer(hwnd,SCROLL_TIMER_ID,SCROLL_TIME,NULL);
1609
1610 return 0;
1611}
1612
1613
1614static LRESULT
1615TRACKBAR_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
1616{
1617 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1618
1619 if (infoPtr->flags & TB_DRAG_MODE)
1620 {
1621 TRACKBAR_SendNotify(hwnd,TB_ENDTRACK);
1622
1623 infoPtr->flags &= ~TB_DRAG_MODE;
1624 ReleaseCapture();
1625 TRACKBAR_UpdateThumb(hwnd); //change arrow color
1626 }
1627
1628 if (infoPtr->flags & TB_SCROLL_MODE)
1629 {
1630 infoPtr->flags &= ~TB_SCROLL_MODE;
1631 ReleaseCapture();
1632 KillTimer(hwnd,SCROLL_TIMER_ID);
1633 }
1634
1635 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_TOOLTIPS)
1636 { /* disable tooltip */
1637 TTTOOLINFOA ti;
1638
1639 ti.cbSize = sizeof(TTTOOLINFOA);
1640 ti.uId = 0;
1641 ti.hwnd = (UINT)hwnd;
1642
1643 infoPtr->flags &= ~TB_SHOW_TOOLTIP;
1644 SendMessageA (infoPtr->hwndToolTip, TTM_TRACKACTIVATE,
1645 (WPARAM)FALSE, (LPARAM)&ti);
1646 }
1647
1648 return 0;
1649}
1650
1651
1652static LRESULT TRACKBAR_Timer(HWND hwnd,WPARAM wParam,LPARAM lParam)
1653{
1654 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(hwnd);
1655 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
1656 POINT mousePoint;
1657 INT mousePlace,prevPos,newPos,vertical;
1658 DOUBLE mousePos;
1659
1660 GetCursorPos(&mousePoint);
1661 ScreenToClient(hwnd,&mousePoint);
1662
1663 vertical = dwStyle & TBS_VERT;
1664 if (vertical) mousePlace = mousePoint.y;
1665 else mousePlace = mousePoint.x;
1666
1667 mousePos = TRACKBAR_ConvertPlaceToPosition(infoPtr,mousePlace,vertical);
1668 prevPos = infoPtr->nPos;
1669
1670 if (mousePos > (INT)mousePos+0.5) newPos = mousePos+1;
1671 else newPos = mousePos;
1672 if (newPos == prevPos) return 0;
1673
1674 if (newPos > prevPos)
1675 { /* similar to VK_NEXT */
1676 infoPtr->nPos += infoPtr->nPageSize;
1677 if (infoPtr->nPos > infoPtr->nRangeMax) infoPtr->nPos = infoPtr->nRangeMax;
1678 if (prevPos != infoPtr->nPos) TRACKBAR_SendNotify(hwnd,TB_PAGEUP);
1679 } else
1680 { /* similar to VK_PRIOR */
1681 infoPtr->nPos -= infoPtr->nPageSize;
1682 if (infoPtr->nPos < infoPtr->nRangeMin) infoPtr->nPos = infoPtr->nRangeMin;
1683 if (prevPos != infoPtr->nPos) TRACKBAR_SendNotify(hwnd,TB_PAGEDOWN);
1684 }
1685
1686 if (prevPos != infoPtr->nPos)
1687 {
1688 infoPtr->flags |= TB_THUMBPOSCHANGED;
1689 TRACKBAR_UpdateThumbPosition(hwnd,prevPos);
1690 }
1691
1692 return 0;
1693}
1694
1695static LRESULT
1696TRACKBAR_CaptureChanged (HWND hwnd, WPARAM wParam, LPARAM lParam)
1697{
1698 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1699
1700 if (infoPtr->flags & TB_DRAGPOSVALID)
1701 {
1702 int lastPos = infoPtr->nPos;
1703 infoPtr->nPos = infoPtr->dragPos;
1704 if (lastPos != infoPtr->nPos) TRACKBAR_UpdateThumbPosition(hwnd,lastPos);
1705 }
1706
1707 infoPtr->flags &= ~ TB_DRAGPOSVALID;
1708
1709 if (infoPtr->flags & TB_SCROLL_MODE)
1710 {
1711 infoPtr->flags &= ~TB_SCROLL_MODE;
1712 KillTimer(hwnd,SCROLL_TIMER_ID);
1713 }
1714
1715 TRACKBAR_SendNotify(hwnd,TB_ENDTRACK);
1716 return 0;
1717}
1718
1719
1720static LRESULT
1721TRACKBAR_Paint (HWND hwnd, WPARAM wParam)
1722{
1723 HDC hdc;
1724 PAINTSTRUCT ps;
1725
1726 hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
1727 TRACKBAR_Draw(hwnd,hdc);
1728 if (!wParam) EndPaint (hwnd, &ps);
1729 return 0;
1730}
1731
1732
1733static LRESULT
1734TRACKBAR_SetFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
1735{
1736 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1737 HDC hdc;
1738 RECT rcClient;
1739
1740// TRACE (trackbar,"\n");
1741 if (!infoPtr->bFocus)
1742 {
1743 infoPtr->bFocus = TRUE;
1744
1745 GetClientRect (hwnd,&rcClient);
1746 hdc = GetDC (hwnd);
1747 DrawFocusRect (hdc,&rcClient);
1748 ReleaseDC(hwnd,hdc);
1749
1750 }
1751 return 0;
1752}
1753
1754static LRESULT
1755TRACKBAR_KillFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
1756{
1757 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1758 HDC hdc;
1759 RECT rcClient;
1760
1761// TRACE (trackbar,"\n");
1762
1763 infoPtr->flags &= ~TB_DRAG_MODE;
1764 if (infoPtr->bFocus)
1765 {
1766 infoPtr->bFocus = FALSE;
1767
1768 GetClientRect(hwnd,&rcClient);
1769 hdc = GetDC (hwnd);
1770 DrawFocusRect(hdc,&rcClient); //XOR removes
1771 ReleaseDC(hwnd,hdc);
1772 }
1773
1774 return 0;
1775}
1776
1777static LRESULT
1778TRACKBAR_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
1779{
1780 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1781
1782 TRACKBAR_CalcChannel (hwnd, infoPtr);
1783 TRACKBAR_AlignBuddies (hwnd, infoPtr);
1784
1785 return 0;
1786}
1787
1788
1789static BOOL
1790TRACKBAR_SendNotify (HWND hwnd, UINT code)
1791{
1792// TRACE (trackbar, "%x\n",code);
1793
1794 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_VERT)
1795 return (BOOL) SendMessageA (GetParent (hwnd),
1796 WM_VSCROLL, (WPARAM)code, (LPARAM)hwnd);
1797
1798 return (BOOL) SendMessageA (GetParent (hwnd),
1799 WM_HSCROLL, (WPARAM)code, (LPARAM)hwnd);
1800}
1801
1802
1803static LRESULT
1804TRACKBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
1805{
1806 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1807 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1808 SHORT clickPlace;
1809 DOUBLE dragPos;
1810 char buf[80];
1811 INT lastDragPos;
1812
1813// TRACE (trackbar, "%x\n",wParam);
1814
1815 if (dwStyle & TBS_VERT) clickPlace=(SHORT)HIWORD(lParam);
1816 else clickPlace=(SHORT)LOWORD(lParam);
1817
1818 if (!(infoPtr->flags & TB_DRAG_MODE)) return TRUE;
1819
1820 lastDragPos = infoPtr->dragPos;
1821 dragPos = TRACKBAR_ConvertPlaceToPosition (infoPtr, clickPlace,
1822 dwStyle & TBS_VERT);
1823 if (dragPos > ((INT)dragPos)+0.5) infoPtr->dragPos = dragPos + 1;
1824 else infoPtr->dragPos = dragPos;
1825
1826 if (lastDragPos == infoPtr->dragPos) return TRUE; //nothing changed
1827
1828 infoPtr->flags |= TB_DRAGPOSVALID;
1829 TRACKBAR_SendNotify (hwnd, TB_THUMBTRACK | (infoPtr->nPos>>16));
1830
1831 if (infoPtr->flags & TB_SHOW_TOOLTIP)
1832 {
1833 POINT pt;
1834 TTTOOLINFOA ti;
1835
1836 ti.cbSize = sizeof(TTTOOLINFOA);
1837 ti.hwnd = hwnd;
1838 ti.uId = 0;
1839 ti.hinst=0;
1840 sprintf (buf,"%d",infoPtr->nPos);
1841 ti.lpszText = (LPSTR) buf;
1842 GetCursorPos (&pt);
1843
1844 if (dwStyle & TBS_VERT) {
1845 SendMessageA (infoPtr->hwndToolTip, TTM_TRACKPOSITION,
1846 0, (LPARAM)MAKELPARAM(pt.x+5, pt.y+15));
1847 } else {
1848 SendMessageA (infoPtr->hwndToolTip, TTM_TRACKPOSITION,
1849 0, (LPARAM)MAKELPARAM(pt.x+15, pt.y+5));
1850 }
1851 SendMessageA (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTA,
1852 0, (LPARAM)&ti);
1853 }
1854
1855 TRACKBAR_UpdateThumbPosition(hwnd,lastDragPos);
1856
1857 return TRUE;
1858}
1859
1860
1861static LRESULT
1862TRACKBAR_KeyDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
1863{
1864 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1865 INT pos;
1866
1867// TRACE (trackbar, "%x\n",wParam);
1868
1869 pos=infoPtr->nPos;
1870 switch (wParam) {
1871 case VK_LEFT:
1872 case VK_UP:
1873 if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
1874 infoPtr->nPos -= infoPtr->nLineSize;
1875 if (infoPtr->nPos < infoPtr->nRangeMin)
1876 infoPtr->nPos = infoPtr->nRangeMin;
1877 TRACKBAR_SendNotify(hwnd,TB_LINEUP);
1878 break;
1879 case VK_RIGHT:
1880 case VK_DOWN:
1881 if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
1882 infoPtr->nPos += infoPtr->nLineSize;
1883 if (infoPtr->nPos > infoPtr->nRangeMax)
1884 infoPtr->nPos = infoPtr->nRangeMax;
1885 TRACKBAR_SendNotify (hwnd, TB_LINEDOWN);
1886 break;
1887 case VK_NEXT:
1888 if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
1889 infoPtr->nPos += infoPtr->nPageSize;
1890 if (infoPtr->nPos > infoPtr->nRangeMax)
1891 infoPtr->nPos = infoPtr->nRangeMax;
1892 TRACKBAR_SendNotify (hwnd, TB_PAGEUP);
1893 break;
1894 case VK_PRIOR:
1895 if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
1896 infoPtr->nPos -= infoPtr->nPageSize;
1897 if (infoPtr->nPos < infoPtr->nRangeMin)
1898 infoPtr->nPos = infoPtr->nRangeMin;
1899 TRACKBAR_SendNotify (hwnd, TB_PAGEDOWN);
1900 break;
1901 case VK_HOME:
1902 if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
1903 infoPtr->nPos = infoPtr->nRangeMin;
1904 TRACKBAR_SendNotify (hwnd, TB_TOP);
1905 break;
1906 case VK_END:
1907 if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
1908 infoPtr->nPos = infoPtr->nRangeMax;
1909 TRACKBAR_SendNotify (hwnd, TB_BOTTOM);
1910 break;
1911 }
1912
1913 if (pos != infoPtr->nPos)
1914 {
1915 infoPtr->flags |= TB_THUMBPOSCHANGED;
1916 TRACKBAR_UpdateThumbPosition(hwnd,pos);
1917 }
1918
1919 return TRUE;
1920}
1921
1922
1923static LRESULT
1924TRACKBAR_KeyUp (HWND hwnd, WPARAM wParam)
1925{
1926 switch (wParam) {
1927 case VK_LEFT:
1928 case VK_UP:
1929 case VK_RIGHT:
1930 case VK_DOWN:
1931 case VK_NEXT:
1932 case VK_PRIOR:
1933 case VK_HOME:
1934 case VK_END:
1935 TRACKBAR_SendNotify (hwnd, TB_ENDTRACK);
1936 }
1937 return TRUE;
1938}
1939
1940
1941LRESULT WINAPI
1942TRACKBAR_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1943{
1944 switch (uMsg)
1945 {
1946 case TBM_CLEARSEL:
1947 return TRACKBAR_ClearSel (hwnd, wParam, lParam);
1948
1949 case TBM_CLEARTICS:
1950 return TRACKBAR_ClearTics (hwnd, wParam, lParam);
1951
1952 case TBM_GETBUDDY:
1953 return TRACKBAR_GetBuddy (hwnd, wParam, lParam);
1954
1955 case TBM_GETCHANNELRECT:
1956 return TRACKBAR_GetChannelRect (hwnd, wParam, lParam);
1957
1958 case TBM_GETLINESIZE:
1959 return TRACKBAR_GetLineSize (hwnd, wParam, lParam);
1960
1961 case TBM_GETNUMTICS:
1962 return TRACKBAR_GetNumTics (hwnd, wParam, lParam);
1963
1964 case TBM_GETPAGESIZE:
1965 return TRACKBAR_GetPageSize (hwnd, wParam, lParam);
1966
1967 case TBM_GETPOS:
1968 return TRACKBAR_GetPos (hwnd, wParam, lParam);
1969
1970 case TBM_GETPTICS:
1971 return TRACKBAR_GetPTics (hwnd);
1972
1973 case TBM_GETRANGEMAX:
1974 return TRACKBAR_GetRangeMax (hwnd, wParam, lParam);
1975
1976 case TBM_GETRANGEMIN:
1977 return TRACKBAR_GetRangeMin (hwnd, wParam, lParam);
1978
1979 case TBM_GETSELEND:
1980 return TRACKBAR_GetSelEnd (hwnd, wParam, lParam);
1981
1982 case TBM_GETSELSTART:
1983 return TRACKBAR_GetSelStart (hwnd, wParam, lParam);
1984
1985 case TBM_GETTHUMBLENGTH:
1986 return TRACKBAR_GetThumbLength (hwnd, wParam, lParam);
1987
1988 case TBM_GETTHUMBRECT:
1989 return TRACKBAR_GetThumbRect (hwnd, wParam, lParam);
1990
1991 case TBM_GETTIC:
1992 return TRACKBAR_GetTic (hwnd, wParam, lParam);
1993
1994 case TBM_GETTICPOS:
1995 return TRACKBAR_GetTicPos (hwnd, wParam, lParam);
1996
1997 case TBM_GETTOOLTIPS:
1998 return TRACKBAR_GetToolTips (hwnd, wParam, lParam);
1999
2000/* case TBM_GETUNICODEFORMAT: */
2001
2002 case TBM_SETBUDDY:
2003 return TRACKBAR_SetBuddy (hwnd, wParam, lParam);
2004
2005 case TBM_SETLINESIZE:
2006 return TRACKBAR_SetLineSize (hwnd, wParam, lParam);
2007
2008 case TBM_SETPAGESIZE:
2009 return TRACKBAR_SetPageSize (hwnd, wParam, lParam);
2010
2011 case TBM_SETPOS:
2012 return TRACKBAR_SetPos (hwnd, wParam, lParam);
2013
2014 case TBM_SETRANGE:
2015 return TRACKBAR_SetRange (hwnd, wParam, lParam);
2016
2017 case TBM_SETRANGEMAX:
2018 return TRACKBAR_SetRangeMax (hwnd, wParam, lParam);
2019
2020 case TBM_SETRANGEMIN:
2021 return TRACKBAR_SetRangeMin (hwnd, wParam, lParam);
2022
2023 case TBM_SETSEL:
2024 return TRACKBAR_SetSel (hwnd, wParam, lParam);
2025
2026 case TBM_SETSELEND:
2027 return TRACKBAR_SetSelEnd (hwnd, wParam, lParam);
2028
2029 case TBM_SETSELSTART:
2030 return TRACKBAR_SetSelStart (hwnd, wParam, lParam);
2031
2032 case TBM_SETTHUMBLENGTH:
2033 return TRACKBAR_SetThumbLength (hwnd, wParam, lParam);
2034
2035 case TBM_SETTIC:
2036 return TRACKBAR_SetTic (hwnd, wParam, lParam);
2037
2038 case TBM_SETTICFREQ:
2039 return TRACKBAR_SetTicFreq (hwnd, wParam);
2040
2041 case TBM_SETTIPSIDE:
2042 return TRACKBAR_SetTipSide (hwnd, wParam, lParam);
2043
2044 case TBM_SETTOOLTIPS:
2045 return TRACKBAR_SetToolTips (hwnd, wParam, lParam);
2046
2047/* case TBM_SETUNICODEFORMAT: */
2048
2049
2050 case WM_CAPTURECHANGED:
2051 return TRACKBAR_CaptureChanged (hwnd, wParam, lParam);
2052
2053 case WM_CREATE:
2054 return TRACKBAR_Create (hwnd, wParam, lParam);
2055
2056 case WM_DESTROY:
2057 return TRACKBAR_Destroy (hwnd, wParam, lParam);
2058
2059/* case WM_ENABLE: */
2060
2061/* case WM_ERASEBKGND: */
2062/* return 0; */
2063
2064 case WM_GETDLGCODE:
2065 return DLGC_WANTARROWS;
2066
2067 case WM_KEYDOWN:
2068 return TRACKBAR_KeyDown (hwnd, wParam, lParam);
2069
2070 case WM_KEYUP:
2071 return TRACKBAR_KeyUp (hwnd, wParam);
2072
2073 case WM_LBUTTONDOWN:
2074 return TRACKBAR_LButtonDown (hwnd, wParam, lParam);
2075
2076 case WM_LBUTTONUP:
2077 return TRACKBAR_LButtonUp (hwnd, wParam, lParam);
2078
2079 case WM_TIMER:
2080 return TRACKBAR_Timer(hwnd,wParam,lParam);
2081
2082 case WM_MOUSEMOVE:
2083 return TRACKBAR_MouseMove (hwnd, wParam, lParam);
2084
2085 case WM_PAINT:
2086 return TRACKBAR_Paint (hwnd, wParam);
2087
2088 case WM_SETFOCUS:
2089 return TRACKBAR_SetFocus (hwnd, wParam, lParam);
2090
2091 case WM_KILLFOCUS:
2092 return TRACKBAR_KillFocus (hwnd, wParam, lParam);
2093
2094 case WM_SIZE:
2095 return TRACKBAR_Size (hwnd, wParam, lParam);
2096
2097 case WM_WININICHANGE:
2098 return TRACKBAR_InitializeThumb (hwnd);
2099
2100 default:
2101// if (uMsg >= WM_USER)
2102// ERR (trackbar, "unknown msg %04x wp=%08x lp=%08lx\n",
2103// uMsg, wParam, lParam);
2104 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
2105 }
2106 return 0;
2107}
2108
2109
2110VOID
2111TRACKBAR_Register (VOID)
2112{
2113 WNDCLASSA wndClass;
2114
2115 if (GlobalFindAtomA (TRACKBAR_CLASSA)) return;
2116
2117 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
2118 wndClass.style = CS_GLOBALCLASS;
2119 wndClass.lpfnWndProc = (WNDPROC)TRACKBAR_WindowProc;
2120 wndClass.cbClsExtra = 0;
2121 wndClass.cbWndExtra = sizeof(TRACKBAR_INFO *);
2122 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
2123 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
2124 wndClass.lpszClassName = TRACKBAR_CLASSA;
2125
2126 RegisterClassA (&wndClass);
2127}
2128
2129
2130VOID
2131TRACKBAR_Unregister (VOID)
2132{
2133 if (GlobalFindAtomA (TRACKBAR_CLASSA))
2134 UnregisterClassA (TRACKBAR_CLASSA, (HINSTANCE)NULL);
2135}
2136
Note: See TracBrowser for help on using the repository browser.