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