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

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

cursor handling fixed

File size: 69.7 KB
Line 
1/* $Id: trackbar.c,v 1.23 1999-11-17 17:06:23 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 * Status: complete
12 * Version: 5.00
13 *
14 * Note: TBM_SETTHUMBLENGTH implemented, COMCTL32 5.00 ignores it
15 * Microsoft(TM) should fix this bug :)
16 */
17
18#include "winbase.h"
19#include "commctrl.h"
20#include "trackbar.h"
21#include <stdio.h>
22
23
24#define TRACKBAR_GetInfoPtr(hwnd) ((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
76static void 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 TRACKBAR_FillHorzTics(TRACKBAR_INFO *infoPtr,HDC hdc,int flags,COLORREF clrTic)
363{
364 RECT rect;
365 INT range = infoPtr->nRangeMax-infoPtr->nRangeMin;
366 INT width = infoPtr->rcChannel.right-infoPtr->rcChannel.left;
367 HBRUSH hbr = CreateSolidBrush(clrTic);
368
369 if (flags & TBS_TOP)
370 {
371 rect.bottom = infoPtr->rcFullThumb.top-SCALE_SPACE-1+1;
372 rect.top = rect.bottom-3;
373 } else
374 {
375 rect.top = infoPtr->rcFullThumb.bottom+SCALE_SPACE+1;
376 rect.bottom = rect.top+3;
377 }
378 rect.left = infoPtr->rcChannel.left+(width*(infoPtr->tics[0]-infoPtr->nRangeMin))/range;
379 rect.right = infoPtr->rcChannel.left+(width*(infoPtr->tics[infoPtr->uNumTics-1]-infoPtr->nRangeMin))/range+1;
380
381 FillRect(hdc,&rect,hbr);
382 DeleteObject(hbr);
383}
384
385static VOID
386TRACKBAR_DrawVertTic (TRACKBAR_INFO *infoPtr, HDC hdc, LONG ticPos,
387 int flags, COLORREF clrTic)
388{
389 RECT rcChannel = infoPtr->rcChannel;
390 int x,y,width,range,side;
391
392 range = infoPtr->nRangeMax-infoPtr->nRangeMin;
393 width = rcChannel.bottom-rcChannel.top;
394
395 if (flags & TBS_LEFT)
396 {
397 x = infoPtr->rcFullThumb.left-SCALE_SPACE-1;
398 side = -1;
399 } else
400 {
401 x = infoPtr->rcFullThumb.right+SCALE_SPACE+1;
402 side = 1;
403 }
404
405
406 if (flags & TIC_SELECTIONMARK)
407 {
408 ticPos -= infoPtr->nRangeMin;
409 if (flags & TIC_SELECTIONMARKMIN) y = rcChannel.top+(width*ticPos)/range-1;
410 else y = rcChannel.top+(width*ticPos)/range+1;
411
412 //first line
413 SetPixel(hdc,x+1*side,y,clrTic);
414 SetPixel(hdc,x+2*side,y,clrTic);
415 //point
416 if (flags & TIC_SELECTIONMARKMIN) y--; else y++;
417 SetPixel(hdc,x+2*side,y,clrTic);
418
419 return;
420 }
421
422 if ((ticPos>infoPtr->nRangeMin) && (ticPos<infoPtr->nRangeMax))
423 {
424 ticPos -= infoPtr->nRangeMin;
425 y = rcChannel.top+(width*ticPos)/range;
426 SetPixel (hdc,x, y,clrTic); //base
427 SetPixel (hdc,x+1*side,y,clrTic);
428 SetPixel (hdc,x+2*side,y,clrTic);
429 }
430
431 if (flags & TIC_EDGE)
432 {
433 if (flags & TIC_LEFTEDGE) y = rcChannel.top;
434 else y = rcChannel.bottom;
435
436 SetPixel (hdc,x,y,clrTic); //base
437 SetPixel (hdc,x+1*side,y,clrTic);
438 SetPixel (hdc,x+2*side,y,clrTic);
439 SetPixel (hdc,x+3*side,y,clrTic);
440 }
441}
442
443static VOID TRACKBAR_FillVertTics(TRACKBAR_INFO *infoPtr,HDC hdc,int flags,COLORREF clrTic)
444{
445 RECT rect;
446 INT range = infoPtr->nRangeMax-infoPtr->nRangeMin;
447 INT width = infoPtr->rcChannel.bottom-infoPtr->rcChannel.top;
448 HBRUSH hbr = CreateSolidBrush(clrTic);
449
450 if (flags & TBS_TOP)
451 {
452 rect.right = infoPtr->rcFullThumb.left-SCALE_SPACE-1+1;
453 rect.left = rect.right-3;
454 } else
455 {
456 rect.left = infoPtr->rcFullThumb.right+SCALE_SPACE+1;
457 rect.right = rect.left+3;
458 }
459 rect.top = infoPtr->rcChannel.top+(width*(infoPtr->tics[0]-infoPtr->nRangeMin))/range;
460 rect.bottom = infoPtr->rcChannel.top+(width*(infoPtr->tics[infoPtr->uNumTics-1]-infoPtr->nRangeMin))/range+1;
461
462 FillRect(hdc,&rect,hbr);
463 DeleteObject(hbr);
464}
465
466static VOID
467TRACKBAR_DrawTics (TRACKBAR_INFO *infoPtr, HDC hdc, LONG ticPos,
468 int flags, COLORREF clrTic)
469{
470 if (flags & TBS_VERT)
471 {
472 if ((flags & TBS_LEFT) || (flags & TBS_BOTH))
473 TRACKBAR_DrawVertTic (infoPtr,hdc,ticPos,flags | TBS_LEFT ,clrTic);
474 //TBS_RIGHT == default
475 if (!(flags & TBS_LEFT) || (flags & TBS_BOTH))
476 TRACKBAR_DrawVertTic(infoPtr,hdc,ticPos,flags & ~TBS_LEFT,clrTic);
477 } else
478 {
479 if ((flags & TBS_TOP) || (flags & TBS_BOTH))
480 TRACKBAR_DrawHorizTic(infoPtr,hdc,ticPos,flags | TBS_TOP,clrTic);
481 //TBS_BOTTOM == default
482 if (!(flags & TBS_TOP) || (flags & TBS_BOTH))
483 TRACKBAR_DrawHorizTic(infoPtr,hdc,ticPos,flags & ~TBS_TOP,clrTic);
484 }
485}
486
487//draw thumb, call only from draw!
488
489static VOID TRACKBAR_DrawThumb(TRACKBAR_INFO *infoPtr,HWND hwnd,HDC hdc,DWORD dwStyle)
490{
491 if (!(dwStyle & TBS_NOTHUMB))
492 {
493 HBRUSH hbr,hbrOld;
494 RECT thumb = infoPtr->rcThumb;
495
496 if (infoPtr->flags & TB_DRAG_MODE || !IsWindowEnabled(hwnd)) hbr = CreateSolidBrush(GetSysColor(COLOR_3DHILIGHT));
497 else hbr = CreateSolidBrush(GetSysColor(COLOR_3DFACE));
498 hbrOld = SelectObject(hdc,hbr);
499
500 if (dwStyle & TBS_BOTH)
501 {
502 DrawEdge(hdc,&thumb,EDGE_RAISED,BF_RECT | BF_ADJUST);
503 FillRect(hdc,&thumb,hbr);
504 } else
505 {
506 POINT points[6];
507 RECT triangle; /* for correct shadows of thumb */
508
509 if (dwStyle & TBS_VERT)
510 { //Vertical
511
512 if (dwStyle & TBS_LEFT)
513 {
514 HPEN oldPen,pen;
515
516 //Outline
517
518 SetPolyFillMode(hdc,WINDING);
519 points[0].x = thumb.left;
520 points[0].y = thumb.top;
521 points[1].x = thumb.left-(thumb.bottom-thumb.top)/2;
522 points[1].y = thumb.top+(thumb.bottom-thumb.top)/2;
523 points[2].x = thumb.left;
524 points[2].y = thumb.bottom;
525 points[3].x = thumb.right;
526 points[3].y = thumb.bottom;
527 points[4].x = thumb.right;
528 points[4].y = thumb.top;
529 points[5].x = points[0].x;
530 points[5].y = points[0].y;
531 Polygon(hdc,points,6);
532
533 //Edge
534
535 thumb.bottom++;
536 thumb.right++;
537 DrawEdge(hdc,&thumb,EDGE_RAISED,BF_BOTTOM | BF_TOP | BF_RIGHT);
538
539 //Draw notch
540
541 triangle.right = points[0].x;
542 triangle.top = points[0].y;
543 triangle.left = points[1].x;
544 triangle.bottom = points[1].y;
545 DrawEdge(hdc,&triangle,EDGE_RAISED,BF_DIAGONAL | BF_DIAGONAL_ENDTOPRIGHT);
546
547 //draw this line direct, DrawEdge not useful
548 pen = GetSysColorPen(COLOR_3DDKSHADOW);
549 oldPen = SelectObject(hdc,pen);
550 MoveToEx(hdc,points[1].x,points[1].y,NULL);
551 LineTo(hdc,points[2].x-1,points[2].y-1);
552 pen = GetSysColorPen(COLOR_BTNSHADOW);
553 SelectObject(hdc,pen);
554 MoveToEx(hdc,points[1].x+1,points[1].y,NULL);
555 LineTo(hdc,points[2].x,points[2].y-1);
556 SelectObject(hdc,oldPen);
557
558 } else //Right
559 {
560 HPEN oldPen,pen;
561
562 //Outline
563
564 SetPolyFillMode(hdc,WINDING);
565 points[0].x = thumb.left;
566 points[0].y = thumb.top;
567 points[1].x = thumb.left;
568 points[1].y = thumb.bottom;
569 points[2].x = thumb.right;
570 points[2].y = thumb.bottom;
571 points[3].x = thumb.right+(thumb.bottom-thumb.top)/2;
572 points[3].y = thumb.bottom-(thumb.bottom-thumb.top)/2;
573 points[4].x = thumb.right;
574 points[4].y = thumb.top;
575 points[5].x = points[0].x;
576 points[5].y = points[0].y;
577 Polygon(hdc,points,6);
578
579 //Edge
580
581 thumb.bottom++;
582 DrawEdge(hdc,&thumb,EDGE_RAISED,BF_BOTTOM | BF_TOP | BF_LEFT);
583
584 //Draw notch
585
586 //draw this line direct, DrawEdge not useful
587 pen = GetSysColorPen(COLOR_3DLIGHT);
588 oldPen = SelectObject(hdc,pen);
589 MoveToEx(hdc,points[4].x,points[4].y,NULL);
590 LineTo(hdc,points[3].x,points[3].y);
591 pen = GetSysColorPen(COLOR_BTNHIGHLIGHT);
592 SelectObject(hdc,pen);
593 MoveToEx(hdc,points[4].x,points[4].y+1,NULL);
594 LineTo(hdc,points[3].x-1,points[3].y);
595 SelectObject(hdc,oldPen);
596
597 triangle.right = points[3].x;
598 triangle.top = points[3].y;
599 triangle.left = points[2].x;
600 triangle.bottom = points[2].y;
601 DrawEdge(hdc,&triangle,EDGE_RAISED,BF_DIAGONAL | BF_DIAGONAL_ENDBOTTOMLEFT);
602 }
603 } else
604 { //Horizontal
605
606 if (dwStyle & TBS_TOP)
607 {
608 //Outline
609
610 SetPolyFillMode(hdc,WINDING);
611 points[0].x = thumb.left;
612 points[0].y = thumb.top;
613 points[1].x = thumb.left+(thumb.right-thumb.left)/2;
614 points[1].y = thumb.top-(thumb.right-thumb.left)/2;
615 points[2].x = thumb.right;
616 points[2].y = thumb.top;
617 points[3].x = thumb.right;
618 points[3].y = thumb.bottom;
619 points[4].x = thumb.left;
620 points[4].y = thumb.bottom;
621 points[5].x = points[0].x;
622 points[5].y = points[0].y;
623 Polygon(hdc,points,6);
624
625 //Edge
626
627 thumb.right++;
628 thumb.bottom++;
629 DrawEdge(hdc,&thumb,EDGE_RAISED,BF_BOTTOM | BF_LEFT | BF_RIGHT);
630
631 //Draw notch
632
633 triangle.left = points[0].x;
634 triangle.bottom = points[0].y;
635 triangle.right = points[1].x;
636 triangle.top = points[1].y;
637 DrawEdge(hdc,&triangle,EDGE_RAISED,BF_DIAGONAL | BF_DIAGONAL_ENDTOPRIGHT);
638
639
640 triangle.left = points[1].x;
641 triangle.top = points[1].y;
642 triangle.right = points[2].x;
643 triangle.bottom = points[2].y;
644 DrawEdge(hdc,&triangle,EDGE_RAISED,BF_DIAGONAL | BF_DIAGONAL_ENDBOTTOMRIGHT);
645
646 } else //Bottom
647 {
648
649 //Outline
650
651 SetPolyFillMode(hdc,WINDING);
652 points[0].x = thumb.left;
653 points[0].y = thumb.top;
654 points[1].x = thumb.right;
655 points[1].y = thumb.top;
656 points[2].x = thumb.right;
657 points[2].y = thumb.bottom;
658 points[3].x = thumb.right-(thumb.right-thumb.left)/2;
659 points[3].y = thumb.bottom+(thumb.right-thumb.left)/2;
660 points[4].x = thumb.left;
661 points[4].y = thumb.bottom;
662 points[5].x = points[0].x;
663 points[5].y = points[0].y;
664 Polygon(hdc,points,6);
665
666 //Edge
667
668 thumb.right++;
669 thumb.bottom++;
670 DrawEdge(hdc,&thumb,EDGE_RAISED,BF_TOP | BF_LEFT | BF_RIGHT);
671
672 //Draw notch
673
674 triangle.right = points[2].x;
675 triangle.top = points[2].y;
676 triangle.left = points[3].x;
677 triangle.bottom = points[3].y;
678 DrawEdge(hdc,&triangle,EDGE_RAISED,BF_DIAGONAL | BF_DIAGONAL_ENDBOTTOMLEFT);
679 triangle.right = points[3].x;
680 triangle.bottom = points[3].y;
681 triangle.left = points[4].x;
682 triangle.top = points[4].y;
683 DrawEdge(hdc,&triangle,EDGE_RAISED,BF_DIAGONAL | BF_DIAGONAL_ENDTOPLEFT);
684
685 }
686 }
687 }
688 SelectObject(hdc,hbrOld);
689 DeleteObject(hbr);
690 }
691}
692
693//draw the trackbar
694
695static VOID TRACKBAR_Draw(HWND hwnd,HDC hdc)
696{
697 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
698 DWORD dwStyle = GetWindowLongA(hwnd, GWL_STYLE);
699 RECT rcClient,rcChannel,rcSelection;
700 HBRUSH hBrush;
701 int i;
702 NMCUSTOMDRAW cdraw;
703 LRESULT cdctlres,cdres;
704
705 GetClientRect(hwnd,&rcClient);
706
707 //Custom draw
708 cdraw.hdr.hwndFrom = hwnd;
709 cdraw.hdr.idFrom = GetWindowLongA(hwnd,GWL_ID);
710 cdraw.hdr.code = NM_CUSTOMDRAW;
711 cdraw.dwDrawStage = CDDS_PREPAINT;
712 cdraw.hdc = hdc;
713 cdraw.dwItemSpec = 0;
714 cdraw.uItemState = CDIS_DEFAULT;
715 cdraw.rc = rcClient;
716 cdraw.lItemlParam = 0;
717
718 cdctlres = SendMessageA(GetParent(hwnd),WM_NOTIFY,(WPARAM)cdraw.hdr.idFrom,(LPARAM)&cdraw);
719
720 if (cdctlres & CDRF_SKIPDEFAULT) return;
721
722 //Background
723 hBrush = CreateSolidBrush(infoPtr->clrBk);
724 FillRect(hdc,&rcClient,hBrush);
725 DeleteObject(hBrush);
726
727 if (infoPtr->flags & TB_DRAGPOSVALID)
728 {
729 infoPtr->nPos = infoPtr->dragPos;
730 infoPtr->flags |= TB_THUMBPOSCHANGED;
731 }
732
733 if (infoPtr->flags & TB_THUMBCHANGED)
734 {
735 if (infoPtr->flags & TB_THUMBSIZECHANGED)
736 {
737 TRACKBAR_CalcChannel(hwnd,infoPtr);
738 TRACKBAR_CalcSelection(hwnd,infoPtr);
739 }
740 TRACKBAR_CalcThumb(hwnd,infoPtr);
741 }
742 if (infoPtr->flags & TB_SELECTIONCHANGED) TRACKBAR_CalcSelection(hwnd,infoPtr);
743 infoPtr->flags &= ~ (TB_THUMBCHANGED | TB_SELECTIONCHANGED | TB_DRAGPOSVALID);
744
745 /* draw channel */
746
747 if (cdctlres & CDRF_NOTIFYITEMDRAW)
748 {
749 cdraw.dwDrawStage = CDDS_ITEMPREPAINT;
750 cdraw.dwItemSpec = TBCD_CHANNEL;
751 cdraw.rc = infoPtr->rcChannel;
752
753 cdres = SendMessageA(GetParent(hwnd),WM_NOTIFY,(WPARAM)cdraw.hdr.idFrom,(LPARAM)&cdraw);
754 } else cdres = 0;
755
756 if (!(cdres & CDRF_SKIPDEFAULT))
757 {
758 rcChannel = infoPtr->rcChannel;
759 rcSelection = infoPtr->rcSelection;
760 DrawEdge(hdc,&rcChannel,EDGE_SUNKEN,BF_RECT | BF_ADJUST);
761
762 if (dwStyle & TBS_ENABLESELRANGE) /* fill the channel */
763 {
764 HBRUSH hbr = CreateSolidBrush(RGB(255,255,255));
765 FillRect(hdc,&rcChannel,hbr);
766 DeleteObject(hbr);
767 if (((dwStyle & TBS_VERT) && (rcSelection.top != rcSelection.bottom)) ||
768 ((!(dwStyle & TBS_VERT)) && (rcSelection.left != rcSelection.right)))
769 {
770 hbr = CreateSolidBrush (COLOR_HIGHLIGHT);
771 FillRect (hdc,&rcSelection,hbr);
772 DeleteObject(hbr);
773 }
774 }
775
776 if (cdctlres & CDRF_NOTIFYITEMDRAW)
777 {
778 cdraw.dwDrawStage = CDDS_ITEMPOSTPAINT;
779
780 SendMessageA(GetParent(hwnd),WM_NOTIFY,(WPARAM)cdraw.hdr.idFrom,(LPARAM)&cdraw);
781 }
782 }
783
784 /* draw tics */
785
786 if (cdctlres & CDRF_NOTIFYITEMDRAW)
787 {
788 cdraw.dwDrawStage = CDDS_ITEMPREPAINT;
789 cdraw.dwItemSpec = TBCD_TICS;
790 SetRectEmpty(&cdraw.rc);
791
792 cdres = SendMessageA(GetParent(hwnd),WM_NOTIFY,(WPARAM)cdraw.hdr.idFrom,(LPARAM)&cdraw);
793 } else cdres = 0;
794
795 if (!(cdres & CDRF_SKIPDEFAULT))
796 {
797 if (!(dwStyle & TBS_NOTICKS))
798 {
799 int ticFlags = dwStyle & 0x0f;
800 COLORREF clrTic = GetSysColor(COLOR_3DDKSHADOW);
801 INT range = infoPtr->nRangeMax-infoPtr->nRangeMin;
802 INT width = (dwStyle & TBS_VERT) ? rcChannel.bottom-rcChannel.top:rcChannel.right-rcChannel.left;
803
804 //check if maximum of visible marks is reached
805 if (dwStyle & TBS_AUTOTICKS && infoPtr->uNumTics > 1 && (INT)(width*infoPtr->tics[0]/range) == (INT)(width*infoPtr->tics[1]/range))
806 {
807 //draw all pixels at once -> much faster
808 if (dwStyle & TBS_VERT)
809 {
810 if ((ticFlags & TBS_LEFT) || (ticFlags & TBS_BOTH))
811 TRACKBAR_FillVertTics(infoPtr,hdc,ticFlags | TBS_LEFT,clrTic);
812 if (!(ticFlags & TBS_LEFT) || (ticFlags & TBS_BOTH))
813 TRACKBAR_FillVertTics(infoPtr,hdc,ticFlags & ~TBS_LEFT,clrTic);
814 } else
815 {
816 if ((ticFlags & TBS_TOP) || (ticFlags & TBS_BOTH))
817 TRACKBAR_FillHorzTics(infoPtr,hdc,ticFlags | TBS_TOP,clrTic);
818 if (!(ticFlags & TBS_TOP) || (ticFlags & TBS_BOTH))
819 TRACKBAR_FillHorzTics(infoPtr,hdc,ticFlags & ~TBS_TOP,clrTic);
820 }
821 } else
822 {
823 for (i = 0;i < infoPtr->uNumTics;i++)
824 TRACKBAR_DrawTics(infoPtr,hdc,infoPtr->tics[i],ticFlags,clrTic);
825 }
826
827 TRACKBAR_DrawTics(infoPtr,hdc,0,ticFlags | TIC_LEFTEDGE,clrTic);
828 TRACKBAR_DrawTics(infoPtr,hdc,0,ticFlags | TIC_RIGHTEDGE,clrTic);
829
830 if ((dwStyle & TBS_ENABLESELRANGE) &&
831 ((dwStyle & TBS_VERT && rcSelection.bottom != rcSelection.top) ||
832 (!(dwStyle & TBS_VERT) && rcSelection.left != rcSelection.right)))
833 {
834 TRACKBAR_DrawTics(infoPtr,hdc,infoPtr->nSelMin,ticFlags | TIC_SELECTIONMARKMIN,clrTic);
835 TRACKBAR_DrawTics(infoPtr,hdc,infoPtr->nSelMax,ticFlags | TIC_SELECTIONMARKMAX,clrTic);
836 }
837 }
838
839 if (cdctlres & CDRF_NOTIFYITEMDRAW)
840 {
841 cdraw.dwDrawStage = CDDS_ITEMPOSTPAINT;
842
843 SendMessageA(GetParent(hwnd),WM_NOTIFY,(WPARAM)cdraw.hdr.idFrom,(LPARAM)&cdraw);
844 }
845 }
846
847 /* draw thumb */
848
849 if (cdctlres & CDRF_NOTIFYITEMDRAW)
850 {
851 cdraw.dwDrawStage = CDDS_ITEMPREPAINT;
852 cdraw.dwItemSpec = TBCD_THUMB;
853 cdraw.rc = infoPtr->rcFullThumb;
854
855 cdres = SendMessageA(GetParent(hwnd),WM_NOTIFY,(WPARAM)cdraw.hdr.idFrom,(LPARAM)&cdraw);
856 } else cdres = 0;
857
858 if (!(cdres & CDRF_SKIPDEFAULT))
859 {
860 TRACKBAR_DrawThumb(infoPtr,hwnd,hdc,dwStyle);
861
862 if (cdctlres & CDRF_NOTIFYITEMDRAW)
863 {
864 cdraw.dwDrawStage = CDDS_ITEMPOSTPAINT;
865
866 SendMessageA(GetParent(hwnd),WM_NOTIFY,(WPARAM)cdraw.hdr.idFrom,(LPARAM)&cdraw);
867 }
868
869 }
870
871 if (infoPtr->bFocus && IsWindowEnabled(hwnd)) DrawFocusRect(hdc,&rcClient);
872
873 if (cdctlres & CDRF_NOTIFYPOSTPAINT)
874 {
875 cdraw.dwDrawStage = CDDS_POSTPAINT;
876 cdraw.dwItemSpec = 0;
877 GetClientRect(hwnd,&cdraw.rc);
878
879 SendMessageA(GetParent(hwnd),WM_NOTIFY,(WPARAM)cdraw.hdr.idFrom,(LPARAM)&cdraw);
880 }
881
882}
883
884//update thumb position
885
886static VOID TRACKBAR_UpdateThumbPosition(HWND hwnd,INT lastPos,BOOL mustRedraw)
887{
888 HDC hdc;
889 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(hwnd);
890 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
891 RECT lastRect,newRect,updateRect;
892 HDC hdcCompatible;
893 HBITMAP bitmap,oldbmp;
894
895 //last
896 lastRect = infoPtr->rcFullThumb;
897
898 //new
899 if (infoPtr->flags & TB_DRAGPOSVALID)
900 {
901 infoPtr->nPos = infoPtr->dragPos;
902 infoPtr->flags &= ~TB_DRAGPOSVALID;
903 }
904 if (!mustRedraw && infoPtr->nPos == lastPos) return;
905
906 if (dwStyle & TBS_NOTHUMB) return;
907
908 TRACKBAR_CalcThumb(hwnd,infoPtr);
909 infoPtr->flags &= ~TB_THUMBCHANGED;
910 newRect = infoPtr->rcFullThumb;
911
912 //same rect?
913 if (!mustRedraw && EqualRect(&lastRect,&newRect)) return;
914
915 //3D frame adjustation
916 lastRect.right++;
917 lastRect.bottom++;
918 newRect.right++;
919 newRect.bottom++;
920
921 //BitBlt from memory -> no flickering
922 updateRect.left = MIN(lastRect.left,newRect.left);
923 updateRect.right = MAX(lastRect.right,newRect.right);
924 updateRect.top = MIN(lastRect.top,newRect.top);
925 updateRect.bottom = MAX(lastRect.bottom,newRect.bottom);
926 hdc = GetDC(hwnd);
927 hdcCompatible = CreateCompatibleDC(hdc);
928 bitmap = CreateCompatibleBitmap(hdc,updateRect.right,updateRect.bottom);
929 oldbmp = SelectObject(hdcCompatible,bitmap);
930 TRACKBAR_Draw(hwnd,hdcCompatible);
931 if (dwStyle & TBS_VERT)
932 {
933 if (lastRect.top > newRect.top && lastRect.top < newRect.bottom)
934 BitBlt(hdc,newRect.left,newRect.top,newRect.right-newRect.left,lastRect.bottom-newRect.top,hdcCompatible,newRect.left,newRect.top,SRCCOPY);
935 else if (lastRect.bottom < newRect.bottom && lastRect.bottom > newRect.top)
936 BitBlt(hdc,lastRect.left,lastRect.top,lastRect.right-lastRect.left,newRect.bottom-lastRect.top,hdcCompatible,lastRect.left,lastRect.top,SRCCOPY);
937 else
938 {
939 BitBlt(hdc,lastRect.left,lastRect.top,lastRect.right-lastRect.left,lastRect.bottom-lastRect.top,hdcCompatible,lastRect.left,lastRect.top,SRCCOPY);
940 BitBlt(hdc,newRect.left,newRect.top,newRect.right-newRect.left,newRect.bottom-newRect.top,hdcCompatible,newRect.left,newRect.top,SRCCOPY);
941 }
942 } else
943 {
944 if (lastRect.right > newRect.left && lastRect.right < newRect.right)
945 BitBlt(hdc,lastRect.left,lastRect.top,newRect.right-lastRect.left,lastRect.bottom-lastRect.top,hdcCompatible,lastRect.left,lastRect.top,SRCCOPY);
946 else if (lastRect.left < newRect.right && lastRect.left > newRect.left)
947 BitBlt(hdc,newRect.left,newRect.top,lastRect.right-newRect.left,newRect.bottom-newRect.top,hdcCompatible,newRect.left,newRect.top,SRCCOPY);
948 else
949 {
950 BitBlt(hdc,lastRect.left,lastRect.top,lastRect.right-lastRect.left,lastRect.bottom-lastRect.top,hdcCompatible,lastRect.left,lastRect.top,SRCCOPY);
951 BitBlt(hdc,newRect.left,newRect.top,newRect.right-newRect.left,newRect.bottom-newRect.top,hdcCompatible,newRect.left,newRect.top,SRCCOPY);
952 }
953 }
954 SelectObject(hdcCompatible,oldbmp);
955 DeleteObject(bitmap);
956 DeleteDC(hdcCompatible);
957 ReleaseDC(hwnd,hdc);
958}
959
960//redraw everything
961
962static VOID TRACKBAR_Refresh (HWND hwnd)
963{
964 HDC hdc;
965
966 hdc = GetDC (hwnd);
967 TRACKBAR_Draw(hwnd,hdc);
968 ReleaseDC(hwnd,hdc);
969}
970
971static VOID
972TRACKBAR_AlignBuddies (HWND hwnd, TRACKBAR_INFO *infoPtr)
973{
974 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
975 HWND hwndParent = GetParent(hwnd);
976 RECT rcSelf,rcBuddy;
977 INT x, y;
978
979 GetWindowRect(hwnd,&rcSelf);
980
981 /* align buddy left or above */
982 if (infoPtr->hwndBuddyLA)
983 {
984 GetWindowRect(infoPtr->hwndBuddyLA,&rcBuddy);
985
986 if (dwStyle & TBS_VERT)
987 { //above
988 x = rcSelf.left-(rcBuddy.right-rcBuddy.left)/2+infoPtr->rcChannel.left+(infoPtr->rcChannel.right-infoPtr->rcChannel.left)/2;
989 y = rcSelf.top-(rcBuddy.bottom-rcBuddy.top);
990 } else
991 { //left
992 x = rcSelf.left+infoPtr->rcChannel.left-(rcBuddy.right-rcBuddy.left)/2;
993 y = rcSelf.top-(rcBuddy.bottom-rcBuddy.top);
994 }
995
996 SetWindowPos(infoPtr->hwndBuddyLA,0,x,y,0,0,SWP_NOZORDER | SWP_NOSIZE);
997 }
998
999
1000 /* align buddy right or below */
1001 if (infoPtr->hwndBuddyRB)
1002 {
1003 GetWindowRect(infoPtr->hwndBuddyRB,&rcBuddy);
1004
1005 if (dwStyle & TBS_VERT)
1006 { //below
1007 x = rcSelf.left-(rcBuddy.right-rcBuddy.left)/2+infoPtr->rcChannel.left+(infoPtr->rcChannel.right-infoPtr->rcChannel.left)/2;
1008 y = rcSelf.bottom;
1009 } else
1010 {
1011 x = rcSelf.right-infoPtr->rcChannel.left-(rcBuddy.right-rcBuddy.left)/2;
1012 y = rcSelf.top-(rcBuddy.bottom-rcBuddy.top);
1013 }
1014
1015 SetWindowPos(infoPtr->hwndBuddyRB,0,x,y,0,0,SWP_NOZORDER | SWP_NOSIZE);
1016 }
1017}
1018
1019
1020static LRESULT
1021TRACKBAR_ClearSel (HWND hwnd, WPARAM wParam, LPARAM lParam)
1022{
1023 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1024
1025 if (infoPtr->nSelMin != infoPtr->nSelMax)
1026 {
1027 infoPtr->nSelMin = 0;
1028 infoPtr->nSelMax = 0;
1029 infoPtr->flags |= TB_SELECTIONCHANGED;
1030
1031 if ((BOOL)wParam) TRACKBAR_Refresh(hwnd);
1032 }
1033
1034 return 0;
1035}
1036
1037
1038static LRESULT
1039TRACKBAR_ClearTics (HWND hwnd, WPARAM wParam, LPARAM lParam)
1040{
1041 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1042
1043 if (!(GetWindowLongA(hwnd, GWL_STYLE) & (TBS_AUTOTICKS | TBS_NOTICKS))) return 0;
1044
1045 if (infoPtr->tics)
1046 {
1047 COMCTL32_Free(infoPtr->tics);
1048 infoPtr->tics = NULL;
1049 infoPtr->uNumTics = 0;
1050
1051 if (wParam) TRACKBAR_Refresh(hwnd);
1052 }
1053
1054 return 0;
1055}
1056
1057
1058static LRESULT
1059TRACKBAR_GetBuddy (HWND hwnd, WPARAM wParam, LPARAM lParam)
1060{
1061 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(hwnd);
1062
1063 if (wParam)
1064 return (LRESULT)infoPtr->hwndBuddyLA; //left or above
1065 else
1066 return (LRESULT)infoPtr->hwndBuddyRB; //right or below
1067}
1068
1069
1070static LRESULT
1071TRACKBAR_GetChannelRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
1072{
1073 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1074 LPRECT lprc = (LPRECT)lParam;
1075
1076 if (lprc == NULL) return 0;
1077
1078 CopyRect(lprc,&infoPtr->rcChannel);
1079
1080 return 0;
1081}
1082
1083
1084static LRESULT
1085TRACKBAR_GetLineSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
1086{
1087 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1088
1089 return infoPtr->nLineSize;
1090}
1091
1092
1093static LRESULT
1094TRACKBAR_GetNumTics (HWND hwnd, WPARAM wParam, LPARAM lParam)
1095{
1096 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1097
1098 if (GetWindowLongA(hwnd, GWL_STYLE) & TBS_NOTICKS) return 0;
1099
1100 return infoPtr->uNumTics+2; //includes last and first tick
1101}
1102
1103
1104static LRESULT
1105TRACKBAR_GetPageSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
1106{
1107 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1108
1109 return infoPtr->nPageSize;
1110}
1111
1112
1113static LRESULT
1114TRACKBAR_GetPos (HWND hwnd, WPARAM wParam, LPARAM lParam)
1115{
1116 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1117
1118 return infoPtr->nPos;
1119}
1120
1121
1122static LRESULT
1123TRACKBAR_GetRangeMax (HWND hwnd, WPARAM wParam, LPARAM lParam)
1124{
1125 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1126
1127 return infoPtr->nRangeMax;
1128}
1129
1130
1131static LRESULT
1132TRACKBAR_GetRangeMin (HWND hwnd, WPARAM wParam, LPARAM lParam)
1133{
1134 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1135
1136 return infoPtr->nRangeMin;
1137}
1138
1139
1140static LRESULT
1141TRACKBAR_GetSelEnd (HWND hwnd, WPARAM wParam, LPARAM lParam)
1142{
1143 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1144
1145 return infoPtr->nSelMax;
1146}
1147
1148
1149static LRESULT
1150TRACKBAR_GetSelStart (HWND hwnd, WPARAM wParam, LPARAM lParam)
1151{
1152 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1153
1154 return infoPtr->nSelMin;
1155}
1156
1157
1158static LRESULT
1159TRACKBAR_GetThumbLength (HWND hwnd, WPARAM wParam, LPARAM lParam)
1160{
1161 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1162
1163 return infoPtr->uThumbLen;
1164}
1165
1166static LRESULT
1167TRACKBAR_GetPTics (HWND hwnd)
1168{
1169 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1170
1171 return (LRESULT)infoPtr->tics;
1172}
1173
1174static LRESULT
1175TRACKBAR_GetThumbRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
1176{
1177 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1178 LPRECT lprc = (LPRECT)lParam;
1179
1180 if (lprc == NULL) return 0;
1181
1182 CopyRect(lprc,&infoPtr->rcFullThumb);
1183
1184 return 0;
1185}
1186
1187
1188static LRESULT
1189TRACKBAR_GetTic (HWND hwnd, WPARAM wParam, LPARAM lParam)
1190{
1191 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1192 INT iTic;
1193
1194 iTic = (INT)wParam;
1195 if ((iTic < 0) || (iTic > infoPtr->uNumTics)) return -1;
1196
1197 return (LRESULT)infoPtr->tics[iTic];
1198
1199}
1200
1201
1202static LRESULT
1203TRACKBAR_GetTicPos (HWND hwnd, WPARAM wParam, LPARAM lParam)
1204{
1205 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1206 INT iTic, range, width, pos;
1207
1208
1209 iTic = (INT)wParam;
1210 if ((iTic < 0) || (iTic > infoPtr->uNumTics)) return -1;
1211
1212 range = infoPtr->nRangeMax-infoPtr->nRangeMin;
1213 width = infoPtr->rcChannel.right-infoPtr->rcChannel.left;
1214 pos = infoPtr->rcChannel.left+(width*(infoPtr->tics[iTic]-infoPtr->nRangeMin))/range;
1215
1216 return (LRESULT) pos;
1217}
1218
1219
1220static LRESULT
1221TRACKBAR_GetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
1222{
1223 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1224
1225 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_TOOLTIPS)
1226 return (LRESULT)infoPtr->hwndToolTip;
1227 return 0;
1228}
1229
1230
1231static
1232TRACKBAR_GetUnicodeFormat(HWND hwnd,WPARAM wParam,LPARAM lParam)
1233{
1234 return FALSE; //Unicode not used
1235}
1236
1237static LRESULT
1238TRACKBAR_SetBuddy (HWND hwnd, WPARAM wParam, LPARAM lParam)
1239{
1240 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(hwnd);
1241 HWND hwndTemp;
1242
1243 if (!(GetParent(lParam) == GetParent(hwnd))) return wParam ? infoPtr->hwndBuddyLA:infoPtr->hwndBuddyRB;
1244
1245 if (wParam)
1246 {
1247 /* buddy is left or above */
1248 hwndTemp = infoPtr->hwndBuddyLA;
1249 infoPtr->hwndBuddyLA = (HWND)lParam;
1250 } else
1251 {
1252 /* buddy is right or below */
1253 hwndTemp = infoPtr->hwndBuddyRB;
1254 infoPtr->hwndBuddyRB = (HWND)lParam;
1255 }
1256
1257 TRACKBAR_AlignBuddies(hwnd,infoPtr);
1258
1259 return (LRESULT)hwndTemp;
1260}
1261
1262
1263static LRESULT
1264TRACKBAR_SetLineSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
1265{
1266 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1267 INT nTemp = infoPtr->nLineSize;
1268
1269 infoPtr->nLineSize = (INT)lParam;
1270
1271 return nTemp;
1272}
1273
1274
1275static LRESULT
1276TRACKBAR_SetPageSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
1277{
1278 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1279 INT nTemp = infoPtr->nPageSize;
1280
1281 infoPtr->nPageSize = (INT)lParam;
1282
1283 return nTemp;
1284}
1285
1286
1287static LRESULT
1288TRACKBAR_SetPos (HWND hwnd, WPARAM wParam, LPARAM lParam)
1289{
1290 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1291 INT lastPos = infoPtr->nPos;
1292
1293 infoPtr->nPos = (INT)LOWORD(lParam);
1294
1295 if (lastPos == infoPtr->nPos) return 0; //nothing changed
1296
1297 if (infoPtr->nPos < infoPtr->nRangeMin)
1298 infoPtr->nPos = infoPtr->nRangeMin;
1299
1300 if (infoPtr->nPos > infoPtr->nRangeMax)
1301 infoPtr->nPos = infoPtr->nRangeMax;
1302 infoPtr->flags |= TB_THUMBPOSCHANGED;
1303
1304 if (wParam) TRACKBAR_UpdateThumbPosition(hwnd,lastPos,FALSE);
1305
1306 return 0;
1307}
1308
1309
1310static LRESULT
1311TRACKBAR_SetRange (HWND hwnd, WPARAM wParam, LPARAM lParam)
1312{
1313 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1314 int newMin,newMax;
1315 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
1316
1317 newMin = (INT)LOWORD(lParam);
1318 newMax = (INT)HIWORD(lParam);
1319
1320 if (newMin == newMax) return 0;
1321 if (newMin > newMax)
1322 { //exchange
1323 int x;
1324
1325 x = newMin;
1326 newMin = newMax;
1327 newMax = x;
1328 }
1329 if (newMin == infoPtr->nRangeMin && newMax == infoPtr->nRangeMax) return 0;
1330
1331 infoPtr->nRangeMin = newMin;
1332 infoPtr->nRangeMax = newMax;
1333
1334 if (infoPtr->nPos < infoPtr->nRangeMin)
1335 {
1336 infoPtr->nPos = infoPtr->nRangeMin;
1337 infoPtr->flags |= TB_THUMBPOSCHANGED;
1338 }
1339 if (infoPtr->nPos > infoPtr->nRangeMax)
1340 {
1341 infoPtr->nPos = infoPtr->nRangeMax;
1342 infoPtr->flags |= TB_THUMBPOSCHANGED;
1343 }
1344
1345 if (infoPtr->nSelMin < infoPtr->nRangeMin)
1346 {
1347 infoPtr->nSelMin = infoPtr->nRangeMin;
1348 infoPtr->flags |= TB_SELECTIONCHANGED;
1349 }
1350 if (infoPtr->nSelMin > infoPtr->nRangeMax)
1351 {
1352 infoPtr->nSelMin = infoPtr->nRangeMax;
1353 infoPtr->flags |= TB_SELECTIONCHANGED;
1354 }
1355 if (infoPtr->nSelMax < infoPtr->nRangeMin)
1356 {
1357 infoPtr->nSelMax = infoPtr->nRangeMin;
1358 infoPtr->flags |= TB_SELECTIONCHANGED;
1359 }
1360 if (infoPtr->nSelMax > infoPtr->nRangeMax)
1361 {
1362 infoPtr->nSelMax = infoPtr->nRangeMax;
1363 infoPtr->flags |= TB_SELECTIONCHANGED;
1364 }
1365
1366 infoPtr->nPageSize = (infoPtr->nRangeMax-infoPtr->nRangeMin)/5;
1367 if (infoPtr->nPageSize == 0) infoPtr->nPageSize = 1;
1368 TRACKBAR_RecalculateTics(hwnd,infoPtr,TRUE);
1369
1370 if (wParam) TRACKBAR_Refresh(hwnd);
1371
1372 return 0;
1373}
1374
1375
1376static LRESULT
1377TRACKBAR_SetRangeMax (HWND hwnd, WPARAM wParam, LPARAM lParam)
1378{
1379 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1380
1381 if ((INT)lParam <= infoPtr->nRangeMin) return 0;
1382 if (infoPtr->nRangeMax == (INT)lParam) return 0;
1383
1384 infoPtr->nRangeMax = (INT)lParam;
1385 if (infoPtr->nPos > infoPtr->nRangeMax)
1386 {
1387 infoPtr->nPos = infoPtr->nRangeMax;
1388 infoPtr->flags |=TB_THUMBPOSCHANGED;
1389 }
1390
1391 infoPtr->nPageSize = (infoPtr->nRangeMax-infoPtr->nRangeMin)/5;
1392 if (infoPtr->nPageSize == 0) infoPtr->nPageSize = 1;
1393 TRACKBAR_RecalculateTics(hwnd,infoPtr,TRUE);
1394
1395 if (wParam) TRACKBAR_Refresh(hwnd);
1396
1397 return 0;
1398}
1399
1400
1401static LRESULT
1402TRACKBAR_SetRangeMin (HWND hwnd, WPARAM wParam, LPARAM lParam)
1403{
1404 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1405
1406 if ((INT)lParam >= infoPtr->nRangeMax) return 0;
1407 if (infoPtr->nRangeMin == (INT)lParam) return 0;
1408
1409 infoPtr->nRangeMin = (INT)lParam;
1410 if (infoPtr->nPos < infoPtr->nRangeMin)
1411 {
1412 infoPtr->nPos = infoPtr->nRangeMin;
1413 infoPtr->flags |=TB_THUMBPOSCHANGED;
1414 }
1415
1416 infoPtr->nPageSize = (infoPtr->nRangeMax-infoPtr->nRangeMin)/5;
1417 if (infoPtr->nPageSize == 0) infoPtr->nPageSize = 1;
1418 TRACKBAR_RecalculateTics(hwnd,infoPtr,TRUE);
1419
1420 if (wParam) TRACKBAR_Refresh(hwnd);
1421
1422 return 0;
1423}
1424
1425
1426static LRESULT
1427TRACKBAR_SetTicFreq (HWND hwnd, WPARAM wParam)
1428{
1429 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1430
1431 if (infoPtr->uTicFreq == (UINT)wParam) return 0;
1432
1433 if (!(GetWindowLongA(hwnd,GWL_STYLE) & TBS_AUTOTICKS)) return 0;
1434
1435 infoPtr->uTicFreq = (UINT)wParam;
1436
1437 TRACKBAR_RecalculateTics(hwnd,infoPtr,FALSE);
1438
1439 TRACKBAR_Refresh(hwnd);
1440
1441 return 0;
1442}
1443
1444
1445static LRESULT
1446TRACKBAR_SetSel(HWND hwnd,WPARAM wParam,LPARAM lParam)
1447{
1448 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1449 INT newMin,newMax,oldMin,oldMax;
1450
1451 oldMin = infoPtr->nSelMin;
1452 oldMax = infoPtr->nSelMax;
1453 newMin = (INT)LOWORD(lParam);
1454 newMax = (INT)HIWORD(lParam);
1455
1456 if (infoPtr->nSelMin == newMin && infoPtr->nSelMax == newMax) return 0;
1457 infoPtr->nSelMin = newMin;
1458 infoPtr->nSelMax = newMax;
1459
1460 if (infoPtr->nSelMin < infoPtr->nRangeMin) infoPtr->nSelMin = infoPtr->nRangeMin;
1461 if (infoPtr->nSelMin > infoPtr->nRangeMax) infoPtr->nSelMin = infoPtr->nRangeMax;
1462 if (infoPtr->nSelMax > infoPtr->nRangeMax) infoPtr->nSelMax = infoPtr->nRangeMax;
1463 if (infoPtr->nSelMax < infoPtr->nRangeMin) infoPtr->nSelMax = infoPtr->nRangeMin;
1464
1465 if (infoPtr->nSelMin > infoPtr->nSelMax) infoPtr->nSelMin = infoPtr->nSelMax;
1466
1467 if (!GetWindowLongA(hwnd, GWL_STYLE) & TBS_ENABLESELRANGE) return 0;
1468
1469 if (oldMin != newMin || oldMax != newMax)
1470 {
1471 infoPtr->flags |= TB_SELECTIONCHANGED;
1472 if (wParam) TRACKBAR_Refresh(hwnd);
1473 }
1474
1475 return 0;
1476}
1477
1478
1479static LRESULT
1480TRACKBAR_SetSelEnd (HWND hwnd, WPARAM wParam, LPARAM lParam)
1481{
1482 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1483 INT oldMax;
1484
1485 if (infoPtr->nSelMax == (INT)lParam) return 0;
1486
1487 oldMax = infoPtr->nSelMax;
1488 infoPtr->nSelMax = (INT)lParam;
1489
1490 if (infoPtr->nSelMax > infoPtr->nRangeMax) infoPtr->nSelMax = infoPtr->nRangeMax;
1491 if (infoPtr->nSelMax < infoPtr->nRangeMin) infoPtr->nSelMax = infoPtr->nRangeMin;
1492
1493 if (infoPtr->nSelMin > infoPtr->nSelMax) infoPtr->nSelMin = infoPtr->nSelMax;
1494
1495 if (!GetWindowLongA(hwnd,GWL_STYLE) & TBS_ENABLESELRANGE) return 0;
1496
1497 if (oldMax != infoPtr->nSelMax)
1498 {
1499 infoPtr->flags |= TB_SELECTIONCHANGED;
1500 if (wParam) TRACKBAR_Refresh(hwnd);
1501 }
1502
1503 return 0;
1504}
1505
1506
1507static LRESULT
1508TRACKBAR_SetSelStart (HWND hwnd, WPARAM wParam, LPARAM lParam)
1509{
1510 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1511 INT oldMin;
1512
1513 if (infoPtr->nSelMin == (INT)lParam) return 0;
1514
1515 oldMin = infoPtr->nSelMin;
1516 infoPtr->nSelMin = (INT)lParam;
1517
1518 if (infoPtr->nSelMin < infoPtr->nRangeMin) infoPtr->nSelMin = infoPtr->nRangeMin;
1519 if (infoPtr->nSelMin > infoPtr->nRangeMax) infoPtr->nSelMin = infoPtr->nRangeMax;
1520
1521 if (infoPtr->nSelMin > infoPtr->nSelMax) infoPtr->nSelMin = infoPtr->nSelMax;
1522
1523 if (!GetWindowLongA(hwnd,GWL_STYLE) & TBS_ENABLESELRANGE) return 0;
1524
1525 if (oldMin != infoPtr->nSelMin)
1526 {
1527 infoPtr->flags |= TB_SELECTIONCHANGED;
1528 if (wParam) TRACKBAR_Refresh(hwnd);
1529 }
1530
1531 return 0;
1532}
1533
1534
1535static LRESULT
1536TRACKBAR_SetThumbLength (HWND hwnd, WPARAM wParam, LPARAM lParam)
1537{
1538 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(hwnd);
1539
1540 if (infoPtr->uThumbLen == (UINT)wParam) return 0;
1541
1542 if (GetWindowLongA(hwnd,GWL_STYLE) & TBS_FIXEDLENGTH) return 0;
1543
1544 infoPtr->uThumbLen = MAX((UINT)wParam,THUMB_MINLEN);
1545 infoPtr->flags |= TB_THUMBSIZECHANGED | TB_THUMBCHANGED;
1546
1547 TRACKBAR_Refresh(hwnd);
1548
1549 return 0;
1550}
1551
1552static void TRACKBAR_QuickSort(LPLONG list,INT lo,INT hi)
1553{
1554 INT i,j,x,y;
1555
1556 i = lo;
1557 j = hi;
1558 x = list[(lo+hi)/2];
1559 do
1560 {
1561 while (list[i] < x) i++;
1562 while (x < list[j]) j--;
1563 if (i <= j)
1564 {
1565 y = list[i];
1566 list[i] = list[j];
1567 list[j] = y;
1568 i++;
1569 j--;
1570 }
1571 } while (i <= j);
1572 if (lo < j) TRACKBAR_QuickSort(list,lo,j);
1573 if (i < hi) TRACKBAR_QuickSort(list,i,hi);
1574}
1575
1576static LRESULT
1577TRACKBAR_SetTic (HWND hwnd, WPARAM wParam, LPARAM lParam)
1578{
1579 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1580 INT nPos = (INT)lParam;
1581 INT x;
1582
1583 if (!(GetWindowLongA(hwnd, GWL_STYLE) & (TBS_AUTOTICKS | TBS_NOTICKS))) return 0;
1584
1585 if ((nPos < infoPtr->nRangeMin) || (nPos > infoPtr->nRangeMax)) return FALSE;
1586
1587 //Check if tick exists
1588 for (x = 0;x < infoPtr->uNumTics;x++)
1589 {
1590 if (infoPtr->tics[x] == nPos) return TRUE; //value is ok
1591 }
1592
1593 infoPtr->uNumTics++;
1594 infoPtr->tics = COMCTL32_ReAlloc(infoPtr->tics,infoPtr->uNumTics*sizeof(DWORD));
1595 infoPtr->tics[infoPtr->uNumTics-1] = nPos;
1596
1597 //Quicksort the list
1598 TRACKBAR_QuickSort(infoPtr->tics,0,infoPtr->uNumTics-1);
1599
1600 TRACKBAR_Refresh(hwnd);
1601
1602 return TRUE;
1603}
1604
1605
1606static LRESULT
1607TRACKBAR_SetTipSide (HWND hwnd, WPARAM wParam, LPARAM lParam)
1608{
1609 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(hwnd);
1610 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
1611 INT fTemp = infoPtr->fLocation;
1612
1613 if (dwStyle & TBS_VERT)
1614 {
1615 if (wParam == TBTS_LEFT || wParam == TBTS_RIGHT) infoPtr->fLocation = (INT)wParam;
1616 } else
1617 {
1618 if (wParam == TBTS_TOP || wParam == TBTS_BOTTOM) infoPtr->fLocation = (INT)wParam;
1619 }
1620
1621 return fTemp;
1622}
1623
1624
1625static LRESULT
1626TRACKBAR_SetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
1627{
1628 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1629
1630 infoPtr->hwndToolTip = (HWND)wParam;
1631
1632 return 0;
1633}
1634
1635static LRESULT
1636TRACKBAR_InitializeThumb (HWND hwnd)
1637{
1638 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1639 RECT clientRect;
1640 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
1641 INT scaleSize;
1642
1643 GetClientRect(hwnd,&clientRect);
1644 infoPtr->uThumbLen = THUMB_LEN; /* initial thumb length */
1645
1646 scaleSize = 2*BORDER_SIZE;
1647 if (dwStyle & TBS_NOTICKS) scaleSize += 0;
1648 else if (dwStyle & TBS_BOTH) scaleSize += 2*(SCALE_SIZE+SCALE_SPACE);
1649 else scaleSize += SCALE_SIZE+SCALE_SPACE;
1650
1651 if (dwStyle & TBS_VERT)
1652 {
1653 INT width = clientRect.right-clientRect.left;
1654
1655 if (infoPtr->uThumbLen+scaleSize > width) infoPtr->uThumbLen = MAX(width-scaleSize,THUMB_MINLEN);
1656 } else
1657 {
1658 INT height = clientRect.bottom-clientRect.top;
1659
1660 if (infoPtr->uThumbLen+scaleSize > height) infoPtr->uThumbLen = MAX(height-scaleSize,THUMB_MINLEN);
1661 }
1662
1663 TRACKBAR_CalcChannel(hwnd,infoPtr);
1664 TRACKBAR_CalcThumb(hwnd,infoPtr);
1665
1666 infoPtr->flags &= ~TB_SELECTIONCHANGED;
1667
1668 return 0;
1669}
1670
1671
1672static LRESULT
1673TRACKBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
1674{
1675 TRACKBAR_INFO *infoPtr;
1676 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
1677
1678 infoPtr = (TRACKBAR_INFO *)COMCTL32_Alloc(sizeof(TRACKBAR_INFO));
1679 SetWindowLongA(hwnd,0,(DWORD)infoPtr);
1680
1681 /* set default values */
1682 infoPtr->nRangeMin = 0;
1683 infoPtr->nRangeMax = 100;
1684 infoPtr->nLineSize = 1;
1685 infoPtr->nPageSize = 20;
1686 infoPtr->nSelMin = 0;
1687 infoPtr->nSelMax = 0;
1688 infoPtr->nPos = 0;
1689
1690 infoPtr->uNumTics = 0; /* start and end tic are not included in count*/
1691 infoPtr->uTicFreq = 1;
1692 infoPtr->tics = NULL;
1693 infoPtr->clrBk = GetSysColor(COLOR_3DFACE);
1694 infoPtr->hwndNotify = GetParent(hwnd);
1695
1696 infoPtr->hwndBuddyLA = 0;
1697 infoPtr->hwndBuddyRB = 0;
1698 infoPtr->flags = 0;
1699 infoPtr->bFocus = FALSE;
1700
1701 if (dwStyle & TBS_VERT)
1702 {
1703 infoPtr->fLocation = (dwStyle & TBS_LEFT) ? TBTS_RIGHT : TBTS_LEFT;
1704 } else
1705 {
1706 infoPtr->fLocation = (dwStyle & TBS_TOP) ? TBTS_BOTTOM : TBTS_TOP;
1707 }
1708
1709 TRACKBAR_InitializeThumb (hwnd);
1710
1711 /* Create tooltip control */
1712 if (dwStyle & TBS_TOOLTIPS)
1713 {
1714 TTTOOLINFOA ti;
1715
1716 infoPtr->hwndToolTip =
1717 CreateWindowExA (WS_EX_TOOLWINDOW,TOOLTIPS_CLASSA,NULL,WS_POPUP,
1718 CW_USEDEFAULT,CW_USEDEFAULT,
1719 CW_USEDEFAULT,CW_USEDEFAULT,
1720 hwnd,0,0,0);
1721
1722 /* Send NM_TOOLTIPSCREATED notification */
1723 if (infoPtr->hwndToolTip)
1724 {
1725 NMTOOLTIPSCREATED nmttc;
1726
1727 nmttc.hdr.hwndFrom = hwnd;
1728 nmttc.hdr.idFrom = GetWindowLongA(hwnd,GWL_ID);
1729 nmttc.hdr.code = NM_TOOLTIPSCREATED;
1730 nmttc.hwndToolTips = infoPtr->hwndToolTip;
1731
1732 SendMessageA(GetParent(hwnd),WM_NOTIFY,(WPARAM)nmttc.hdr.idFrom,(LPARAM)&nmttc);
1733 }
1734
1735 ZeroMemory(&ti,sizeof(TTTOOLINFOA));
1736 ti.cbSize = sizeof(TTTOOLINFOA);
1737 ti.uFlags = TTF_TRACK | TTF_CENTERTIP | TTF_ABSOLUTE;
1738 ti.hwnd = hwnd;
1739 ti.uId = 0;
1740 ti.lpszText = ""; /* LPSTR_TEXTCALLBACK */
1741 SetRectEmpty(&ti.rect);
1742
1743 SendMessageA(infoPtr->hwndToolTip,TTM_ADDTOOLA,0,(LPARAM)&ti);
1744 } else infoPtr->hwndToolTip = 0;
1745
1746 return 0;
1747}
1748
1749
1750static LRESULT
1751TRACKBAR_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
1752{
1753 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1754
1755 /* delete tooltip control */
1756 if (infoPtr->hwndToolTip) DestroyWindow(infoPtr->hwndToolTip);
1757
1758 COMCTL32_Free(infoPtr->tics);
1759 COMCTL32_Free(infoPtr);
1760
1761 return 0;
1762}
1763
1764static VOID TRACKBAR_CalcToolTipPos(HWND hwnd,DWORD dwStyle,TRACKBAR_INFO *infoPtr,POINT *pt)
1765{
1766 if (dwStyle & TBS_VERT)
1767 {
1768 if (infoPtr->fLocation == TBTS_RIGHT)
1769 {
1770 pt->x = infoPtr->rcFullThumb.right;
1771 pt->y = infoPtr->rcFullThumb.top+(infoPtr->rcFullThumb.bottom-infoPtr->rcFullThumb.top)/2;
1772 } else
1773 {
1774 pt->x = infoPtr->rcFullThumb.left-15; //CB: optimize!
1775 pt->y = infoPtr->rcFullThumb.top+(infoPtr->rcFullThumb.bottom-infoPtr->rcFullThumb.top)/2;
1776 }
1777
1778 } else
1779 {
1780 if (infoPtr->fLocation == TBTS_TOP)
1781 {
1782 pt->x = infoPtr->rcFullThumb.left+(infoPtr->rcFullThumb.right-infoPtr->rcFullThumb.left)/2;
1783 pt->y = infoPtr->rcFullThumb.top-15; //CB: optimize!
1784 } else
1785 {
1786 pt->x = infoPtr->rcFullThumb.left+(infoPtr->rcFullThumb.right-infoPtr->rcFullThumb.left)/2;
1787 pt->y = infoPtr->rcFullThumb.bottom;
1788 }
1789 }
1790 ClientToScreen(hwnd,pt);
1791}
1792
1793static LRESULT
1794TRACKBAR_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
1795{
1796 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1797 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1798 int clickPlace,prevPos,vertical;
1799 DOUBLE clickPos;
1800 RECT thumb,fullThumb;
1801 POINT clickPoint;
1802
1803 SetFocus (hwnd);
1804
1805 vertical = dwStyle & TBS_VERT;
1806 clickPoint.x = (INT)LOWORD(lParam);
1807 clickPoint.y = (INT)HIWORD(lParam);
1808
1809
1810 if (vertical) clickPlace = clickPoint.y;
1811 else clickPlace = clickPoint.x;
1812
1813 //Button down on thumb?
1814 thumb = infoPtr->rcThumb;
1815 fullThumb = infoPtr->rcFullThumb;
1816 if ((vertical &&
1817 clickPoint.y >= thumb.top &&
1818 clickPoint.y <= thumb.bottom &&
1819 ((dwStyle & TBS_BOTH &&
1820 clickPoint.x >= thumb.left &&
1821 clickPoint.x <= thumb.right
1822 ) ||
1823 (dwStyle & TBS_LEFT &&
1824 clickPoint.x <= thumb.right &&
1825 (clickPoint.x >= thumb.left ||
1826 (clickPoint.x >= fullThumb.left &&
1827 (thumb.left-clickPoint.x <= clickPoint.y-thumb.top &&
1828 thumb.left-clickPoint.x <= thumb.bottom-clickPoint.y
1829 )
1830 )
1831 )
1832 ) ||
1833 (!(dwStyle & (TBS_BOTH | TBS_LEFT)) &&
1834 clickPoint.x >= thumb.left &&
1835 (clickPoint.x <= thumb.right ||
1836 (clickPoint.x <= fullThumb.right &&
1837 (clickPoint.x-thumb.right <= clickPoint.y-thumb.top &&
1838 clickPoint.x-thumb.right <= thumb.bottom-clickPoint.y
1839 )
1840 )
1841 )
1842 ))
1843 ) ||
1844 (!vertical &&
1845 clickPoint.x >= thumb.left &&
1846 clickPoint.x <= thumb.right &&
1847 ((dwStyle & TBS_BOTH &&
1848 clickPoint.y >= thumb.top &&
1849 clickPoint.y <= thumb.bottom
1850 ) ||
1851 (dwStyle & TBS_TOP &&
1852 clickPoint.y <= thumb.bottom &&
1853 (clickPoint.y >= thumb.top ||
1854 (clickPoint.y >= fullThumb.top &&
1855 (thumb.top-clickPoint.y <= clickPoint.x-thumb.left &&
1856 thumb.top-clickPoint.y <= thumb.right-clickPoint.x
1857 )
1858 )
1859 )
1860 ) ||
1861 (!(dwStyle & (TBS_BOTH | TBS_TOP)) &&
1862 clickPoint.y >= thumb.top &&
1863 (clickPoint.y <= thumb.bottom ||
1864 (clickPoint.y <= fullThumb.bottom &&
1865 (clickPoint.y-thumb.bottom <= clickPoint.x-thumb.left &&
1866 clickPoint.y-thumb.bottom <= thumb.right-clickPoint.x
1867 )
1868 )
1869 )
1870 ))
1871 ))
1872 {
1873 infoPtr->flags |= TB_DRAG_MODE;
1874 if (dwStyle & TBS_TOOLTIPS)
1875 { /* enable tooltip */
1876 TTTOOLINFOA ti;
1877 POINT pt;
1878 char buf[80];
1879
1880 TRACKBAR_CalcToolTipPos(hwnd,dwStyle,infoPtr,&pt);
1881 SendMessageA(infoPtr->hwndToolTip,TTM_TRACKPOSITION,0,(LPARAM)MAKELPARAM(pt.x,pt.y));
1882
1883 ti.cbSize = sizeof(TTTOOLINFOA);
1884 ti.uId = 0;
1885 ti.hwnd = (UINT)hwnd;
1886 ti.hinst = 0;
1887 sprintf (buf,"%d",infoPtr->nPos);
1888 ti.lpszText = (LPSTR)buf;
1889
1890 infoPtr->flags |= TB_SHOW_TOOLTIP;
1891 SetCapture(hwnd);
1892
1893 SendMessageA(infoPtr->hwndToolTip,TTM_UPDATETIPTEXTA,0,(LPARAM)&ti);
1894 SendMessageA(infoPtr->hwndToolTip,TTM_TRACKACTIVATE,(WPARAM)TRUE,(LPARAM)&ti);
1895 }
1896 SetCapture(hwnd);
1897 TRACKBAR_UpdateThumbPosition(hwnd,infoPtr->nPos,TRUE); //change arrow color
1898 return 0;
1899 }
1900 else if ((vertical &&
1901 (clickPoint.y >= thumb.top) &&
1902 (clickPoint.y <= thumb.bottom)) ||
1903 (!vertical &&
1904 (clickPoint.x >= thumb.left) &&
1905 (clickPoint.x <= thumb.right)))
1906 {
1907 //ScrollMode
1908 infoPtr->flags |= TB_SCROLL_MODE;
1909 SetCapture(hwnd);
1910 SetTimer(hwnd,SCROLL_TIMER_ID,SCROLL_TIME,NULL);
1911
1912 return 0;
1913 }
1914
1915 clickPos = TRACKBAR_ConvertPlaceToPosition(infoPtr,clickPlace,vertical);
1916 prevPos = infoPtr->nPos;
1917
1918 if (clickPos > prevPos)
1919 { /* similar to VK_NEXT */
1920 infoPtr->nPos += infoPtr->nPageSize;
1921 if (infoPtr->nPos > infoPtr->nRangeMax) infoPtr->nPos = infoPtr->nRangeMax;
1922 if (prevPos != infoPtr->nPos) TRACKBAR_SendNotify(hwnd,TB_PAGEUP);
1923 } else
1924 { /* similar to VK_PRIOR */
1925 infoPtr->nPos -= infoPtr->nPageSize;
1926 if (infoPtr->nPos < infoPtr->nRangeMin) infoPtr->nPos = infoPtr->nRangeMin;
1927 if (prevPos != infoPtr->nPos) TRACKBAR_SendNotify(hwnd,TB_PAGEDOWN);
1928 }
1929
1930 if (prevPos != infoPtr->nPos)
1931 {
1932 infoPtr->flags |= TB_THUMBPOSCHANGED;
1933 TRACKBAR_UpdateThumbPosition(hwnd,prevPos,TRUE);
1934 }
1935
1936 //ScrollMode
1937 infoPtr->flags |= TB_SCROLL_MODE;
1938 SetCapture(hwnd);
1939 SetTimer(hwnd,SCROLL_TIMER_ID,SCROLL_TIME,NULL);
1940
1941 return 0;
1942}
1943
1944
1945static LRESULT
1946TRACKBAR_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
1947{
1948 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1949
1950 if (infoPtr->flags & TB_DRAG_MODE)
1951 {
1952 TRACKBAR_SendNotify(hwnd,TB_ENDTRACK);
1953
1954 infoPtr->flags &= ~TB_DRAG_MODE;
1955
1956 if (GetCapture() == hwnd)
1957 {
1958 NMHDR nmhdr;
1959
1960 nmhdr.hwndFrom = hwnd;
1961 nmhdr.idFrom = GetWindowLongA(hwnd,GWL_ID);
1962 nmhdr.code = NM_RELEASEDCAPTURE;
1963
1964 SendMessageA(GetParent(hwnd),WM_NOTIFY,(WPARAM)nmhdr.idFrom,(LPARAM)&nmhdr);
1965
1966 ReleaseCapture();
1967 }
1968
1969 TRACKBAR_UpdateThumbPosition(hwnd,infoPtr->nPos,TRUE); //change arrow color
1970 }
1971
1972 if (infoPtr->flags & TB_SCROLL_MODE)
1973 {
1974 infoPtr->flags &= ~TB_SCROLL_MODE;
1975
1976 if (GetCapture() == hwnd)
1977 {
1978 NMHDR nmhdr;
1979
1980 nmhdr.hwndFrom = hwnd;
1981 nmhdr.idFrom = GetWindowLongA(hwnd,GWL_ID);
1982 nmhdr.code = NM_RELEASEDCAPTURE;
1983
1984 SendMessageA(GetParent(hwnd),WM_NOTIFY,(WPARAM)nmhdr.idFrom,(LPARAM)&nmhdr);
1985
1986 ReleaseCapture();
1987 }
1988
1989 KillTimer(hwnd,SCROLL_TIMER_ID);
1990 }
1991
1992 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_TOOLTIPS)
1993 { /* disable tooltip */
1994 TTTOOLINFOA ti;
1995
1996 ti.cbSize = sizeof(TTTOOLINFOA);
1997 ti.uId = 0;
1998 ti.hwnd = (UINT)hwnd;
1999
2000 infoPtr->flags &= ~TB_SHOW_TOOLTIP;
2001 SendMessageA (infoPtr->hwndToolTip,TTM_TRACKACTIVATE,(WPARAM)FALSE,(LPARAM)&ti);
2002 }
2003
2004 return 0;
2005}
2006
2007
2008static LRESULT TRACKBAR_Timer(HWND hwnd,WPARAM wParam,LPARAM lParam)
2009{
2010 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(hwnd);
2011 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
2012 POINT mousePoint;
2013 INT mousePlace,prevPos,newPos,vertical;
2014 DOUBLE mousePos;
2015
2016 GetCursorPos(&mousePoint);
2017 ScreenToClient(hwnd,&mousePoint);
2018
2019 vertical = dwStyle & TBS_VERT;
2020 if (vertical) mousePlace = mousePoint.y;
2021 else mousePlace = mousePoint.x;
2022
2023 mousePos = TRACKBAR_ConvertPlaceToPosition(infoPtr,mousePlace,vertical);
2024 prevPos = infoPtr->nPos;
2025
2026 if (mousePos > (INT)mousePos+0.5) newPos = mousePos+1;
2027 else newPos = mousePos;
2028 if (newPos == prevPos) return 0;
2029
2030 if (newPos > prevPos)
2031 { /* similar to VK_NEXT */
2032 infoPtr->nPos += infoPtr->nPageSize;
2033 if (infoPtr->nPos > infoPtr->nRangeMax) infoPtr->nPos = infoPtr->nRangeMax;
2034 if (prevPos != infoPtr->nPos) TRACKBAR_SendNotify(hwnd,TB_PAGEUP);
2035 } else
2036 { /* similar to VK_PRIOR */
2037 infoPtr->nPos -= infoPtr->nPageSize;
2038 if (infoPtr->nPos < infoPtr->nRangeMin) infoPtr->nPos = infoPtr->nRangeMin;
2039 if (prevPos != infoPtr->nPos) TRACKBAR_SendNotify(hwnd,TB_PAGEDOWN);
2040 }
2041
2042 if (prevPos != infoPtr->nPos)
2043 {
2044 infoPtr->flags |= TB_THUMBPOSCHANGED;
2045 TRACKBAR_UpdateThumbPosition(hwnd,prevPos,FALSE);
2046 }
2047
2048 return 0;
2049}
2050
2051static LRESULT
2052TRACKBAR_SetUnicodeFormat(HWND hwnd,WPARAM wParam,LPARAM lParam)
2053{
2054 //wParam = new format
2055
2056 return FALSE; //previous was no Unicode
2057}
2058
2059static LRESULT
2060TRACKBAR_CaptureChanged (HWND hwnd, WPARAM wParam, LPARAM lParam)
2061{
2062 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
2063
2064 if (infoPtr->flags & TB_DRAGPOSVALID)
2065 {
2066 int lastPos = infoPtr->nPos;
2067 infoPtr->nPos = infoPtr->dragPos;
2068 if (lastPos != infoPtr->nPos) TRACKBAR_UpdateThumbPosition(hwnd,lastPos,TRUE);
2069 }
2070
2071 infoPtr->flags &= ~ TB_DRAGPOSVALID;
2072
2073 if (infoPtr->flags & TB_SCROLL_MODE)
2074 {
2075 infoPtr->flags &= ~TB_SCROLL_MODE;
2076 KillTimer(hwnd,SCROLL_TIMER_ID);
2077 }
2078
2079 TRACKBAR_SendNotify(hwnd,TB_ENDTRACK);
2080 return 0;
2081}
2082
2083
2084static LRESULT
2085TRACKBAR_Paint (HWND hwnd, WPARAM wParam)
2086{
2087 HDC hdc;
2088 PAINTSTRUCT ps;
2089
2090 hdc = wParam == 0 ? BeginPaint(hwnd,&ps) : (HDC)wParam;
2091 TRACKBAR_Draw(hwnd,hdc);
2092 if (!wParam) EndPaint(hwnd,&ps);
2093 return 0;
2094}
2095
2096
2097static LRESULT
2098TRACKBAR_SetFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
2099{
2100 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
2101 HDC hdc;
2102 RECT rcClient;
2103
2104// TRACE (trackbar,"\n");
2105 if (!infoPtr->bFocus && IsWindowEnabled(hwnd))
2106 {
2107 infoPtr->bFocus = TRUE;
2108
2109 GetClientRect (hwnd,&rcClient);
2110 hdc = GetDC (hwnd);
2111 DrawFocusRect (hdc,&rcClient);
2112 ReleaseDC(hwnd,hdc);
2113
2114 }
2115 return 0;
2116}
2117
2118static LRESULT
2119TRACKBAR_KillFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
2120{
2121 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
2122 HDC hdc;
2123 RECT rcClient;
2124
2125// TRACE (trackbar,"\n");
2126
2127 infoPtr->flags &= ~TB_DRAG_MODE;
2128 if (infoPtr->bFocus && IsWindowEnabled(hwnd))
2129 {
2130 infoPtr->bFocus = FALSE;
2131
2132 GetClientRect(hwnd,&rcClient);
2133 hdc = GetDC (hwnd);
2134 DrawFocusRect(hdc,&rcClient); //XOR removes
2135 ReleaseDC(hwnd,hdc);
2136 }
2137
2138 return 0;
2139}
2140
2141static LRESULT
2142TRACKBAR_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
2143{
2144 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
2145
2146 TRACKBAR_CalcChannel (hwnd, infoPtr);
2147 TRACKBAR_AlignBuddies (hwnd, infoPtr);
2148
2149 return 0;
2150}
2151
2152
2153static BOOL
2154TRACKBAR_SendNotify (HWND hwnd, UINT code)
2155{
2156// TRACE (trackbar, "%x\n",code);
2157
2158 if (GetWindowLongA(hwnd, GWL_STYLE) & TBS_VERT)
2159 {
2160 return (BOOL)SendMessageA(GetParent(hwnd),WM_VSCROLL,(WPARAM)code,(LPARAM)hwnd);
2161 } else
2162 {
2163 return (BOOL)SendMessageA(GetParent(hwnd),WM_HSCROLL,(WPARAM)code,(LPARAM)hwnd);
2164 }
2165}
2166
2167
2168static LRESULT
2169TRACKBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
2170{
2171 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
2172 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
2173 SHORT clickPlace;
2174 DOUBLE dragPos;
2175
2176// TRACE (trackbar, "%x\n",wParam);
2177
2178 if (!(infoPtr->flags & TB_DRAG_MODE)) return TRUE;
2179
2180 if (dwStyle & TBS_VERT) clickPlace = (SHORT)HIWORD(lParam);
2181 else clickPlace = (SHORT)LOWORD(lParam);
2182
2183 dragPos = TRACKBAR_ConvertPlaceToPosition(infoPtr,clickPlace,dwStyle & TBS_VERT);
2184 if (dragPos > ((INT)dragPos)+0.5) infoPtr->dragPos = dragPos + 1;
2185 else infoPtr->dragPos = dragPos;
2186
2187 if (infoPtr->nPos == infoPtr->dragPos) return TRUE; //nothing changed
2188
2189 infoPtr->flags |= TB_DRAGPOSVALID;
2190
2191 TRACKBAR_UpdateThumbPosition(hwnd,infoPtr->nPos,FALSE); //infoPtr->nPos now set
2192
2193 TRACKBAR_SendNotify(hwnd,TB_THUMBTRACK | (infoPtr->nPos >> 16));
2194
2195 if (infoPtr->flags & TB_SHOW_TOOLTIP)
2196 {
2197 POINT pt;
2198 TTTOOLINFOA ti;
2199 char buf[80];
2200
2201 ti.cbSize = sizeof(TTTOOLINFOA);
2202 ti.hwnd = hwnd;
2203 ti.uId = 0;
2204 ti.hinst = 0;
2205 sprintf (buf,"%d",infoPtr->nPos);
2206 ti.lpszText = (LPSTR)buf;
2207
2208 SendMessageA(infoPtr->hwndToolTip,TTM_UPDATETIPTEXTA,0,(LPARAM)&ti);
2209 TRACKBAR_CalcToolTipPos(hwnd,dwStyle,infoPtr,&pt);
2210 SendMessageA(infoPtr->hwndToolTip,TTM_TRACKPOSITION,0,(LPARAM)MAKELPARAM(pt.x,pt.y));
2211 }
2212
2213 return 0;
2214}
2215
2216static LRESULT
2217TRACKBAR_Enable(HWND hwnd,WPARAM wParam,LPARAM lParam)
2218{
2219 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(hwnd);
2220 BOOL oldFocus = infoPtr->bFocus;
2221
2222 if (wParam) infoPtr->bFocus = (GetFocus() == hwnd);
2223 else infoPtr->bFocus = FALSE;
2224
2225 if (oldFocus != infoPtr->bFocus) TRACKBAR_Refresh(hwnd);
2226 else TRACKBAR_UpdateThumbPosition(hwnd,infoPtr->nPos,TRUE);
2227
2228 return 0;
2229}
2230
2231static LRESULT
2232TRACKBAR_KeyDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
2233{
2234 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(hwnd);
2235 INT pos;
2236
2237// TRACE (trackbar, "%x\n",wParam);
2238
2239 if (infoPtr->flags & TB_DRAG_MODE) return TRUE;
2240
2241 pos = infoPtr->nPos;
2242 switch (wParam) {
2243 case VK_LEFT:
2244 case VK_UP:
2245 if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
2246 infoPtr->nPos -= infoPtr->nLineSize;
2247 if (infoPtr->nPos < infoPtr->nRangeMin)
2248 infoPtr->nPos = infoPtr->nRangeMin;
2249 TRACKBAR_SendNotify(hwnd,TB_LINEUP);
2250 break;
2251 case VK_RIGHT:
2252 case VK_DOWN:
2253 if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
2254 infoPtr->nPos += infoPtr->nLineSize;
2255 if (infoPtr->nPos > infoPtr->nRangeMax)
2256 infoPtr->nPos = infoPtr->nRangeMax;
2257 TRACKBAR_SendNotify (hwnd, TB_LINEDOWN);
2258 break;
2259 case VK_NEXT:
2260 if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
2261 infoPtr->nPos += infoPtr->nPageSize;
2262 if (infoPtr->nPos > infoPtr->nRangeMax)
2263 infoPtr->nPos = infoPtr->nRangeMax;
2264 TRACKBAR_SendNotify (hwnd, TB_PAGEUP);
2265 break;
2266 case VK_PRIOR:
2267 if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
2268 infoPtr->nPos -= infoPtr->nPageSize;
2269 if (infoPtr->nPos < infoPtr->nRangeMin)
2270 infoPtr->nPos = infoPtr->nRangeMin;
2271 TRACKBAR_SendNotify (hwnd, TB_PAGEDOWN);
2272 break;
2273 case VK_HOME:
2274 if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
2275 infoPtr->nPos = infoPtr->nRangeMin;
2276 TRACKBAR_SendNotify (hwnd, TB_TOP);
2277 break;
2278 case VK_END:
2279 if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
2280 infoPtr->nPos = infoPtr->nRangeMax;
2281 TRACKBAR_SendNotify (hwnd, TB_BOTTOM);
2282 break;
2283 }
2284
2285 if (pos != infoPtr->nPos)
2286 {
2287 infoPtr->flags |= TB_THUMBPOSCHANGED;
2288 TRACKBAR_UpdateThumbPosition(hwnd,pos,FALSE);
2289 }
2290
2291 return TRUE;
2292}
2293
2294
2295static LRESULT
2296TRACKBAR_KeyUp (HWND hwnd, WPARAM wParam)
2297{
2298 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(hwnd);
2299
2300 if (infoPtr->flags & TB_DRAG_MODE) return TRUE;
2301
2302 switch (wParam) {
2303 case VK_LEFT:
2304 case VK_UP:
2305 case VK_RIGHT:
2306 case VK_DOWN:
2307 case VK_NEXT:
2308 case VK_PRIOR:
2309 case VK_HOME:
2310 case VK_END:
2311 TRACKBAR_SendNotify (hwnd, TB_ENDTRACK);
2312 }
2313 return TRUE;
2314}
2315
2316
2317static LRESULT WINAPI
2318TRACKBAR_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
2319{
2320 switch (uMsg)
2321 {
2322 case TBM_CLEARSEL:
2323 return TRACKBAR_ClearSel (hwnd, wParam, lParam);
2324
2325 case TBM_CLEARTICS:
2326 return TRACKBAR_ClearTics (hwnd, wParam, lParam);
2327
2328 case TBM_GETBUDDY:
2329 return TRACKBAR_GetBuddy (hwnd, wParam, lParam);
2330
2331 case TBM_GETCHANNELRECT:
2332 return TRACKBAR_GetChannelRect (hwnd, wParam, lParam);
2333
2334 case TBM_GETLINESIZE:
2335 return TRACKBAR_GetLineSize (hwnd, wParam, lParam);
2336
2337 case TBM_GETNUMTICS:
2338 return TRACKBAR_GetNumTics (hwnd, wParam, lParam);
2339
2340 case TBM_GETPAGESIZE:
2341 return TRACKBAR_GetPageSize (hwnd, wParam, lParam);
2342
2343 case TBM_GETPOS:
2344 return TRACKBAR_GetPos (hwnd, wParam, lParam);
2345
2346 case TBM_GETPTICS:
2347 return TRACKBAR_GetPTics (hwnd);
2348
2349 case TBM_GETRANGEMAX:
2350 return TRACKBAR_GetRangeMax (hwnd, wParam, lParam);
2351
2352 case TBM_GETRANGEMIN:
2353 return TRACKBAR_GetRangeMin (hwnd, wParam, lParam);
2354
2355 case TBM_GETSELEND:
2356 return TRACKBAR_GetSelEnd (hwnd, wParam, lParam);
2357
2358 case TBM_GETSELSTART:
2359 return TRACKBAR_GetSelStart (hwnd, wParam, lParam);
2360
2361 case TBM_GETTHUMBLENGTH:
2362 return TRACKBAR_GetThumbLength (hwnd, wParam, lParam);
2363
2364 case TBM_GETTHUMBRECT:
2365 return TRACKBAR_GetThumbRect (hwnd, wParam, lParam);
2366
2367 case TBM_GETTIC:
2368 return TRACKBAR_GetTic (hwnd, wParam, lParam);
2369
2370 case TBM_GETTICPOS:
2371 return TRACKBAR_GetTicPos (hwnd, wParam, lParam);
2372
2373 case TBM_GETTOOLTIPS:
2374 return TRACKBAR_GetToolTips (hwnd, wParam, lParam);
2375
2376 case TBM_GETUNICODEFORMAT:
2377 return TRACKBAR_GetUnicodeFormat(hwnd,wParam,lParam);
2378
2379 case TBM_SETBUDDY:
2380 return TRACKBAR_SetBuddy (hwnd, wParam, lParam);
2381
2382 case TBM_SETLINESIZE:
2383 return TRACKBAR_SetLineSize (hwnd, wParam, lParam);
2384
2385 case TBM_SETPAGESIZE:
2386 return TRACKBAR_SetPageSize (hwnd, wParam, lParam);
2387
2388 case TBM_SETPOS:
2389 return TRACKBAR_SetPos (hwnd, wParam, lParam);
2390
2391 case TBM_SETRANGE:
2392 return TRACKBAR_SetRange (hwnd, wParam, lParam);
2393
2394 case TBM_SETRANGEMAX:
2395 return TRACKBAR_SetRangeMax (hwnd, wParam, lParam);
2396
2397 case TBM_SETRANGEMIN:
2398 return TRACKBAR_SetRangeMin (hwnd, wParam, lParam);
2399
2400 case TBM_SETSEL:
2401 return TRACKBAR_SetSel (hwnd, wParam, lParam);
2402
2403 case TBM_SETSELEND:
2404 return TRACKBAR_SetSelEnd (hwnd, wParam, lParam);
2405
2406 case TBM_SETSELSTART:
2407 return TRACKBAR_SetSelStart (hwnd, wParam, lParam);
2408
2409 case TBM_SETTHUMBLENGTH:
2410 return TRACKBAR_SetThumbLength (hwnd, wParam, lParam);
2411
2412 case TBM_SETTIC:
2413 return TRACKBAR_SetTic (hwnd, wParam, lParam);
2414
2415 case TBM_SETTICFREQ:
2416 return TRACKBAR_SetTicFreq (hwnd, wParam);
2417
2418 case TBM_SETTIPSIDE:
2419 return TRACKBAR_SetTipSide (hwnd, wParam, lParam);
2420
2421 case TBM_SETTOOLTIPS:
2422 return TRACKBAR_SetToolTips (hwnd, wParam, lParam);
2423
2424 case TBM_SETUNICODEFORMAT:
2425 return TRACKBAR_SetUnicodeFormat(hwnd,wParam,lParam);
2426
2427 case WM_CAPTURECHANGED:
2428 return TRACKBAR_CaptureChanged (hwnd, wParam, lParam);
2429
2430 case WM_CREATE:
2431 return TRACKBAR_Create (hwnd, wParam, lParam);
2432
2433 case WM_DESTROY:
2434 return TRACKBAR_Destroy (hwnd, wParam, lParam);
2435
2436 case WM_ENABLE:
2437 return TRACKBAR_Enable(hwnd,wParam,lParam);
2438
2439 case WM_ERASEBKGND:
2440 return 1;
2441
2442 case WM_GETDLGCODE:
2443 return DLGC_WANTARROWS;
2444
2445 case WM_KEYDOWN:
2446 return TRACKBAR_KeyDown (hwnd, wParam, lParam);
2447
2448 case WM_KEYUP:
2449 return TRACKBAR_KeyUp (hwnd, wParam);
2450
2451 case WM_LBUTTONDOWN:
2452 return TRACKBAR_LButtonDown (hwnd, wParam, lParam);
2453
2454 case WM_LBUTTONUP:
2455 return TRACKBAR_LButtonUp (hwnd, wParam, lParam);
2456
2457 case WM_TIMER:
2458 return TRACKBAR_Timer(hwnd,wParam,lParam);
2459
2460 case WM_MOUSEMOVE:
2461 return TRACKBAR_MouseMove (hwnd, wParam, lParam);
2462
2463 case WM_PAINT:
2464 return TRACKBAR_Paint (hwnd, wParam);
2465
2466 case WM_SETFOCUS:
2467 return TRACKBAR_SetFocus (hwnd, wParam, lParam);
2468
2469 case WM_KILLFOCUS:
2470 return TRACKBAR_KillFocus (hwnd, wParam, lParam);
2471
2472 case WM_SIZE:
2473 return TRACKBAR_Size (hwnd, wParam, lParam);
2474
2475 case WM_WININICHANGE:
2476 return TRACKBAR_InitializeThumb (hwnd);
2477
2478 default:
2479// if (uMsg >= WM_USER)
2480// ERR (trackbar, "unknown msg %04x wp=%08x lp=%08lx\n",
2481// uMsg, wParam, lParam);
2482 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
2483 }
2484 return 0;
2485}
2486
2487
2488VOID
2489TRACKBAR_Register (VOID)
2490{
2491 WNDCLASSA wndClass;
2492
2493//SvL: Don't check this now
2494// if (GlobalFindAtomA (TRACKBAR_CLASSA)) return;
2495
2496 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
2497 wndClass.style = CS_GLOBALCLASS;
2498 wndClass.lpfnWndProc = (WNDPROC)TRACKBAR_WindowProc;
2499 wndClass.cbClsExtra = 0;
2500 wndClass.cbWndExtra = sizeof(TRACKBAR_INFO *);
2501 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
2502 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
2503 wndClass.lpszClassName = TRACKBAR_CLASSA;
2504
2505 RegisterClassA (&wndClass);
2506}
2507
2508
2509VOID
2510TRACKBAR_Unregister (VOID)
2511{
2512 if (GlobalFindAtomA (TRACKBAR_CLASSA))
2513 UnregisterClassA (TRACKBAR_CLASSA, (HINSTANCE)NULL);
2514}
2515
Note: See TracBrowser for help on using the repository browser.