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

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

Updates for new DrawEdge and colors

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