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

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

Unicode and other extensions

File size: 59.4 KB
Line 
1/* $Id: trackbar.c,v 1.11 1999-07-04 21:06:00 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 > newMax)
1163 { //exchange
1164 int x;
1165
1166 x = newMin;
1167 newMin = newMax;
1168 newMax = x;
1169 }
1170 if (newMin == infoPtr->nRangeMin && newMax == infoPtr->nRangeMax) return 0;
1171
1172 infoPtr->nRangeMin = newMin;
1173 infoPtr->nRangeMax = newMax;
1174
1175 if (infoPtr->nPos < infoPtr->nRangeMin)
1176 {
1177 infoPtr->nPos = infoPtr->nRangeMin;
1178 infoPtr->flags |= TB_THUMBPOSCHANGED;
1179 }
1180 if (infoPtr->nPos > infoPtr->nRangeMax)
1181 {
1182 infoPtr->nPos = infoPtr->nRangeMax;
1183 infoPtr->flags |= TB_THUMBPOSCHANGED;
1184 }
1185
1186 if (infoPtr->nSelMin < infoPtr->nRangeMin)
1187 {
1188 infoPtr->nSelMin = infoPtr->nRangeMin;
1189 infoPtr->flags |= TB_SELECTIONCHANGED;
1190 }
1191 if (infoPtr->nSelMin > infoPtr->nRangeMax)
1192 {
1193 infoPtr->nSelMin = infoPtr->nRangeMax;
1194 infoPtr->flags |= TB_SELECTIONCHANGED;
1195 }
1196 if (infoPtr->nSelMax < infoPtr->nRangeMin)
1197 {
1198 infoPtr->nSelMax = infoPtr->nRangeMin;
1199 infoPtr->flags |= TB_SELECTIONCHANGED;
1200 }
1201 if (infoPtr->nSelMax > infoPtr->nRangeMax)
1202 {
1203 infoPtr->nSelMax = infoPtr->nRangeMax;
1204 infoPtr->flags |= TB_SELECTIONCHANGED;
1205 }
1206
1207 infoPtr->nPageSize = (infoPtr->nRangeMax-infoPtr->nRangeMin)/5;
1208 if (infoPtr->nPageSize == 0) infoPtr->nPageSize = 1;
1209 TRACKBAR_RecalculateTics(hwnd,infoPtr,TRUE);
1210
1211 if (wParam) TRACKBAR_Refresh(hwnd);
1212
1213 return 0;
1214}
1215
1216
1217static LRESULT
1218TRACKBAR_SetRangeMax (HWND hwnd, WPARAM wParam, LPARAM lParam)
1219{
1220 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1221
1222 if ((INT)lParam <= infoPtr->nRangeMin) return 0;
1223 if (infoPtr->nRangeMax == (INT)lParam) return 0;
1224
1225 infoPtr->nRangeMax = (INT)lParam;
1226 if (infoPtr->nPos > infoPtr->nRangeMax)
1227 {
1228 infoPtr->nPos = infoPtr->nRangeMax;
1229 infoPtr->flags |=TB_THUMBPOSCHANGED;
1230 }
1231
1232 infoPtr->nPageSize = (infoPtr->nRangeMax-infoPtr->nRangeMin)/5;
1233 if (infoPtr->nPageSize == 0) infoPtr->nPageSize = 1;
1234 TRACKBAR_RecalculateTics(hwnd,infoPtr,TRUE);
1235
1236 if (wParam) TRACKBAR_Refresh(hwnd);
1237
1238 return 0;
1239}
1240
1241
1242static LRESULT
1243TRACKBAR_SetRangeMin (HWND hwnd, WPARAM wParam, LPARAM lParam)
1244{
1245 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1246
1247 if ((INT)lParam >= infoPtr->nRangeMax) return 0;
1248 if (infoPtr->nRangeMin == (INT)lParam) return 0;
1249
1250 infoPtr->nRangeMin = (INT)lParam;
1251 if (infoPtr->nPos < infoPtr->nRangeMin)
1252 {
1253 infoPtr->nPos = infoPtr->nRangeMin;
1254 infoPtr->flags |=TB_THUMBPOSCHANGED;
1255 }
1256
1257 infoPtr->nPageSize = (infoPtr->nRangeMax-infoPtr->nRangeMin)/5;
1258 if (infoPtr->nPageSize == 0) infoPtr->nPageSize = 1;
1259 TRACKBAR_RecalculateTics(hwnd,infoPtr,TRUE);
1260
1261 if (wParam) TRACKBAR_Refresh(hwnd);
1262
1263 return 0;
1264}
1265
1266
1267static LRESULT
1268TRACKBAR_SetTicFreq (HWND hwnd, WPARAM wParam)
1269{
1270 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1271
1272 if (infoPtr->uTicFreq == (UINT)wParam) return 0;
1273
1274 if (!(GetWindowLongA(hwnd,GWL_STYLE) & TBS_AUTOTICKS)) return 0;
1275
1276 infoPtr->uTicFreq = (UINT)wParam;
1277
1278 TRACKBAR_RecalculateTics(hwnd,infoPtr,FALSE);
1279
1280 TRACKBAR_Refresh(hwnd);
1281
1282 return 0;
1283}
1284
1285
1286static LRESULT
1287TRACKBAR_SetSel(HWND hwnd,WPARAM wParam,LPARAM lParam)
1288{
1289 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1290 INT newMin,newMax,oldMin,oldMax;
1291
1292 oldMin = infoPtr->nSelMin;
1293 oldMax = infoPtr->nSelMax;
1294 newMin = (INT)LOWORD(lParam);
1295 newMax = (INT)HIWORD(lParam);
1296
1297 if (infoPtr->nSelMin == newMin && infoPtr->nSelMax == newMax) return 0;
1298 infoPtr->nSelMin = newMin;
1299 infoPtr->nSelMax = newMax;
1300
1301 if (infoPtr->nSelMin < infoPtr->nRangeMin) infoPtr->nSelMin = infoPtr->nRangeMin;
1302 if (infoPtr->nSelMin > infoPtr->nRangeMax) infoPtr->nSelMin = infoPtr->nRangeMax;
1303 if (infoPtr->nSelMax > infoPtr->nRangeMax) infoPtr->nSelMax = infoPtr->nRangeMax;
1304 if (infoPtr->nSelMax < infoPtr->nRangeMin) infoPtr->nSelMax = infoPtr->nRangeMin;
1305
1306 if (infoPtr->nSelMin > infoPtr->nSelMax) infoPtr->nSelMin = infoPtr->nSelMax;
1307
1308 if (!GetWindowLongA(hwnd, GWL_STYLE) & TBS_ENABLESELRANGE) return 0;
1309
1310 if (oldMin != newMin || oldMax != newMax)
1311 {
1312 infoPtr->flags |= TB_SELECTIONCHANGED;
1313 if (wParam) TRACKBAR_Refresh(hwnd);
1314 }
1315
1316 return 0;
1317}
1318
1319
1320static LRESULT
1321TRACKBAR_SetSelEnd (HWND hwnd, WPARAM wParam, LPARAM lParam)
1322{
1323 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1324 INT oldMax;
1325
1326 if (infoPtr->nSelMax == (INT)lParam) return 0;
1327
1328 oldMax = infoPtr->nSelMax;
1329 infoPtr->nSelMax = (INT)lParam;
1330
1331 if (infoPtr->nSelMax > infoPtr->nRangeMax) infoPtr->nSelMax = infoPtr->nRangeMax;
1332 if (infoPtr->nSelMax < infoPtr->nRangeMin) infoPtr->nSelMax = infoPtr->nRangeMin;
1333
1334 if (infoPtr->nSelMin > infoPtr->nSelMax) infoPtr->nSelMin = infoPtr->nSelMax;
1335
1336 if (!GetWindowLongA(hwnd,GWL_STYLE) & TBS_ENABLESELRANGE) return 0;
1337
1338 if (oldMax != infoPtr->nSelMax)
1339 {
1340 infoPtr->flags |= TB_SELECTIONCHANGED;
1341 if (wParam) TRACKBAR_Refresh(hwnd);
1342 }
1343
1344 return 0;
1345}
1346
1347
1348static LRESULT
1349TRACKBAR_SetSelStart (HWND hwnd, WPARAM wParam, LPARAM lParam)
1350{
1351 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1352 INT oldMin;
1353
1354 if (infoPtr->nSelMin == (INT)lParam) return 0;
1355
1356 oldMin = infoPtr->nSelMin;
1357 infoPtr->nSelMin = (INT)lParam;
1358
1359 if (infoPtr->nSelMin < infoPtr->nRangeMin) infoPtr->nSelMin = infoPtr->nRangeMin;
1360 if (infoPtr->nSelMin > infoPtr->nRangeMax) infoPtr->nSelMin = infoPtr->nRangeMax;
1361
1362 if (infoPtr->nSelMin > infoPtr->nSelMax) infoPtr->nSelMin = infoPtr->nSelMax;
1363
1364 if (!GetWindowLongA(hwnd,GWL_STYLE) & TBS_ENABLESELRANGE) return 0;
1365
1366 if (oldMin != infoPtr->nSelMin)
1367 {
1368 infoPtr->flags |= TB_SELECTIONCHANGED;
1369 if (wParam) TRACKBAR_Refresh(hwnd);
1370 }
1371
1372 return 0;
1373}
1374
1375
1376static LRESULT
1377TRACKBAR_SetThumbLength (HWND hwnd, WPARAM wParam, LPARAM lParam)
1378{
1379 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1380
1381 if (infoPtr->uThumbLen == (UINT)wParam) return 0;
1382
1383 if (!(GetWindowLongA (hwnd, GWL_STYLE) & TBS_FIXEDLENGTH)) return 0;
1384
1385 infoPtr->uThumbLen = (UINT)wParam;
1386 infoPtr->flags |= TB_THUMBSIZECHANGED;
1387
1388 TRACKBAR_Refresh(hwnd);
1389
1390 return 0;
1391}
1392
1393static void TRACKBAR_QuickSort(LPLONG list,INT lo,INT hi)
1394{
1395 INT i,j,x,y;
1396
1397 i = lo;
1398 j = hi;
1399 x = list[(lo+hi)/2];
1400 do
1401 {
1402 while (list[i] < x) i++;
1403 while (x < list[j]) j--;
1404 if (i <= j)
1405 {
1406 y = list[i];
1407 list[i] = list[j];
1408 list[j] = y;
1409 i++;
1410 j--;
1411 }
1412 } while (i <= j);
1413 if (lo < j) TRACKBAR_QuickSort(list,lo,j);
1414 if (i < hi) TRACKBAR_QuickSort(list,i,hi);
1415}
1416
1417static LRESULT
1418TRACKBAR_SetTic (HWND hwnd, WPARAM wParam, LPARAM lParam)
1419{
1420 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1421 INT nPos = (INT)lParam;
1422 INT x;
1423
1424 if (!(GetWindowLongA(hwnd, GWL_STYLE) & (TBS_AUTOTICKS | TBS_NOTICKS))) return 0;
1425
1426 if ((nPos < infoPtr->nRangeMin) || (nPos > infoPtr->nRangeMax)) return FALSE;
1427
1428 //Check if tick exists
1429 for (x = 0;x < infoPtr->uNumTics;x++)
1430 {
1431 if (infoPtr->tics[x] == nPos) return TRUE; //value is ok
1432 }
1433
1434 infoPtr->uNumTics++;
1435 infoPtr->tics = COMCTL32_ReAlloc(infoPtr->tics,infoPtr->uNumTics*sizeof(DWORD));
1436 infoPtr->tics[infoPtr->uNumTics-1] = nPos;
1437
1438 //Quicksort the list
1439 TRACKBAR_QuickSort(infoPtr->tics,0,infoPtr->uNumTics-1);
1440
1441 TRACKBAR_Refresh(hwnd);
1442
1443 return TRUE;
1444}
1445
1446
1447static LRESULT
1448TRACKBAR_SetTipSide (HWND hwnd, WPARAM wParam, LPARAM lParam)
1449{
1450 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1451 INT fTemp = infoPtr->fLocation;
1452
1453 infoPtr->fLocation = (INT)wParam;
1454
1455 return fTemp;
1456}
1457
1458
1459static LRESULT
1460TRACKBAR_SetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
1461{
1462 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1463
1464 infoPtr->hwndToolTip = (HWND)wParam;
1465
1466 return 0;
1467}
1468
1469
1470/* case TBM_SETUNICODEFORMAT: */
1471
1472
1473static LRESULT
1474TRACKBAR_InitializeThumb (HWND hwnd)
1475{
1476 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1477 RECT clientRect;
1478 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
1479 INT scaleSize;
1480
1481 GetClientRect(hwnd,&clientRect);
1482 infoPtr->uThumbLen = THUMB_LEN; /* initial thumb length */
1483
1484 scaleSize = 2*BORDER_SIZE;
1485 if (dwStyle & TBS_NOTICKS) scaleSize += 0;
1486 else if (dwStyle & TBS_BOTH) scaleSize += 2*(SCALE_SIZE+SCALE_SPACE);
1487 else scaleSize += SCALE_SIZE+SCALE_SPACE;
1488
1489 if (dwStyle & TBS_VERT)
1490 {
1491 INT width = clientRect.right-clientRect.left;
1492
1493 if (infoPtr->uThumbLen+scaleSize > width) infoPtr->uThumbLen = MAX(width-scaleSize,THUMB_MINLEN);
1494 } else
1495 {
1496 INT height = clientRect.bottom-clientRect.top;
1497
1498 if (infoPtr->uThumbLen+scaleSize > height) infoPtr->uThumbLen = MAX(height-scaleSize,THUMB_MINLEN);
1499 }
1500
1501 TRACKBAR_CalcChannel(hwnd,infoPtr);
1502 TRACKBAR_CalcThumb(hwnd,infoPtr);
1503
1504 infoPtr->flags &= ~TB_SELECTIONCHANGED;
1505
1506 return 0;
1507}
1508
1509
1510static LRESULT
1511TRACKBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
1512{
1513 TRACKBAR_INFO *infoPtr;
1514
1515 infoPtr = (TRACKBAR_INFO *)COMCTL32_Alloc (sizeof(TRACKBAR_INFO));
1516 SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
1517
1518 /* set default values */
1519 infoPtr->nRangeMin = 0;
1520 infoPtr->nRangeMax = 100;
1521 infoPtr->nLineSize = 1;
1522 infoPtr->nPageSize = 20;
1523 infoPtr->nSelMin = 0;
1524 infoPtr->nSelMax = 0;
1525 infoPtr->nPos = 0;
1526
1527 infoPtr->uNumTics = 0; /* start and end tic are not included in count*/
1528 infoPtr->uTicFreq = 1;
1529 infoPtr->tics = NULL;
1530 infoPtr->clrBk = GetSysColor(COLOR_3DFACE);
1531 infoPtr->hwndNotify = GetParent(hwnd);
1532
1533 TRACKBAR_InitializeThumb (hwnd);
1534
1535 /* Create tooltip control */
1536 if (GetWindowLongA(hwnd,GWL_STYLE) & TBS_TOOLTIPS)
1537 {
1538 TTTOOLINFOA ti;
1539
1540 infoPtr->hwndToolTip =
1541 CreateWindowExA (WS_EX_TOOLWINDOW,TOOLTIPS_CLASSA,NULL,WS_POPUP,
1542 CW_USEDEFAULT,CW_USEDEFAULT,
1543 CW_USEDEFAULT,CW_USEDEFAULT,
1544 hwnd,0,0,0);
1545
1546 /* Send NM_TOOLTIPSCREATED notification */
1547 if (infoPtr->hwndToolTip)
1548 {
1549 NMTOOLTIPSCREATED nmttc;
1550
1551 nmttc.hdr.hwndFrom = hwnd;
1552 nmttc.hdr.idFrom = GetWindowLongA(hwnd,GWL_ID);
1553 nmttc.hdr.code = NM_TOOLTIPSCREATED;
1554 nmttc.hwndToolTips = infoPtr->hwndToolTip;
1555
1556 SendMessageA(GetParent(hwnd),WM_NOTIFY,(WPARAM)nmttc.hdr.idFrom,(LPARAM)&nmttc);
1557 }
1558
1559 ZeroMemory(&ti,sizeof(TTTOOLINFOA));
1560 ti.cbSize = sizeof(TTTOOLINFOA);
1561 ti.uFlags = TTF_TRACK | TTF_CENTERTIP;
1562 ti.hwnd = hwnd;
1563 ti.uId = 0;
1564 ti.lpszText = "Test"; /* LPSTR_TEXTCALLBACK */
1565 SetRectEmpty(&ti.rect);
1566
1567 SendMessageA(infoPtr->hwndToolTip,TTM_ADDTOOLA,0,(LPARAM)&ti);
1568 }
1569
1570 return 0;
1571}
1572
1573
1574static LRESULT
1575TRACKBAR_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
1576{
1577 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1578
1579 /* delete tooltip control */
1580 if (infoPtr->hwndToolTip) DestroyWindow(infoPtr->hwndToolTip);
1581
1582 COMCTL32_Free(infoPtr->tics);
1583 COMCTL32_Free(infoPtr);
1584
1585 return 0;
1586}
1587
1588/* pt intialized with cursor position */
1589
1590static VOID TRACKBAR_CalcToolTipPos(HWND hwnd,DWORD dwStyle,TRACKBAR_INFO *infoPtr,POINT *pt)
1591{
1592 if (dwStyle & TBS_VERT)
1593 {
1594 pt->x += 5;
1595 pt->y += 15;
1596 } else
1597 {
1598 pt->x += 15;
1599 pt->y += 5;
1600 }
1601}
1602
1603static LRESULT
1604TRACKBAR_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
1605{
1606 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1607 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1608 int clickPlace,prevPos,vertical;
1609 DOUBLE clickPos;
1610 RECT thumb;
1611 POINT clickPoint;
1612
1613 SetFocus (hwnd);
1614
1615 vertical = dwStyle & TBS_VERT;
1616 clickPoint.x = (INT)LOWORD(lParam);
1617 clickPoint.y = (INT)HIWORD(lParam);
1618
1619
1620 if (vertical) clickPlace = clickPoint.y;
1621 else clickPlace = clickPoint.x;
1622
1623 //Button down on thumb?
1624 thumb = infoPtr->rcFullThumb; //approzimative
1625 if ((vertical &&
1626 (clickPoint.y >= thumb.top) &&
1627 (clickPoint.y <= thumb.bottom) &&
1628 (clickPoint.x >= thumb.left) &&
1629 (clickPoint.x <= thumb.right)) ||
1630 (!vertical &&
1631 (clickPoint.x >= thumb.left) &&
1632 (clickPoint.x <= thumb.right) &&
1633 (clickPoint.y >= thumb.top) &&
1634 (clickPoint.y <= thumb.bottom)))
1635 {
1636 infoPtr->flags |= TB_DRAG_MODE;
1637 if (dwStyle & TBS_TOOLTIPS)
1638 { /* enable tooltip */
1639 TTTOOLINFOA ti;
1640 POINT pt;
1641 char buf[80];
1642
1643 GetCursorPos(&pt);
1644 TRACKBAR_CalcToolTipPos(hwnd,dwStyle,infoPtr,&pt);
1645 SendMessageA(infoPtr->hwndToolTip,TTM_TRACKPOSITION,0,(LPARAM)MAKELPARAM(pt.x,pt.y));
1646
1647 ti.cbSize = sizeof(TTTOOLINFOA);
1648 ti.uId = 0;
1649 ti.hwnd = (UINT)hwnd;
1650 ti.hinst = 0;
1651 sprintf (buf,"%d",infoPtr->nPos);
1652 ti.lpszText = (LPSTR)buf;
1653
1654 infoPtr->flags |= TB_SHOW_TOOLTIP;
1655 SetCapture(hwnd);
1656
1657 SendMessageA(infoPtr->hwndToolTip,TTM_UPDATETIPTEXTA,0,(LPARAM)&ti);
1658 SendMessageA(infoPtr->hwndToolTip,TTM_TRACKACTIVATE,(WPARAM)TRUE,(LPARAM)&ti);
1659 }
1660 SetCapture(hwnd);
1661 TRACKBAR_UpdateThumb(hwnd); //change arrow color
1662 return 0;
1663 }
1664 else if ((vertical &&
1665 (clickPoint.y >= thumb.top) &&
1666 (clickPoint.y <= thumb.bottom)) ||
1667 (!vertical &&
1668 (clickPoint.x >= thumb.left) &&
1669 (clickPoint.x <= thumb.right)))
1670 {
1671 //ScrollMode
1672 infoPtr->flags |= TB_SCROLL_MODE;
1673 SetCapture(hwnd);
1674 SetTimer(hwnd,SCROLL_TIMER_ID,SCROLL_TIME,NULL);
1675
1676 return 0;
1677 }
1678
1679 clickPos = TRACKBAR_ConvertPlaceToPosition(infoPtr,clickPlace,vertical);
1680 prevPos = infoPtr->nPos;
1681
1682 if (clickPos > prevPos)
1683 { /* similar to VK_NEXT */
1684 infoPtr->nPos += infoPtr->nPageSize;
1685 if (infoPtr->nPos > infoPtr->nRangeMax) infoPtr->nPos = infoPtr->nRangeMax;
1686 if (prevPos != infoPtr->nPos) TRACKBAR_SendNotify(hwnd,TB_PAGEUP);
1687 } else
1688 { /* similar to VK_PRIOR */
1689 infoPtr->nPos -= infoPtr->nPageSize;
1690 if (infoPtr->nPos < infoPtr->nRangeMin) infoPtr->nPos = infoPtr->nRangeMin;
1691 if (prevPos != infoPtr->nPos) TRACKBAR_SendNotify(hwnd,TB_PAGEDOWN);
1692 }
1693
1694 if (prevPos != infoPtr->nPos)
1695 {
1696 infoPtr->flags |= TB_THUMBPOSCHANGED;
1697 TRACKBAR_UpdateThumbPosition(hwnd,prevPos);
1698 }
1699
1700 //ScrollMode
1701 infoPtr->flags |= TB_SCROLL_MODE;
1702 SetCapture(hwnd);
1703 SetTimer(hwnd,SCROLL_TIMER_ID,SCROLL_TIME,NULL);
1704
1705 return 0;
1706}
1707
1708
1709static LRESULT
1710TRACKBAR_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
1711{
1712 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1713
1714 if (infoPtr->flags & TB_DRAG_MODE)
1715 {
1716 TRACKBAR_SendNotify(hwnd,TB_ENDTRACK);
1717
1718 infoPtr->flags &= ~TB_DRAG_MODE;
1719 ReleaseCapture();
1720 TRACKBAR_UpdateThumb(hwnd); //change arrow color
1721 }
1722
1723 if (infoPtr->flags & TB_SCROLL_MODE)
1724 {
1725 infoPtr->flags &= ~TB_SCROLL_MODE;
1726 ReleaseCapture();
1727 KillTimer(hwnd,SCROLL_TIMER_ID);
1728 }
1729
1730 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_TOOLTIPS)
1731 { /* disable tooltip */
1732 TTTOOLINFOA ti;
1733
1734 ti.cbSize = sizeof(TTTOOLINFOA);
1735 ti.uId = 0;
1736 ti.hwnd = (UINT)hwnd;
1737
1738 infoPtr->flags &= ~TB_SHOW_TOOLTIP;
1739 SendMessageA (infoPtr->hwndToolTip,TTM_TRACKACTIVATE,(WPARAM)FALSE,(LPARAM)&ti);
1740 }
1741
1742 return 0;
1743}
1744
1745
1746static LRESULT TRACKBAR_Timer(HWND hwnd,WPARAM wParam,LPARAM lParam)
1747{
1748 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(hwnd);
1749 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
1750 POINT mousePoint;
1751 INT mousePlace,prevPos,newPos,vertical;
1752 DOUBLE mousePos;
1753
1754 GetCursorPos(&mousePoint);
1755 ScreenToClient(hwnd,&mousePoint);
1756
1757 vertical = dwStyle & TBS_VERT;
1758 if (vertical) mousePlace = mousePoint.y;
1759 else mousePlace = mousePoint.x;
1760
1761 mousePos = TRACKBAR_ConvertPlaceToPosition(infoPtr,mousePlace,vertical);
1762 prevPos = infoPtr->nPos;
1763
1764 if (mousePos > (INT)mousePos+0.5) newPos = mousePos+1;
1765 else newPos = mousePos;
1766 if (newPos == prevPos) return 0;
1767
1768 if (newPos > prevPos)
1769 { /* similar to VK_NEXT */
1770 infoPtr->nPos += infoPtr->nPageSize;
1771 if (infoPtr->nPos > infoPtr->nRangeMax) infoPtr->nPos = infoPtr->nRangeMax;
1772 if (prevPos != infoPtr->nPos) TRACKBAR_SendNotify(hwnd,TB_PAGEUP);
1773 } else
1774 { /* similar to VK_PRIOR */
1775 infoPtr->nPos -= infoPtr->nPageSize;
1776 if (infoPtr->nPos < infoPtr->nRangeMin) infoPtr->nPos = infoPtr->nRangeMin;
1777 if (prevPos != infoPtr->nPos) TRACKBAR_SendNotify(hwnd,TB_PAGEDOWN);
1778 }
1779
1780 if (prevPos != infoPtr->nPos)
1781 {
1782 infoPtr->flags |= TB_THUMBPOSCHANGED;
1783 TRACKBAR_UpdateThumbPosition(hwnd,prevPos);
1784 }
1785
1786 return 0;
1787}
1788
1789static LRESULT
1790TRACKBAR_CaptureChanged (HWND hwnd, WPARAM wParam, LPARAM lParam)
1791{
1792 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1793
1794 if (infoPtr->flags & TB_DRAGPOSVALID)
1795 {
1796 int lastPos = infoPtr->nPos;
1797 infoPtr->nPos = infoPtr->dragPos;
1798 if (lastPos != infoPtr->nPos) TRACKBAR_UpdateThumbPosition(hwnd,lastPos);
1799 }
1800
1801 infoPtr->flags &= ~ TB_DRAGPOSVALID;
1802
1803 if (infoPtr->flags & TB_SCROLL_MODE)
1804 {
1805 infoPtr->flags &= ~TB_SCROLL_MODE;
1806 KillTimer(hwnd,SCROLL_TIMER_ID);
1807 }
1808
1809 TRACKBAR_SendNotify(hwnd,TB_ENDTRACK);
1810 return 0;
1811}
1812
1813
1814static LRESULT
1815TRACKBAR_Paint (HWND hwnd, WPARAM wParam)
1816{
1817 HDC hdc;
1818 PAINTSTRUCT ps;
1819
1820 hdc = wParam == 0 ? BeginPaint(hwnd,&ps) : (HDC)wParam;
1821 TRACKBAR_Draw(hwnd,hdc);
1822 if (!wParam) EndPaint(hwnd,&ps);
1823 return 0;
1824}
1825
1826
1827static LRESULT
1828TRACKBAR_SetFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
1829{
1830 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1831 HDC hdc;
1832 RECT rcClient;
1833
1834// TRACE (trackbar,"\n");
1835 if (!infoPtr->bFocus)
1836 {
1837 infoPtr->bFocus = TRUE;
1838
1839 GetClientRect (hwnd,&rcClient);
1840 hdc = GetDC (hwnd);
1841 DrawFocusRect (hdc,&rcClient);
1842 ReleaseDC(hwnd,hdc);
1843
1844 }
1845 return 0;
1846}
1847
1848static LRESULT
1849TRACKBAR_KillFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
1850{
1851 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1852 HDC hdc;
1853 RECT rcClient;
1854
1855// TRACE (trackbar,"\n");
1856
1857 infoPtr->flags &= ~TB_DRAG_MODE;
1858 if (infoPtr->bFocus)
1859 {
1860 infoPtr->bFocus = FALSE;
1861
1862 GetClientRect(hwnd,&rcClient);
1863 hdc = GetDC (hwnd);
1864 DrawFocusRect(hdc,&rcClient); //XOR removes
1865 ReleaseDC(hwnd,hdc);
1866 }
1867
1868 return 0;
1869}
1870
1871static LRESULT
1872TRACKBAR_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
1873{
1874 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1875
1876 TRACKBAR_CalcChannel (hwnd, infoPtr);
1877 TRACKBAR_AlignBuddies (hwnd, infoPtr);
1878
1879 return 0;
1880}
1881
1882
1883static BOOL
1884TRACKBAR_SendNotify (HWND hwnd, UINT code)
1885{
1886// TRACE (trackbar, "%x\n",code);
1887
1888 if (GetWindowLongA(hwnd, GWL_STYLE) & TBS_VERT)
1889 {
1890 return (BOOL)SendMessageA(GetParent(hwnd),WM_VSCROLL,(WPARAM)code,(LPARAM)hwnd);
1891 } else
1892 {
1893 return (BOOL)SendMessageA(GetParent(hwnd),WM_HSCROLL,(WPARAM)code,(LPARAM)hwnd);
1894 }
1895}
1896
1897
1898static LRESULT
1899TRACKBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
1900{
1901 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1902 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
1903 SHORT clickPlace;
1904 DOUBLE dragPos;
1905
1906// TRACE (trackbar, "%x\n",wParam);
1907
1908 if (!(infoPtr->flags & TB_DRAG_MODE)) return TRUE;
1909
1910 if (dwStyle & TBS_VERT) clickPlace = (SHORT)HIWORD(lParam);
1911 else clickPlace = (SHORT)LOWORD(lParam);
1912
1913 dragPos = TRACKBAR_ConvertPlaceToPosition(infoPtr,clickPlace,dwStyle & TBS_VERT);
1914 if (dragPos > ((INT)dragPos)+0.5) infoPtr->dragPos = dragPos + 1;
1915 else infoPtr->dragPos = dragPos;
1916
1917 if (infoPtr->nPos == infoPtr->dragPos) return TRUE; //nothing changed
1918
1919 infoPtr->flags |= TB_DRAGPOSVALID;
1920
1921 TRACKBAR_UpdateThumbPosition(hwnd,infoPtr->nPos); //infoPtr->nPos now set
1922
1923 TRACKBAR_SendNotify(hwnd,TB_THUMBTRACK | (infoPtr->nPos >> 16));
1924
1925 if (infoPtr->flags & TB_SHOW_TOOLTIP)
1926 {
1927 POINT pt;
1928 TTTOOLINFOA ti;
1929 char buf[80];
1930
1931 ti.cbSize = sizeof(TTTOOLINFOA);
1932 ti.hwnd = hwnd;
1933 ti.uId = 0;
1934 ti.hinst = 0;
1935 sprintf (buf,"%d",infoPtr->nPos);
1936 ti.lpszText = (LPSTR)buf;
1937 GetCursorPos(&pt);
1938 TRACKBAR_CalcToolTipPos(hwnd,dwStyle,infoPtr,&pt);
1939
1940 SendMessageA(infoPtr->hwndToolTip,TTM_UPDATETIPTEXTA,0,(LPARAM)&ti);
1941 SendMessageA(infoPtr->hwndToolTip,TTM_TRACKPOSITION,0,(LPARAM)MAKELPARAM(pt.x,pt.y));
1942 }
1943
1944 return TRUE;
1945}
1946
1947
1948static LRESULT
1949TRACKBAR_KeyDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
1950{
1951 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(hwnd);
1952 INT pos;
1953
1954// TRACE (trackbar, "%x\n",wParam);
1955
1956 if (infoPtr->flags & TB_DRAG_MODE) return TRUE;
1957
1958 pos = infoPtr->nPos;
1959 switch (wParam) {
1960 case VK_LEFT:
1961 case VK_UP:
1962 if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
1963 infoPtr->nPos -= infoPtr->nLineSize;
1964 if (infoPtr->nPos < infoPtr->nRangeMin)
1965 infoPtr->nPos = infoPtr->nRangeMin;
1966 TRACKBAR_SendNotify(hwnd,TB_LINEUP);
1967 break;
1968 case VK_RIGHT:
1969 case VK_DOWN:
1970 if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
1971 infoPtr->nPos += infoPtr->nLineSize;
1972 if (infoPtr->nPos > infoPtr->nRangeMax)
1973 infoPtr->nPos = infoPtr->nRangeMax;
1974 TRACKBAR_SendNotify (hwnd, TB_LINEDOWN);
1975 break;
1976 case VK_NEXT:
1977 if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
1978 infoPtr->nPos += infoPtr->nPageSize;
1979 if (infoPtr->nPos > infoPtr->nRangeMax)
1980 infoPtr->nPos = infoPtr->nRangeMax;
1981 TRACKBAR_SendNotify (hwnd, TB_PAGEUP);
1982 break;
1983 case VK_PRIOR:
1984 if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
1985 infoPtr->nPos -= infoPtr->nPageSize;
1986 if (infoPtr->nPos < infoPtr->nRangeMin)
1987 infoPtr->nPos = infoPtr->nRangeMin;
1988 TRACKBAR_SendNotify (hwnd, TB_PAGEDOWN);
1989 break;
1990 case VK_HOME:
1991 if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
1992 infoPtr->nPos = infoPtr->nRangeMin;
1993 TRACKBAR_SendNotify (hwnd, TB_TOP);
1994 break;
1995 case VK_END:
1996 if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
1997 infoPtr->nPos = infoPtr->nRangeMax;
1998 TRACKBAR_SendNotify (hwnd, TB_BOTTOM);
1999 break;
2000 }
2001
2002 if (pos != infoPtr->nPos)
2003 {
2004 infoPtr->flags |= TB_THUMBPOSCHANGED;
2005 TRACKBAR_UpdateThumbPosition(hwnd,pos);
2006 }
2007
2008 return TRUE;
2009}
2010
2011
2012static LRESULT
2013TRACKBAR_KeyUp (HWND hwnd, WPARAM wParam)
2014{
2015 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(hwnd);
2016
2017 if (infoPtr->flags & TB_DRAG_MODE) return TRUE;
2018
2019 switch (wParam) {
2020 case VK_LEFT:
2021 case VK_UP:
2022 case VK_RIGHT:
2023 case VK_DOWN:
2024 case VK_NEXT:
2025 case VK_PRIOR:
2026 case VK_HOME:
2027 case VK_END:
2028 TRACKBAR_SendNotify (hwnd, TB_ENDTRACK);
2029 }
2030 return TRUE;
2031}
2032
2033
2034LRESULT WINAPI
2035TRACKBAR_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
2036{
2037 switch (uMsg)
2038 {
2039 case TBM_CLEARSEL:
2040 return TRACKBAR_ClearSel (hwnd, wParam, lParam);
2041
2042 case TBM_CLEARTICS:
2043 return TRACKBAR_ClearTics (hwnd, wParam, lParam);
2044
2045 case TBM_GETBUDDY:
2046 return TRACKBAR_GetBuddy (hwnd, wParam, lParam);
2047
2048 case TBM_GETCHANNELRECT:
2049 return TRACKBAR_GetChannelRect (hwnd, wParam, lParam);
2050
2051 case TBM_GETLINESIZE:
2052 return TRACKBAR_GetLineSize (hwnd, wParam, lParam);
2053
2054 case TBM_GETNUMTICS:
2055 return TRACKBAR_GetNumTics (hwnd, wParam, lParam);
2056
2057 case TBM_GETPAGESIZE:
2058 return TRACKBAR_GetPageSize (hwnd, wParam, lParam);
2059
2060 case TBM_GETPOS:
2061 return TRACKBAR_GetPos (hwnd, wParam, lParam);
2062
2063 case TBM_GETPTICS:
2064 return TRACKBAR_GetPTics (hwnd);
2065
2066 case TBM_GETRANGEMAX:
2067 return TRACKBAR_GetRangeMax (hwnd, wParam, lParam);
2068
2069 case TBM_GETRANGEMIN:
2070 return TRACKBAR_GetRangeMin (hwnd, wParam, lParam);
2071
2072 case TBM_GETSELEND:
2073 return TRACKBAR_GetSelEnd (hwnd, wParam, lParam);
2074
2075 case TBM_GETSELSTART:
2076 return TRACKBAR_GetSelStart (hwnd, wParam, lParam);
2077
2078 case TBM_GETTHUMBLENGTH:
2079 return TRACKBAR_GetThumbLength (hwnd, wParam, lParam);
2080
2081 case TBM_GETTHUMBRECT:
2082 return TRACKBAR_GetThumbRect (hwnd, wParam, lParam);
2083
2084 case TBM_GETTIC:
2085 return TRACKBAR_GetTic (hwnd, wParam, lParam);
2086
2087 case TBM_GETTICPOS:
2088 return TRACKBAR_GetTicPos (hwnd, wParam, lParam);
2089
2090 case TBM_GETTOOLTIPS:
2091 return TRACKBAR_GetToolTips (hwnd, wParam, lParam);
2092
2093/* case TBM_GETUNICODEFORMAT: */
2094
2095 case TBM_SETBUDDY:
2096 return TRACKBAR_SetBuddy (hwnd, wParam, lParam);
2097
2098 case TBM_SETLINESIZE:
2099 return TRACKBAR_SetLineSize (hwnd, wParam, lParam);
2100
2101 case TBM_SETPAGESIZE:
2102 return TRACKBAR_SetPageSize (hwnd, wParam, lParam);
2103
2104 case TBM_SETPOS:
2105 return TRACKBAR_SetPos (hwnd, wParam, lParam);
2106
2107 case TBM_SETRANGE:
2108 return TRACKBAR_SetRange (hwnd, wParam, lParam);
2109
2110 case TBM_SETRANGEMAX:
2111 return TRACKBAR_SetRangeMax (hwnd, wParam, lParam);
2112
2113 case TBM_SETRANGEMIN:
2114 return TRACKBAR_SetRangeMin (hwnd, wParam, lParam);
2115
2116 case TBM_SETSEL:
2117 return TRACKBAR_SetSel (hwnd, wParam, lParam);
2118
2119 case TBM_SETSELEND:
2120 return TRACKBAR_SetSelEnd (hwnd, wParam, lParam);
2121
2122 case TBM_SETSELSTART:
2123 return TRACKBAR_SetSelStart (hwnd, wParam, lParam);
2124
2125 case TBM_SETTHUMBLENGTH:
2126 return TRACKBAR_SetThumbLength (hwnd, wParam, lParam);
2127
2128 case TBM_SETTIC:
2129 return TRACKBAR_SetTic (hwnd, wParam, lParam);
2130
2131 case TBM_SETTICFREQ:
2132 return TRACKBAR_SetTicFreq (hwnd, wParam);
2133
2134 case TBM_SETTIPSIDE:
2135 return TRACKBAR_SetTipSide (hwnd, wParam, lParam);
2136
2137 case TBM_SETTOOLTIPS:
2138 return TRACKBAR_SetToolTips (hwnd, wParam, lParam);
2139
2140/* case TBM_SETUNICODEFORMAT: */
2141
2142
2143 case WM_CAPTURECHANGED:
2144 return TRACKBAR_CaptureChanged (hwnd, wParam, lParam);
2145
2146 case WM_CREATE:
2147 return TRACKBAR_Create (hwnd, wParam, lParam);
2148
2149 case WM_DESTROY:
2150 return TRACKBAR_Destroy (hwnd, wParam, lParam);
2151
2152/* case WM_ENABLE: */
2153
2154/* case WM_ERASEBKGND: */
2155/* return 0; */
2156
2157 case WM_GETDLGCODE:
2158 return DLGC_WANTARROWS;
2159
2160 case WM_KEYDOWN:
2161 return TRACKBAR_KeyDown (hwnd, wParam, lParam);
2162
2163 case WM_KEYUP:
2164 return TRACKBAR_KeyUp (hwnd, wParam);
2165
2166 case WM_LBUTTONDOWN:
2167 return TRACKBAR_LButtonDown (hwnd, wParam, lParam);
2168
2169 case WM_LBUTTONUP:
2170 return TRACKBAR_LButtonUp (hwnd, wParam, lParam);
2171
2172 case WM_TIMER:
2173 return TRACKBAR_Timer(hwnd,wParam,lParam);
2174
2175 case WM_MOUSEMOVE:
2176 return TRACKBAR_MouseMove (hwnd, wParam, lParam);
2177
2178 case WM_PAINT:
2179 return TRACKBAR_Paint (hwnd, wParam);
2180
2181 case WM_SETFOCUS:
2182 return TRACKBAR_SetFocus (hwnd, wParam, lParam);
2183
2184 case WM_KILLFOCUS:
2185 return TRACKBAR_KillFocus (hwnd, wParam, lParam);
2186
2187 case WM_SIZE:
2188 return TRACKBAR_Size (hwnd, wParam, lParam);
2189
2190 case WM_WININICHANGE:
2191 return TRACKBAR_InitializeThumb (hwnd);
2192
2193 default:
2194// if (uMsg >= WM_USER)
2195// ERR (trackbar, "unknown msg %04x wp=%08x lp=%08lx\n",
2196// uMsg, wParam, lParam);
2197 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
2198 }
2199 return 0;
2200}
2201
2202
2203VOID
2204TRACKBAR_Register (VOID)
2205{
2206 WNDCLASSA wndClass;
2207
2208 if (GlobalFindAtomA (TRACKBAR_CLASSA)) return;
2209
2210 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
2211 wndClass.style = CS_GLOBALCLASS;
2212 wndClass.lpfnWndProc = (WNDPROC)TRACKBAR_WindowProc;
2213 wndClass.cbClsExtra = 0;
2214 wndClass.cbWndExtra = sizeof(TRACKBAR_INFO *);
2215 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
2216 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
2217 wndClass.lpszClassName = TRACKBAR_CLASSA;
2218
2219 RegisterClassA (&wndClass);
2220}
2221
2222
2223VOID
2224TRACKBAR_Unregister (VOID)
2225{
2226 if (GlobalFindAtomA (TRACKBAR_CLASSA))
2227 UnregisterClassA (TRACKBAR_CLASSA, (HINSTANCE)NULL);
2228}
2229
Note: See TracBrowser for help on using the repository browser.