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

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

trackbar finished

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