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

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

unicode and other changes

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