Abey George (of Macadamian/Corel)
[wine.git] / dlls / comctl32 / trackbar.c
blobdbcf2f3e90d1ee9d9022c057f1708bec08972a31
1 /*
2 * Trackbar control
4 * Copyright 1998, 1999 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.
26 #include <stdio.h>
28 #include "winbase.h"
29 #include "commctrl.h"
30 #include "trackbar.h"
31 #include "debugtools.h"
33 DEFAULT_DEBUG_CHANNEL(trackbar);
36 #define TRACKBAR_GetInfoPtr(wndPtr) ((TRACKBAR_INFO *)GetWindowLongA (hwnd,0))
39 /* Used by TRACKBAR_Refresh to find out which parts of the control
40 need to be recalculated */
42 #define TB_THUMBPOSCHANGED 1
43 #define TB_THUMBSIZECHANGED 2
44 #define TB_THUMBCHANGED (TB_THUMBPOSCHANGED | TB_THUMBPOSCHANGED)
45 #define TB_SELECTIONCHANGED 4
46 #define TB_DRAG_MODE 16 /* we're dragging the slider */
47 #define TB_DRAGPOSVALID 32 /* current Position is in dragPos */
48 #define TB_SHOW_TOOLTIP 64 /* tooltip-style enabled and tooltip on */
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 BOOL TRACKBAR_SendNotify (HWND hwnd, UINT code);
60 static void TRACKBAR_RecalculateTics (TRACKBAR_INFO *infoPtr)
62 int i,tic,nrTics;
64 if (infoPtr->uTicFreq && infoPtr->nRangeMax >= infoPtr->nRangeMin)
65 nrTics=(infoPtr->nRangeMax - infoPtr->nRangeMin)/infoPtr->uTicFreq;
66 else {
67 nrTics=0;
68 COMCTL32_Free (infoPtr->tics);
69 infoPtr->tics=NULL;
70 infoPtr->uNumTics=0;
71 return;
74 if (nrTics!=infoPtr->uNumTics) {
75 infoPtr->tics=COMCTL32_ReAlloc (infoPtr->tics,
76 (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 DOUBLE
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;
103 pos+=infoPtr->nRangeMin;
104 if (pos > infoPtr->nRangeMax)
105 pos = infoPtr->nRangeMax;
106 else if (pos < infoPtr->nRangeMin)
107 pos = infoPtr->nRangeMin;
109 TRACE("%.2f\n",pos);
110 return pos;
114 static VOID
115 TRACKBAR_CalcChannel (HWND hwnd, TRACKBAR_INFO *infoPtr)
117 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
118 INT cyChannel;
119 RECT lpRect,*channel = & infoPtr->rcChannel;
121 GetClientRect (hwnd, &lpRect);
123 if (dwStyle & TBS_ENABLESELRANGE)
124 cyChannel = max(infoPtr->uThumbLen - 8, 4);
125 else
126 cyChannel = 4;
128 if (dwStyle & TBS_VERT) {
129 channel->top = lpRect.top + 8;
130 channel->bottom = lpRect.bottom - 8;
132 if (dwStyle & TBS_BOTH) {
133 channel->left = (lpRect.right - cyChannel) / 2;
134 channel->right = (lpRect.right + cyChannel) / 2;
136 else if (dwStyle & TBS_LEFT) {
137 channel->left = lpRect.left + 10;
138 channel->right = channel->left + cyChannel;
140 else { /* TBS_RIGHT */
141 channel->right = lpRect.right - 10;
142 channel->left = channel->right - cyChannel;
145 else {
146 channel->left = lpRect.left + 8;
147 channel->right = lpRect.right - 8;
148 if (dwStyle & TBS_BOTH) {
149 channel->top = (lpRect.bottom - cyChannel) / 2;
150 channel->bottom = (lpRect.bottom + cyChannel) / 2;
152 else if (dwStyle & TBS_TOP) {
153 channel->top = lpRect.top + 10;
154 channel->bottom = channel->top + cyChannel;
156 else { /* TBS_BOTTOM */
157 channel->bottom = lpRect.bottom - 10;
158 channel->top = channel->bottom - cyChannel;
163 static VOID
164 TRACKBAR_CalcThumb (HWND hwnd, TRACKBAR_INFO *infoPtr)
166 RECT *thumb;
167 int range, width;
169 thumb=&infoPtr->rcThumb;
170 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
171 if (!range) return; /* FIXME: may this happen? */
172 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_VERT) {
173 width=infoPtr->rcChannel.bottom - infoPtr->rcChannel.top;
174 thumb->left = infoPtr->rcChannel.left - 1;
175 thumb->right = infoPtr->rcChannel.left + infoPtr->uThumbLen - 8;
176 thumb->top = infoPtr->rcChannel.top +
177 (width*infoPtr->nPos)/range - 5;
178 thumb->bottom = thumb->top + infoPtr->uThumbLen/3;
180 } else {
181 width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
182 thumb->left = infoPtr->rcChannel.left +
183 (width*infoPtr->nPos)/range - 5;
184 thumb->right = thumb->left + infoPtr->uThumbLen/3;
185 thumb->top = infoPtr->rcChannel.top - 1;
186 thumb->bottom = infoPtr->rcChannel.top + infoPtr->uThumbLen - 8;
190 static VOID
191 TRACKBAR_CalcSelection (HWND hwnd, TRACKBAR_INFO *infoPtr)
193 RECT *selection;
194 int range, width;
196 selection= & infoPtr->rcSelection;
197 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
198 width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
200 if (range <= 0)
201 SetRectEmpty (selection);
202 else
203 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_VERT) {
204 selection->left = infoPtr->rcChannel.left +
205 (width*infoPtr->nSelMin)/range;
206 selection->right = infoPtr->rcChannel.left +
207 (width*infoPtr->nSelMax)/range;
208 selection->top = infoPtr->rcChannel.top + 2;
209 selection->bottom = infoPtr->rcChannel.bottom - 2;
210 } else {
211 selection->top = infoPtr->rcChannel.top +
212 (width*infoPtr->nSelMin)/range;
213 selection->bottom = infoPtr->rcChannel.top +
214 (width*infoPtr->nSelMax)/range;
215 selection->left = infoPtr->rcChannel.left + 2;
216 selection->right = infoPtr->rcChannel.right - 2;
220 /* Trackbar drawing code. I like my spaghetti done milanese. */
222 /* ticPos is in tic-units, not in pixels */
224 static VOID
225 TRACKBAR_DrawHorizTic (TRACKBAR_INFO *infoPtr, HDC hdc, LONG ticPos,
226 int flags, COLORREF clrTic)
228 RECT rcChannel=infoPtr->rcChannel;
229 int x,y,width,range,side;
231 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
232 width=rcChannel.right - rcChannel.left;
234 if (flags & TBS_TOP) {
235 y=rcChannel.top-2;
236 side=-1;
237 } else {
238 y=rcChannel.bottom+2;
239 side=1;
242 if (flags & TIC_SELECTIONMARK) {
243 if (flags & TIC_SELECTIONMARKMIN)
244 x=rcChannel.left + (width*ticPos)/range - 1;
245 else
246 x=rcChannel.left + (width*ticPos)/range + 1;
248 SetPixel (hdc, x,y+6*side, clrTic);
249 SetPixel (hdc, x,y+7*side, clrTic);
250 return;
253 if ((ticPos>infoPtr->nRangeMin) && (ticPos<infoPtr->nRangeMax)) {
254 x=rcChannel.left + (width*ticPos)/range;
255 SetPixel (hdc, x,y+5*side, clrTic);
256 SetPixel (hdc, x,y+6*side, clrTic);
257 SetPixel (hdc, x,y+7*side, clrTic);
260 if (flags & TIC_EDGE) {
261 if (flags & TIC_LEFTEDGE)
262 x=rcChannel.left;
263 else
264 x=rcChannel.right;
266 SetPixel (hdc, x,y+5*side, clrTic);
267 SetPixel (hdc, x,y+6*side, clrTic);
268 SetPixel (hdc, x,y+7*side, clrTic);
269 SetPixel (hdc, x,y+8*side, clrTic);
274 static VOID
275 TRACKBAR_DrawVertTic (TRACKBAR_INFO *infoPtr, HDC hdc, LONG ticPos,
276 int flags, COLORREF clrTic)
278 RECT rcChannel=infoPtr->rcChannel;
279 int x,y,width,range,side;
281 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
282 width=rcChannel.bottom - rcChannel.top;
284 if (flags & TBS_TOP) {
285 x=rcChannel.right-2;
286 side=-1;
287 } else {
288 x=rcChannel.left+2;
289 side=1;
293 if (flags & TIC_SELECTIONMARK) {
294 if (flags & TIC_SELECTIONMARKMIN)
295 y=rcChannel.top + (width*ticPos)/range - 1;
296 else
297 y=rcChannel.top + (width*ticPos)/range + 1;
299 SetPixel (hdc, x+6*side, y, clrTic);
300 SetPixel (hdc, x+7*side, y, clrTic);
301 return;
304 if ((ticPos>infoPtr->nRangeMin) && (ticPos<infoPtr->nRangeMax)) {
305 y=rcChannel.top + (width*ticPos)/range;
306 SetPixel (hdc, x+5*side, y, clrTic);
307 SetPixel (hdc, x+6*side, y, clrTic);
308 SetPixel (hdc, x+7*side, y, clrTic);
311 if (flags & TIC_EDGE) {
312 if (flags & TIC_LEFTEDGE)
313 y=rcChannel.top;
314 else
315 y=rcChannel.bottom;
317 SetPixel (hdc, x+5*side, y, clrTic);
318 SetPixel (hdc, x+6*side, y, clrTic);
319 SetPixel (hdc, x+7*side, y, clrTic);
320 SetPixel (hdc, x+8*side, y, clrTic);
326 static VOID
327 TRACKBAR_DrawTics (TRACKBAR_INFO *infoPtr, HDC hdc, LONG ticPos,
328 int flags, COLORREF clrTic)
331 if (flags & TBS_VERT) {
332 if ((flags & TBS_TOP) || (flags & TBS_BOTH))
333 TRACKBAR_DrawVertTic (infoPtr, hdc, ticPos,
334 flags | TBS_TOP , clrTic);
335 if (!(flags & TBS_TOP) || (flags & TBS_BOTH))
336 TRACKBAR_DrawVertTic (infoPtr, hdc, ticPos, flags, clrTic);
337 return;
340 if ((flags & TBS_TOP) || (flags & TBS_BOTH))
341 TRACKBAR_DrawHorizTic (infoPtr, hdc, ticPos, flags | TBS_TOP , clrTic);
343 if (!(flags & TBS_TOP) || (flags & TBS_BOTH))
344 TRACKBAR_DrawHorizTic (infoPtr, hdc, ticPos, flags, clrTic);
349 static VOID
350 TRACKBAR_Refresh (HWND hwnd, HDC hdc)
352 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
353 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
354 RECT rcClient, rcChannel, rcSelection;
355 HBRUSH hBrush;
356 int i;
358 GetClientRect (hwnd, &rcClient);
359 hBrush = CreateSolidBrush (infoPtr->clrBk);
360 FillRect (hdc, &rcClient, hBrush);
361 DeleteObject (hBrush);
363 if (infoPtr->flags & TB_DRAGPOSVALID) {
364 infoPtr->nPos=infoPtr->dragPos;
365 infoPtr->flags |= TB_THUMBPOSCHANGED;
368 if (infoPtr->flags & TB_THUMBCHANGED) {
369 TRACKBAR_CalcThumb (hwnd, infoPtr);
370 if (infoPtr->flags & TB_THUMBSIZECHANGED)
371 TRACKBAR_CalcChannel (hwnd, infoPtr);
373 if (infoPtr->flags & TB_SELECTIONCHANGED)
374 TRACKBAR_CalcSelection (hwnd, infoPtr);
375 infoPtr->flags &= ~ (TB_THUMBCHANGED | TB_SELECTIONCHANGED |
376 TB_DRAGPOSVALID);
378 /* draw channel */
380 rcChannel = infoPtr->rcChannel;
381 rcSelection= infoPtr->rcSelection;
382 DrawEdge (hdc, &rcChannel, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
384 if (dwStyle & TBS_ENABLESELRANGE) { /* fill the channel */
385 HBRUSH hbr = CreateSolidBrush (RGB(255,255,255));
386 FillRect (hdc, &rcChannel, hbr);
387 if (((dwStyle & TBS_VERT) &&
388 (rcSelection.left!=rcSelection.right)) ||
389 ((!(dwStyle & TBS_VERT)) &&
390 (rcSelection.left!=rcSelection.right))) {
391 hbr=CreateSolidBrush (COLOR_HIGHLIGHT);
392 FillRect (hdc, &rcSelection, hbr);
394 DeleteObject (hbr);
398 /* draw tics */
400 if (!(dwStyle & TBS_NOTICKS)) {
401 int ticFlags = dwStyle & 0x0f;
402 COLORREF clrTic=GetSysColor (COLOR_3DDKSHADOW);
404 for (i=0; i<infoPtr->uNumTics; i++)
405 TRACKBAR_DrawTics (infoPtr, hdc, infoPtr->tics[i],
406 ticFlags, clrTic);
408 TRACKBAR_DrawTics (infoPtr, hdc, 0, ticFlags | TIC_LEFTEDGE, clrTic);
409 TRACKBAR_DrawTics (infoPtr, hdc, 0, ticFlags | TIC_RIGHTEDGE, clrTic);
411 if ((dwStyle & TBS_ENABLESELRANGE) &&
412 (rcSelection.left!=rcSelection.right)) {
413 TRACKBAR_DrawTics (infoPtr, hdc, infoPtr->nSelMin,
414 ticFlags | TIC_SELECTIONMARKMIN, clrTic);
415 TRACKBAR_DrawTics (infoPtr, hdc, infoPtr->nSelMax,
416 ticFlags | TIC_SELECTIONMARKMAX, clrTic);
420 /* draw thumb */
422 if (!(dwStyle & TBS_NOTHUMB)) {
424 HBRUSH hbr = CreateSolidBrush (COLOR_BTNFACE);
425 RECT thumb = infoPtr->rcThumb;
427 SelectObject (hdc, hbr);
429 if (dwStyle & TBS_BOTH) {
430 FillRect (hdc, &thumb, hbr);
431 DrawEdge (hdc, &thumb, EDGE_RAISED, BF_TOPLEFT);
432 } else {
433 POINT points[5];
435 /* first, fill the thumb */
436 /* FIXME: revamp. check for TBS_VERT */
438 SetPolyFillMode (hdc,WINDING);
439 points[0].x=thumb.left;
440 points[0].y=thumb.top;
441 points[1].x=thumb.right - 1;
442 points[1].y=thumb.top;
443 points[2].x=thumb.right - 1;
444 points[2].y=thumb.bottom -2;
445 points[3].x=thumb.left;
446 points[3].y=thumb.bottom -2;
447 points[4].x=points[0].x;
448 points[4].y=points[0].y;
449 Polygon (hdc, points, 5);
451 if (dwStyle & TBS_VERT) {
452 /* draw edge */
453 } else {
454 DrawEdge (hdc, &thumb, EDGE_RAISED, BF_TOPLEFT);
457 DeleteObject (hbr);
460 if (infoPtr->bFocus)
461 DrawFocusRect (hdc, &rcClient);
465 static VOID
466 TRACKBAR_AlignBuddies (HWND hwnd, TRACKBAR_INFO *infoPtr)
468 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
469 HWND hwndParent = GetParent (hwnd);
470 RECT rcSelf, rcBuddy;
471 INT x, y;
473 GetWindowRect (hwnd, &rcSelf);
474 MapWindowPoints (HWND_DESKTOP, hwndParent, (LPPOINT)&rcSelf, 2);
476 /* align buddy left or above */
477 if (infoPtr->hwndBuddyLA) {
478 GetWindowRect (infoPtr->hwndBuddyLA, &rcBuddy);
479 MapWindowPoints (HWND_DESKTOP, hwndParent, (LPPOINT)&rcBuddy, 2);
481 if (dwStyle & TBS_VERT) {
482 x = (infoPtr->rcChannel.right + infoPtr->rcChannel.left) / 2 -
483 (rcBuddy.right - rcBuddy.left) / 2 + rcSelf.left;
484 y = rcSelf.top - (rcBuddy.bottom - rcBuddy.top);
486 else {
487 x = rcSelf.left - (rcBuddy.right - rcBuddy.left);
488 y = (infoPtr->rcChannel.bottom + infoPtr->rcChannel.top) / 2 -
489 (rcBuddy.bottom - rcBuddy.top) / 2 + rcSelf.top;
492 SetWindowPos (infoPtr->hwndBuddyLA, 0, x, y, 0, 0,
493 SWP_NOZORDER | SWP_NOSIZE);
497 /* align buddy right or below */
498 if (infoPtr->hwndBuddyRB) {
499 GetWindowRect (infoPtr->hwndBuddyRB, &rcBuddy);
500 MapWindowPoints (HWND_DESKTOP, hwndParent, (LPPOINT)&rcBuddy, 2);
502 if (dwStyle & TBS_VERT) {
503 x = (infoPtr->rcChannel.right + infoPtr->rcChannel.left) / 2 -
504 (rcBuddy.right - rcBuddy.left) / 2 + rcSelf.left;
505 y = rcSelf.bottom;
507 else {
508 x = rcSelf.right;
509 y = (infoPtr->rcChannel.bottom + infoPtr->rcChannel.top) / 2 -
510 (rcBuddy.bottom - rcBuddy.top) / 2 + rcSelf.top;
512 SetWindowPos (infoPtr->hwndBuddyRB, 0, x, y, 0, 0,
513 SWP_NOZORDER | SWP_NOSIZE);
518 static LRESULT
519 TRACKBAR_ClearSel (HWND hwnd, WPARAM wParam, LPARAM lParam)
521 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
523 infoPtr->nSelMin = 0;
524 infoPtr->nSelMax = 0;
525 infoPtr->flags |= TB_SELECTIONCHANGED;
527 if ((BOOL)wParam)
528 InvalidateRect (hwnd, NULL, FALSE);
530 return 0;
534 static LRESULT
535 TRACKBAR_ClearTics (HWND hwnd, WPARAM wParam, LPARAM lParam)
537 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
539 if (infoPtr->tics) {
540 COMCTL32_Free (infoPtr->tics);
541 infoPtr->tics = NULL;
542 infoPtr->uNumTics = 0;
545 if (wParam)
546 InvalidateRect (hwnd, NULL, FALSE);
548 return 0;
552 static LRESULT
553 TRACKBAR_GetBuddy (HWND hwnd, WPARAM wParam, LPARAM lParam)
555 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
557 if (wParam) /* buddy is left or above */
558 return (LRESULT)infoPtr->hwndBuddyLA;
560 /* buddy is right or below */
561 return (LRESULT) infoPtr->hwndBuddyRB;
565 static LRESULT
566 TRACKBAR_GetChannelRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
568 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
569 LPRECT lprc = (LPRECT)lParam;
571 if (lprc == NULL)
572 return 0;
574 lprc->left = infoPtr->rcChannel.left;
575 lprc->right = infoPtr->rcChannel.right;
576 lprc->bottom = infoPtr->rcChannel.bottom;
577 lprc->top = infoPtr->rcChannel.top;
579 return 0;
583 static LRESULT
584 TRACKBAR_GetLineSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
586 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
588 return infoPtr->nLineSize;
592 static LRESULT
593 TRACKBAR_GetNumTics (HWND hwnd, WPARAM wParam, LPARAM lParam)
595 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
597 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_NOTICKS)
598 return 0;
600 return infoPtr->uNumTics+2;
604 static LRESULT
605 TRACKBAR_GetPageSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
607 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
609 return infoPtr->nPageSize;
613 static LRESULT
614 TRACKBAR_GetPos (HWND hwnd, WPARAM wParam, LPARAM lParam)
616 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
618 return infoPtr->nPos;
622 static LRESULT
623 TRACKBAR_GetRangeMax (HWND hwnd, WPARAM wParam, LPARAM lParam)
625 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
627 return infoPtr->nRangeMax;
631 static LRESULT
632 TRACKBAR_GetRangeMin (HWND hwnd, WPARAM wParam, LPARAM lParam)
634 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
636 return infoPtr->nRangeMin;
640 static LRESULT
641 TRACKBAR_GetSelEnd (HWND hwnd, WPARAM wParam, LPARAM lParam)
643 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
645 return infoPtr->nSelMax;
649 static LRESULT
650 TRACKBAR_GetSelStart (HWND hwnd, WPARAM wParam, LPARAM lParam)
652 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
654 return infoPtr->nSelMin;
658 static LRESULT
659 TRACKBAR_GetThumbLength (HWND hwnd, WPARAM wParam, LPARAM lParam)
661 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
663 return infoPtr->uThumbLen;
666 static LRESULT
667 TRACKBAR_GetPTics (HWND hwnd)
669 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
671 return (LRESULT) infoPtr->tics;
674 static LRESULT
675 TRACKBAR_GetThumbRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
677 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
678 LPRECT lprc = (LPRECT)lParam;
680 if (lprc == NULL)
681 return 0;
683 lprc->left = infoPtr->rcThumb.left;
684 lprc->right = infoPtr->rcThumb.right;
685 lprc->bottom = infoPtr->rcThumb.bottom;
686 lprc->top = infoPtr->rcThumb.top;
688 return 0;
692 static LRESULT
693 TRACKBAR_GetTic (HWND hwnd, WPARAM wParam, LPARAM lParam)
695 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
696 INT iTic;
698 iTic=(INT) wParam;
699 if ((iTic<0) || (iTic>infoPtr->uNumTics))
700 return -1;
702 return (LRESULT) infoPtr->tics[iTic];
707 static LRESULT
708 TRACKBAR_GetTicPos (HWND hwnd, WPARAM wParam, LPARAM lParam)
710 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
711 INT iTic, range, width, pos;
714 iTic=(INT ) wParam;
715 if ((iTic<0) || (iTic>infoPtr->uNumTics))
716 return -1;
718 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
719 width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
720 pos=infoPtr->rcChannel.left + (width * infoPtr->tics[iTic]) / range;
723 return (LRESULT) pos;
727 static LRESULT
728 TRACKBAR_GetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
730 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
732 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_TOOLTIPS)
733 return (LRESULT)infoPtr->hwndToolTip;
734 return 0;
738 /* case TBM_GETUNICODEFORMAT: */
741 static LRESULT
742 TRACKBAR_SetBuddy (HWND hwnd, WPARAM wParam, LPARAM lParam)
744 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
745 HWND hwndTemp;
747 if (wParam) {
748 /* buddy is left or above */
749 hwndTemp = infoPtr->hwndBuddyLA;
750 infoPtr->hwndBuddyLA = (HWND)lParam;
752 FIXME("move buddy!\n");
754 else {
755 /* buddy is right or below */
756 hwndTemp = infoPtr->hwndBuddyRB;
757 infoPtr->hwndBuddyRB = (HWND)lParam;
759 FIXME("move buddy!\n");
762 TRACKBAR_AlignBuddies (hwnd, infoPtr);
764 return (LRESULT)hwndTemp;
768 static LRESULT
769 TRACKBAR_SetLineSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
771 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
772 INT nTemp = infoPtr->nLineSize;
774 infoPtr->nLineSize = (INT)lParam;
776 return nTemp;
780 static LRESULT
781 TRACKBAR_SetPageSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
783 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
784 INT nTemp = infoPtr->nPageSize;
786 infoPtr->nPageSize = (INT)lParam;
788 return nTemp;
792 static LRESULT
793 TRACKBAR_SetPos (HWND hwnd, WPARAM wParam, LPARAM lParam)
795 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
797 infoPtr->nPos = (INT)lParam;
799 if (infoPtr->nPos < infoPtr->nRangeMin)
800 infoPtr->nPos = infoPtr->nRangeMin;
802 if (infoPtr->nPos > infoPtr->nRangeMax)
803 infoPtr->nPos = infoPtr->nRangeMax;
804 infoPtr->flags |= TB_THUMBPOSCHANGED;
806 if (wParam)
807 InvalidateRect (hwnd, NULL, FALSE);
809 return 0;
813 static LRESULT
814 TRACKBAR_SetRange (HWND hwnd, WPARAM wParam, LPARAM lParam)
816 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
817 infoPtr->nRangeMin = (INT)LOWORD(lParam);
818 infoPtr->nRangeMax = (INT)HIWORD(lParam);
820 if (infoPtr->nPos < infoPtr->nRangeMin) {
821 infoPtr->nPos = infoPtr->nRangeMin;
822 infoPtr->flags |=TB_THUMBPOSCHANGED;
825 if (infoPtr->nPos > infoPtr->nRangeMax) {
826 infoPtr->nPos = infoPtr->nRangeMax;
827 infoPtr->flags |=TB_THUMBPOSCHANGED;
830 infoPtr->nPageSize=(infoPtr->nRangeMax - infoPtr->nRangeMin)/5;
831 if (infoPtr->nPageSize == 0)
832 infoPtr->nPageSize = 1;
833 TRACKBAR_RecalculateTics (infoPtr);
835 if (wParam)
836 InvalidateRect (hwnd, NULL, FALSE);
838 return 0;
842 static LRESULT
843 TRACKBAR_SetRangeMax (HWND hwnd, WPARAM wParam, LPARAM lParam)
845 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
847 infoPtr->nRangeMax = (INT)lParam;
848 if (infoPtr->nPos > infoPtr->nRangeMax) {
849 infoPtr->nPos = infoPtr->nRangeMax;
850 infoPtr->flags |=TB_THUMBPOSCHANGED;
853 infoPtr->nPageSize=(infoPtr->nRangeMax - infoPtr->nRangeMin)/5;
854 if (infoPtr->nPageSize == 0)
855 infoPtr->nPageSize = 1;
856 TRACKBAR_RecalculateTics (infoPtr);
858 if (wParam)
859 InvalidateRect (hwnd, NULL, FALSE);
861 return 0;
865 static LRESULT
866 TRACKBAR_SetRangeMin (HWND hwnd, WPARAM wParam, LPARAM lParam)
868 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
870 infoPtr->nRangeMin = (INT)lParam;
871 if (infoPtr->nPos < infoPtr->nRangeMin) {
872 infoPtr->nPos = infoPtr->nRangeMin;
873 infoPtr->flags |=TB_THUMBPOSCHANGED;
876 infoPtr->nPageSize=(infoPtr->nRangeMax - infoPtr->nRangeMin)/5;
877 if (infoPtr->nPageSize == 0)
878 infoPtr->nPageSize = 1;
879 TRACKBAR_RecalculateTics (infoPtr);
881 if (wParam)
882 InvalidateRect (hwnd, NULL, FALSE);
884 return 0;
888 static LRESULT
889 TRACKBAR_SetTicFreq (HWND hwnd, WPARAM wParam)
891 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
893 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_AUTOTICKS)
894 infoPtr->uTicFreq=(UINT) wParam;
896 TRACKBAR_RecalculateTics (infoPtr);
898 InvalidateRect (hwnd, NULL, FALSE);
900 return 0;
904 static LRESULT
905 TRACKBAR_SetSel (HWND hwnd, WPARAM wParam, LPARAM lParam)
907 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
909 infoPtr->nSelMin = (INT)LOWORD(lParam);
910 infoPtr->nSelMax = (INT)HIWORD(lParam);
911 infoPtr->flags |=TB_SELECTIONCHANGED;
913 if (!GetWindowLongA (hwnd, GWL_STYLE) & TBS_ENABLESELRANGE)
914 return 0;
916 if (infoPtr->nSelMin < infoPtr->nRangeMin)
917 infoPtr->nSelMin = infoPtr->nRangeMin;
918 if (infoPtr->nSelMax > infoPtr->nRangeMax)
919 infoPtr->nSelMax = infoPtr->nRangeMax;
921 if (wParam)
922 InvalidateRect (hwnd, NULL, FALSE);
925 return 0;
929 static LRESULT
930 TRACKBAR_SetSelEnd (HWND hwnd, WPARAM wParam, LPARAM lParam)
932 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
934 if (!GetWindowLongA (hwnd, GWL_STYLE) & TBS_ENABLESELRANGE)
935 return 0;
937 infoPtr->nSelMax = (INT)lParam;
938 infoPtr->flags |= TB_SELECTIONCHANGED;
940 if (infoPtr->nSelMax > infoPtr->nRangeMax)
941 infoPtr->nSelMax = infoPtr->nRangeMax;
943 if (wParam)
944 InvalidateRect (hwnd, NULL, FALSE);
946 return 0;
950 static LRESULT
951 TRACKBAR_SetSelStart (HWND hwnd, WPARAM wParam, LPARAM lParam)
953 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
955 if (!GetWindowLongA (hwnd, GWL_STYLE) & TBS_ENABLESELRANGE)
956 return 0;
958 infoPtr->nSelMin = (INT)lParam;
959 infoPtr->flags |=TB_SELECTIONCHANGED;
961 if (infoPtr->nSelMin < infoPtr->nRangeMin)
962 infoPtr->nSelMin = infoPtr->nRangeMin;
964 if (wParam)
965 InvalidateRect (hwnd, NULL, FALSE);
967 return 0;
971 static LRESULT
972 TRACKBAR_SetThumbLength (HWND hwnd, WPARAM wParam, LPARAM lParam)
974 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
976 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_FIXEDLENGTH)
977 infoPtr->uThumbLen = (UINT)wParam;
979 infoPtr->flags |= TB_THUMBSIZECHANGED;
981 InvalidateRect (hwnd, NULL, FALSE);
983 return 0;
987 static LRESULT
988 TRACKBAR_SetTic (HWND hwnd, WPARAM wParam, LPARAM lParam)
990 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
991 INT nPos = (INT)lParam;
993 if ((nPos < infoPtr->nRangeMin) || (nPos> infoPtr->nRangeMax))
994 return FALSE;
996 infoPtr->uNumTics++;
997 infoPtr->tics=COMCTL32_ReAlloc( infoPtr->tics,
998 (infoPtr->uNumTics)*sizeof (DWORD));
999 infoPtr->tics[infoPtr->uNumTics-1]=nPos;
1001 InvalidateRect (hwnd, NULL, FALSE);
1003 return TRUE;
1007 static LRESULT
1008 TRACKBAR_SetTipSide (HWND hwnd, WPARAM wParam, LPARAM lParam)
1010 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1011 INT fTemp = infoPtr->fLocation;
1013 infoPtr->fLocation = (INT)wParam;
1015 return fTemp;
1019 static LRESULT
1020 TRACKBAR_SetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
1022 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1024 infoPtr->hwndToolTip = (HWND)wParam;
1026 return 0;
1030 /* case TBM_SETUNICODEFORMAT: */
1033 static LRESULT
1034 TRACKBAR_InitializeThumb (HWND hwnd)
1036 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1038 infoPtr->uThumbLen = 23; /* initial thumb length */
1040 TRACKBAR_CalcChannel (hwnd,infoPtr);
1041 TRACKBAR_CalcThumb (hwnd, infoPtr);
1042 infoPtr->flags &= ~TB_SELECTIONCHANGED;
1044 return 0;
1048 static LRESULT
1049 TRACKBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
1051 TRACKBAR_INFO *infoPtr;
1053 infoPtr = (TRACKBAR_INFO *)COMCTL32_Alloc (sizeof(TRACKBAR_INFO));
1054 SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
1056 /* set default values */
1057 infoPtr->nRangeMin = 0;
1058 infoPtr->nRangeMax = 100;
1059 infoPtr->nLineSize = 1;
1060 infoPtr->nPageSize = 20;
1061 infoPtr->nSelMin = 0;
1062 infoPtr->nSelMax = 0;
1063 infoPtr->nPos = 0;
1065 infoPtr->uNumTics = 0; /* start and end tic are not included in count*/
1066 infoPtr->uTicFreq = 1;
1067 infoPtr->tics = NULL;
1068 infoPtr->clrBk = GetSysColor (COLOR_BTNFACE);
1069 infoPtr->hwndNotify = GetParent (hwnd);
1071 TRACKBAR_InitializeThumb (hwnd);
1073 /* Create tooltip control */
1074 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_TOOLTIPS) {
1075 TTTOOLINFOA ti;
1077 infoPtr->hwndToolTip =
1078 CreateWindowExA (0, TOOLTIPS_CLASSA, NULL, 0,
1079 CW_USEDEFAULT, CW_USEDEFAULT,
1080 CW_USEDEFAULT, CW_USEDEFAULT,
1081 hwnd, 0, 0, 0);
1083 /* Send NM_TOOLTIPSCREATED notification */
1084 if (infoPtr->hwndToolTip) {
1085 NMTOOLTIPSCREATED nmttc;
1087 nmttc.hdr.hwndFrom = hwnd;
1088 nmttc.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1089 nmttc.hdr.code = NM_TOOLTIPSCREATED;
1090 nmttc.hwndToolTips = infoPtr->hwndToolTip;
1092 SendMessageA (GetParent (hwnd), WM_NOTIFY,
1093 (WPARAM)nmttc.hdr.idFrom, (LPARAM)&nmttc);
1096 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
1097 ti.cbSize = sizeof(TTTOOLINFOA);
1098 ti.uFlags = TTF_IDISHWND | TTF_TRACK;
1099 ti.hwnd = hwnd;
1100 ti.uId = 0;
1101 ti.lpszText = "Test"; /* LPSTR_TEXTCALLBACK */
1102 SetRectEmpty (&ti.rect);
1104 SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA, 0, (LPARAM)&ti);
1107 return 0;
1111 static LRESULT
1112 TRACKBAR_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
1114 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1116 /* delete tooltip control */
1117 if (infoPtr->hwndToolTip)
1118 DestroyWindow (infoPtr->hwndToolTip);
1120 COMCTL32_Free (infoPtr);
1121 SetWindowLongA (hwnd, 0, 0);
1122 return 0;
1126 static LRESULT
1127 TRACKBAR_KillFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
1129 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1131 TRACE("\n");
1133 infoPtr->bFocus = FALSE;
1134 infoPtr->flags &= ~TB_DRAG_MODE;
1136 InvalidateRect (hwnd, NULL, FALSE);
1138 return 0;
1142 static LRESULT
1143 TRACKBAR_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
1145 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1146 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1147 int clickPlace,prevPos,vertical;
1148 DOUBLE clickPos;
1150 SetFocus (hwnd);
1152 vertical = (dwStyle & TBS_VERT) ? 1 : 0;
1153 if (vertical)
1154 clickPlace=(INT)HIWORD(lParam);
1155 else
1156 clickPlace=(INT)LOWORD(lParam);
1158 if ((vertical &&
1159 (clickPlace>infoPtr->rcThumb.top) &&
1160 (clickPlace<infoPtr->rcThumb.bottom)) ||
1161 (!vertical &&
1162 (clickPlace>infoPtr->rcThumb.left) &&
1163 (clickPlace<infoPtr->rcThumb.right))) {
1164 infoPtr->flags |= TB_DRAG_MODE;
1165 if (dwStyle & TBS_TOOLTIPS) { /* enable tooltip */
1166 TTTOOLINFOA ti;
1167 POINT pt;
1169 GetCursorPos (&pt);
1170 SendMessageA (infoPtr->hwndToolTip, TTM_TRACKPOSITION, 0,
1171 (LPARAM)MAKELPARAM(pt.x, pt.y));
1173 ti.cbSize = sizeof(TTTOOLINFOA);
1174 ti.uId = 0;
1175 ti.hwnd = (UINT)hwnd;
1177 infoPtr->flags |= TB_SHOW_TOOLTIP;
1178 SetCapture (hwnd);
1179 SendMessageA (infoPtr->hwndToolTip, TTM_TRACKACTIVATE,
1180 (WPARAM)TRUE, (LPARAM)&ti);
1182 return 0;
1185 clickPos = TRACKBAR_ConvertPlaceToPosition (infoPtr, clickPlace, vertical);
1186 prevPos = infoPtr->nPos;
1188 if (vertical ^ (clickPos < (int)prevPos)) { /* similar to VK_NEXT */
1189 infoPtr->nPos += infoPtr->nPageSize;
1190 if (infoPtr->nPos > infoPtr->nRangeMax)
1191 infoPtr->nPos = infoPtr->nRangeMax;
1192 TRACKBAR_SendNotify (hwnd, TB_PAGEUP);
1193 } else {
1194 infoPtr->nPos -= infoPtr->nPageSize; /* similar to VK_PRIOR */
1195 if (infoPtr->nPos < infoPtr->nRangeMin)
1196 infoPtr->nPos = infoPtr->nRangeMin;
1197 TRACKBAR_SendNotify (hwnd, TB_PAGEDOWN);
1200 if (prevPos!=infoPtr->nPos) {
1201 infoPtr->flags |= TB_THUMBPOSCHANGED;
1202 InvalidateRect (hwnd, NULL, FALSE);
1205 return 0;
1209 static LRESULT
1210 TRACKBAR_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
1212 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1214 TRACKBAR_SendNotify (hwnd, TB_ENDTRACK);
1216 if (infoPtr->flags & TB_DRAG_MODE)
1218 infoPtr->flags &= ~TB_DRAG_MODE;
1219 ReleaseCapture ();
1222 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_TOOLTIPS) { /* disable tooltip */
1223 TTTOOLINFOA ti;
1225 ti.cbSize = sizeof(TTTOOLINFOA);
1226 ti.uId = 0;
1227 ti.hwnd = (UINT)hwnd;
1229 infoPtr->flags &= ~TB_SHOW_TOOLTIP;
1230 SendMessageA (infoPtr->hwndToolTip, TTM_TRACKACTIVATE,
1231 (WPARAM)FALSE, (LPARAM)&ti);
1234 InvalidateRect (hwnd, NULL, FALSE);
1236 return 0;
1240 static LRESULT
1241 TRACKBAR_CaptureChanged (HWND hwnd, WPARAM wParam, LPARAM lParam)
1243 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1245 if (infoPtr->flags & TB_DRAGPOSVALID) {
1246 infoPtr->nPos=infoPtr->dragPos;
1247 InvalidateRect (hwnd, NULL, FALSE);
1250 infoPtr->flags &= ~ TB_DRAGPOSVALID;
1252 TRACKBAR_SendNotify (hwnd, TB_ENDTRACK);
1253 return 0;
1257 static LRESULT
1258 TRACKBAR_Paint (HWND hwnd, WPARAM wParam)
1260 HDC hdc;
1261 PAINTSTRUCT ps;
1263 hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
1264 TRACKBAR_Refresh (hwnd, hdc);
1265 if(!wParam)
1266 EndPaint (hwnd, &ps);
1267 return 0;
1271 static LRESULT
1272 TRACKBAR_SetFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
1274 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1276 TRACE("\n");
1277 infoPtr->bFocus = TRUE;
1279 InvalidateRect (hwnd, NULL, FALSE);
1281 return 0;
1285 static LRESULT
1286 TRACKBAR_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
1288 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1290 TRACKBAR_CalcChannel (hwnd, infoPtr);
1291 TRACKBAR_AlignBuddies (hwnd, infoPtr);
1293 return 0;
1297 static BOOL
1298 TRACKBAR_SendNotify (HWND hwnd, UINT code)
1300 TRACE("%x\n",code);
1302 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_VERT)
1303 return (BOOL) SendMessageA (GetParent (hwnd),
1304 WM_VSCROLL, (WPARAM)code, (LPARAM)hwnd);
1306 return (BOOL) SendMessageA (GetParent (hwnd),
1307 WM_HSCROLL, (WPARAM)code, (LPARAM)hwnd);
1311 static LRESULT
1312 TRACKBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
1314 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1315 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1316 SHORT clickPlace;
1317 DOUBLE dragPos;
1318 char buf[80];
1320 TRACE("%x\n",wParam);
1322 if (dwStyle & TBS_VERT)
1323 clickPlace=(SHORT)HIWORD(lParam);
1324 else
1325 clickPlace=(SHORT)LOWORD(lParam);
1327 if (!(infoPtr->flags & TB_DRAG_MODE))
1328 return TRUE;
1330 SetCapture (hwnd);
1331 dragPos = TRACKBAR_ConvertPlaceToPosition (infoPtr, clickPlace,
1332 dwStyle & TBS_VERT);
1333 if (dragPos > ((INT)dragPos) + 0.5)
1334 infoPtr->dragPos = dragPos + 1;
1335 else
1336 infoPtr->dragPos = dragPos;
1338 infoPtr->flags |= TB_DRAGPOSVALID;
1339 TRACKBAR_SendNotify (hwnd, TB_THUMBTRACK | (infoPtr->nPos<<16));
1341 if (infoPtr->flags & TB_SHOW_TOOLTIP) {
1342 POINT pt;
1343 TTTOOLINFOA ti;
1345 ti.cbSize = sizeof(TTTOOLINFOA);
1346 ti.hwnd = hwnd;
1347 ti.uId = 0;
1348 ti.hinst=0;
1349 sprintf (buf,"%d",infoPtr->nPos);
1350 ti.lpszText = (LPSTR) buf;
1351 GetCursorPos (&pt);
1353 if (dwStyle & TBS_VERT) {
1354 SendMessageA (infoPtr->hwndToolTip, TTM_TRACKPOSITION,
1355 0, (LPARAM)MAKELPARAM(pt.x+5, pt.y+15));
1356 } else {
1357 SendMessageA (infoPtr->hwndToolTip, TTM_TRACKPOSITION,
1358 0, (LPARAM)MAKELPARAM(pt.x+15, pt.y+5));
1360 SendMessageA (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTA,
1361 0, (LPARAM)&ti);
1364 InvalidateRect (hwnd, NULL, FALSE);
1365 UpdateWindow (hwnd);
1367 return TRUE;
1371 static LRESULT
1372 TRACKBAR_KeyDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
1374 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1375 INT pos;
1377 TRACE("%x\n",wParam);
1379 pos=infoPtr->nPos;
1380 switch (wParam) {
1381 case VK_LEFT:
1382 case VK_UP:
1383 if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
1384 infoPtr->nPos -= infoPtr->nLineSize;
1385 if (infoPtr->nPos < infoPtr->nRangeMin)
1386 infoPtr->nPos = infoPtr->nRangeMin;
1387 TRACKBAR_SendNotify (hwnd, TB_LINEUP);
1388 break;
1389 case VK_RIGHT:
1390 case VK_DOWN:
1391 if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
1392 infoPtr->nPos += infoPtr->nLineSize;
1393 if (infoPtr->nPos > infoPtr->nRangeMax)
1394 infoPtr->nPos = infoPtr->nRangeMax;
1395 TRACKBAR_SendNotify (hwnd, TB_LINEDOWN);
1396 break;
1397 case VK_NEXT:
1398 if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
1399 infoPtr->nPos += infoPtr->nPageSize;
1400 if (infoPtr->nPos > infoPtr->nRangeMax)
1401 infoPtr->nPos = infoPtr->nRangeMax;
1402 TRACKBAR_SendNotify (hwnd, TB_PAGEUP);
1403 break;
1404 case VK_PRIOR:
1405 if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
1406 infoPtr->nPos -= infoPtr->nPageSize;
1407 if (infoPtr->nPos < infoPtr->nRangeMin)
1408 infoPtr->nPos = infoPtr->nRangeMin;
1409 TRACKBAR_SendNotify (hwnd, TB_PAGEDOWN);
1410 break;
1411 case VK_HOME:
1412 if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
1413 infoPtr->nPos = infoPtr->nRangeMin;
1414 TRACKBAR_SendNotify (hwnd, TB_TOP);
1415 break;
1416 case VK_END:
1417 if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
1418 infoPtr->nPos = infoPtr->nRangeMax;
1419 TRACKBAR_SendNotify (hwnd, TB_BOTTOM);
1420 break;
1423 if (pos!=infoPtr->nPos) {
1424 infoPtr->flags |=TB_THUMBPOSCHANGED;
1425 InvalidateRect (hwnd, NULL, FALSE);
1428 return TRUE;
1432 static LRESULT
1433 TRACKBAR_KeyUp (HWND hwnd, WPARAM wParam)
1435 switch (wParam) {
1436 case VK_LEFT:
1437 case VK_UP:
1438 case VK_RIGHT:
1439 case VK_DOWN:
1440 case VK_NEXT:
1441 case VK_PRIOR:
1442 case VK_HOME:
1443 case VK_END:
1444 TRACKBAR_SendNotify (hwnd, TB_ENDTRACK);
1446 return TRUE;
1450 static LRESULT WINAPI
1451 TRACKBAR_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1453 TRACE("hwnd=%x msg=%x wparam=%x lparam=%lx\n", hwnd, uMsg, wParam, lParam);
1454 if (!TRACKBAR_GetInfoPtr (hwnd) && (uMsg != WM_CREATE))
1455 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
1456 switch (uMsg)
1458 case TBM_CLEARSEL:
1459 return TRACKBAR_ClearSel (hwnd, wParam, lParam);
1461 case TBM_CLEARTICS:
1462 return TRACKBAR_ClearTics (hwnd, wParam, lParam);
1464 case TBM_GETBUDDY:
1465 return TRACKBAR_GetBuddy (hwnd, wParam, lParam);
1467 case TBM_GETCHANNELRECT:
1468 return TRACKBAR_GetChannelRect (hwnd, wParam, lParam);
1470 case TBM_GETLINESIZE:
1471 return TRACKBAR_GetLineSize (hwnd, wParam, lParam);
1473 case TBM_GETNUMTICS:
1474 return TRACKBAR_GetNumTics (hwnd, wParam, lParam);
1476 case TBM_GETPAGESIZE:
1477 return TRACKBAR_GetPageSize (hwnd, wParam, lParam);
1479 case TBM_GETPOS:
1480 return TRACKBAR_GetPos (hwnd, wParam, lParam);
1482 case TBM_GETPTICS:
1483 return TRACKBAR_GetPTics (hwnd);
1485 case TBM_GETRANGEMAX:
1486 return TRACKBAR_GetRangeMax (hwnd, wParam, lParam);
1488 case TBM_GETRANGEMIN:
1489 return TRACKBAR_GetRangeMin (hwnd, wParam, lParam);
1491 case TBM_GETSELEND:
1492 return TRACKBAR_GetSelEnd (hwnd, wParam, lParam);
1494 case TBM_GETSELSTART:
1495 return TRACKBAR_GetSelStart (hwnd, wParam, lParam);
1497 case TBM_GETTHUMBLENGTH:
1498 return TRACKBAR_GetThumbLength (hwnd, wParam, lParam);
1500 case TBM_GETTHUMBRECT:
1501 return TRACKBAR_GetThumbRect (hwnd, wParam, lParam);
1503 case TBM_GETTIC:
1504 return TRACKBAR_GetTic (hwnd, wParam, lParam);
1506 case TBM_GETTICPOS:
1507 return TRACKBAR_GetTicPos (hwnd, wParam, lParam);
1509 case TBM_GETTOOLTIPS:
1510 return TRACKBAR_GetToolTips (hwnd, wParam, lParam);
1512 /* case TBM_GETUNICODEFORMAT: */
1514 case TBM_SETBUDDY:
1515 return TRACKBAR_SetBuddy (hwnd, wParam, lParam);
1517 case TBM_SETLINESIZE:
1518 return TRACKBAR_SetLineSize (hwnd, wParam, lParam);
1520 case TBM_SETPAGESIZE:
1521 return TRACKBAR_SetPageSize (hwnd, wParam, lParam);
1523 case TBM_SETPOS:
1524 return TRACKBAR_SetPos (hwnd, wParam, lParam);
1526 case TBM_SETRANGE:
1527 return TRACKBAR_SetRange (hwnd, wParam, lParam);
1529 case TBM_SETRANGEMAX:
1530 return TRACKBAR_SetRangeMax (hwnd, wParam, lParam);
1532 case TBM_SETRANGEMIN:
1533 return TRACKBAR_SetRangeMin (hwnd, wParam, lParam);
1535 case TBM_SETSEL:
1536 return TRACKBAR_SetSel (hwnd, wParam, lParam);
1538 case TBM_SETSELEND:
1539 return TRACKBAR_SetSelEnd (hwnd, wParam, lParam);
1541 case TBM_SETSELSTART:
1542 return TRACKBAR_SetSelStart (hwnd, wParam, lParam);
1544 case TBM_SETTHUMBLENGTH:
1545 return TRACKBAR_SetThumbLength (hwnd, wParam, lParam);
1547 case TBM_SETTIC:
1548 return TRACKBAR_SetTic (hwnd, wParam, lParam);
1550 case TBM_SETTICFREQ:
1551 return TRACKBAR_SetTicFreq (hwnd, wParam);
1553 case TBM_SETTIPSIDE:
1554 return TRACKBAR_SetTipSide (hwnd, wParam, lParam);
1556 case TBM_SETTOOLTIPS:
1557 return TRACKBAR_SetToolTips (hwnd, wParam, lParam);
1559 /* case TBM_SETUNICODEFORMAT: */
1562 case WM_CAPTURECHANGED:
1563 return TRACKBAR_CaptureChanged (hwnd, wParam, lParam);
1565 case WM_CREATE:
1566 return TRACKBAR_Create (hwnd, wParam, lParam);
1568 case WM_DESTROY:
1569 return TRACKBAR_Destroy (hwnd, wParam, lParam);
1571 /* case WM_ENABLE: */
1573 /* case WM_ERASEBKGND: */
1574 /* return 0; */
1576 case WM_GETDLGCODE:
1577 return DLGC_WANTARROWS;
1579 case WM_KEYDOWN:
1580 return TRACKBAR_KeyDown (hwnd, wParam, lParam);
1582 case WM_KEYUP:
1583 return TRACKBAR_KeyUp (hwnd, wParam);
1585 case WM_KILLFOCUS:
1586 return TRACKBAR_KillFocus (hwnd, wParam, lParam);
1588 case WM_LBUTTONDOWN:
1589 return TRACKBAR_LButtonDown (hwnd, wParam, lParam);
1591 case WM_LBUTTONUP:
1592 return TRACKBAR_LButtonUp (hwnd, wParam, lParam);
1594 case WM_MOUSEMOVE:
1595 return TRACKBAR_MouseMove (hwnd, wParam, lParam);
1597 case WM_PAINT:
1598 return TRACKBAR_Paint (hwnd, wParam);
1600 case WM_SETFOCUS:
1601 return TRACKBAR_SetFocus (hwnd, wParam, lParam);
1603 case WM_SIZE:
1604 return TRACKBAR_Size (hwnd, wParam, lParam);
1606 case WM_WININICHANGE:
1607 return TRACKBAR_InitializeThumb (hwnd);
1609 default:
1610 if (uMsg >= WM_USER)
1611 ERR("unknown msg %04x wp=%08x lp=%08lx\n",
1612 uMsg, wParam, lParam);
1613 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
1615 return 0;
1619 VOID
1620 TRACKBAR_Register (void)
1622 WNDCLASSA wndClass;
1624 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
1625 wndClass.style = CS_GLOBALCLASS;
1626 wndClass.lpfnWndProc = (WNDPROC)TRACKBAR_WindowProc;
1627 wndClass.cbClsExtra = 0;
1628 wndClass.cbWndExtra = sizeof(TRACKBAR_INFO *);
1629 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
1630 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
1631 wndClass.lpszClassName = TRACKBAR_CLASSA;
1633 RegisterClassA (&wndClass);
1637 VOID
1638 TRACKBAR_Unregister (void)
1640 UnregisterClassA (TRACKBAR_CLASSA, (HINSTANCE)NULL);