Recovery of release 990110 after disk crash.
[wine.git] / dlls / comctl32 / trackbar.c
blob65863b405810ca1396e9d018062966cc7897ec87
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 "windows.h"
28 #include "commctrl.h"
29 #include "trackbar.h"
30 #include "win.h"
31 #include "debug.h"
34 #define TRACKBAR_GetInfoPtr(wndPtr) ((TRACKBAR_INFO *)wndPtr->wExtra[0])
37 /* Used by TRACKBAR_Refresh to find out which parts of the control
38 need to be recalculated */
40 #define TB_THUMBPOSCHANGED 1
41 #define TB_THUMBSIZECHANGED 2
42 #define TB_THUMBCHANGED (TB_THUMBPOSCHANGED | TB_THUMBPOSCHANGED)
43 #define TB_SELECTIONCHANGED 4
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?*/
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)
59 static BOOL32 TRACKBAR_SendNotify (WND *wndPtr, UINT32 code);
61 void TRACKBAR_RecalculateTics (TRACKBAR_INFO *infoPtr)
64 int i,tic,nrTics;
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;
76 if (nrTics!=infoPtr->uNumTics) {
77 infoPtr->tics=COMCTL32_ReAlloc (infoPtr->tics, (nrTics+1)*sizeof (DWORD));
78 infoPtr->uNumTics=nrTics;
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;
87 /* converts from physical (mouse) position to logical position
88 (in range of trackbar) */
90 static inline INT32
91 TRACKBAR_ConvertPlaceToPosition (TRACKBAR_INFO *infoPtr, int place,
92 int vertical)
94 double range,width,pos;
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;
105 TRACE (trackbar,"%.2f\n",pos);
106 return pos;
111 static VOID
112 TRACKBAR_CalcChannel (WND *wndPtr, TRACKBAR_INFO *infoPtr)
114 INT32 cyChannel;
115 RECT32 lpRect,*channel = & infoPtr->rcChannel;
117 GetClientRect32 (wndPtr->hwndSelf, &lpRect);
119 if (wndPtr->dwStyle & TBS_ENABLESELRANGE)
120 cyChannel = MAX(infoPtr->uThumbLen - 8, 4);
121 else
122 cyChannel = 4;
124 if (wndPtr->dwStyle & TBS_VERT) {
125 channel->top = lpRect.top + 8;
126 channel->bottom = lpRect.bottom - 8;
128 if (wndPtr->dwStyle & TBS_BOTH) {
129 channel->left = (lpRect.right - cyChannel) / 2;
130 channel->right = (lpRect.right + cyChannel) / 2;
132 else if (wndPtr->dwStyle & TBS_LEFT) {
133 channel->left = lpRect.left + 10;
134 channel->right = channel->left + cyChannel;
136 else { /* TBS_RIGHT */
137 channel->right = lpRect.right - 10;
138 channel->left = channel->right - cyChannel;
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;
148 else if (wndPtr->dwStyle & TBS_TOP) {
149 channel->top = lpRect.top + 10;
150 channel->bottom = channel->top + cyChannel;
152 else { /* TBS_BOTTOM */
153 channel->bottom = lpRect.bottom - 10;
154 channel->top = channel->bottom - cyChannel;
159 static VOID
160 TRACKBAR_CalcThumb (WND *wndPtr, TRACKBAR_INFO *infoPtr)
163 RECT32 *thumb;
164 int range, width;
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;
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;
186 static VOID
187 TRACKBAR_CalcSelection (WND *wndPtr, TRACKBAR_INFO *infoPtr)
189 RECT32 *selection;
190 int range, width;
192 selection= & infoPtr->rcSelection;
193 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
194 width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
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;
217 static void
218 TRACKBAR_QueueRefresh (WND *wndPtr)
221 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
223 TRACE (trackbar,"queued\n");
224 if (infoPtr->flags & TB_REFRESH_TIMER_SET) {
225 KillTimer32 (wndPtr->hwndSelf, TB_REFRESH_TIMER);
228 SetTimer32 (wndPtr->hwndSelf, TB_REFRESH_TIMER, TB_REFRESH_DELAY, 0);
229 infoPtr->flags|=TB_REFRESH_TIMER_SET;
236 /* Trackbar drawing code. I like my spaghetti done milanese. */
238 /* ticPos is in tic-units, not in pixels */
240 static VOID
241 TRACKBAR_DrawHorizTic (TRACKBAR_INFO *infoPtr, HDC32 hdc, LONG ticPos,
242 int flags, COLORREF clrTic)
245 RECT32 rcChannel=infoPtr->rcChannel;
246 int x,y,width,range,side;
248 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
249 width=rcChannel.right - rcChannel.left;
251 if (flags & TBS_TOP) {
252 y=rcChannel.top-2;
253 side=-1;
254 } else {
255 y=rcChannel.bottom+2;
256 side=1;
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;
265 SetPixel32 (hdc, x,y+6*side, clrTic);
266 SetPixel32 (hdc, x,y+7*side, clrTic);
267 return;
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);
277 if (flags & TIC_EDGE) {
278 if (flags & TIC_LEFTEDGE)
279 x=rcChannel.left;
280 else
281 x=rcChannel.right;
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);
291 static VOID
292 TRACKBAR_DrawVertTic (TRACKBAR_INFO *infoPtr, HDC32 hdc, LONG ticPos,
293 int flags, COLORREF clrTic)
296 RECT32 rcChannel=infoPtr->rcChannel;
297 int x,y,width,range,side;
299 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
300 width=rcChannel.bottom - rcChannel.top;
302 if (flags & TBS_TOP) {
303 x=rcChannel.right-2;
304 side=-1;
305 } else {
306 x=rcChannel.left+2;
307 side=1;
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;
317 SetPixel32 (hdc, x+6*side, y, clrTic);
318 SetPixel32 (hdc, x+7*side, y, clrTic);
319 return;
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);
329 if (flags & TIC_EDGE) {
330 if (flags & TIC_LEFTEDGE)
331 y=rcChannel.top;
332 else
333 y=rcChannel.bottom;
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);
344 static VOID
345 TRACKBAR_DrawTics (TRACKBAR_INFO *infoPtr, HDC32 hdc, LONG ticPos,
346 int flags, COLORREF clrTic)
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;
359 if ((flags & TBS_TOP) || (flags & TBS_BOTH))
360 TRACKBAR_DrawHorizTic (infoPtr, hdc, ticPos, flags | TBS_TOP , clrTic);
362 if (!(flags & TBS_TOP) || (flags & TBS_BOTH))
363 TRACKBAR_DrawHorizTic (infoPtr, hdc, ticPos, flags, clrTic);
368 static VOID
369 TRACKBAR_Refresh (WND *wndPtr, HDC32 hdc)
371 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
372 RECT32 rcClient, rcChannel, rcSelection;
373 HBRUSH32 hBrush = CreateSolidBrush32 (infoPtr->clrBk);
374 int i;
376 GetClientRect32 (wndPtr->hwndSelf, &rcClient);
377 hBrush = CreateSolidBrush32 (infoPtr->clrBk);
378 FillRect32 (hdc, &rcClient, hBrush);
379 DeleteObject32 (hBrush);
381 if (infoPtr->flags & TB_REFRESH_TIMER_SET) {
382 KillTimer32 (wndPtr->hwndSelf, TB_REFRESH_TIMER);
383 infoPtr->flags &= ~TB_REFRESH_TIMER_SET;
386 if (infoPtr->flags & TB_DRAGPOSVALID) {
387 infoPtr->nPos=infoPtr->dragPos;
388 infoPtr->flags |= TB_THUMBPOSCHANGED;
391 if (infoPtr->flags & TB_THUMBCHANGED) {
392 TRACKBAR_CalcThumb (wndPtr, infoPtr);
393 if (infoPtr->flags & TB_THUMBSIZECHANGED)
394 TRACKBAR_CalcChannel (wndPtr, infoPtr);
396 if (infoPtr->flags & TB_SELECTIONCHANGED)
397 TRACKBAR_CalcSelection (wndPtr, infoPtr);
398 infoPtr->flags &= ~ (TB_THUMBCHANGED | TB_SELECTIONCHANGED | TB_DRAGPOSVALID);
400 /* draw channel */
402 rcChannel = infoPtr->rcChannel;
403 rcSelection= infoPtr->rcSelection;
404 DrawEdge32 (hdc, &rcChannel, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
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);
416 DeleteObject32 (hbr);
420 /* draw tics */
422 if (!(wndPtr->dwStyle & TBS_NOTICKS)) {
423 int ticFlags=wndPtr->dwStyle & 0x0f;
424 COLORREF clrTic=GetSysColor32 (COLOR_3DDKSHADOW);
426 for (i=0; i<infoPtr->uNumTics; i++)
427 TRACKBAR_DrawTics (infoPtr, hdc, infoPtr->tics[i],
428 ticFlags, clrTic);
430 TRACKBAR_DrawTics (infoPtr, hdc, 0, ticFlags | TIC_LEFTEDGE, clrTic);
431 TRACKBAR_DrawTics (infoPtr, hdc, 0, ticFlags | TIC_RIGHTEDGE, clrTic);
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);
442 /* draw thumb */
444 if (!(wndPtr->dwStyle & TBS_NOTHUMB)) {
446 HBRUSH32 hbr = CreateSolidBrush32 (COLOR_BACKGROUND);
447 RECT32 thumb = infoPtr->rcThumb;
449 SelectObject32 (hdc, hbr);
451 if (wndPtr->dwStyle & TBS_BOTH) {
452 FillRect32 (hdc, &thumb, hbr);
453 DrawEdge32 (hdc, &thumb, EDGE_RAISED, BF_TOPLEFT);
454 } else {
456 POINT32 points[6];
458 /* first, fill the thumb */
459 /* FIXME: revamp. check for TBS_VERT */
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);
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);
482 /* draw notch */
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);
496 DeleteObject32 (hbr);
499 if (infoPtr->bFocus)
500 DrawFocusRect32 (hdc, &rcClient);
506 static VOID
507 TRACKBAR_AlignBuddies (WND *wndPtr, TRACKBAR_INFO *infoPtr)
509 HWND32 hwndParent = GetParent32 (wndPtr->hwndSelf);
510 RECT32 rcSelf, rcBuddy;
511 INT32 x, y;
513 GetWindowRect32 (wndPtr->hwndSelf, &rcSelf);
514 MapWindowPoints32 (HWND_DESKTOP, hwndParent, (LPPOINT32)&rcSelf, 2);
516 /* align buddy left or above */
517 if (infoPtr->hwndBuddyLA) {
518 GetWindowRect32 (infoPtr->hwndBuddyLA, &rcBuddy);
519 MapWindowPoints32 (HWND_DESKTOP, hwndParent, (LPPOINT32)&rcBuddy, 2);
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);
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;
532 SetWindowPos32 (infoPtr->hwndBuddyLA, 0, x, y, 0, 0,
533 SWP_NOZORDER | SWP_NOSIZE);
537 /* align buddy right or below */
538 if (infoPtr->hwndBuddyRB) {
539 GetWindowRect32 (infoPtr->hwndBuddyRB, &rcBuddy);
540 MapWindowPoints32 (HWND_DESKTOP, hwndParent, (LPPOINT32)&rcBuddy, 2);
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;
547 else {
548 x = rcSelf.right;
549 y = (infoPtr->rcChannel.bottom + infoPtr->rcChannel.top) / 2 -
550 (rcBuddy.bottom - rcBuddy.top) / 2 + rcSelf.top;
552 SetWindowPos32 (infoPtr->hwndBuddyRB, 0, x, y, 0, 0,
553 SWP_NOZORDER | SWP_NOSIZE);
558 static LRESULT
559 TRACKBAR_ClearSel (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
561 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
563 infoPtr->nSelMin = 0;
564 infoPtr->nSelMax = 0;
565 infoPtr->flags |=TB_SELECTIONCHANGED;
567 if ((BOOL32)wParam) {
568 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
569 TRACKBAR_Refresh (wndPtr, hdc);
570 ReleaseDC32 (wndPtr->hwndSelf, hdc);
573 return 0;
577 static LRESULT
578 TRACKBAR_ClearTics (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
580 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
582 if (infoPtr->tics) {
583 COMCTL32_Free (infoPtr->tics);
584 infoPtr->tics = NULL;
585 infoPtr->uNumTics = 0;
588 if (wParam) {
589 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
590 TRACKBAR_Refresh (wndPtr, hdc);
591 ReleaseDC32 (wndPtr->hwndSelf, hdc);
594 return 0;
598 static LRESULT
599 TRACKBAR_GetBuddy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
601 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
603 if (wParam) /* buddy is left or above */
604 return (LRESULT)infoPtr->hwndBuddyLA;
606 /* buddy is right or below */
607 return (LRESULT) infoPtr->hwndBuddyRB;
611 static LRESULT
612 TRACKBAR_GetChannelRect (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
614 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
615 LPRECT32 lprc = (LPRECT32)lParam;
617 if (lprc == NULL)
618 return 0;
620 lprc->left = infoPtr->rcChannel.left;
621 lprc->right = infoPtr->rcChannel.right;
622 lprc->bottom = infoPtr->rcChannel.bottom;
623 lprc->top = infoPtr->rcChannel.top;
625 return 0;
629 static LRESULT
630 TRACKBAR_GetLineSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
632 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
634 return infoPtr->nLineSize;
638 static LRESULT
639 TRACKBAR_GetNumTics (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
641 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
643 if (wndPtr->dwStyle & TBS_NOTICKS)
644 return 0;
646 return infoPtr->uNumTics+2;
650 static LRESULT
651 TRACKBAR_GetPageSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
653 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
655 return infoPtr->nPageSize;
659 static LRESULT
660 TRACKBAR_GetPos (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
662 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
664 return infoPtr->nPos;
670 static LRESULT
671 TRACKBAR_GetRangeMax (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
673 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
675 return infoPtr->nRangeMax;
679 static LRESULT
680 TRACKBAR_GetRangeMin (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
682 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
684 return infoPtr->nRangeMin;
688 static LRESULT
689 TRACKBAR_GetSelEnd (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
691 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
693 return infoPtr->nSelMax;
697 static LRESULT
698 TRACKBAR_GetSelStart (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
700 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
702 return infoPtr->nSelMin;
706 static LRESULT
707 TRACKBAR_GetThumbLength (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
709 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
711 return infoPtr->uThumbLen;
714 static LRESULT
715 TRACKBAR_GetPTics (WND *wndPtr)
717 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
719 return (LRESULT) infoPtr->tics;
722 static LRESULT
723 TRACKBAR_GetThumbRect (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
725 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
726 LPRECT32 lprc = (LPRECT32)lParam;
728 if (lprc == NULL)
729 return 0;
731 lprc->left = infoPtr->rcThumb.left;
732 lprc->right = infoPtr->rcThumb.right;
733 lprc->bottom = infoPtr->rcThumb.bottom;
734 lprc->top = infoPtr->rcThumb.top;
736 return 0;
743 static LRESULT
744 TRACKBAR_GetTic (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
747 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
748 INT32 iTic;
750 iTic=(INT32) wParam;
751 if ((iTic<0) || (iTic>infoPtr->uNumTics))
752 return -1;
754 return (LRESULT) infoPtr->tics[iTic];
759 static LRESULT
760 TRACKBAR_GetTicPos (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
763 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
764 INT32 iTic, range, width, pos;
767 iTic=(INT32 ) wParam;
768 if ((iTic<0) || (iTic>infoPtr->uNumTics))
769 return -1;
771 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
772 width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
773 pos=infoPtr->rcChannel.left + (width * infoPtr->tics[iTic]) / range;
776 return (LRESULT) pos;
779 static LRESULT
780 TRACKBAR_GetToolTips (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
782 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
784 if (wndPtr->dwStyle & TBS_TOOLTIPS)
785 return (LRESULT)infoPtr->hwndToolTip;
786 return 0;
790 /* case TBM_GETUNICODEFORMAT: */
793 static LRESULT
794 TRACKBAR_SetBuddy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
796 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
797 HWND32 hwndTemp;
799 if (wParam) {
800 /* buddy is left or above */
801 hwndTemp = infoPtr->hwndBuddyLA;
802 infoPtr->hwndBuddyLA = (HWND32)lParam;
804 FIXME (trackbar, "move buddy!\n");
806 else {
807 /* buddy is right or below */
808 hwndTemp = infoPtr->hwndBuddyRB;
809 infoPtr->hwndBuddyRB = (HWND32)lParam;
811 FIXME (trackbar, "move buddy!\n");
814 TRACKBAR_AlignBuddies (wndPtr, infoPtr);
816 return (LRESULT)hwndTemp;
820 static LRESULT
821 TRACKBAR_SetLineSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
823 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
824 INT32 nTemp = infoPtr->nLineSize;
826 infoPtr->nLineSize = (INT32)lParam;
828 return nTemp;
832 static LRESULT
833 TRACKBAR_SetPageSize (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
835 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
836 INT32 nTemp = infoPtr->nPageSize;
838 infoPtr->nPageSize = (INT32)lParam;
840 return nTemp;
844 static LRESULT
845 TRACKBAR_SetPos (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
847 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
849 infoPtr->nPos = (INT32)HIWORD(lParam);
851 if (infoPtr->nPos < infoPtr->nRangeMin)
852 infoPtr->nPos = infoPtr->nRangeMin;
854 if (infoPtr->nPos > infoPtr->nRangeMax)
855 infoPtr->nPos = infoPtr->nRangeMax;
856 infoPtr->flags |=TB_THUMBPOSCHANGED;
858 if (wParam) {
859 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
860 TRACKBAR_Refresh (wndPtr, hdc);
861 ReleaseDC32 (wndPtr->hwndSelf, hdc);
864 return 0;
868 static LRESULT
869 TRACKBAR_SetRange (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
871 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
872 infoPtr->nRangeMin = (INT32)LOWORD(lParam);
873 infoPtr->nRangeMax = (INT32)HIWORD(lParam);
875 if (infoPtr->nPos < infoPtr->nRangeMin) {
876 infoPtr->nPos = infoPtr->nRangeMin;
877 infoPtr->flags |=TB_THUMBPOSCHANGED;
880 if (infoPtr->nPos > infoPtr->nRangeMax) {
881 infoPtr->nPos = infoPtr->nRangeMax;
882 infoPtr->flags |=TB_THUMBPOSCHANGED;
885 infoPtr->nPageSize=(infoPtr->nRangeMax - infoPtr->nRangeMin)/5;
886 TRACKBAR_RecalculateTics (infoPtr);
888 if (wParam) {
889 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
890 TRACKBAR_Refresh (wndPtr, hdc);
891 ReleaseDC32 (wndPtr->hwndSelf, hdc);
894 return 0;
898 static LRESULT
899 TRACKBAR_SetRangeMax (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
901 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
903 infoPtr->nRangeMax = (INT32)lParam;
904 if (infoPtr->nPos > infoPtr->nRangeMax) {
905 infoPtr->nPos = infoPtr->nRangeMax;
906 infoPtr->flags |=TB_THUMBPOSCHANGED;
909 infoPtr->nPageSize=(infoPtr->nRangeMax - infoPtr->nRangeMin)/5;
910 TRACKBAR_RecalculateTics (infoPtr);
912 if (wParam) {
913 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
914 TRACKBAR_Refresh (wndPtr, hdc);
915 ReleaseDC32 (wndPtr->hwndSelf, hdc);
918 return 0;
922 static LRESULT
923 TRACKBAR_SetRangeMin (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
925 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
927 infoPtr->nRangeMin = (INT32)lParam;
928 if (infoPtr->nPos < infoPtr->nRangeMin) {
929 infoPtr->nPos = infoPtr->nRangeMin;
930 infoPtr->flags |=TB_THUMBPOSCHANGED;
933 infoPtr->nPageSize=(infoPtr->nRangeMax - infoPtr->nRangeMin)/5;
934 TRACKBAR_RecalculateTics (infoPtr);
936 if (wParam) {
937 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
938 TRACKBAR_Refresh (wndPtr, hdc);
939 ReleaseDC32 (wndPtr->hwndSelf, hdc);
942 return 0;
945 static LRESULT
946 TRACKBAR_SetTicFreq (WND *wndPtr, WPARAM32 wParam)
948 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
949 HDC32 hdc;
951 if (wndPtr->dwStyle & TBS_AUTOTICKS)
952 infoPtr->uTicFreq=(UINT32) wParam;
954 TRACKBAR_RecalculateTics (infoPtr);
956 hdc = GetDC32 (wndPtr->hwndSelf);
957 TRACKBAR_Refresh (wndPtr, hdc);
958 ReleaseDC32 (wndPtr->hwndSelf, hdc);
959 return 0;
963 static LRESULT
964 TRACKBAR_SetSel (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
966 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
968 infoPtr->nSelMin = (INT32)LOWORD(lParam);
969 infoPtr->nSelMax = (INT32)HIWORD(lParam);
970 infoPtr->flags |=TB_SELECTIONCHANGED;
972 if (!wndPtr->dwStyle & TBS_ENABLESELRANGE)
973 return 0;
975 if (infoPtr->nSelMin < infoPtr->nRangeMin)
976 infoPtr->nSelMin = infoPtr->nRangeMin;
977 if (infoPtr->nSelMax > infoPtr->nRangeMax)
978 infoPtr->nSelMax = infoPtr->nRangeMax;
980 if (wParam) {
981 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
982 TRACKBAR_Refresh (wndPtr, hdc);
983 ReleaseDC32 (wndPtr->hwndSelf, hdc);
986 return 0;
990 static LRESULT
991 TRACKBAR_SetSelEnd (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
993 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
995 if (!wndPtr->dwStyle & TBS_ENABLESELRANGE)
996 return 0;
998 infoPtr->nSelMax = (INT32)lParam;
999 infoPtr->flags |=TB_SELECTIONCHANGED;
1001 if (infoPtr->nSelMax > infoPtr->nRangeMax)
1002 infoPtr->nSelMax = infoPtr->nRangeMax;
1004 if (wParam) {
1005 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
1006 TRACKBAR_Refresh (wndPtr, hdc);
1007 ReleaseDC32 (wndPtr->hwndSelf, hdc);
1010 return 0;
1014 static LRESULT
1015 TRACKBAR_SetSelStart (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1017 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1019 if (!wndPtr->dwStyle & TBS_ENABLESELRANGE)
1020 return 0;
1022 infoPtr->nSelMin = (INT32)lParam;
1023 infoPtr->flags |=TB_SELECTIONCHANGED;
1024 if (infoPtr->nSelMin < infoPtr->nRangeMin)
1025 infoPtr->nSelMin = infoPtr->nRangeMin;
1027 if (wParam) {
1028 HDC32 hdc = GetDC32 (wndPtr->hwndSelf);
1029 TRACKBAR_Refresh (wndPtr, hdc);
1030 ReleaseDC32 (wndPtr->hwndSelf, hdc);
1033 return 0;
1037 static LRESULT
1038 TRACKBAR_SetThumbLength (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1040 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1041 HDC32 hdc;
1043 if (wndPtr->dwStyle & TBS_FIXEDLENGTH)
1044 infoPtr->uThumbLen = (UINT32)wParam;
1046 hdc = GetDC32 (wndPtr->hwndSelf);
1047 infoPtr->flags |=TB_THUMBSIZECHANGED;
1048 TRACKBAR_Refresh (wndPtr, hdc);
1049 ReleaseDC32 (wndPtr->hwndSelf, hdc);
1051 return 0;
1055 static LRESULT
1056 TRACKBAR_SetTic (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1058 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1059 INT32 nPos = (INT32)lParam;
1060 HDC32 hdc;
1062 if ((nPos < infoPtr->nRangeMin) || (nPos> infoPtr->nRangeMax))
1063 return FALSE;
1065 infoPtr->uNumTics++;
1066 infoPtr->tics=COMCTL32_ReAlloc( infoPtr->tics,
1067 (infoPtr->uNumTics)*sizeof (DWORD));
1068 infoPtr->tics[infoPtr->uNumTics-1]=nPos;
1070 hdc = GetDC32 (wndPtr->hwndSelf);
1071 TRACKBAR_Refresh (wndPtr, hdc);
1072 ReleaseDC32 (wndPtr->hwndSelf, hdc);
1074 return TRUE;
1080 static LRESULT
1081 TRACKBAR_SetTipSide (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1083 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1084 INT32 fTemp = infoPtr->fLocation;
1086 infoPtr->fLocation = (INT32)wParam;
1088 return fTemp;
1092 static LRESULT
1093 TRACKBAR_SetToolTips (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1095 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1097 infoPtr->hwndToolTip = (HWND32)wParam;
1099 return 0;
1103 /* case TBM_SETUNICODEFORMAT: */
1106 static LRESULT
1107 TRACKBAR_InitializeThumb (WND *wndPtr)
1109 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1111 infoPtr->uThumbLen = 23; /* initial thumb length */
1113 TRACKBAR_CalcChannel (wndPtr,infoPtr);
1114 TRACKBAR_CalcThumb (wndPtr, infoPtr);
1115 infoPtr->flags &= ~TB_SELECTIONCHANGED;
1117 return 0;
1121 static LRESULT
1122 TRACKBAR_Create (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1124 TRACKBAR_INFO *infoPtr;
1126 infoPtr = (TRACKBAR_INFO *)COMCTL32_Alloc (sizeof(TRACKBAR_INFO));
1127 wndPtr->wExtra[0] = (DWORD)infoPtr;
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;
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);
1144 TRACKBAR_InitializeThumb (wndPtr);
1146 if (wndPtr->dwStyle & TBS_TOOLTIPS) { /* Create tooltip control */
1147 TTTOOLINFO32A ti;
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);
1155 /* Send NM_TOOLTIPSCREATED notification */
1156 if (infoPtr->hwndToolTip) {
1157 NMTOOLTIPSCREATED nmttc;
1159 nmttc.hdr.hwndFrom = wndPtr->hwndSelf;
1160 nmttc.hdr.idFrom = wndPtr->wIDmenu;
1161 nmttc.hdr.code = NM_TOOLTIPSCREATED;
1162 nmttc.hwndToolTips = infoPtr->hwndToolTip;
1164 SendMessage32A (GetParent32 (wndPtr->hwndSelf), WM_NOTIFY,
1165 (WPARAM32)wndPtr->wIDmenu, (LPARAM)&nmttc);
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);
1176 SendMessage32A (infoPtr->hwndToolTip, TTM_ADDTOOL32A, 0, (LPARAM)&ti);
1179 return 0;
1183 static LRESULT
1184 TRACKBAR_Destroy (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1186 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1188 if (infoPtr->flags & TB_REFRESH_TIMER_SET)
1189 KillTimer32 (wndPtr->hwndSelf, TB_REFRESH_TIMER);
1191 /* delete tooltip control */
1192 if (infoPtr->hwndToolTip)
1193 DestroyWindow32 (infoPtr->hwndToolTip);
1195 COMCTL32_Free (infoPtr);
1196 return 0;
1200 static LRESULT
1201 TRACKBAR_KillFocus (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1203 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1205 TRACE (trackbar,"\n");
1207 infoPtr->bFocus = FALSE;
1208 infoPtr->flags &= ~TB_DRAG_MODE;
1209 TRACKBAR_QueueRefresh (wndPtr);
1210 InvalidateRect32 (wndPtr->hwndSelf, NULL, TRUE);
1212 return 0;
1216 static LRESULT
1217 TRACKBAR_LButtonDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1219 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1220 int clickPlace,prevPos,clickPos,vertical;
1222 SetFocus32 (wndPtr->hwndSelf);
1224 vertical=wndPtr->dwStyle & TBS_VERT;
1225 if (vertical)
1226 clickPlace=(INT32)HIWORD(lParam);
1227 else
1228 clickPlace=(INT32)LOWORD(lParam);
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;
1241 GetCursorPos32 (&pt);
1242 SendMessage32A (infoPtr->hwndToolTip, TTM_TRACKPOSITION, 0,
1243 (LPARAM)MAKELPARAM(pt.x, pt.y));
1245 ti.cbSize = sizeof(TTTOOLINFO32A);
1246 ti.uId = 0;
1247 ti.hwnd = (UINT32)wndPtr->hwndSelf;
1249 infoPtr->flags |= TB_SHOW_TOOLTIP;
1250 SetCapture32 (wndPtr->hwndSelf);
1251 SendMessage32A (infoPtr->hwndToolTip, TTM_TRACKACTIVATE,
1252 (WPARAM32)TRUE, (LPARAM)&ti);
1254 return 0;
1257 clickPos=TRACKBAR_ConvertPlaceToPosition (infoPtr, clickPlace, vertical);
1258 prevPos = infoPtr->nPos;
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);
1272 if (prevPos!=infoPtr->nPos) {
1273 infoPtr->flags |=TB_THUMBPOSCHANGED;
1274 TRACKBAR_QueueRefresh (wndPtr);
1277 return 0;
1280 static LRESULT
1281 TRACKBAR_LButtonUp (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1283 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1285 TRACKBAR_QueueRefresh (wndPtr);
1286 TRACKBAR_SendNotify (wndPtr, TB_ENDTRACK);
1288 infoPtr->flags &= ~TB_DRAG_MODE;
1290 if (wndPtr->dwStyle & TBS_TOOLTIPS) { /* disable tooltip */
1291 TTTOOLINFO32A ti;
1293 ti.cbSize = sizeof(TTTOOLINFO32A);
1294 ti.uId = 0;
1295 ti.hwnd = (UINT32)wndPtr->hwndSelf;
1297 infoPtr->flags &= ~TB_SHOW_TOOLTIP;
1298 ReleaseCapture ();
1299 SendMessage32A (infoPtr->hwndToolTip, TTM_TRACKACTIVATE,
1300 (WPARAM32)FALSE, (LPARAM)&ti);
1303 return 0;
1306 static LRESULT
1307 TRACKBAR_CaptureChanged (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1309 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1311 if (infoPtr->flags & TB_DRAGPOSVALID) {
1312 infoPtr->nPos=infoPtr->dragPos;
1313 TRACKBAR_QueueRefresh (wndPtr);
1316 infoPtr->flags &= ~ TB_DRAGPOSVALID;
1318 TRACKBAR_SendNotify (wndPtr, TB_ENDTRACK);
1319 return 0;
1322 static LRESULT
1323 TRACKBAR_Paint (WND *wndPtr, WPARAM32 wParam)
1325 HDC32 hdc;
1326 PAINTSTRUCT32 ps;
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;
1336 static LRESULT
1337 TRACKBAR_SetFocus (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1339 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1340 HDC32 hdc;
1342 TRACE (trackbar,"\n");
1343 infoPtr->bFocus = TRUE;
1345 hdc = GetDC32 (wndPtr->hwndSelf);
1346 TRACKBAR_Refresh (wndPtr, hdc);
1347 ReleaseDC32 (wndPtr->hwndSelf, hdc);
1349 return 0;
1353 static LRESULT
1354 TRACKBAR_Size (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1356 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1358 TRACKBAR_CalcChannel (wndPtr, infoPtr);
1359 TRACKBAR_AlignBuddies (wndPtr, infoPtr);
1361 return 0;
1366 static BOOL32
1367 TRACKBAR_SendNotify (WND *wndPtr, UINT32 code)
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);
1375 return (BOOL32) SendMessage32A (GetParent32 (wndPtr->hwndSelf),
1376 WM_HSCROLL, (WPARAM32)code, (LPARAM) wndPtr->hwndSelf);
1377 return 0;
1380 static LRESULT
1381 TRACKBAR_MouseMove (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1383 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1384 INT32 clickPlace,vertical;
1385 HDC32 hdc;
1386 char buf[80];
1388 TRACE (trackbar, "%x\n",wParam);
1390 vertical=wndPtr->dwStyle & TBS_VERT;
1391 if (vertical)
1392 clickPlace=(INT32)HIWORD(lParam);
1393 else
1394 clickPlace=(INT32)LOWORD(lParam);
1396 if (!(infoPtr->flags & TB_DRAG_MODE)) return TRUE;
1398 infoPtr->dragPos=TRACKBAR_ConvertPlaceToPosition (infoPtr, clickPlace, vertical);
1399 infoPtr->flags|= TB_DRAGPOSVALID;
1400 TRACKBAR_SendNotify (wndPtr, TB_THUMBTRACK | (infoPtr->nPos>>16));
1402 if (infoPtr->flags & TB_SHOW_TOOLTIP) {
1403 POINT32 pt;
1404 TTTOOLINFO32A ti;
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);
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));
1421 SendMessage32A (infoPtr->hwndToolTip, TTM_UPDATETIPTEXT32A,
1422 0, (LPARAM)&ti);
1425 hdc = GetDC32 (wndPtr->hwndSelf);
1426 TRACKBAR_Refresh (wndPtr, hdc);
1427 ReleaseDC32 (wndPtr->hwndSelf, hdc);
1429 return TRUE;
1433 static LRESULT
1434 TRACKBAR_KeyDown (WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1436 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1437 INT32 pos;
1439 TRACE (trackbar, "%x\n",wParam);
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;
1485 if (pos!=infoPtr->nPos) {
1486 infoPtr->flags |=TB_THUMBPOSCHANGED;
1487 TRACKBAR_QueueRefresh (wndPtr);
1490 return TRUE;
1493 static LRESULT
1494 TRACKBAR_KeyUp (WND *wndPtr, WPARAM32 wParam)
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);
1506 return TRUE;
1510 static LRESULT
1511 TRACKBAR_HandleTimer ( WND *wndPtr, WPARAM32 wParam, LPARAM lParam)
1513 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr(wndPtr);
1514 HDC32 hdc;
1516 TRACE (trackbar,"timer\n");
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;
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;
1531 return 1;
1535 LRESULT WINAPI
1536 TRACKBAR_WindowProc (HWND32 hwnd, UINT32 uMsg, WPARAM32 wParam, LPARAM lParam)
1538 WND *wndPtr = WIN_FindWndPtr(hwnd);
1540 /* TRACE (trackbar, "msg %04x wp=%08x lp=%08lx\n", uMsg, wParam, lParam); */
1542 switch (uMsg)
1544 case TBM_CLEARSEL:
1545 return TRACKBAR_ClearSel (wndPtr, wParam, lParam);
1547 case TBM_CLEARTICS:
1548 return TRACKBAR_ClearTics (wndPtr, wParam, lParam);
1550 case TBM_GETBUDDY:
1551 return TRACKBAR_GetBuddy (wndPtr, wParam, lParam);
1553 case TBM_GETCHANNELRECT:
1554 return TRACKBAR_GetChannelRect (wndPtr, wParam, lParam);
1556 case TBM_GETLINESIZE:
1557 return TRACKBAR_GetLineSize (wndPtr, wParam, lParam);
1559 case TBM_GETNUMTICS:
1560 return TRACKBAR_GetNumTics (wndPtr, wParam, lParam);
1562 case TBM_GETPAGESIZE:
1563 return TRACKBAR_GetPageSize (wndPtr, wParam, lParam);
1565 case TBM_GETPOS:
1566 return TRACKBAR_GetPos (wndPtr, wParam, lParam);
1568 case TBM_GETPTICS:
1569 return TRACKBAR_GetPTics (wndPtr);
1571 case TBM_GETRANGEMAX:
1572 return TRACKBAR_GetRangeMax (wndPtr, wParam, lParam);
1574 case TBM_GETRANGEMIN:
1575 return TRACKBAR_GetRangeMin (wndPtr, wParam, lParam);
1577 case TBM_GETSELEND:
1578 return TRACKBAR_GetSelEnd (wndPtr, wParam, lParam);
1580 case TBM_GETSELSTART:
1581 return TRACKBAR_GetSelStart (wndPtr, wParam, lParam);
1583 case TBM_GETTHUMBLENGTH:
1584 return TRACKBAR_GetThumbLength (wndPtr, wParam, lParam);
1586 case TBM_GETTHUMBRECT:
1587 return TRACKBAR_GetThumbRect (wndPtr, wParam, lParam);
1589 case TBM_GETTIC:
1590 return TRACKBAR_GetTic (wndPtr, wParam, lParam);
1592 case TBM_GETTICPOS:
1593 return TRACKBAR_GetTicPos (wndPtr, wParam, lParam);
1595 case TBM_GETTOOLTIPS:
1596 return TRACKBAR_GetToolTips (wndPtr, wParam, lParam);
1598 /* case TBM_GETUNICODEFORMAT: */
1600 case TBM_SETBUDDY:
1601 return TRACKBAR_SetBuddy (wndPtr, wParam, lParam);
1603 case TBM_SETLINESIZE:
1604 return TRACKBAR_SetLineSize (wndPtr, wParam, lParam);
1606 case TBM_SETPAGESIZE:
1607 return TRACKBAR_SetPageSize (wndPtr, wParam, lParam);
1609 case TBM_SETPOS:
1610 return TRACKBAR_SetPos (wndPtr, wParam, lParam);
1612 case TBM_SETRANGE:
1613 return TRACKBAR_SetRange (wndPtr, wParam, lParam);
1615 case TBM_SETRANGEMAX:
1616 return TRACKBAR_SetRangeMax (wndPtr, wParam, lParam);
1618 case TBM_SETRANGEMIN:
1619 return TRACKBAR_SetRangeMin (wndPtr, wParam, lParam);
1621 case TBM_SETSEL:
1622 return TRACKBAR_SetSel (wndPtr, wParam, lParam);
1624 case TBM_SETSELEND:
1625 return TRACKBAR_SetSelEnd (wndPtr, wParam, lParam);
1627 case TBM_SETSELSTART:
1628 return TRACKBAR_SetSelStart (wndPtr, wParam, lParam);
1630 case TBM_SETTHUMBLENGTH:
1631 return TRACKBAR_SetThumbLength (wndPtr, wParam, lParam);
1633 case TBM_SETTIC:
1634 return TRACKBAR_SetTic (wndPtr, wParam, lParam);
1636 case TBM_SETTICFREQ:
1637 return TRACKBAR_SetTicFreq (wndPtr, wParam);
1640 case TBM_SETTIPSIDE:
1641 return TRACKBAR_SetTipSide (wndPtr, wParam, lParam);
1643 case TBM_SETTOOLTIPS:
1644 return TRACKBAR_SetToolTips (wndPtr, wParam, lParam);
1646 /* case TBM_SETUNICODEFORMAT: */
1649 case WM_CAPTURECHANGED:
1650 return TRACKBAR_CaptureChanged (wndPtr, wParam, lParam);
1652 case WM_CREATE:
1653 return TRACKBAR_Create (wndPtr, wParam, lParam);
1655 case WM_DESTROY:
1656 return TRACKBAR_Destroy (wndPtr, wParam, lParam);
1658 /* case WM_ENABLE: */
1660 /* case WM_ERASEBKGND: */
1661 /* return 0; */
1663 case WM_GETDLGCODE:
1664 return DLGC_WANTARROWS;
1666 case WM_KEYDOWN:
1667 return TRACKBAR_KeyDown (wndPtr, wParam, lParam);
1669 case WM_KEYUP:
1670 return TRACKBAR_KeyUp (wndPtr, wParam);
1672 case WM_KILLFOCUS:
1673 return TRACKBAR_KillFocus (wndPtr, wParam, lParam);
1675 case WM_LBUTTONDOWN:
1676 return TRACKBAR_LButtonDown (wndPtr, wParam, lParam);
1678 case WM_LBUTTONUP:
1679 return TRACKBAR_LButtonUp (wndPtr, wParam, lParam);
1681 case WM_MOUSEMOVE:
1682 return TRACKBAR_MouseMove (wndPtr, wParam, lParam);
1684 case WM_PAINT:
1685 return TRACKBAR_Paint (wndPtr, wParam);
1687 case WM_SETFOCUS:
1688 return TRACKBAR_SetFocus (wndPtr, wParam, lParam);
1690 case WM_SIZE:
1691 return TRACKBAR_Size (wndPtr, wParam, lParam);
1693 case WM_TIMER:
1694 return TRACKBAR_HandleTimer (wndPtr, wParam, lParam);
1696 case WM_WININICHANGE:
1697 return TRACKBAR_InitializeThumb (wndPtr);
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);
1705 return 0;
1709 VOID
1710 TRACKBAR_Register (VOID)
1712 WNDCLASS32A wndClass;
1714 if (GlobalFindAtom32A (TRACKBAR_CLASS32A)) return;
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;
1725 RegisterClass32A (&wndClass);
1729 VOID
1730 TRACKBAR_Unregister (VOID)
1732 if (GlobalFindAtom32A (TRACKBAR_CLASS32A))
1733 UnregisterClass32A (TRACKBAR_CLASS32A, (HINSTANCE32)NULL);