Release 990225.
[wine/multimedia.git] / dlls / comctl32 / trackbar.c
blob575ba0492d2b4043ecbc0dabcc415a67759aa9ef
1 /*
2 * Trackbar control
4 * Copyright 1998 Eric Kohl <ekohl@abo.rhein-zeitung.de>
5 * Copyright 1998,1999 Alex Priem <alexp@sci.kun.nl>
8 * TODO:
9 * - Some messages.
10 * - more display code.
11 * - handle dragging slider better
12 * - better tic handling.
13 * - more notifications.
17 /* known bugs:
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.
27 #include "commctrl.h"
28 #include "trackbar.h"
29 #include "win.h"
30 #include "debug.h"
33 #define TRACKBAR_GetInfoPtr(wndPtr) ((TRACKBAR_INFO *)wndPtr->wExtra[0])
36 /* Used by TRACKBAR_Refresh to find out which parts of the control
37 need to be recalculated */
39 #define TB_THUMBPOSCHANGED 1
40 #define TB_THUMBSIZECHANGED 2
41 #define TB_THUMBCHANGED (TB_THUMBPOSCHANGED | TB_THUMBPOSCHANGED)
42 #define TB_SELECTIONCHANGED 4
44 #define TB_DRAG_MODE 16 /* we're dragging the slider */
45 #define TB_DRAGPOSVALID 32 /* current Position is in dragPos */
46 #define TB_SHOW_TOOLTIP 64 /* tooltip-style enabled and tooltip on */
47 #define TB_REFRESH_TIMER_SET 128 /* is a TRACBKAR_Refresh queued?*/
50 /* helper defines for TRACKBAR_DrawTic */
51 #define TIC_LEFTEDGE 0x20
52 #define TIC_RIGHTEDGE 0x40
53 #define TIC_EDGE (TIC_LEFTEDGE | TIC_RIGHTEDGE)
54 #define TIC_SELECTIONMARKMAX 0x80
55 #define TIC_SELECTIONMARKMIN 0x100
56 #define TIC_SELECTIONMARK (TIC_SELECTIONMARKMAX | TIC_SELECTIONMARKMIN)
58 static BOOL32 TRACKBAR_SendNotify (WND *wndPtr, UINT32 code);
60 void TRACKBAR_RecalculateTics (TRACKBAR_INFO *infoPtr)
63 int i,tic,nrTics;
65 if (infoPtr->uTicFreq)
66 nrTics=(infoPtr->nRangeMax - infoPtr->nRangeMin)/infoPtr->uTicFreq;
67 else {
68 nrTics=0;
69 COMCTL32_Free (infoPtr->tics);
70 infoPtr->tics=NULL;
71 infoPtr->uNumTics=0;
72 return;
75 if (nrTics!=infoPtr->uNumTics) {
76 infoPtr->tics=COMCTL32_ReAlloc (infoPtr->tics, (nrTics+1)*sizeof (DWORD));
77 infoPtr->uNumTics=nrTics;
79 infoPtr->uNumTics=nrTics;
80 tic=infoPtr->nRangeMin+infoPtr->uTicFreq;
81 for (i=0; i<nrTics; i++,tic+=infoPtr->uTicFreq)
82 infoPtr->tics[i]=tic;
86 /* converts from physical (mouse) position to logical position
87 (in range of trackbar) */
89 static inline INT32
90 TRACKBAR_ConvertPlaceToPosition (TRACKBAR_INFO *infoPtr, int place,
91 int vertical)
93 double range,width,pos;
95 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
96 if (vertical) {
97 width=infoPtr->rcChannel.bottom - infoPtr->rcChannel.top;
98 pos=(range*(place - infoPtr->rcChannel.top)) / width;
99 } else {
100 width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
101 pos=(range*(place - infoPtr->rcChannel.left)) / width;
104 TRACE (trackbar,"%.2f\n",pos);
105 return pos;
110 static VOID
111 TRACKBAR_CalcChannel (WND *wndPtr, TRACKBAR_INFO *infoPtr)
113 INT32 cyChannel;
114 RECT32 lpRect,*channel = & infoPtr->rcChannel;
116 GetClientRect32 (wndPtr->hwndSelf, &lpRect);
118 if (wndPtr->dwStyle & TBS_ENABLESELRANGE)
119 cyChannel = MAX(infoPtr->uThumbLen - 8, 4);
120 else
121 cyChannel = 4;
123 if (wndPtr->dwStyle & TBS_VERT) {
124 channel->top = lpRect.top + 8;
125 channel->bottom = lpRect.bottom - 8;
127 if (wndPtr->dwStyle & TBS_BOTH) {
128 channel->left = (lpRect.right - cyChannel) / 2;
129 channel->right = (lpRect.right + cyChannel) / 2;
131 else if (wndPtr->dwStyle & TBS_LEFT) {
132 channel->left = lpRect.left + 10;
133 channel->right = channel->left + cyChannel;
135 else { /* TBS_RIGHT */
136 channel->right = lpRect.right - 10;
137 channel->left = channel->right - cyChannel;
140 else {
141 channel->left = lpRect.left + 8;
142 channel->right = lpRect.right - 8;
143 if (wndPtr->dwStyle & TBS_BOTH) {
144 channel->top = (lpRect.bottom - cyChannel) / 2;
145 channel->bottom = (lpRect.bottom + cyChannel) / 2;
147 else if (wndPtr->dwStyle & TBS_TOP) {
148 channel->top = lpRect.top + 10;
149 channel->bottom = channel->top + cyChannel;
151 else { /* TBS_BOTTOM */
152 channel->bottom = lpRect.bottom - 10;
153 channel->top = channel->bottom - cyChannel;
158 static VOID
159 TRACKBAR_CalcThumb (WND *wndPtr, TRACKBAR_INFO *infoPtr)
162 RECT32 *thumb;
163 int range, width;
165 thumb=&infoPtr->rcThumb;
166 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
167 if (wndPtr->dwStyle & TBS_VERT) {
168 width=infoPtr->rcChannel.bottom - infoPtr->rcChannel.top;
169 thumb->left = infoPtr->rcChannel.left - 1;
170 thumb->right = infoPtr->rcChannel.left + infoPtr->uThumbLen - 8;
171 thumb->top = infoPtr->rcChannel.top +
172 (width*infoPtr->nPos)/range - 5;
173 thumb->bottom = thumb->top + infoPtr->uThumbLen/3;
175 } else {
176 width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
177 thumb->left = infoPtr->rcChannel.left +
178 (width*infoPtr->nPos)/range - 5;
179 thumb->right = thumb->left + infoPtr->uThumbLen/3;
180 thumb->top = infoPtr->rcChannel.top - 1;
181 thumb->bottom = infoPtr->rcChannel.top + infoPtr->uThumbLen - 8;
185 static VOID
186 TRACKBAR_CalcSelection (WND *wndPtr, TRACKBAR_INFO *infoPtr)
188 RECT32 *selection;
189 int range, width;
191 selection= & infoPtr->rcSelection;
192 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
193 width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
195 if (range <= 0)
196 SetRectEmpty32 (selection);
197 else
198 if (wndPtr->dwStyle & TBS_VERT) {
199 selection->left = infoPtr->rcChannel.left +
200 (width*infoPtr->nSelMin)/range;
201 selection->right = infoPtr->rcChannel.left +
202 (width*infoPtr->nSelMax)/range;
203 selection->top = infoPtr->rcChannel.top + 2;
204 selection->bottom = infoPtr->rcChannel.bottom - 2;
205 } else {
206 selection->top = infoPtr->rcChannel.top +
207 (width*infoPtr->nSelMin)/range;
208 selection->bottom = infoPtr->rcChannel.top +
209 (width*infoPtr->nSelMax)/range;
210 selection->left = infoPtr->rcChannel.left + 2;
211 selection->right = infoPtr->rcChannel.right - 2;
216 static void
217 TRACKBAR_QueueRefresh (WND *wndPtr)
220 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
222 TRACE (trackbar,"queued\n");
223 if (infoPtr->flags & TB_REFRESH_TIMER_SET) {
224 KillTimer32 (wndPtr->hwndSelf, TB_REFRESH_TIMER);
227 SetTimer32 (wndPtr->hwndSelf, TB_REFRESH_TIMER, TB_REFRESH_DELAY, 0);
228 infoPtr->flags|=TB_REFRESH_TIMER_SET;
235 /* Trackbar drawing code. I like my spaghetti done milanese. */
237 /* ticPos is in tic-units, not in pixels */
239 static VOID
240 TRACKBAR_DrawHorizTic (TRACKBAR_INFO *infoPtr, HDC32 hdc, LONG ticPos,
241 int flags, COLORREF clrTic)
244 RECT32 rcChannel=infoPtr->rcChannel;
245 int x,y,width,range,side;
247 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
248 width=rcChannel.right - rcChannel.left;
250 if (flags & TBS_TOP) {
251 y=rcChannel.top-2;
252 side=-1;
253 } else {
254 y=rcChannel.bottom+2;
255 side=1;
258 if (flags & TIC_SELECTIONMARK) {
259 if (flags & TIC_SELECTIONMARKMIN)
260 x=rcChannel.left + (width*ticPos)/range - 1;
261 else
262 x=rcChannel.left + (width*ticPos)/range + 1;
264 SetPixel32 (hdc, x,y+6*side, clrTic);
265 SetPixel32 (hdc, x,y+7*side, clrTic);
266 return;
269 if ((ticPos>infoPtr->nRangeMin) && (ticPos<infoPtr->nRangeMax)) {
270 x=rcChannel.left + (width*ticPos)/range;
271 SetPixel32 (hdc, x,y+5*side, clrTic);
272 SetPixel32 (hdc, x,y+6*side, clrTic);
273 SetPixel32 (hdc, x,y+7*side, clrTic);
276 if (flags & TIC_EDGE) {
277 if (flags & TIC_LEFTEDGE)
278 x=rcChannel.left;
279 else
280 x=rcChannel.right;
282 SetPixel32 (hdc, x,y+5*side, clrTic);
283 SetPixel32 (hdc, x,y+6*side, clrTic);
284 SetPixel32 (hdc, x,y+7*side, clrTic);
285 SetPixel32 (hdc, x,y+8*side, clrTic);
290 static VOID
291 TRACKBAR_DrawVertTic (TRACKBAR_INFO *infoPtr, HDC32 hdc, LONG ticPos,
292 int flags, COLORREF clrTic)
295 RECT32 rcChannel=infoPtr->rcChannel;
296 int x,y,width,range,side;
298 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
299 width=rcChannel.bottom - rcChannel.top;
301 if (flags & TBS_TOP) {
302 x=rcChannel.right-2;
303 side=-1;
304 } else {
305 x=rcChannel.left+2;
306 side=1;
310 if (flags & TIC_SELECTIONMARK) {
311 if (flags & TIC_SELECTIONMARKMIN)
312 y=rcChannel.top + (width*ticPos)/range - 1;
313 else
314 y=rcChannel.top + (width*ticPos)/range + 1;
316 SetPixel32 (hdc, x+6*side, y, clrTic);
317 SetPixel32 (hdc, x+7*side, y, clrTic);
318 return;
321 if ((ticPos>infoPtr->nRangeMin) && (ticPos<infoPtr->nRangeMax)) {
322 y=rcChannel.top + (width*ticPos)/range;
323 SetPixel32 (hdc, x+5*side, y, clrTic);
324 SetPixel32 (hdc, x+6*side, y, clrTic);
325 SetPixel32 (hdc, x+7*side, y, clrTic);
328 if (flags & TIC_EDGE) {
329 if (flags & TIC_LEFTEDGE)
330 y=rcChannel.top;
331 else
332 y=rcChannel.bottom;
334 SetPixel32 (hdc, x+5*side, y, clrTic);
335 SetPixel32 (hdc, x+6*side, y, clrTic);
336 SetPixel32 (hdc, x+7*side, y, clrTic);
337 SetPixel32 (hdc, x+8*side, y, clrTic);
343 static VOID
344 TRACKBAR_DrawTics (TRACKBAR_INFO *infoPtr, HDC32 hdc, LONG ticPos,
345 int flags, COLORREF clrTic)
349 if (flags & TBS_VERT) {
350 if ((flags & TBS_TOP) || (flags & TBS_BOTH))
351 TRACKBAR_DrawVertTic (infoPtr, hdc, ticPos,
352 flags | TBS_TOP , clrTic);
353 if (!(flags & TBS_TOP) || (flags & TBS_BOTH))
354 TRACKBAR_DrawVertTic (infoPtr, hdc, ticPos, flags, clrTic);
355 return;
358 if ((flags & TBS_TOP) || (flags & TBS_BOTH))
359 TRACKBAR_DrawHorizTic (infoPtr, hdc, ticPos, flags | TBS_TOP , clrTic);
361 if (!(flags & TBS_TOP) || (flags & TBS_BOTH))
362 TRACKBAR_DrawHorizTic (infoPtr, hdc, ticPos, flags, clrTic);
367 static VOID
368 TRACKBAR_Refresh (WND *wndPtr, HDC32 hdc)
370 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
371 RECT32 rcClient, rcChannel, rcSelection;
372 HBRUSH32 hBrush = CreateSolidBrush32 (infoPtr->clrBk);
373 int i;
375 GetClientRect32 (wndPtr->hwndSelf, &rcClient);
376 hBrush = CreateSolidBrush32 (infoPtr->clrBk);
377 FillRect32 (hdc, &rcClient, hBrush);
378 DeleteObject32 (hBrush);
380 if (infoPtr->flags & TB_REFRESH_TIMER_SET) {
381 KillTimer32 (wndPtr->hwndSelf, TB_REFRESH_TIMER);
382 infoPtr->flags &= ~TB_REFRESH_TIMER_SET;
385 if (infoPtr->flags & TB_DRAGPOSVALID) {
386 infoPtr->nPos=infoPtr->dragPos;
387 infoPtr->flags |= TB_THUMBPOSCHANGED;
390 if (infoPtr->flags & TB_THUMBCHANGED) {
391 TRACKBAR_CalcThumb (wndPtr, infoPtr);
392 if (infoPtr->flags & TB_THUMBSIZECHANGED)
393 TRACKBAR_CalcChannel (wndPtr, infoPtr);
395 if (infoPtr->flags & TB_SELECTIONCHANGED)
396 TRACKBAR_CalcSelection (wndPtr, infoPtr);
397 infoPtr->flags &= ~ (TB_THUMBCHANGED | TB_SELECTIONCHANGED | TB_DRAGPOSVALID);
399 /* draw channel */
401 rcChannel = infoPtr->rcChannel;
402 rcSelection= infoPtr->rcSelection;
403 DrawEdge32 (hdc, &rcChannel, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
405 if (wndPtr->dwStyle & TBS_ENABLESELRANGE) { /* fill the channel */
406 HBRUSH32 hbr = CreateSolidBrush32 (RGB(255,255,255));
407 FillRect32 (hdc, &rcChannel, hbr);
408 if (((wndPtr->dwStyle & TBS_VERT) &&
409 (rcSelection.left!=rcSelection.right)) ||
410 ((!(wndPtr->dwStyle & TBS_VERT)) &&
411 (rcSelection.left!=rcSelection.right))) {
412 hbr=CreateSolidBrush32 (COLOR_HIGHLIGHT);
413 FillRect32 (hdc, &rcSelection, hbr);
415 DeleteObject32 (hbr);
419 /* draw tics */
421 if (!(wndPtr->dwStyle & TBS_NOTICKS)) {
422 int ticFlags=wndPtr->dwStyle & 0x0f;
423 COLORREF clrTic=GetSysColor32 (COLOR_3DDKSHADOW);
425 for (i=0; i<infoPtr->uNumTics; i++)
426 TRACKBAR_DrawTics (infoPtr, hdc, infoPtr->tics[i],
427 ticFlags, clrTic);
429 TRACKBAR_DrawTics (infoPtr, hdc, 0, ticFlags | TIC_LEFTEDGE, clrTic);
430 TRACKBAR_DrawTics (infoPtr, hdc, 0, ticFlags | TIC_RIGHTEDGE, clrTic);
432 if ((wndPtr->dwStyle & TBS_ENABLESELRANGE) &&
433 (rcSelection.left!=rcSelection.right)) {
434 TRACKBAR_DrawTics (infoPtr, hdc, infoPtr->nSelMin,
435 ticFlags | TIC_SELECTIONMARKMIN, clrTic);
436 TRACKBAR_DrawTics (infoPtr, hdc, infoPtr->nSelMax,
437 ticFlags | TIC_SELECTIONMARKMAX, clrTic);
441 /* draw thumb */
443 if (!(wndPtr->dwStyle & TBS_NOTHUMB)) {
445 HBRUSH32 hbr = CreateSolidBrush32 (COLOR_BACKGROUND);
446 RECT32 thumb = infoPtr->rcThumb;
448 SelectObject32 (hdc, hbr);
450 if (wndPtr->dwStyle & TBS_BOTH) {
451 FillRect32 (hdc, &thumb, hbr);
452 DrawEdge32 (hdc, &thumb, EDGE_RAISED, BF_TOPLEFT);
453 } else {
455 POINT32 points[6];
457 /* first, fill the thumb */
458 /* FIXME: revamp. check for TBS_VERT */
460 SetPolyFillMode32 (hdc,WINDING);
461 points[0].x=thumb.left;
462 points[0].y=thumb.top;
463 points[1].x=thumb.right - 1;
464 points[1].y=thumb.top;
465 points[2].x=thumb.right - 1;
466 points[2].y=thumb.bottom -2;
467 points[3].x=(thumb.right + thumb.left-1)/2;
468 points[3].y=thumb.bottom+4;
469 points[4].x=thumb.left;
470 points[4].y=thumb.bottom -2;
471 points[5].x=points[0].x;
472 points[5].y=points[0].y;
473 Polygon32 (hdc, points, 6);
475 if (wndPtr->dwStyle & TBS_VERT) {
476 /* draw edge */
477 } else {
478 RECT32 triangle; /* for correct shadows of thumb */
479 DrawEdge32 (hdc, &thumb, EDGE_RAISED, BF_TOPLEFT);
481 /* draw notch */
483 triangle.right = thumb.right+5;
484 triangle.left = points[3].x+5;
485 triangle.top = thumb.bottom +5;
486 triangle.bottom= thumb.bottom +1;
487 DrawEdge32 (hdc, &triangle, EDGE_SUNKEN,
488 BF_DIAGONAL | BF_TOP | BF_RIGHT);
489 triangle.left = thumb.left+6;
490 triangle.right = points[3].x+6;
491 DrawEdge32 (hdc, &triangle, EDGE_RAISED,
492 BF_DIAGONAL | BF_TOP | BF_LEFT);
495 DeleteObject32 (hbr);
498 if (infoPtr->bFocus)
499 DrawFocusRect32 (hdc, &rcClient);
505 static VOID
506 TRACKBAR_AlignBuddies (WND *wndPtr, TRACKBAR_INFO *infoPtr)
508 HWND32 hwndParent = GetParent32 (wndPtr->hwndSelf);
509 RECT32 rcSelf, rcBuddy;
510 INT32 x, y;
512 GetWindowRect32 (wndPtr->hwndSelf, &rcSelf);
513 MapWindowPoints32 (HWND_DESKTOP, hwndParent, (LPPOINT32)&rcSelf, 2);
515 /* align buddy left or above */
516 if (infoPtr->hwndBuddyLA) {
517 GetWindowRect32 (infoPtr->hwndBuddyLA, &rcBuddy);
518 MapWindowPoints32 (HWND_DESKTOP, hwndParent, (LPPOINT32)&rcBuddy, 2);
520 if (wndPtr->dwStyle & TBS_VERT) {
521 x = (infoPtr->rcChannel.right + infoPtr->rcChannel.left) / 2 -
522 (rcBuddy.right - rcBuddy.left) / 2 + rcSelf.left;
523 y = rcSelf.top - (rcBuddy.bottom - rcBuddy.top);
525 else {
526 x = rcSelf.left - (rcBuddy.right - rcBuddy.left);
527 y = (infoPtr->rcChannel.bottom + infoPtr->rcChannel.top) / 2 -
528 (rcBuddy.bottom - rcBuddy.top) / 2 + rcSelf.top;
531 SetWindowPos32 (infoPtr->hwndBuddyLA, 0, x, y, 0, 0,
532 SWP_NOZORDER | SWP_NOSIZE);
536 /* align buddy right or below */
537 if (infoPtr->hwndBuddyRB) {
538 GetWindowRect32 (infoPtr->hwndBuddyRB, &rcBuddy);
539 MapWindowPoints32 (HWND_DESKTOP, hwndParent, (LPPOINT32)&rcBuddy, 2);
541 if (wndPtr->dwStyle & TBS_VERT) {
542 x = (infoPtr->rcChannel.right + infoPtr->rcChannel.left) / 2 -
543 (rcBuddy.right - rcBuddy.left) / 2 + rcSelf.left;
544 y = rcSelf.bottom;
546 else {
547 x = rcSelf.right;
548 y = (infoPtr->rcChannel.bottom + infoPtr->rcChannel.top) / 2 -
549 (rcBuddy.bottom - rcBuddy.top) / 2 + rcSelf.top;
551 SetWindowPos32 (infoPtr->hwndBuddyRB, 0, x, y, 0, 0,
552 SWP_NOZORDER | SWP_NOSIZE);
557 static LRESULT
558 TRACKBAR_ClearSel (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
560 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
562 infoPtr->nSelMin = 0;
563 infoPtr->nSelMax = 0;
564 infoPtr->flags |=TB_SELECTIONCHANGED;
566 if ((BOOL32)wParam) {
567 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
568 TRACKBAR_Refresh (wndPtr, hdc);
569 ReleaseDC32 (wndPtr->hwndSelf, hdc);
572 return 0;
576 static LRESULT
577 TRACKBAR_ClearTics (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
579 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
581 if (infoPtr->tics) {
582 COMCTL32_Free (infoPtr->tics);
583 infoPtr->tics = NULL;
584 infoPtr->uNumTics = 0;
587 if (wParam) {
588 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
589 TRACKBAR_Refresh (wndPtr, hdc);
590 ReleaseDC32 (wndPtr->hwndSelf, hdc);
593 return 0;
597 static LRESULT
598 TRACKBAR_GetBuddy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
600 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
602 if (wParam) /* buddy is left or above */
603 return (LRESULT)infoPtr->hwndBuddyLA;
605 /* buddy is right or below */
606 return (LRESULT) infoPtr->hwndBuddyRB;
610 static LRESULT
611 TRACKBAR_GetChannelRect (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
613 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
614 LPRECT32 lprc = (LPRECT32)lParam;
616 if (lprc == NULL)
617 return 0;
619 lprc->left = infoPtr->rcChannel.left;
620 lprc->right = infoPtr->rcChannel.right;
621 lprc->bottom = infoPtr->rcChannel.bottom;
622 lprc->top = infoPtr->rcChannel.top;
624 return 0;
628 static LRESULT
629 TRACKBAR_GetLineSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
631 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
633 return infoPtr->nLineSize;
637 static LRESULT
638 TRACKBAR_GetNumTics (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
640 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
642 if (wndPtr->dwStyle & TBS_NOTICKS)
643 return 0;
645 return infoPtr->uNumTics+2;
649 static LRESULT
650 TRACKBAR_GetPageSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
652 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
654 return infoPtr->nPageSize;
658 static LRESULT
659 TRACKBAR_GetPos (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
661 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
663 return infoPtr->nPos;
669 static LRESULT
670 TRACKBAR_GetRangeMax (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
672 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
674 return infoPtr->nRangeMax;
678 static LRESULT
679 TRACKBAR_GetRangeMin (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
681 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
683 return infoPtr->nRangeMin;
687 static LRESULT
688 TRACKBAR_GetSelEnd (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
690 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
692 return infoPtr->nSelMax;
696 static LRESULT
697 TRACKBAR_GetSelStart (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
699 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
701 return infoPtr->nSelMin;
705 static LRESULT
706 TRACKBAR_GetThumbLength (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
708 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
710 return infoPtr->uThumbLen;
713 static LRESULT
714 TRACKBAR_GetPTics (WND *wndPtr)
716 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
718 return (LRESULT) infoPtr->tics;
721 static LRESULT
722 TRACKBAR_GetThumbRect (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
724 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
725 LPRECT32 lprc = (LPRECT32)lParam;
727 if (lprc == NULL)
728 return 0;
730 lprc->left = infoPtr->rcThumb.left;
731 lprc->right = infoPtr->rcThumb.right;
732 lprc->bottom = infoPtr->rcThumb.bottom;
733 lprc->top = infoPtr->rcThumb.top;
735 return 0;
742 static LRESULT
743 TRACKBAR_GetTic (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
746 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
747 INT32 iTic;
749 iTic=(INT32) wParam;
750 if ((iTic<0) || (iTic>infoPtr->uNumTics))
751 return -1;
753 return (LRESULT) infoPtr->tics[iTic];
758 static LRESULT
759 TRACKBAR_GetTicPos (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
762 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
763 INT32 iTic, range, width, pos;
766 iTic=(INT32 ) wParam;
767 if ((iTic<0) || (iTic>infoPtr->uNumTics))
768 return -1;
770 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
771 width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
772 pos=infoPtr->rcChannel.left + (width * infoPtr->tics[iTic]) / range;
775 return (LRESULT) pos;
778 static LRESULT
779 TRACKBAR_GetToolTips (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
781 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
783 if (wndPtr->dwStyle & TBS_TOOLTIPS)
784 return (LRESULT)infoPtr->hwndToolTip;
785 return 0;
789 /* case TBM_GETUNICODEFORMAT: */
792 static LRESULT
793 TRACKBAR_SetBuddy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
795 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
796 HWND32 hwndTemp;
798 if (wParam) {
799 /* buddy is left or above */
800 hwndTemp = infoPtr->hwndBuddyLA;
801 infoPtr->hwndBuddyLA = (HWND32)lParam;
803 FIXME (trackbar, "move buddy!\n");
805 else {
806 /* buddy is right or below */
807 hwndTemp = infoPtr->hwndBuddyRB;
808 infoPtr->hwndBuddyRB = (HWND32)lParam;
810 FIXME (trackbar, "move buddy!\n");
813 TRACKBAR_AlignBuddies (wndPtr, infoPtr);
815 return (LRESULT)hwndTemp;
819 static LRESULT
820 TRACKBAR_SetLineSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
822 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
823 INT32 nTemp = infoPtr->nLineSize;
825 infoPtr->nLineSize = (INT32)lParam;
827 return nTemp;
831 static LRESULT
832 TRACKBAR_SetPageSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
834 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
835 INT32 nTemp = infoPtr->nPageSize;
837 infoPtr->nPageSize = (INT32)lParam;
839 return nTemp;
843 static LRESULT
844 TRACKBAR_SetPos (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
846 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
848 infoPtr->nPos = (INT32)HIWORD(lParam);
850 if (infoPtr->nPos < infoPtr->nRangeMin)
851 infoPtr->nPos = infoPtr->nRangeMin;
853 if (infoPtr->nPos > infoPtr->nRangeMax)
854 infoPtr->nPos = infoPtr->nRangeMax;
855 infoPtr->flags |=TB_THUMBPOSCHANGED;
857 if (wParam) {
858 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
859 TRACKBAR_Refresh (wndPtr, hdc);
860 ReleaseDC32 (wndPtr->hwndSelf, hdc);
863 return 0;
867 static LRESULT
868 TRACKBAR_SetRange (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
870 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
871 infoPtr->nRangeMin = (INT32)LOWORD(lParam);
872 infoPtr->nRangeMax = (INT32)HIWORD(lParam);
874 if (infoPtr->nPos < infoPtr->nRangeMin) {
875 infoPtr->nPos = infoPtr->nRangeMin;
876 infoPtr->flags |=TB_THUMBPOSCHANGED;
879 if (infoPtr->nPos > infoPtr->nRangeMax) {
880 infoPtr->nPos = infoPtr->nRangeMax;
881 infoPtr->flags |=TB_THUMBPOSCHANGED;
884 infoPtr->nPageSize=(infoPtr->nRangeMax - infoPtr->nRangeMin)/5;
885 TRACKBAR_RecalculateTics (infoPtr);
887 if (wParam) {
888 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
889 TRACKBAR_Refresh (wndPtr, hdc);
890 ReleaseDC32 (wndPtr->hwndSelf, hdc);
893 return 0;
897 static LRESULT
898 TRACKBAR_SetRangeMax (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
900 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
902 infoPtr->nRangeMax = (INT32)lParam;
903 if (infoPtr->nPos > infoPtr->nRangeMax) {
904 infoPtr->nPos = infoPtr->nRangeMax;
905 infoPtr->flags |=TB_THUMBPOSCHANGED;
908 infoPtr->nPageSize=(infoPtr->nRangeMax - infoPtr->nRangeMin)/5;
909 TRACKBAR_RecalculateTics (infoPtr);
911 if (wParam) {
912 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
913 TRACKBAR_Refresh (wndPtr, hdc);
914 ReleaseDC32 (wndPtr->hwndSelf, hdc);
917 return 0;
921 static LRESULT
922 TRACKBAR_SetRangeMin (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
924 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
926 infoPtr->nRangeMin = (INT32)lParam;
927 if (infoPtr->nPos < infoPtr->nRangeMin) {
928 infoPtr->nPos = infoPtr->nRangeMin;
929 infoPtr->flags |=TB_THUMBPOSCHANGED;
932 infoPtr->nPageSize=(infoPtr->nRangeMax - infoPtr->nRangeMin)/5;
933 TRACKBAR_RecalculateTics (infoPtr);
935 if (wParam) {
936 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
937 TRACKBAR_Refresh (wndPtr, hdc);
938 ReleaseDC32 (wndPtr->hwndSelf, hdc);
941 return 0;
944 static LRESULT
945 TRACKBAR_SetTicFreq (WND *wndPtr, WPARAM32 wParam)
947 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
948 HDC32 hdc;
950 if (wndPtr->dwStyle & TBS_AUTOTICKS)
951 infoPtr->uTicFreq=(UINT32) wParam;
953 TRACKBAR_RecalculateTics (infoPtr);
955 hdc = GetDC32 (wndPtr->hwndSelf);
956 TRACKBAR_Refresh (wndPtr, hdc);
957 ReleaseDC32 (wndPtr->hwndSelf, hdc);
958 return 0;
962 static LRESULT
963 TRACKBAR_SetSel (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
965 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
967 infoPtr->nSelMin = (INT32)LOWORD(lParam);
968 infoPtr->nSelMax = (INT32)HIWORD(lParam);
969 infoPtr->flags |=TB_SELECTIONCHANGED;
971 if (!wndPtr->dwStyle & TBS_ENABLESELRANGE)
972 return 0;
974 if (infoPtr->nSelMin < infoPtr->nRangeMin)
975 infoPtr->nSelMin = infoPtr->nRangeMin;
976 if (infoPtr->nSelMax > infoPtr->nRangeMax)
977 infoPtr->nSelMax = infoPtr->nRangeMax;
979 if (wParam) {
980 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
981 TRACKBAR_Refresh (wndPtr, hdc);
982 ReleaseDC32 (wndPtr->hwndSelf, hdc);
985 return 0;
989 static LRESULT
990 TRACKBAR_SetSelEnd (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
992 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
994 if (!wndPtr->dwStyle & TBS_ENABLESELRANGE)
995 return 0;
997 infoPtr->nSelMax = (INT32)lParam;
998 infoPtr->flags |=TB_SELECTIONCHANGED;
1000 if (infoPtr->nSelMax > infoPtr->nRangeMax)
1001 infoPtr->nSelMax = infoPtr->nRangeMax;
1003 if (wParam) {
1004 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
1005 TRACKBAR_Refresh (wndPtr, hdc);
1006 ReleaseDC32 (wndPtr->hwndSelf, hdc);
1009 return 0;
1013 static LRESULT
1014 TRACKBAR_SetSelStart (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1016 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1018 if (!wndPtr->dwStyle & TBS_ENABLESELRANGE)
1019 return 0;
1021 infoPtr->nSelMin = (INT32)lParam;
1022 infoPtr->flags |=TB_SELECTIONCHANGED;
1023 if (infoPtr->nSelMin < infoPtr->nRangeMin)
1024 infoPtr->nSelMin = infoPtr->nRangeMin;
1026 if (wParam) {
1027 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
1028 TRACKBAR_Refresh (wndPtr, hdc);
1029 ReleaseDC32 (wndPtr->hwndSelf, hdc);
1032 return 0;
1036 static LRESULT
1037 TRACKBAR_SetThumbLength (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1039 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1040 HDC32 hdc;
1042 if (wndPtr->dwStyle & TBS_FIXEDLENGTH)
1043 infoPtr->uThumbLen = (UINT32)wParam;
1045 hdc = GetDC32 (wndPtr->hwndSelf);
1046 infoPtr->flags |=TB_THUMBSIZECHANGED;
1047 TRACKBAR_Refresh (wndPtr, hdc);
1048 ReleaseDC32 (wndPtr->hwndSelf, hdc);
1050 return 0;
1054 static LRESULT
1055 TRACKBAR_SetTic (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1057 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1058 INT32 nPos = (INT32)lParam;
1059 HDC32 hdc;
1061 if ((nPos < infoPtr->nRangeMin) || (nPos> infoPtr->nRangeMax))
1062 return FALSE;
1064 infoPtr->uNumTics++;
1065 infoPtr->tics=COMCTL32_ReAlloc( infoPtr->tics,
1066 (infoPtr->uNumTics)*sizeof (DWORD));
1067 infoPtr->tics[infoPtr->uNumTics-1]=nPos;
1069 hdc = GetDC32 (wndPtr->hwndSelf);
1070 TRACKBAR_Refresh (wndPtr, hdc);
1071 ReleaseDC32 (wndPtr->hwndSelf, hdc);
1073 return TRUE;
1079 static LRESULT
1080 TRACKBAR_SetTipSide (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1082 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1083 INT32 fTemp = infoPtr->fLocation;
1085 infoPtr->fLocation = (INT32)wParam;
1087 return fTemp;
1091 static LRESULT
1092 TRACKBAR_SetToolTips (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1094 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1096 infoPtr->hwndToolTip = (HWND32)wParam;
1098 return 0;
1102 /* case TBM_SETUNICODEFORMAT: */
1105 static LRESULT
1106 TRACKBAR_InitializeThumb (WND *wndPtr)
1108 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1110 infoPtr->uThumbLen = 23; /* initial thumb length */
1112 TRACKBAR_CalcChannel (wndPtr,infoPtr);
1113 TRACKBAR_CalcThumb (wndPtr, infoPtr);
1114 infoPtr->flags &= ~TB_SELECTIONCHANGED;
1116 return 0;
1120 static LRESULT
1121 TRACKBAR_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1123 TRACKBAR_INFO *infoPtr;
1125 infoPtr = (TRACKBAR_INFO *)COMCTL32_Alloc (sizeof(TRACKBAR_INFO));
1126 wndPtr->wExtra[0] = (DWORD)infoPtr;
1129 infoPtr->nRangeMin = 0; /* default values */
1130 infoPtr->nRangeMax = 100;
1131 infoPtr->nLineSize = 1;
1132 infoPtr->nPageSize = 20;
1133 infoPtr->nSelMin = 0;
1134 infoPtr->nSelMax = 0;
1135 infoPtr->nPos = 0;
1137 infoPtr->uNumTics = 0; /* start and end tic are not included in count*/
1138 infoPtr->uTicFreq = 1;
1139 infoPtr->tics = NULL;
1140 infoPtr->clrBk = GetSysColor32 (COLOR_BACKGROUND);
1141 infoPtr->hwndNotify = GetParent32 (wndPtr->hwndSelf);
1143 TRACKBAR_InitializeThumb (wndPtr);
1145 if (wndPtr->dwStyle & TBS_TOOLTIPS) { /* Create tooltip control */
1146 TTTOOLINFO32A ti;
1148 infoPtr->hwndToolTip =
1149 CreateWindowEx32A (0, TOOLTIPS_CLASS32A, NULL, 0,
1150 CW_USEDEFAULT32, CW_USEDEFAULT32,
1151 CW_USEDEFAULT32, CW_USEDEFAULT32,
1152 wndPtr->hwndSelf, 0, 0, 0);
1154 /* Send NM_TOOLTIPSCREATED notification */
1155 if (infoPtr->hwndToolTip) {
1156 NMTOOLTIPSCREATED nmttc;
1158 nmttc.hdr.hwndFrom = wndPtr->hwndSelf;
1159 nmttc.hdr.idFrom = wndPtr->wIDmenu;
1160 nmttc.hdr.code = NM_TOOLTIPSCREATED;
1161 nmttc.hwndToolTips = infoPtr->hwndToolTip;
1163 SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
1164 (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmttc);
1167 ZeroMemory (&ti, sizeof(TTTOOLINFO32A));
1168 ti.cbSize = sizeof(TTTOOLINFO32A);
1169 ti.uFlags = TTF_IDISHWND | TTF_TRACK;
1170 ti.hwnd = wndPtr->hwndSelf;
1171 ti.uId = 0;
1172 ti.lpszText = "Test"; /* LPSTR_TEXTCALLBACK */
1173 SetRectEmpty32 (&ti.rect);
1175 SendMessage32A (infoPtr->hwndToolTip, TTM_ADDTOOL32A, 0, (LPARAM)&ti);
1178 return 0;
1182 static LRESULT
1183 TRACKBAR_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1185 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1187 if (infoPtr->flags & TB_REFRESH_TIMER_SET)
1188 KillTimer32 (wndPtr->hwndSelf, TB_REFRESH_TIMER);
1190 /* delete tooltip control */
1191 if (infoPtr->hwndToolTip)
1192 DestroyWindow32 (infoPtr->hwndToolTip);
1194 COMCTL32_Free (infoPtr);
1195 return 0;
1199 static LRESULT
1200 TRACKBAR_KillFocus (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1202 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1204 TRACE (trackbar,"\n");
1206 infoPtr->bFocus = FALSE;
1207 infoPtr->flags &= ~TB_DRAG_MODE;
1208 TRACKBAR_QueueRefresh (wndPtr);
1209 InvalidateRect32 (wndPtr->hwndSelf, NULL, TRUE);
1211 return 0;
1215 static LRESULT
1216 TRACKBAR_LButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1218 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1219 int clickPlace,prevPos,clickPos,vertical;
1221 SetFocus32 (wndPtr->hwndSelf);
1223 vertical=wndPtr->dwStyle & TBS_VERT;
1224 if (vertical)
1225 clickPlace=(INT32)HIWORD(lParam);
1226 else
1227 clickPlace=(INT32)LOWORD(lParam);
1229 if ((vertical &&
1230 (clickPlace>infoPtr->rcThumb.top) &&
1231 (clickPlace<infoPtr->rcThumb.bottom)) ||
1232 (!vertical &&
1233 (clickPlace>infoPtr->rcThumb.left) &&
1234 (clickPlace<infoPtr->rcThumb.right))) {
1235 infoPtr->flags |= TB_DRAG_MODE;
1236 if (wndPtr->dwStyle & TBS_TOOLTIPS) { /* enable tooltip */
1237 TTTOOLINFO32A ti;
1238 POINT32 pt;
1240 GetCursorPos32 (&pt);
1241 SendMessage32A (infoPtr->hwndToolTip, TTM_TRACKPOSITION, 0,
1242 (LPARAM)MAKELPARAM(pt.x, pt.y));
1244 ti.cbSize = sizeof(TTTOOLINFO32A);
1245 ti.uId = 0;
1246 ti.hwnd = (UINT32)wndPtr->hwndSelf;
1248 infoPtr->flags |= TB_SHOW_TOOLTIP;
1249 SetCapture32 (wndPtr->hwndSelf);
1250 SendMessage32A (infoPtr->hwndToolTip, TTM_TRACKACTIVATE,
1251 (WPARAM32)TRUE, (LPARAM)&ti);
1253 return 0;
1256 clickPos=TRACKBAR_ConvertPlaceToPosition (infoPtr, clickPlace, vertical);
1257 prevPos = infoPtr->nPos;
1259 if (clickPos > prevPos) { /* similar to VK_NEXT */
1260 infoPtr->nPos += infoPtr->nPageSize;
1261 if (infoPtr->nPos > infoPtr->nRangeMax)
1262 infoPtr->nPos = infoPtr->nRangeMax;
1263 TRACKBAR_SendNotify (wndPtr, TB_PAGEUP);
1264 } else {
1265 infoPtr->nPos -= infoPtr->nPageSize; /* similar to VK_PRIOR */
1266 if (infoPtr->nPos < infoPtr->nRangeMin)
1267 infoPtr->nPos = infoPtr->nRangeMin;
1268 TRACKBAR_SendNotify (wndPtr, TB_PAGEDOWN);
1271 if (prevPos!=infoPtr->nPos) {
1272 infoPtr->flags |=TB_THUMBPOSCHANGED;
1273 TRACKBAR_QueueRefresh (wndPtr);
1276 return 0;
1279 static LRESULT
1280 TRACKBAR_LButtonUp (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1282 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1284 TRACKBAR_QueueRefresh (wndPtr);
1285 TRACKBAR_SendNotify (wndPtr, TB_ENDTRACK);
1287 infoPtr->flags &= ~TB_DRAG_MODE;
1289 if (wndPtr->dwStyle & TBS_TOOLTIPS) { /* disable tooltip */
1290 TTTOOLINFO32A ti;
1292 ti.cbSize = sizeof(TTTOOLINFO32A);
1293 ti.uId = 0;
1294 ti.hwnd = (UINT32)wndPtr->hwndSelf;
1296 infoPtr->flags &= ~TB_SHOW_TOOLTIP;
1297 ReleaseCapture ();
1298 SendMessage32A (infoPtr->hwndToolTip, TTM_TRACKACTIVATE,
1299 (WPARAM32)FALSE, (LPARAM)&ti);
1302 return 0;
1305 static LRESULT
1306 TRACKBAR_CaptureChanged (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1308 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1310 if (infoPtr->flags & TB_DRAGPOSVALID) {
1311 infoPtr->nPos=infoPtr->dragPos;
1312 TRACKBAR_QueueRefresh (wndPtr);
1315 infoPtr->flags &= ~ TB_DRAGPOSVALID;
1317 TRACKBAR_SendNotify (wndPtr, TB_ENDTRACK);
1318 return 0;
1321 static LRESULT
1322 TRACKBAR_Paint (WND *wndPtr, WPARAM32 wParam)
1324 HDC32 hdc;
1325 PAINTSTRUCT32 ps;
1327 hdc = wParam==0 ? BeginPaint32 (wndPtr->hwndSelf, &ps) : (HDC32)wParam;
1328 TRACKBAR_Refresh (wndPtr, hdc);
1329 if(!wParam)
1330 EndPaint32 (wndPtr->hwndSelf, &ps);
1331 return 0;
1335 static LRESULT
1336 TRACKBAR_SetFocus (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1338 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1339 HDC32 hdc;
1341 TRACE (trackbar,"\n");
1342 infoPtr->bFocus = TRUE;
1344 hdc = GetDC32 (wndPtr->hwndSelf);
1345 TRACKBAR_Refresh (wndPtr, hdc);
1346 ReleaseDC32 (wndPtr->hwndSelf, hdc);
1348 return 0;
1352 static LRESULT
1353 TRACKBAR_Size (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1355 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1357 TRACKBAR_CalcChannel (wndPtr, infoPtr);
1358 TRACKBAR_AlignBuddies (wndPtr, infoPtr);
1360 return 0;
1365 static BOOL32
1366 TRACKBAR_SendNotify (WND *wndPtr, UINT32 code)
1369 TRACE (trackbar, "%x\n",code);
1370 if (wndPtr->dwStyle & TBS_VERT)
1371 return (BOOL32) SendMessage32A (GetParent32 (wndPtr->hwndSelf),
1372 WM_VSCROLL, (WPARAM32)code, (LPARAM) wndPtr->hwndSelf);
1374 return (BOOL32) SendMessage32A (GetParent32 (wndPtr->hwndSelf),
1375 WM_HSCROLL, (WPARAM32)code, (LPARAM) wndPtr->hwndSelf);
1376 return 0;
1379 static LRESULT
1380 TRACKBAR_MouseMove (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1382 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1383 INT32 clickPlace,vertical;
1384 HDC32 hdc;
1385 char buf[80];
1387 TRACE (trackbar, "%x\n",wParam);
1389 vertical=wndPtr->dwStyle & TBS_VERT;
1390 if (vertical)
1391 clickPlace=(INT32)HIWORD(lParam);
1392 else
1393 clickPlace=(INT32)LOWORD(lParam);
1395 if (!(infoPtr->flags & TB_DRAG_MODE)) return TRUE;
1397 infoPtr->dragPos=TRACKBAR_ConvertPlaceToPosition (infoPtr, clickPlace, vertical);
1398 infoPtr->flags|= TB_DRAGPOSVALID;
1399 TRACKBAR_SendNotify (wndPtr, TB_THUMBTRACK | (infoPtr->nPos>>16));
1401 if (infoPtr->flags & TB_SHOW_TOOLTIP) {
1402 POINT32 pt;
1403 TTTOOLINFO32A ti;
1405 ti.cbSize = sizeof(TTTOOLINFO32A);
1406 ti.hwnd = wndPtr->hwndSelf;
1407 ti.uId = 0;
1408 ti.hinst=0;
1409 sprintf (buf,"%d",infoPtr->nPos);
1410 ti.lpszText = (LPSTR) buf;
1411 GetCursorPos32 (&pt);
1413 if (vertical) {
1414 SendMessage32A (infoPtr->hwndToolTip, TTM_TRACKPOSITION,
1415 0, (LPARAM)MAKELPARAM(pt.x+5, pt.y+15));
1416 } else {
1417 SendMessage32A (infoPtr->hwndToolTip, TTM_TRACKPOSITION,
1418 0, (LPARAM)MAKELPARAM(pt.x+15, pt.y+5));
1420 SendMessage32A (infoPtr->hwndToolTip, TTM_UPDATETIPTEXT32A,
1421 0, (LPARAM)&ti);
1424 hdc = GetDC32 (wndPtr->hwndSelf);
1425 TRACKBAR_Refresh (wndPtr, hdc);
1426 ReleaseDC32 (wndPtr->hwndSelf, hdc);
1428 return TRUE;
1432 static LRESULT
1433 TRACKBAR_KeyDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1435 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1436 INT32 pos;
1438 TRACE (trackbar, "%x\n",wParam);
1440 pos=infoPtr->nPos;
1441 switch (wParam) {
1442 case VK_LEFT:
1443 case VK_UP:
1444 if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
1445 infoPtr->nPos -= infoPtr->nLineSize;
1446 if (infoPtr->nPos < infoPtr->nRangeMin)
1447 infoPtr->nPos = infoPtr->nRangeMin;
1448 TRACKBAR_SendNotify (wndPtr, TB_LINEUP);
1449 break;
1450 case VK_RIGHT:
1451 case VK_DOWN:
1452 if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
1453 infoPtr->nPos += infoPtr->nLineSize;
1454 if (infoPtr->nPos > infoPtr->nRangeMax)
1455 infoPtr->nPos = infoPtr->nRangeMax;
1456 TRACKBAR_SendNotify (wndPtr, TB_LINEDOWN);
1457 break;
1458 case VK_NEXT:
1459 if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
1460 infoPtr->nPos += infoPtr->nPageSize;
1461 if (infoPtr->nPos > infoPtr->nRangeMax)
1462 infoPtr->nPos = infoPtr->nRangeMax;
1463 TRACKBAR_SendNotify (wndPtr, TB_PAGEUP);
1464 break;
1465 case VK_PRIOR:
1466 if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
1467 infoPtr->nPos -= infoPtr->nPageSize;
1468 if (infoPtr->nPos < infoPtr->nRangeMin)
1469 infoPtr->nPos = infoPtr->nRangeMin;
1470 TRACKBAR_SendNotify (wndPtr, TB_PAGEDOWN);
1471 break;
1472 case VK_HOME:
1473 if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
1474 infoPtr->nPos = infoPtr->nRangeMin;
1475 TRACKBAR_SendNotify (wndPtr, TB_TOP);
1476 break;
1477 case VK_END:
1478 if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
1479 infoPtr->nPos = infoPtr->nRangeMax;
1480 TRACKBAR_SendNotify (wndPtr, TB_BOTTOM);
1481 break;
1484 if (pos!=infoPtr->nPos) {
1485 infoPtr->flags |=TB_THUMBPOSCHANGED;
1486 TRACKBAR_QueueRefresh (wndPtr);
1489 return TRUE;
1492 static LRESULT
1493 TRACKBAR_KeyUp (WND *wndPtr, WPARAM32 wParam)
1495 switch (wParam) {
1496 case VK_LEFT:
1497 case VK_UP:
1498 case VK_RIGHT:
1499 case VK_DOWN:
1500 case VK_NEXT:
1501 case VK_PRIOR:
1502 case VK_HOME:
1503 case VK_END: TRACKBAR_SendNotify (wndPtr, TB_ENDTRACK);
1505 return TRUE;
1509 static LRESULT
1510 TRACKBAR_HandleTimer ( WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1512 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1513 HDC32 hdc;
1515 TRACE (trackbar,"timer\n");
1517 switch (wParam) {
1518 case TB_REFRESH_TIMER:
1519 KillTimer32 (wndPtr->hwndSelf, TB_REFRESH_TIMER );
1520 if (infoPtr->flags & TB_DRAGPOSVALID) {
1521 infoPtr->nPos=infoPtr->dragPos;
1522 infoPtr->flags |= TB_THUMBPOSCHANGED;
1524 infoPtr->flags &= ~ (TB_REFRESH_TIMER_SET | TB_DRAGPOSVALID);
1525 hdc=GetDC32 (wndPtr->hwndSelf);
1526 TRACKBAR_Refresh (wndPtr, hdc);
1527 ReleaseDC32 (wndPtr->hwndSelf, hdc);
1528 return 0;
1530 return 1;
1534 LRESULT WINAPI
1535 TRACKBAR_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
1537 WND *wndPtr = WIN_FindWndPtr(hwnd);
1539 /* TRACE (trackbar, "msg %04x wp=%08x lp=%08lx\n", uMsg, wParam, lParam); */
1541 switch (uMsg)
1543 case TBM_CLEARSEL:
1544 return TRACKBAR_ClearSel (wndPtr, wParam, lParam);
1546 case TBM_CLEARTICS:
1547 return TRACKBAR_ClearTics (wndPtr, wParam, lParam);
1549 case TBM_GETBUDDY:
1550 return TRACKBAR_GetBuddy (wndPtr, wParam, lParam);
1552 case TBM_GETCHANNELRECT:
1553 return TRACKBAR_GetChannelRect (wndPtr, wParam, lParam);
1555 case TBM_GETLINESIZE:
1556 return TRACKBAR_GetLineSize (wndPtr, wParam, lParam);
1558 case TBM_GETNUMTICS:
1559 return TRACKBAR_GetNumTics (wndPtr, wParam, lParam);
1561 case TBM_GETPAGESIZE:
1562 return TRACKBAR_GetPageSize (wndPtr, wParam, lParam);
1564 case TBM_GETPOS:
1565 return TRACKBAR_GetPos (wndPtr, wParam, lParam);
1567 case TBM_GETPTICS:
1568 return TRACKBAR_GetPTics (wndPtr);
1570 case TBM_GETRANGEMAX:
1571 return TRACKBAR_GetRangeMax (wndPtr, wParam, lParam);
1573 case TBM_GETRANGEMIN:
1574 return TRACKBAR_GetRangeMin (wndPtr, wParam, lParam);
1576 case TBM_GETSELEND:
1577 return TRACKBAR_GetSelEnd (wndPtr, wParam, lParam);
1579 case TBM_GETSELSTART:
1580 return TRACKBAR_GetSelStart (wndPtr, wParam, lParam);
1582 case TBM_GETTHUMBLENGTH:
1583 return TRACKBAR_GetThumbLength (wndPtr, wParam, lParam);
1585 case TBM_GETTHUMBRECT:
1586 return TRACKBAR_GetThumbRect (wndPtr, wParam, lParam);
1588 case TBM_GETTIC:
1589 return TRACKBAR_GetTic (wndPtr, wParam, lParam);
1591 case TBM_GETTICPOS:
1592 return TRACKBAR_GetTicPos (wndPtr, wParam, lParam);
1594 case TBM_GETTOOLTIPS:
1595 return TRACKBAR_GetToolTips (wndPtr, wParam, lParam);
1597 /* case TBM_GETUNICODEFORMAT: */
1599 case TBM_SETBUDDY:
1600 return TRACKBAR_SetBuddy (wndPtr, wParam, lParam);
1602 case TBM_SETLINESIZE:
1603 return TRACKBAR_SetLineSize (wndPtr, wParam, lParam);
1605 case TBM_SETPAGESIZE:
1606 return TRACKBAR_SetPageSize (wndPtr, wParam, lParam);
1608 case TBM_SETPOS:
1609 return TRACKBAR_SetPos (wndPtr, wParam, lParam);
1611 case TBM_SETRANGE:
1612 return TRACKBAR_SetRange (wndPtr, wParam, lParam);
1614 case TBM_SETRANGEMAX:
1615 return TRACKBAR_SetRangeMax (wndPtr, wParam, lParam);
1617 case TBM_SETRANGEMIN:
1618 return TRACKBAR_SetRangeMin (wndPtr, wParam, lParam);
1620 case TBM_SETSEL:
1621 return TRACKBAR_SetSel (wndPtr, wParam, lParam);
1623 case TBM_SETSELEND:
1624 return TRACKBAR_SetSelEnd (wndPtr, wParam, lParam);
1626 case TBM_SETSELSTART:
1627 return TRACKBAR_SetSelStart (wndPtr, wParam, lParam);
1629 case TBM_SETTHUMBLENGTH:
1630 return TRACKBAR_SetThumbLength (wndPtr, wParam, lParam);
1632 case TBM_SETTIC:
1633 return TRACKBAR_SetTic (wndPtr, wParam, lParam);
1635 case TBM_SETTICFREQ:
1636 return TRACKBAR_SetTicFreq (wndPtr, wParam);
1639 case TBM_SETTIPSIDE:
1640 return TRACKBAR_SetTipSide (wndPtr, wParam, lParam);
1642 case TBM_SETTOOLTIPS:
1643 return TRACKBAR_SetToolTips (wndPtr, wParam, lParam);
1645 /* case TBM_SETUNICODEFORMAT: */
1648 case WM_CAPTURECHANGED:
1649 return TRACKBAR_CaptureChanged (wndPtr, wParam, lParam);
1651 case WM_CREATE:
1652 return TRACKBAR_Create (wndPtr, wParam, lParam);
1654 case WM_DESTROY:
1655 return TRACKBAR_Destroy (wndPtr, wParam, lParam);
1657 /* case WM_ENABLE: */
1659 /* case WM_ERASEBKGND: */
1660 /* return 0; */
1662 case WM_GETDLGCODE:
1663 return DLGC_WANTARROWS;
1665 case WM_KEYDOWN:
1666 return TRACKBAR_KeyDown (wndPtr, wParam, lParam);
1668 case WM_KEYUP:
1669 return TRACKBAR_KeyUp (wndPtr, wParam);
1671 case WM_KILLFOCUS:
1672 return TRACKBAR_KillFocus (wndPtr, wParam, lParam);
1674 case WM_LBUTTONDOWN:
1675 return TRACKBAR_LButtonDown (wndPtr, wParam, lParam);
1677 case WM_LBUTTONUP:
1678 return TRACKBAR_LButtonUp (wndPtr, wParam, lParam);
1680 case WM_MOUSEMOVE:
1681 return TRACKBAR_MouseMove (wndPtr, wParam, lParam);
1683 case WM_PAINT:
1684 return TRACKBAR_Paint (wndPtr, wParam);
1686 case WM_SETFOCUS:
1687 return TRACKBAR_SetFocus (wndPtr, wParam, lParam);
1689 case WM_SIZE:
1690 return TRACKBAR_Size (wndPtr, wParam, lParam);
1692 case WM_TIMER:
1693 return TRACKBAR_HandleTimer (wndPtr, wParam, lParam);
1695 case WM_WININICHANGE:
1696 return TRACKBAR_InitializeThumb (wndPtr);
1698 default:
1699 if (uMsg >= WM_USER)
1700 ERR (trackbar, "unknown msg %04x wp=%08x lp=%08lx\n",
1701 uMsg, wParam, lParam);
1702 return DefWindowProc32A (hwnd, uMsg, wParam, lParam);
1704 return 0;
1708 VOID
1709 TRACKBAR_Register (VOID)
1711 WNDCLASS32A wndClass;
1713 if (GlobalFindAtom32A (TRACKBAR_CLASS32A)) return;
1715 ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
1716 wndClass.style = CS_GLOBALCLASS;
1717 wndClass.lpfnWndProc = (WNDPROC32)TRACKBAR_WindowProc;
1718 wndClass.cbClsExtra = 0;
1719 wndClass.cbWndExtra = sizeof(TRACKBAR_INFO *);
1720 wndClass.hCursor = LoadCursor32A (0, IDC_ARROW32A);
1721 wndClass.hbrBackground = (HBRUSH32)(COLOR_3DFACE + 1);
1722 wndClass.lpszClassName = TRACKBAR_CLASS32A;
1724 RegisterClass32A (&wndClass);
1728 VOID
1729 TRACKBAR_Unregister (VOID)
1731 if (GlobalFindAtom32A (TRACKBAR_CLASS32A))
1732 UnregisterClass32A (TRACKBAR_CLASS32A, (HINSTANCE32)NULL);