Added xxx_Unregister() functions to all common controls.
[wine] / dlls / comctl32 / trackbar.c
1 /*
2  * Trackbar control
3  *
4  * Copyright 1998 Eric Kohl <ekohl@abo.rhein-zeitung.de>
5  * Copyright 1998 Alex Priem <alexp@sci.kun.nl>
6  *
7  * NOTES
8
9  *
10  * TODO:
11  *   - Some messages.
12  *   - more display code.
13  *   - handle dragging slider better
14  *   - better tic handling.
15  *   - more notifications.
16  *   - tooltips
17  */
18
19 /* known bugs:
20
21         -TBM_SETRANGEMAX & TBM_SETRANGEMIN should only change the view of the
22    trackbar, not the actual amount of tics in the list.
23         -TBM_GETTIC & TBM_GETTICPOS shouldn't rely on infoPtr->tics being sorted.
24         -code currently only handles horizontal trackbars correct.
25         -TB_DRAGTIMER behaves wierd.
26 */
27
28
29
30 #include "windows.h"
31 #include "commctrl.h"
32 #include "trackbar.h"
33 #include "heap.h"
34 #include "win.h"
35 #include "debug.h"
36
37
38 #define TRACKBAR_GetInfoPtr(wndPtr) ((TRACKBAR_INFO *)wndPtr->wExtra[0])
39
40
41 /* Used by TRACKBAR_Refresh to find out which parts of the control 
42         need to be recalculated */
43
44 #define TB_THUMBPOSCHANGED      1
45 #define TB_THUMBSIZECHANGED 2
46 #define TB_THUMBCHANGED         3
47 #define TB_SELECTIONCHANGED 4
48 #define TB_DRAG_TIMER_SET       16
49 #define TB_DRAGPOSVALID         32
50
51
52 static BOOL32 TRACKBAR_SendNotify (WND *wndPtr, UINT32 code);
53
54 void TRACKBAR_RecalculateTics (TRACKBAR_INFO *infoPtr)
55
56 {
57     int i,tic,nrTics;
58
59         if (infoPtr->uTicFreq) 
60         nrTics=(infoPtr->nRangeMax - infoPtr->nRangeMin)/infoPtr->uTicFreq;
61         else {
62                 nrTics=0;
63                 HeapFree (SystemHeap,0,infoPtr->tics);
64                 infoPtr->tics=NULL;
65                 infoPtr->uNumTics=0;
66                 return;
67         }
68
69     if (nrTics!=infoPtr->uNumTics) {
70         infoPtr->tics=HeapReAlloc( SystemHeap, 0, infoPtr->tics,
71                            (nrTics+1)*sizeof (DWORD));
72         infoPtr->uNumTics=nrTics;
73     }
74         infoPtr->uNumTics=nrTics;
75     tic=infoPtr->nRangeMin+infoPtr->uTicFreq;
76     for (i=0; i<nrTics; i++,tic+=infoPtr->uTicFreq)
77                infoPtr->tics[i]=tic;
78 }
79
80
81 /* converts from physical (mouse) position to logical position 
82    (in range of trackbar) */
83
84 static inline INT32
85 TRACKBAR_ConvertPlaceToPosition (TRACKBAR_INFO *infoPtr, int place) 
86 {
87         double range,width,pos;
88
89     range=infoPtr->nRangeMax - infoPtr->nRangeMin;
90     width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
91         pos=(range*(place - infoPtr->rcChannel.left)) / width;
92         
93     TRACE (trackbar,"%.2f\n",pos);
94     return pos;
95 }
96
97
98
99 static VOID
100 TRACKBAR_CalcChannel (WND *wndPtr, TRACKBAR_INFO *infoPtr)
101 {
102     INT32 cyChannel;
103         RECT32 lpRect,*channel = & infoPtr->rcChannel;
104
105     GetClientRect32 (wndPtr->hwndSelf, &lpRect);
106
107     if (wndPtr->dwStyle & TBS_ENABLESELRANGE)
108                 cyChannel = MAX(infoPtr->uThumbLen - 8, 4);
109     else
110                 cyChannel = 4;
111
112     if (wndPtr->dwStyle & TBS_VERT) {
113                 channel->top    = lpRect.top + 8;
114                 channel->bottom = lpRect.bottom - 8;
115
116                         if (wndPtr->dwStyle & TBS_BOTH) {
117                         channel->left  = (lpRect.bottom - cyChannel) / 2;
118                         channel->right = (lpRect.bottom + cyChannel) / 2;
119                         }
120                         else if (wndPtr->dwStyle & TBS_LEFT) {
121                                 channel->left  = lpRect.left + 10;
122                                 channel->right = channel->left + cyChannel;
123                                 }
124                                 else { /* TBS_RIGHT */
125                                 channel->right = lpRect.right - 10;
126                                 channel->left  = channel->right - cyChannel;
127                                 }
128         }
129         else {
130                         channel->left = lpRect.left + 8;
131                         channel->right = lpRect.right - 8;
132                         if (wndPtr->dwStyle & TBS_BOTH) {
133                         channel->top            = (lpRect.bottom - cyChannel) / 2;
134                         channel->bottom         = (lpRect.bottom + cyChannel) / 2;
135                         }
136                         else if (wndPtr->dwStyle & TBS_TOP) {
137                                 channel->top    = lpRect.top + 10;
138                                 channel->bottom = channel->top + cyChannel;
139                                 }
140                                 else { /* TBS_BOTTOM */
141                                 channel->bottom = lpRect.bottom - 10;
142                                 channel->top    = channel->bottom - cyChannel;
143                                 }
144         }
145 }
146
147 static VOID
148 TRACKBAR_CalcThumb (WND *wndPtr, TRACKBAR_INFO *infoPtr)
149
150 {
151         RECT32 *thumb;
152         int range, width;
153         
154         thumb=&infoPtr->rcThumb;
155         range=infoPtr->nRangeMax - infoPtr->nRangeMin;
156     width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
157
158         thumb->left  = infoPtr->rcChannel.left +
159                                         (width*infoPtr->nPos)/range - 5;
160         thumb->right  = thumb->left + infoPtr->uThumbLen/3;
161         thumb->top        = infoPtr->rcChannel.top - 1;
162         thumb->bottom = infoPtr->rcChannel.top + infoPtr->uThumbLen - 8;
163 }
164
165 static VOID
166 TRACKBAR_CalcSelection (WND *wndPtr, TRACKBAR_INFO *infoPtr)
167 {
168         RECT32 *selection;
169         int range, width;
170
171         selection= & infoPtr->rcSelection;
172         range=infoPtr->nRangeMax - infoPtr->nRangeMin;
173         width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
174
175         if (range > 0) {
176                 selection->left   = infoPtr->rcChannel.left +
177                                                 (width*infoPtr->nSelMin)/range;
178                 selection->right  = infoPtr->rcChannel.left +
179                                                 (width*infoPtr->nSelMax)/range;
180                 selection->top    = infoPtr->rcChannel.top + 2;
181                 selection->bottom = infoPtr->rcChannel.bottom - 2;
182         }
183         else
184                 SetRectEmpty32 (selection);
185 }
186
187
188
189 static VOID
190 TRACKBAR_Refresh (WND *wndPtr, HDC32 hdc)
191 {
192         TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
193         RECT32 rcClient, rcChannel, rcSelection;
194         HBRUSH32 hBrush = CreateSolidBrush32 (infoPtr->clrBk);
195         INT32 x,y,tic;
196         int i,range,width;
197
198     GetClientRect32 (wndPtr->hwndSelf, &rcClient);
199         hBrush = CreateSolidBrush32 (infoPtr->clrBk);
200         FillRect32 (hdc, &rcClient, hBrush);
201     DeleteObject32 (hBrush);
202
203         
204         
205         if (infoPtr->flags & TB_THUMBCHANGED) {
206                 TRACKBAR_CalcThumb      (wndPtr, infoPtr);
207                 if (infoPtr->flags & TB_THUMBSIZECHANGED) 
208                         TRACKBAR_CalcChannel (wndPtr, infoPtr);
209         }
210         if (infoPtr->flags & TB_SELECTIONCHANGED)
211                 TRACKBAR_CalcSelection (wndPtr, infoPtr);
212         infoPtr->flags &= ~ (TB_THUMBCHANGED | TB_SELECTIONCHANGED);
213
214     /* draw channel */
215
216     rcChannel = infoPtr->rcChannel;
217     rcSelection= infoPtr->rcSelection;
218     DrawEdge32 (hdc, &rcChannel, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
219
220     if (wndPtr->dwStyle & TBS_ENABLESELRANGE) {          /* fill the channel */
221                 HBRUSH32 hbr = CreateSolidBrush32 (RGB(255,255,255));
222                 FillRect32 (hdc, &rcChannel, hbr);
223                 if (rcSelection.left!=rcSelection.right) {
224                         hbr=CreateSolidBrush32 (COLOR_HIGHLIGHT); 
225                         FillRect32 (hdc, &rcSelection, hbr);
226                 }
227                 DeleteObject32 (hbr);
228     }
229
230
231     /* draw tics */
232
233     if (!(wndPtr->dwStyle & TBS_NOTICKS)) {
234                 COLORREF clrTic=GetSysColor32 (COLOR_3DDKSHADOW);
235
236         x=rcChannel.left;
237         y=rcChannel.bottom+2;
238                 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
239                 width=rcChannel.right - rcChannel.left;
240         if (wndPtr->dwStyle & TBS_VERT) { /* swap x/y */
241         }
242
243     if ((wndPtr->dwStyle & TBS_TOP) || (wndPtr->dwStyle & TBS_BOTH)) {
244         /* draw upper tics */
245      }
246
247 //    if (!((wndPtr->dwStyle & TBS_TOP) || (!(wndPtr->dwStyle & TBS_BOTH)))) 
248         /* draw lower tics */
249 //    if (wndPtr->dwStyle & TBS_AUTOTICKS) 
250         for (i=0; i<infoPtr->uNumTics; i++) {
251                         tic=infoPtr->tics[i];
252                         if ((tic>infoPtr->nRangeMin) && (tic<infoPtr->nRangeMax)) {
253                 x=rcChannel.left + (width*tic)/range;
254                 SetPixel32 (hdc, x,y+5, clrTic);
255                 SetPixel32 (hdc, x,y+6, clrTic);
256                 SetPixel32 (hdc, x,y+7, clrTic);
257                         }
258           }
259            if ((wndPtr->dwStyle & TBS_ENABLESELRANGE) && 
260                    (rcSelection.left!=rcSelection.right)) {
261                         x=rcChannel.left + (width*infoPtr->nSelMin)/range - 1;
262                 SetPixel32 (hdc, x,y+6, clrTic);
263                 SetPixel32 (hdc, x,y+7, clrTic);
264                         x=rcChannel.left + (width*infoPtr->nSelMax)/range + 1; 
265                 SetPixel32 (hdc, x,y+6, clrTic);
266                 SetPixel32 (hdc, x,y+7, clrTic);
267                 }
268                 
269            x=rcChannel.left;
270        SetPixel32 (hdc, x,y+5, clrTic);
271        SetPixel32 (hdc, x,y+6, clrTic);
272        SetPixel32 (hdc, x,y+7, clrTic);
273        SetPixel32 (hdc, x,y+8, clrTic);
274            x=rcChannel.right;
275        SetPixel32 (hdc, x,y+5, clrTic);
276        SetPixel32 (hdc, x,y+6, clrTic);
277        SetPixel32 (hdc, x,y+7, clrTic);
278        SetPixel32 (hdc, x,y+8, clrTic);
279 //     }
280     }
281
282  
283      /* draw thumb */
284
285      if (!(wndPtr->dwStyle & TBS_NOTHUMB)) {
286         HBRUSH32 hbr = CreateSolidBrush32 (COLOR_BACKGROUND);
287                 RECT32 thumb = infoPtr->rcThumb;
288
289                 SelectObject32 (hdc, hbr);
290                 
291                 if (wndPtr->dwStyle & TBS_BOTH) {
292                 FillRect32 (hdc, &thumb, hbr);
293                         DrawEdge32 (hdc, &thumb, EDGE_RAISED, BF_TOPLEFT);
294                 } else {
295
296                 POINT32 points[6];
297                 RECT32 triangle;        /* for correct shadows of thumb */
298
299                         /* first, fill the thumb */
300                 
301                 SetPolyFillMode32 (hdc,WINDING);
302                 points[0].x=thumb.left;
303                 points[0].y=thumb.top;
304                 points[1].x=thumb.right - 1;
305                 points[1].y=thumb.top;
306                 points[2].x=thumb.right - 1;
307                 points[2].y=thumb.bottom -2;
308                 points[3].x=(thumb.right + thumb.left-1)/2;
309                 points[3].y=thumb.bottom+4;
310                 points[4].x=thumb.left;
311                 points[4].y=thumb.bottom -2;
312                 points[5].x=points[0].x;
313                 points[5].y=points[0].y;
314                 Polygon32 (hdc, points, 6);
315                 DrawEdge32 (hdc, &thumb, EDGE_RAISED, BF_TOPLEFT);
316 //              DrawEdge32 (hdc, &thumb, EDGE_SUNKEN, BF_BOTTOMRIGHT);
317
318                         /* draw notch */
319
320                 triangle.right = thumb.right+5;
321                 triangle.left  = points[3].x+5;
322                 triangle.top   = thumb.bottom +5;
323                 triangle.bottom= thumb.bottom +1;
324                 DrawEdge32 (hdc, &triangle, EDGE_SUNKEN, BF_DIAGONAL | BF_TOP | BF_RIGHT);
325                 triangle.left  = thumb.left+6;
326                 triangle.right = points[3].x+6;
327                 DrawEdge32 (hdc, &triangle, EDGE_RAISED, BF_DIAGONAL | BF_TOP | BF_LEFT);
328                 }
329                 DeleteObject32 (hbr);
330      }
331
332     if (infoPtr->bFocus)
333                 DrawFocusRect32 (hdc, &rcClient);
334 }
335
336
337
338
339 static VOID
340 TRACKBAR_AlignBuddies (WND *wndPtr, TRACKBAR_INFO *infoPtr)
341 {
342     HWND32 hwndParent = GetParent32 (wndPtr->hwndSelf);
343     RECT32 rcSelf, rcBuddy;
344     INT32 x, y;
345
346     GetWindowRect32 (wndPtr->hwndSelf, &rcSelf);
347     MapWindowPoints32 (HWND_DESKTOP, hwndParent, (LPPOINT32)&rcSelf, 2);
348
349     /* align buddy left or above */
350     if (infoPtr->hwndBuddyLA) {
351         GetWindowRect32 (infoPtr->hwndBuddyLA, &rcBuddy);
352         MapWindowPoints32 (HWND_DESKTOP, hwndParent, (LPPOINT32)&rcBuddy, 2);
353
354         if (wndPtr->dwStyle & TBS_VERT) {
355             x = (infoPtr->rcChannel.right + infoPtr->rcChannel.left) / 2 -
356                 (rcBuddy.right - rcBuddy.left) / 2 + rcSelf.left;
357             y = rcSelf.top - (rcBuddy.bottom - rcBuddy.top);
358         }
359         else {
360             x = rcSelf.left - (rcBuddy.right - rcBuddy.left);
361             y = (infoPtr->rcChannel.bottom + infoPtr->rcChannel.top) / 2 -
362                 (rcBuddy.bottom - rcBuddy.top) / 2 + rcSelf.top;
363         }
364
365         SetWindowPos32 (infoPtr->hwndBuddyLA, 0, x, y, 0, 0,
366                         SWP_NOZORDER | SWP_NOSIZE);
367     }
368
369
370     /* align buddy right or below */
371     if (infoPtr->hwndBuddyRB) {
372         GetWindowRect32 (infoPtr->hwndBuddyRB, &rcBuddy);
373         MapWindowPoints32 (HWND_DESKTOP, hwndParent, (LPPOINT32)&rcBuddy, 2);
374
375         if (wndPtr->dwStyle & TBS_VERT) {
376             x = (infoPtr->rcChannel.right + infoPtr->rcChannel.left) / 2 -
377                 (rcBuddy.right - rcBuddy.left) / 2 + rcSelf.left;
378             y = rcSelf.bottom;
379         }
380         else {
381             x = rcSelf.right;
382             y = (infoPtr->rcChannel.bottom + infoPtr->rcChannel.top) / 2 -
383                 (rcBuddy.bottom - rcBuddy.top) / 2 + rcSelf.top;
384         }
385         SetWindowPos32 (infoPtr->hwndBuddyRB, 0, x, y, 0, 0,
386                         SWP_NOZORDER | SWP_NOSIZE);
387     }
388 }
389
390
391 static LRESULT
392 TRACKBAR_ClearSel (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
393 {
394     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
395
396     infoPtr->nSelMin = 0;
397     infoPtr->nSelMax = 0;
398         infoPtr->flags |=TB_SELECTIONCHANGED;
399
400     if ((BOOL32)wParam) {
401                 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
402                 TRACKBAR_Refresh (wndPtr, hdc);
403                 ReleaseDC32 (wndPtr->hwndSelf, hdc);
404     }
405
406     return 0;
407 }
408
409
410 static LRESULT
411 TRACKBAR_ClearTics (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
412 {
413     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
414
415     if (infoPtr->tics) {
416                 HeapFree (GetProcessHeap (), 0, infoPtr->tics);
417                 infoPtr->tics = NULL;
418                 infoPtr->uNumTics = 0;
419     }
420
421     if (wParam) {
422                 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
423                 TRACKBAR_Refresh (wndPtr, hdc);
424                 ReleaseDC32 (wndPtr->hwndSelf, hdc);
425     }
426
427     return 0;
428 }
429
430
431 static LRESULT
432 TRACKBAR_GetBuddy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
433 {
434     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
435
436     if (wParam)          /* buddy is left or above */
437                 return (LRESULT)infoPtr->hwndBuddyLA;
438
439     /* buddy is right or below */
440     return (LRESULT) infoPtr->hwndBuddyRB;
441 }
442
443
444 static LRESULT
445 TRACKBAR_GetChannelRect (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
446 {
447     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
448     LPRECT32 lprc = (LPRECT32)lParam;
449
450     if (lprc == NULL)
451                 return 0;
452
453     lprc->left   = infoPtr->rcChannel.left;
454     lprc->right  = infoPtr->rcChannel.right;
455     lprc->bottom = infoPtr->rcChannel.bottom;
456     lprc->top    = infoPtr->rcChannel.top;
457
458     return 0;
459 }
460
461
462 static LRESULT
463 TRACKBAR_GetLineSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
464 {
465     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
466
467     return infoPtr->nLineSize;
468 }
469
470
471 static LRESULT
472 TRACKBAR_GetNumTics (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
473 {
474     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
475
476     if (wndPtr->dwStyle & TBS_NOTICKS)
477                 return 0;
478
479     return infoPtr->uNumTics+2;
480 }
481
482
483 static LRESULT
484 TRACKBAR_GetPageSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
485 {
486     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
487
488     return infoPtr->nPageSize;
489 }
490
491
492 static LRESULT
493 TRACKBAR_GetPos (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
494 {
495     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
496
497     return infoPtr->nPos;
498 }
499
500
501
502
503 static LRESULT
504 TRACKBAR_GetRangeMax (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
505 {
506     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
507
508     return infoPtr->nRangeMax;
509 }
510
511
512 static LRESULT
513 TRACKBAR_GetRangeMin (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
514 {
515     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
516
517     return infoPtr->nRangeMin;
518 }
519
520
521 static LRESULT
522 TRACKBAR_GetSelEnd (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
523 {
524     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
525
526     return infoPtr->nSelMax;
527 }
528
529
530 static LRESULT
531 TRACKBAR_GetSelStart (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
532 {
533     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
534
535     return infoPtr->nSelMin;
536 }
537
538
539 static LRESULT
540 TRACKBAR_GetThumbLength (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
541 {
542     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
543
544     return infoPtr->uThumbLen;
545 }
546
547 static LRESULT
548 TRACKBAR_GetPTics (WND *wndPtr)
549 {
550     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
551     
552    return (LRESULT) infoPtr->tics;
553 }
554
555 static LRESULT
556 TRACKBAR_GetThumbRect (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
557 {
558     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
559     LPRECT32 lprc = (LPRECT32)lParam;
560     
561     if (lprc == NULL)
562                 return 0; 
563    
564     lprc->left   = infoPtr->rcThumb.left;
565     lprc->right  = infoPtr->rcThumb.right;
566     lprc->bottom = infoPtr->rcThumb.bottom;
567     lprc->top    = infoPtr->rcThumb.top;
568    
569     return 0;
570 }  
571
572
573
574
575
576 static LRESULT
577 TRACKBAR_GetTic (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
578
579 {
580  TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
581  INT32 iTic;
582
583  iTic=(INT32) wParam;
584  if ((iTic<0) || (iTic>infoPtr->uNumTics)) 
585         return -1;
586
587  return (LRESULT) infoPtr->tics[iTic];
588
589 }
590
591
592 static LRESULT
593 TRACKBAR_GetTicPos (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
594
595 {
596  TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
597  INT32 iTic, range, width, pos;
598  
599
600  iTic=(INT32 ) wParam;
601  if ((iTic<0) || (iTic>infoPtr->uNumTics)) 
602         return -1;
603
604  range=infoPtr->nRangeMax - infoPtr->nRangeMin;
605  width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
606  pos=infoPtr->rcChannel.left + (width * infoPtr->tics[iTic]) / range;
607
608
609  return (LRESULT) pos;
610 }
611
612 static LRESULT
613 TRACKBAR_GetToolTips (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
614 {
615     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
616
617     if (wndPtr->dwStyle & TBS_TOOLTIPS)
618                 return (LRESULT)infoPtr->hwndToolTip;
619     return 0;
620 }
621
622
623 //      case TBM_GETUNICODEFORMAT:
624
625
626 static LRESULT
627 TRACKBAR_SetBuddy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
628 {
629     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
630     HWND32 hwndTemp;
631
632     if (wParam) {
633         /* buddy is left or above */
634         hwndTemp = infoPtr->hwndBuddyLA;
635         infoPtr->hwndBuddyLA = (HWND32)lParam;
636
637         FIXME (trackbar, "move buddy!\n");
638     }
639     else {
640                 /* buddy is right or below */
641                 hwndTemp = infoPtr->hwndBuddyRB;
642                 infoPtr->hwndBuddyRB = (HWND32)lParam;
643
644                 FIXME (trackbar, "move buddy!\n");
645     }
646
647     TRACKBAR_AlignBuddies (wndPtr, infoPtr);
648
649     return (LRESULT)hwndTemp;
650 }
651
652
653 static LRESULT
654 TRACKBAR_SetLineSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
655 {
656     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
657     INT32 nTemp = infoPtr->nLineSize;
658
659     infoPtr->nLineSize = (INT32)lParam;
660
661     return nTemp;
662 }
663
664
665 static LRESULT
666 TRACKBAR_SetPageSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
667 {
668     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
669     INT32 nTemp = infoPtr->nPageSize;
670
671     infoPtr->nPageSize = (INT32)lParam;
672
673     return nTemp;
674 }
675
676
677 static LRESULT
678 TRACKBAR_SetPos (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
679 {
680     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
681
682     infoPtr->nPos = (INT32)HIWORD(lParam);
683
684     if (infoPtr->nPos < infoPtr->nRangeMin)
685         infoPtr->nPos = infoPtr->nRangeMin;
686
687     if (infoPtr->nPos > infoPtr->nRangeMax)
688         infoPtr->nPos = infoPtr->nRangeMax;
689         infoPtr->flags |=TB_THUMBPOSCHANGED;
690
691     if (wParam) {
692                 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
693                 TRACKBAR_Refresh (wndPtr, hdc);
694                 ReleaseDC32 (wndPtr->hwndSelf, hdc);
695     }
696
697     return 0;
698 }
699
700
701 static LRESULT
702 TRACKBAR_SetRange (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
703 {
704     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
705     infoPtr->nRangeMin = (INT32)LOWORD(lParam);
706     infoPtr->nRangeMax = (INT32)HIWORD(lParam);
707
708     if (infoPtr->nPos < infoPtr->nRangeMin) {
709                 infoPtr->nPos = infoPtr->nRangeMin;
710                 infoPtr->flags |=TB_THUMBPOSCHANGED;
711         }
712
713     if (infoPtr->nPos > infoPtr->nRangeMax) {
714                 infoPtr->nPos = infoPtr->nRangeMax;
715                 infoPtr->flags |=TB_THUMBPOSCHANGED;
716         }
717
718         infoPtr->nPageSize=(infoPtr->nRangeMax -  infoPtr->nRangeMin)/5;
719         TRACKBAR_RecalculateTics (infoPtr);
720
721     if (wParam) {
722                 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
723                 TRACKBAR_Refresh (wndPtr, hdc);
724                 ReleaseDC32 (wndPtr->hwndSelf, hdc);
725     }
726
727     return 0;
728 }
729
730
731 static LRESULT
732 TRACKBAR_SetRangeMax (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
733 {
734     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
735
736     infoPtr->nRangeMax = (INT32)lParam;
737     if (infoPtr->nPos > infoPtr->nRangeMax) {
738                 infoPtr->nPos = infoPtr->nRangeMax;
739                 infoPtr->flags |=TB_THUMBPOSCHANGED;
740         }
741
742         infoPtr->nPageSize=(infoPtr->nRangeMax -  infoPtr->nRangeMin)/5;
743         TRACKBAR_RecalculateTics (infoPtr);
744
745     if (wParam) {
746                 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
747                 TRACKBAR_Refresh (wndPtr, hdc);
748                 ReleaseDC32 (wndPtr->hwndSelf, hdc);
749     }
750
751     return 0;
752 }
753
754
755 static LRESULT
756 TRACKBAR_SetRangeMin (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
757 {
758     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
759
760     infoPtr->nRangeMin = (INT32)lParam;
761     if (infoPtr->nPos < infoPtr->nRangeMin) {
762                 infoPtr->nPos = infoPtr->nRangeMin;
763                 infoPtr->flags |=TB_THUMBPOSCHANGED;
764         }
765
766         infoPtr->nPageSize=(infoPtr->nRangeMax -  infoPtr->nRangeMin)/5;
767         TRACKBAR_RecalculateTics (infoPtr);
768
769     if (wParam) {
770                 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
771                 TRACKBAR_Refresh (wndPtr, hdc);
772                 ReleaseDC32 (wndPtr->hwndSelf, hdc);
773     }
774
775     return 0;
776 }
777
778 static LRESULT
779 TRACKBAR_SetTicFreq (WND *wndPtr, WPARAM32 wParam)
780 {
781     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
782         HDC32 hdc;
783         
784     if (wndPtr->dwStyle & TBS_AUTOTICKS) 
785                 infoPtr->uTicFreq=(UINT32) wParam; 
786         
787         TRACKBAR_RecalculateTics (infoPtr);
788
789         hdc = GetDC32 (wndPtr->hwndSelf);
790     TRACKBAR_Refresh (wndPtr, hdc);
791     ReleaseDC32 (wndPtr->hwndSelf, hdc);
792         return 0;
793 }   
794
795
796 static LRESULT
797 TRACKBAR_SetSel (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
798 {
799     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
800
801     infoPtr->nSelMin = (INT32)LOWORD(lParam);
802     infoPtr->nSelMax = (INT32)HIWORD(lParam);
803         infoPtr->flags |=TB_SELECTIONCHANGED;
804
805     if (!wndPtr->dwStyle & TBS_ENABLESELRANGE)
806                 return 0;
807
808     if (infoPtr->nSelMin < infoPtr->nRangeMin)
809                 infoPtr->nSelMin = infoPtr->nRangeMin;
810     if (infoPtr->nSelMax > infoPtr->nRangeMax)
811                 infoPtr->nSelMax = infoPtr->nRangeMax;
812
813     if (wParam) {
814                 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
815                 TRACKBAR_Refresh (wndPtr, hdc);
816                 ReleaseDC32 (wndPtr->hwndSelf, hdc);
817     }
818
819     return 0;
820 }
821
822
823 static LRESULT
824 TRACKBAR_SetSelEnd (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
825 {
826     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
827
828     if (!wndPtr->dwStyle & TBS_ENABLESELRANGE)
829         return 0;
830
831     infoPtr->nSelMax = (INT32)lParam;
832         infoPtr->flags  |=TB_SELECTIONCHANGED;
833         
834     if (infoPtr->nSelMax > infoPtr->nRangeMax)
835                 infoPtr->nSelMax = infoPtr->nRangeMax;
836
837     if (wParam) {
838                 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
839                 TRACKBAR_Refresh (wndPtr, hdc);
840                 ReleaseDC32 (wndPtr->hwndSelf, hdc);
841     }
842
843     return 0;
844 }
845
846
847 static LRESULT
848 TRACKBAR_SetSelStart (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
849 {
850     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
851
852     if (!wndPtr->dwStyle & TBS_ENABLESELRANGE)
853         return 0;
854
855     infoPtr->nSelMin = (INT32)lParam;
856         infoPtr->flags  |=TB_SELECTIONCHANGED;
857     if (infoPtr->nSelMin < infoPtr->nRangeMin)
858                 infoPtr->nSelMin = infoPtr->nRangeMin;
859
860     if (wParam) {
861                 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
862                 TRACKBAR_Refresh (wndPtr, hdc);
863                 ReleaseDC32 (wndPtr->hwndSelf, hdc);
864     }
865
866     return 0;
867 }
868
869
870 static LRESULT
871 TRACKBAR_SetThumbLength (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
872 {
873     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
874         HDC32 hdc;
875
876     if (wndPtr->dwStyle & TBS_FIXEDLENGTH)
877                 infoPtr->uThumbLen = (UINT32)wParam;
878
879         hdc = GetDC32 (wndPtr->hwndSelf);
880         infoPtr->flags |=TB_THUMBSIZECHANGED;
881         TRACKBAR_Refresh (wndPtr, hdc);
882         ReleaseDC32 (wndPtr->hwndSelf, hdc);
883         
884     return 0;
885 }
886
887
888 static LRESULT
889 TRACKBAR_SetTic (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
890 {
891     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
892     INT32 nPos = (INT32)lParam;
893         HDC32 hdc;
894
895     if ((nPos < infoPtr->nRangeMin) || (nPos> infoPtr->nRangeMax))
896                 return FALSE;
897
898         infoPtr->uNumTics++;
899     infoPtr->tics=HeapReAlloc( SystemHeap, 0, infoPtr->tics,
900                            (infoPtr->uNumTics)*sizeof (DWORD));
901     infoPtr->tics[infoPtr->uNumTics-1]=nPos;
902
903         hdc = GetDC32 (wndPtr->hwndSelf);
904     TRACKBAR_Refresh (wndPtr, hdc);
905     ReleaseDC32 (wndPtr->hwndSelf, hdc);
906
907     return TRUE;
908 }
909
910
911
912
913 static LRESULT
914 TRACKBAR_SetTipSide (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
915 {
916     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
917     INT32 fTemp = infoPtr->fLocation;
918
919     infoPtr->fLocation = (INT32)wParam;
920         
921     return fTemp;
922 }
923
924
925 static LRESULT
926 TRACKBAR_SetToolTips (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
927 {
928     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
929
930     infoPtr->hwndToolTip = (HWND32)wParam;
931
932     return 0;
933 }
934
935
936 //      case TBM_SETUNICODEFORMAT:
937
938
939 static LRESULT
940 TRACKBAR_InitializeThumb (WND *wndPtr)
941 {
942     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
943
944     infoPtr->uThumbLen = 23;   /* initial thumb length */
945
946         TRACKBAR_CalcChannel (wndPtr,infoPtr);
947         TRACKBAR_CalcThumb (wndPtr, infoPtr);
948         infoPtr->flags &= ~TB_SELECTIONCHANGED;
949
950         return 0;
951 }
952
953
954 static LRESULT
955 TRACKBAR_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
956 {
957     TRACKBAR_INFO *infoPtr;
958
959     infoPtr = (TRACKBAR_INFO *)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY,
960                                           sizeof(TRACKBAR_INFO));
961     wndPtr->wExtra[0] = (DWORD)infoPtr;
962
963
964     infoPtr->nRangeMin = 0;                      /* default values */
965     infoPtr->nRangeMax = 100;
966     infoPtr->nLineSize = 1;
967     infoPtr->nPageSize = 20;
968     infoPtr->nSelMin   = 0;
969     infoPtr->nSelMax   = 0;
970     infoPtr->nPos      = 0;
971
972     infoPtr->uNumTics  = 0;    /* start and end tic are not included in count*/
973         infoPtr->uTicFreq  = 1;
974         infoPtr->tics      = NULL;
975         infoPtr->clrBk     = GetSysColor32 (COLOR_BACKGROUND);
976
977         TRACKBAR_InitializeThumb (wndPtr);
978         
979     return 0;
980 }
981
982
983 static LRESULT
984 TRACKBAR_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
985 {
986     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
987
988         if (infoPtr->flags & TB_DRAG_TIMER_SET) 
989         KillTimer32 (wndPtr->hwndSelf, TB_DRAG_TIMER);
990
991     HeapFree (GetProcessHeap (), 0, infoPtr);
992     return 0;
993 }
994
995
996 static LRESULT
997 TRACKBAR_KillFocus (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
998 {
999     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1000     HDC32 hdc;
1001
1002         TRACE (trackbar,"\n");
1003
1004         if (infoPtr->flags & TB_DRAG_TIMER_SET) 
1005                  KillTimer32 (wndPtr->hwndSelf, TB_DRAG_TIMER);
1006
1007     infoPtr->bFocus = FALSE;
1008     hdc = GetDC32 (wndPtr->hwndSelf);
1009     TRACKBAR_Refresh (wndPtr, hdc);
1010     ReleaseDC32 (wndPtr->hwndSelf, hdc);
1011     InvalidateRect32 (wndPtr->hwndSelf, NULL, TRUE);
1012
1013     return 0;
1014 }
1015
1016
1017 static LRESULT
1018 TRACKBAR_LButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1019 {
1020     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1021         int clickPlace,prevPos,clickPos;
1022         
1023     SetFocus32 (wndPtr->hwndSelf);
1024
1025         clickPlace=(INT32)LOWORD(lParam);
1026
1027         if ((clickPlace>infoPtr->rcThumb.left) && 
1028                 (clickPlace<infoPtr->rcThumb.right)) {
1029                 SetTimer32 (wndPtr->hwndSelf, TB_DRAG_TIMER, TB_DRAG_DELAY, 0);
1030                 infoPtr->flags |= TB_DRAG_TIMER_SET;
1031                 return 0;
1032         }
1033
1034         clickPos=TRACKBAR_ConvertPlaceToPosition (infoPtr, clickPlace);
1035         prevPos = infoPtr->nPos;
1036
1037         if (clickPos > prevPos) {                                       /* similar to VK_NEXT */
1038                 infoPtr->nPos += infoPtr->nPageSize;
1039         if (infoPtr->nPos > infoPtr->nRangeMax)
1040                         infoPtr->nPos = infoPtr->nRangeMax;
1041                 TRACKBAR_SendNotify (wndPtr, TB_PAGEUP);  
1042         } else {
1043         infoPtr->nPos -= infoPtr->nPageSize;    /* similar to VK_PRIOR */
1044         if (infoPtr->nPos < infoPtr->nRangeMin)
1045             infoPtr->nPos = infoPtr->nRangeMin;
1046         TRACKBAR_SendNotify (wndPtr, TB_PAGEDOWN);
1047         }
1048
1049         if (prevPos!=infoPtr->nPos) {
1050         HDC32 hdc;
1051
1052         hdc=GetDC32 (wndPtr->hwndSelf);
1053                 infoPtr->flags |=TB_THUMBPOSCHANGED;
1054         TRACKBAR_Refresh (wndPtr, hdc);
1055         ReleaseDC32 (wndPtr->hwndSelf, hdc);
1056         }
1057         
1058     return 0;
1059 }
1060
1061 static LRESULT
1062 TRACKBAR_LButtonUp (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1063 {
1064     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1065
1066         if (infoPtr->flags & TB_DRAG_TIMER_SET) {
1067                 KillTimer32 (wndPtr->hwndSelf, TB_DRAG_TIMER);
1068         infoPtr->flags &= ~TB_DRAG_TIMER_SET;
1069         }
1070
1071         TRACKBAR_SendNotify (wndPtr, TB_ENDTRACK);
1072
1073     return 0;
1074 }
1075
1076 static LRESULT
1077 TRACKBAR_CaptureChanged (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1078 {
1079     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1080         
1081         if (infoPtr->flags & TB_DRAG_TIMER_SET) 
1082                  KillTimer32 (wndPtr->hwndSelf, TB_DRAG_TIMER);
1083
1084         if (infoPtr->flags & TB_DRAGPOSVALID) 
1085                 infoPtr->nPos=infoPtr->dragPos;
1086
1087         infoPtr->flags &= ~ (TB_DRAGPOSVALID | TB_DRAG_TIMER_SET);
1088
1089         TRACKBAR_SendNotify (wndPtr, TB_ENDTRACK);
1090         return 0;
1091 }
1092
1093 static LRESULT
1094 TRACKBAR_Paint (WND *wndPtr, WPARAM32 wParam)
1095 {
1096     HDC32 hdc;
1097     PAINTSTRUCT32 ps;
1098
1099     hdc = wParam==0 ? BeginPaint32 (wndPtr->hwndSelf, &ps) : (HDC32)wParam;
1100     TRACKBAR_Refresh (wndPtr, hdc);
1101     if(!wParam)
1102         EndPaint32 (wndPtr->hwndSelf, &ps);
1103     return 0;
1104 }
1105
1106
1107 static LRESULT
1108 TRACKBAR_SetFocus (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1109 {
1110     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1111     HDC32 hdc;
1112
1113         TRACE (trackbar,"\n");
1114     infoPtr->bFocus = TRUE;
1115
1116     hdc = GetDC32 (wndPtr->hwndSelf);
1117     TRACKBAR_Refresh (wndPtr, hdc);
1118     ReleaseDC32 (wndPtr->hwndSelf, hdc);
1119
1120     return 0;
1121 }
1122
1123
1124 static LRESULT
1125 TRACKBAR_Size (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1126 {
1127     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1128
1129     TRACKBAR_CalcChannel (wndPtr, infoPtr);
1130     TRACKBAR_AlignBuddies (wndPtr, infoPtr);
1131
1132     return 0;
1133 }
1134
1135
1136
1137 static BOOL32
1138 TRACKBAR_SendNotify (WND *wndPtr, UINT32 code)
1139
1140 {
1141     TRACE (trackbar, "%x\n",code);
1142         if (wndPtr->dwStyle & TBS_VERT) 
1143         return (BOOL32) SendMessage32A (GetParent32 (wndPtr->hwndSelf), 
1144                                                 WM_VSCROLL, (WPARAM32)code, (LPARAM) wndPtr->hwndSelf);
1145
1146         return (BOOL32) SendMessage32A (GetParent32 (wndPtr->hwndSelf), 
1147                                                 WM_HSCROLL, (WPARAM32)code, (LPARAM) wndPtr->hwndSelf);
1148 }
1149
1150 static LRESULT
1151 TRACKBAR_MouseMove (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1152 {
1153     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1154         INT32 clickPlace;
1155                         
1156         clickPlace=(INT32)LOWORD(lParam);
1157
1158         infoPtr->dragPos=TRACKBAR_ConvertPlaceToPosition (infoPtr, clickPlace);
1159         infoPtr->flags|=TB_DRAGPOSVALID;
1160
1161         TRACKBAR_SendNotify (wndPtr, TB_THUMBTRACK | (infoPtr->dragPos>>16));
1162         return TRUE;
1163 }
1164
1165
1166 static LRESULT
1167 TRACKBAR_KeyDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1168 {
1169     TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1170         INT32 pos;
1171
1172     TRACE (trackbar, "%x\n",wParam);
1173
1174         pos=infoPtr->nPos;
1175         switch (wParam) {
1176                 case VK_LEFT:
1177                 case VK_UP: 
1178                         if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
1179                         infoPtr->nPos -= infoPtr->nLineSize;
1180                         if (infoPtr->nPos < infoPtr->nRangeMin) 
1181                                 infoPtr->nPos = infoPtr->nRangeMin;
1182                         TRACKBAR_SendNotify (wndPtr, TB_LINEUP);
1183                         break;
1184                 case VK_RIGHT:
1185                 case VK_DOWN: 
1186                         if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
1187                         infoPtr->nPos += infoPtr->nLineSize;
1188                         if (infoPtr->nPos > infoPtr->nRangeMax) 
1189                                 infoPtr->nPos = infoPtr->nRangeMax;
1190                         TRACKBAR_SendNotify (wndPtr, TB_LINEDOWN);
1191             break;
1192                 case VK_NEXT:
1193                         if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
1194                         infoPtr->nPos += infoPtr->nPageSize;
1195                         if (infoPtr->nPos > infoPtr->nRangeMax) 
1196                                 infoPtr->nPos = infoPtr->nRangeMax;
1197                          TRACKBAR_SendNotify (wndPtr, TB_PAGEUP);
1198             break;
1199                 case VK_PRIOR:
1200                         if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
1201                         infoPtr->nPos -= infoPtr->nPageSize;
1202                         if (infoPtr->nPos < infoPtr->nRangeMin) 
1203                                 infoPtr->nPos = infoPtr->nRangeMin;
1204                         TRACKBAR_SendNotify (wndPtr, TB_PAGEDOWN);
1205             break;
1206                 case VK_HOME: 
1207                         if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
1208                         infoPtr->nPos = infoPtr->nRangeMin;
1209                         TRACKBAR_SendNotify (wndPtr, TB_TOP);
1210             break;
1211                 case VK_END: 
1212                         if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
1213                         infoPtr->nPos = infoPtr->nRangeMax;
1214                         TRACKBAR_SendNotify (wndPtr, TB_BOTTOM);
1215             break;
1216         }
1217
1218  if (pos!=infoPtr->nPos) { 
1219         HDC32 hdc;
1220
1221         hdc=GetDC32 (wndPtr->hwndSelf);
1222         infoPtr->flags |=TB_THUMBPOSCHANGED;
1223         TRACKBAR_Refresh (wndPtr, hdc);
1224         ReleaseDC32 (wndPtr->hwndSelf, hdc);
1225  }
1226
1227  return TRUE;
1228 }
1229
1230 static LRESULT
1231 TRACKBAR_KeyUp (WND *wndPtr, WPARAM32 wParam)
1232 {
1233         switch (wParam) {
1234                 case VK_LEFT:
1235                 case VK_UP: 
1236                 case VK_RIGHT:
1237                 case VK_DOWN: 
1238                 case VK_NEXT:
1239                 case VK_PRIOR:
1240                 case VK_HOME: 
1241                 case VK_END:    TRACKBAR_SendNotify (wndPtr, TB_ENDTRACK);
1242         }
1243  return TRUE;
1244 }
1245
1246
1247 static LRESULT 
1248 TRACKBAR_HandleTimer ( WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1249 {
1250  TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1251  HDC32 hdc;
1252
1253  TRACE (trackbar,"timer\n");
1254
1255  switch (wParam) {
1256         case TB_DRAG_TIMER: 
1257                 if (infoPtr->flags & TB_DRAGPOSVALID)  {
1258                         infoPtr->nPos=infoPtr->dragPos;
1259                         infoPtr->flags |= TB_THUMBPOSCHANGED;
1260                 }
1261                 infoPtr->flags &= ~ (TB_DRAG_TIMER_SET | TB_DRAGPOSVALID);
1262         hdc=GetDC32 (wndPtr->hwndSelf);
1263         TRACKBAR_Refresh (wndPtr, hdc);
1264         ReleaseDC32 (wndPtr->hwndSelf, hdc);
1265                 return 0;
1266         }
1267  return 1;
1268 }
1269
1270
1271 LRESULT WINAPI
1272 TRACKBAR_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
1273 {
1274     WND *wndPtr = WIN_FindWndPtr(hwnd);
1275
1276     switch (uMsg)
1277     {
1278         case TBM_CLEARSEL:
1279             return TRACKBAR_ClearSel (wndPtr, wParam, lParam);
1280
1281         case TBM_CLEARTICS:
1282             return TRACKBAR_ClearTics (wndPtr, wParam, lParam);
1283
1284         case TBM_GETBUDDY:
1285             return TRACKBAR_GetBuddy (wndPtr, wParam, lParam);
1286
1287         case TBM_GETCHANNELRECT:
1288             return TRACKBAR_GetChannelRect (wndPtr, wParam, lParam);
1289
1290         case TBM_GETLINESIZE:
1291             return TRACKBAR_GetLineSize (wndPtr, wParam, lParam);
1292
1293         case TBM_GETNUMTICS:
1294             return TRACKBAR_GetNumTics (wndPtr, wParam, lParam);
1295
1296         case TBM_GETPAGESIZE:
1297             return TRACKBAR_GetPageSize (wndPtr, wParam, lParam);
1298
1299         case TBM_GETPOS:
1300             return TRACKBAR_GetPos (wndPtr, wParam, lParam);
1301
1302         case TBM_GETPTICS:
1303                  return TRACKBAR_GetPTics (wndPtr);
1304
1305         case TBM_GETRANGEMAX:
1306             return TRACKBAR_GetRangeMax (wndPtr, wParam, lParam);
1307
1308         case TBM_GETRANGEMIN:
1309             return TRACKBAR_GetRangeMin (wndPtr, wParam, lParam);
1310
1311         case TBM_GETSELEND:
1312             return TRACKBAR_GetSelEnd (wndPtr, wParam, lParam);
1313
1314         case TBM_GETSELSTART:
1315             return TRACKBAR_GetSelStart (wndPtr, wParam, lParam);
1316
1317         case TBM_GETTHUMBLENGTH:
1318             return TRACKBAR_GetThumbLength (wndPtr, wParam, lParam);
1319
1320         case TBM_GETTHUMBRECT:
1321         return TRACKBAR_GetThumbRect (wndPtr, wParam, lParam);
1322
1323     case TBM_GETTIC:
1324         return TRACKBAR_GetTic (wndPtr, wParam, lParam);
1325  
1326     case TBM_GETTICPOS:
1327         return TRACKBAR_GetTicPos (wndPtr, wParam, lParam);
1328  
1329         case TBM_GETTOOLTIPS:
1330             return TRACKBAR_GetToolTips (wndPtr, wParam, lParam);
1331
1332 //      case TBM_GETUNICODEFORMAT:
1333
1334         case TBM_SETBUDDY:
1335             return TRACKBAR_SetBuddy (wndPtr, wParam, lParam);
1336
1337         case TBM_SETLINESIZE:
1338             return TRACKBAR_SetLineSize (wndPtr, wParam, lParam);
1339
1340         case TBM_SETPAGESIZE:
1341             return TRACKBAR_SetPageSize (wndPtr, wParam, lParam);
1342
1343         case TBM_SETPOS:
1344             return TRACKBAR_SetPos (wndPtr, wParam, lParam);
1345
1346         case TBM_SETRANGE:
1347             return TRACKBAR_SetRange (wndPtr, wParam, lParam);
1348
1349         case TBM_SETRANGEMAX:
1350             return TRACKBAR_SetRangeMax (wndPtr, wParam, lParam);
1351
1352         case TBM_SETRANGEMIN:
1353             return TRACKBAR_SetRangeMin (wndPtr, wParam, lParam);
1354
1355         case TBM_SETSEL:
1356             return TRACKBAR_SetSel (wndPtr, wParam, lParam);
1357
1358         case TBM_SETSELEND:
1359             return TRACKBAR_SetSelEnd (wndPtr, wParam, lParam);
1360
1361         case TBM_SETSELSTART:
1362             return TRACKBAR_SetSelStart (wndPtr, wParam, lParam);
1363
1364         case TBM_SETTHUMBLENGTH:
1365             return TRACKBAR_SetThumbLength (wndPtr, wParam, lParam);
1366
1367         case TBM_SETTIC:
1368             return TRACKBAR_SetTic (wndPtr, wParam, lParam);
1369
1370     case TBM_SETTICFREQ:
1371        return TRACKBAR_SetTicFreq (wndPtr, wParam);
1372
1373
1374         case TBM_SETTIPSIDE:
1375             return TRACKBAR_SetTipSide (wndPtr, wParam, lParam);
1376
1377         case TBM_SETTOOLTIPS:
1378             return TRACKBAR_SetToolTips (wndPtr, wParam, lParam);
1379
1380 //      case TBM_SETUNICODEFORMAT:
1381
1382
1383         case WM_CAPTURECHANGED:
1384             return TRACKBAR_CaptureChanged (wndPtr, wParam, lParam);
1385
1386         case WM_CREATE:
1387             return TRACKBAR_Create (wndPtr, wParam, lParam);
1388
1389         case WM_DESTROY:
1390             return TRACKBAR_Destroy (wndPtr, wParam, lParam);
1391
1392 //      case WM_ENABLE:
1393
1394 //      case WM_ERASEBKGND:
1395 //          return 0;
1396
1397         case WM_GETDLGCODE:
1398             return DLGC_WANTARROWS;
1399
1400         case WM_KEYDOWN:
1401        return TRACKBAR_KeyDown (wndPtr, wParam, lParam);
1402         
1403         case WM_KEYUP:
1404        return TRACKBAR_KeyUp (wndPtr, wParam);
1405
1406         case WM_KILLFOCUS:
1407             return TRACKBAR_KillFocus (wndPtr, wParam, lParam);
1408
1409         case WM_LBUTTONDOWN:
1410             return TRACKBAR_LButtonDown (wndPtr, wParam, lParam);
1411
1412         case WM_LBUTTONUP:
1413             return TRACKBAR_LButtonUp (wndPtr, wParam, lParam);
1414
1415         case WM_MOUSEMOVE:
1416             return TRACKBAR_MouseMove (wndPtr, wParam, lParam);
1417
1418         case WM_PAINT:
1419             return TRACKBAR_Paint (wndPtr, wParam);
1420
1421         case WM_SETFOCUS:
1422             return TRACKBAR_SetFocus (wndPtr, wParam, lParam);
1423
1424         case WM_SIZE:
1425             return TRACKBAR_Size (wndPtr, wParam, lParam);
1426
1427         case WM_TIMER:
1428                 return TRACKBAR_HandleTimer (wndPtr, wParam, lParam);
1429
1430         case WM_WININICHANGE:
1431                 return TRACKBAR_InitializeThumb (wndPtr);
1432
1433         default:
1434             if (uMsg >= WM_USER)
1435                 ERR (trackbar, "unknown msg %04x wp=%08x lp=%08lx\n",
1436                      uMsg, wParam, lParam);
1437             return DefWindowProc32A (hwnd, uMsg, wParam, lParam);
1438     }
1439     return 0;
1440 }
1441
1442
1443 VOID
1444 TRACKBAR_Register (VOID)
1445 {
1446     WNDCLASS32A wndClass;
1447
1448     if (GlobalFindAtom32A (TRACKBAR_CLASS32A)) return;
1449
1450     ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
1451     wndClass.style         = CS_GLOBALCLASS;
1452     wndClass.lpfnWndProc   = (WNDPROC32)TRACKBAR_WindowProc;
1453     wndClass.cbClsExtra    = 0;
1454     wndClass.cbWndExtra    = sizeof(TRACKBAR_INFO *);
1455     wndClass.hCursor       = LoadCursor32A (0, IDC_ARROW32A);
1456     wndClass.hbrBackground = (HBRUSH32)(COLOR_3DFACE + 1);
1457     wndClass.lpszClassName = TRACKBAR_CLASS32A;
1458  
1459     RegisterClass32A (&wndClass);
1460 }
1461
1462
1463 VOID
1464 TRACKBAR_Unregister (VOID)
1465 {
1466     if (GlobalFindAtom32A (TRACKBAR_CLASS32A))
1467         UnregisterClass32A (TRACKBAR_CLASS32A, (HINSTANCE32)NULL);
1468 }
1469