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

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

bugs fixed

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