Fixed hash function.
[wine/dcerpc.git] / dlls / comctl32 / trackbar.c
bloba9f3fb5a70b33526ace9d80f4d07104b5cb7b0da
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.
27 #include "winbase.h"
28 #include "commctrl.h"
29 #include "trackbar.h"
30 #include "debugtools.h"
32 DEFAULT_DEBUG_CHANNEL(trackbar)
35 #define TRACKBAR_GetInfoPtr(wndPtr) ((TRACKBAR_INFO *)GetWindowLongA (hwnd,0))
38 /* Used by TRACKBAR_Refresh to find out which parts of the control
39 need to be recalculated */
41 #define TB_THUMBPOSCHANGED 1
42 #define TB_THUMBSIZECHANGED 2
43 #define TB_THUMBCHANGED (TB_THUMBPOSCHANGED | TB_THUMBPOSCHANGED)
44 #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 */
49 /* helper defines for TRACKBAR_DrawTic */
50 #define TIC_LEFTEDGE 0x20
51 #define TIC_RIGHTEDGE 0x40
52 #define TIC_EDGE (TIC_LEFTEDGE | TIC_RIGHTEDGE)
53 #define TIC_SELECTIONMARKMAX 0x80
54 #define TIC_SELECTIONMARKMIN 0x100
55 #define TIC_SELECTIONMARK (TIC_SELECTIONMARKMAX | TIC_SELECTIONMARKMIN)
57 static BOOL TRACKBAR_SendNotify (HWND hwnd, UINT code);
59 static void TRACKBAR_RecalculateTics (TRACKBAR_INFO *infoPtr)
61 int i,tic,nrTics;
63 if (infoPtr->uTicFreq && infoPtr->nRangeMax >= infoPtr->nRangeMin)
64 nrTics=(infoPtr->nRangeMax - infoPtr->nRangeMin)/infoPtr->uTicFreq;
65 else {
66 nrTics=0;
67 COMCTL32_Free (infoPtr->tics);
68 infoPtr->tics=NULL;
69 infoPtr->uNumTics=0;
70 return;
73 if (nrTics!=infoPtr->uNumTics) {
74 infoPtr->tics=COMCTL32_ReAlloc (infoPtr->tics,
75 (nrTics+1)*sizeof (DWORD));
76 infoPtr->uNumTics=nrTics;
78 infoPtr->uNumTics=nrTics;
79 tic=infoPtr->nRangeMin+infoPtr->uTicFreq;
80 for (i=0; i<nrTics; i++,tic+=infoPtr->uTicFreq)
81 infoPtr->tics[i]=tic;
85 /* converts from physical (mouse) position to logical position
86 (in range of trackbar) */
88 static inline DOUBLE
89 TRACKBAR_ConvertPlaceToPosition (TRACKBAR_INFO *infoPtr, int place,
90 int vertical)
92 double range,width,pos;
94 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
95 if (vertical) {
96 width=infoPtr->rcChannel.bottom - infoPtr->rcChannel.top;
97 pos=(range*(place - infoPtr->rcChannel.top)) / width;
98 } else {
99 width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
100 pos=(range*(place - infoPtr->rcChannel.left)) / width;
103 if (pos > infoPtr->nRangeMax)
104 pos = infoPtr->nRangeMax;
105 else if (pos < infoPtr->nRangeMin)
106 pos = infoPtr->nRangeMin;
108 TRACE("%.2f\n",pos);
109 return pos;
113 static VOID
114 TRACKBAR_CalcChannel (HWND hwnd, TRACKBAR_INFO *infoPtr)
116 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
117 INT cyChannel;
118 RECT lpRect,*channel = & infoPtr->rcChannel;
120 GetClientRect (hwnd, &lpRect);
122 if (dwStyle & TBS_ENABLESELRANGE)
123 cyChannel = MAX(infoPtr->uThumbLen - 8, 4);
124 else
125 cyChannel = 4;
127 if (dwStyle & TBS_VERT) {
128 channel->top = lpRect.top + 8;
129 channel->bottom = lpRect.bottom - 8;
131 if (dwStyle & TBS_BOTH) {
132 channel->left = (lpRect.right - cyChannel) / 2;
133 channel->right = (lpRect.right + cyChannel) / 2;
135 else if (dwStyle & TBS_LEFT) {
136 channel->left = lpRect.left + 10;
137 channel->right = channel->left + cyChannel;
139 else { /* TBS_RIGHT */
140 channel->right = lpRect.right - 10;
141 channel->left = channel->right - cyChannel;
144 else {
145 channel->left = lpRect.left + 8;
146 channel->right = lpRect.right - 8;
147 if (dwStyle & TBS_BOTH) {
148 channel->top = (lpRect.bottom - cyChannel) / 2;
149 channel->bottom = (lpRect.bottom + cyChannel) / 2;
151 else if (dwStyle & TBS_TOP) {
152 channel->top = lpRect.top + 10;
153 channel->bottom = channel->top + cyChannel;
155 else { /* TBS_BOTTOM */
156 channel->bottom = lpRect.bottom - 10;
157 channel->top = channel->bottom - cyChannel;
162 static VOID
163 TRACKBAR_CalcThumb (HWND hwnd, TRACKBAR_INFO *infoPtr)
165 RECT *thumb;
166 int range, width;
168 thumb=&infoPtr->rcThumb;
169 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
170 if (!range) return; /* FIXME: may this happen? */
171 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_VERT) {
172 width=infoPtr->rcChannel.bottom - infoPtr->rcChannel.top;
173 thumb->left = infoPtr->rcChannel.left - 1;
174 thumb->right = infoPtr->rcChannel.left + infoPtr->uThumbLen - 8;
175 thumb->top = infoPtr->rcChannel.top +
176 (width*infoPtr->nPos)/range - 5;
177 thumb->bottom = thumb->top + infoPtr->uThumbLen/3;
179 } else {
180 width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
181 thumb->left = infoPtr->rcChannel.left +
182 (width*infoPtr->nPos)/range - 5;
183 thumb->right = thumb->left + infoPtr->uThumbLen/3;
184 thumb->top = infoPtr->rcChannel.top - 1;
185 thumb->bottom = infoPtr->rcChannel.top + infoPtr->uThumbLen - 8;
189 static VOID
190 TRACKBAR_CalcSelection (HWND hwnd, TRACKBAR_INFO *infoPtr)
192 RECT *selection;
193 int range, width;
195 selection= & infoPtr->rcSelection;
196 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
197 width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
199 if (range <= 0)
200 SetRectEmpty (selection);
201 else
202 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_VERT) {
203 selection->left = infoPtr->rcChannel.left +
204 (width*infoPtr->nSelMin)/range;
205 selection->right = infoPtr->rcChannel.left +
206 (width*infoPtr->nSelMax)/range;
207 selection->top = infoPtr->rcChannel.top + 2;
208 selection->bottom = infoPtr->rcChannel.bottom - 2;
209 } else {
210 selection->top = infoPtr->rcChannel.top +
211 (width*infoPtr->nSelMin)/range;
212 selection->bottom = infoPtr->rcChannel.top +
213 (width*infoPtr->nSelMax)/range;
214 selection->left = infoPtr->rcChannel.left + 2;
215 selection->right = infoPtr->rcChannel.right - 2;
219 /* Trackbar drawing code. I like my spaghetti done milanese. */
221 /* ticPos is in tic-units, not in pixels */
223 static VOID
224 TRACKBAR_DrawHorizTic (TRACKBAR_INFO *infoPtr, HDC hdc, LONG ticPos,
225 int flags, COLORREF clrTic)
227 RECT rcChannel=infoPtr->rcChannel;
228 int x,y,width,range,side;
230 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
231 width=rcChannel.right - rcChannel.left;
233 if (flags & TBS_TOP) {
234 y=rcChannel.top-2;
235 side=-1;
236 } else {
237 y=rcChannel.bottom+2;
238 side=1;
241 if (flags & TIC_SELECTIONMARK) {
242 if (flags & TIC_SELECTIONMARKMIN)
243 x=rcChannel.left + (width*ticPos)/range - 1;
244 else
245 x=rcChannel.left + (width*ticPos)/range + 1;
247 SetPixel (hdc, x,y+6*side, clrTic);
248 SetPixel (hdc, x,y+7*side, clrTic);
249 return;
252 if ((ticPos>infoPtr->nRangeMin) && (ticPos<infoPtr->nRangeMax)) {
253 x=rcChannel.left + (width*ticPos)/range;
254 SetPixel (hdc, x,y+5*side, clrTic);
255 SetPixel (hdc, x,y+6*side, clrTic);
256 SetPixel (hdc, x,y+7*side, clrTic);
259 if (flags & TIC_EDGE) {
260 if (flags & TIC_LEFTEDGE)
261 x=rcChannel.left;
262 else
263 x=rcChannel.right;
265 SetPixel (hdc, x,y+5*side, clrTic);
266 SetPixel (hdc, x,y+6*side, clrTic);
267 SetPixel (hdc, x,y+7*side, clrTic);
268 SetPixel (hdc, x,y+8*side, clrTic);
273 static VOID
274 TRACKBAR_DrawVertTic (TRACKBAR_INFO *infoPtr, HDC hdc, LONG ticPos,
275 int flags, COLORREF clrTic)
277 RECT rcChannel=infoPtr->rcChannel;
278 int x,y,width,range,side;
280 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
281 width=rcChannel.bottom - rcChannel.top;
283 if (flags & TBS_TOP) {
284 x=rcChannel.right-2;
285 side=-1;
286 } else {
287 x=rcChannel.left+2;
288 side=1;
292 if (flags & TIC_SELECTIONMARK) {
293 if (flags & TIC_SELECTIONMARKMIN)
294 y=rcChannel.top + (width*ticPos)/range - 1;
295 else
296 y=rcChannel.top + (width*ticPos)/range + 1;
298 SetPixel (hdc, x+6*side, y, clrTic);
299 SetPixel (hdc, x+7*side, y, clrTic);
300 return;
303 if ((ticPos>infoPtr->nRangeMin) && (ticPos<infoPtr->nRangeMax)) {
304 y=rcChannel.top + (width*ticPos)/range;
305 SetPixel (hdc, x+5*side, y, clrTic);
306 SetPixel (hdc, x+6*side, y, clrTic);
307 SetPixel (hdc, x+7*side, y, clrTic);
310 if (flags & TIC_EDGE) {
311 if (flags & TIC_LEFTEDGE)
312 y=rcChannel.top;
313 else
314 y=rcChannel.bottom;
316 SetPixel (hdc, x+5*side, y, clrTic);
317 SetPixel (hdc, x+6*side, y, clrTic);
318 SetPixel (hdc, x+7*side, y, clrTic);
319 SetPixel (hdc, x+8*side, y, clrTic);
325 static VOID
326 TRACKBAR_DrawTics (TRACKBAR_INFO *infoPtr, HDC hdc, LONG ticPos,
327 int flags, COLORREF clrTic)
330 if (flags & TBS_VERT) {
331 if ((flags & TBS_TOP) || (flags & TBS_BOTH))
332 TRACKBAR_DrawVertTic (infoPtr, hdc, ticPos,
333 flags | TBS_TOP , clrTic);
334 if (!(flags & TBS_TOP) || (flags & TBS_BOTH))
335 TRACKBAR_DrawVertTic (infoPtr, hdc, ticPos, flags, clrTic);
336 return;
339 if ((flags & TBS_TOP) || (flags & TBS_BOTH))
340 TRACKBAR_DrawHorizTic (infoPtr, hdc, ticPos, flags | TBS_TOP , clrTic);
342 if (!(flags & TBS_TOP) || (flags & TBS_BOTH))
343 TRACKBAR_DrawHorizTic (infoPtr, hdc, ticPos, flags, clrTic);
348 static VOID
349 TRACKBAR_Refresh (HWND hwnd, HDC hdc)
351 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
352 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
353 RECT rcClient, rcChannel, rcSelection;
354 HBRUSH hBrush = CreateSolidBrush (infoPtr->clrBk);
355 int i;
357 GetClientRect (hwnd, &rcClient);
358 hBrush = CreateSolidBrush (infoPtr->clrBk);
359 FillRect (hdc, &rcClient, hBrush);
360 DeleteObject (hBrush);
362 if (infoPtr->flags & TB_DRAGPOSVALID) {
363 infoPtr->nPos=infoPtr->dragPos;
364 infoPtr->flags |= TB_THUMBPOSCHANGED;
367 if (infoPtr->flags & TB_THUMBCHANGED) {
368 TRACKBAR_CalcThumb (hwnd, infoPtr);
369 if (infoPtr->flags & TB_THUMBSIZECHANGED)
370 TRACKBAR_CalcChannel (hwnd, infoPtr);
372 if (infoPtr->flags & TB_SELECTIONCHANGED)
373 TRACKBAR_CalcSelection (hwnd, infoPtr);
374 infoPtr->flags &= ~ (TB_THUMBCHANGED | TB_SELECTIONCHANGED |
375 TB_DRAGPOSVALID);
377 /* draw channel */
379 rcChannel = infoPtr->rcChannel;
380 rcSelection= infoPtr->rcSelection;
381 DrawEdge (hdc, &rcChannel, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
383 if (dwStyle & TBS_ENABLESELRANGE) { /* fill the channel */
384 HBRUSH hbr = CreateSolidBrush (RGB(255,255,255));
385 FillRect (hdc, &rcChannel, hbr);
386 if (((dwStyle & TBS_VERT) &&
387 (rcSelection.left!=rcSelection.right)) ||
388 ((!(dwStyle & TBS_VERT)) &&
389 (rcSelection.left!=rcSelection.right))) {
390 hbr=CreateSolidBrush (COLOR_HIGHLIGHT);
391 FillRect (hdc, &rcSelection, hbr);
393 DeleteObject (hbr);
397 /* draw tics */
399 if (!(dwStyle & TBS_NOTICKS)) {
400 int ticFlags = dwStyle & 0x0f;
401 COLORREF clrTic=GetSysColor (COLOR_3DDKSHADOW);
403 for (i=0; i<infoPtr->uNumTics; i++)
404 TRACKBAR_DrawTics (infoPtr, hdc, infoPtr->tics[i],
405 ticFlags, clrTic);
407 TRACKBAR_DrawTics (infoPtr, hdc, 0, ticFlags | TIC_LEFTEDGE, clrTic);
408 TRACKBAR_DrawTics (infoPtr, hdc, 0, ticFlags | TIC_RIGHTEDGE, clrTic);
410 if ((dwStyle & TBS_ENABLESELRANGE) &&
411 (rcSelection.left!=rcSelection.right)) {
412 TRACKBAR_DrawTics (infoPtr, hdc, infoPtr->nSelMin,
413 ticFlags | TIC_SELECTIONMARKMIN, clrTic);
414 TRACKBAR_DrawTics (infoPtr, hdc, infoPtr->nSelMax,
415 ticFlags | TIC_SELECTIONMARKMAX, clrTic);
419 /* draw thumb */
421 if (!(dwStyle & TBS_NOTHUMB)) {
423 HBRUSH hbr = CreateSolidBrush (COLOR_BACKGROUND);
424 RECT thumb = infoPtr->rcThumb;
426 SelectObject (hdc, hbr);
428 if (dwStyle & TBS_BOTH) {
429 FillRect (hdc, &thumb, hbr);
430 DrawEdge (hdc, &thumb, EDGE_RAISED, BF_TOPLEFT);
431 } else {
433 POINT points[6];
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.right + thumb.left-1)/2;
446 points[3].y=thumb.bottom+4;
447 points[4].x=thumb.left;
448 points[4].y=thumb.bottom -2;
449 points[5].x=points[0].x;
450 points[5].y=points[0].y;
451 Polygon (hdc, points, 6);
453 if (dwStyle & TBS_VERT) {
454 /* draw edge */
455 } else {
456 RECT triangle; /* for correct shadows of thumb */
457 DrawEdge (hdc, &thumb, EDGE_RAISED, BF_TOPLEFT);
459 /* draw notch */
461 triangle.right = thumb.right+5;
462 triangle.left = points[3].x+5;
463 triangle.top = thumb.bottom +5;
464 triangle.bottom= thumb.bottom +1;
465 DrawEdge (hdc, &triangle, EDGE_SUNKEN,
466 BF_DIAGONAL | BF_TOP | BF_RIGHT);
467 triangle.left = thumb.left+6;
468 triangle.right = points[3].x+6;
469 DrawEdge (hdc, &triangle, EDGE_RAISED,
470 BF_DIAGONAL | BF_TOP | BF_LEFT);
473 DeleteObject (hbr);
476 if (infoPtr->bFocus)
477 DrawFocusRect (hdc, &rcClient);
481 static VOID
482 TRACKBAR_AlignBuddies (HWND hwnd, TRACKBAR_INFO *infoPtr)
484 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
485 HWND hwndParent = GetParent (hwnd);
486 RECT rcSelf, rcBuddy;
487 INT x, y;
489 GetWindowRect (hwnd, &rcSelf);
490 MapWindowPoints (HWND_DESKTOP, hwndParent, (LPPOINT)&rcSelf, 2);
492 /* align buddy left or above */
493 if (infoPtr->hwndBuddyLA) {
494 GetWindowRect (infoPtr->hwndBuddyLA, &rcBuddy);
495 MapWindowPoints (HWND_DESKTOP, hwndParent, (LPPOINT)&rcBuddy, 2);
497 if (dwStyle & TBS_VERT) {
498 x = (infoPtr->rcChannel.right + infoPtr->rcChannel.left) / 2 -
499 (rcBuddy.right - rcBuddy.left) / 2 + rcSelf.left;
500 y = rcSelf.top - (rcBuddy.bottom - rcBuddy.top);
502 else {
503 x = rcSelf.left - (rcBuddy.right - rcBuddy.left);
504 y = (infoPtr->rcChannel.bottom + infoPtr->rcChannel.top) / 2 -
505 (rcBuddy.bottom - rcBuddy.top) / 2 + rcSelf.top;
508 SetWindowPos (infoPtr->hwndBuddyLA, 0, x, y, 0, 0,
509 SWP_NOZORDER | SWP_NOSIZE);
513 /* align buddy right or below */
514 if (infoPtr->hwndBuddyRB) {
515 GetWindowRect (infoPtr->hwndBuddyRB, &rcBuddy);
516 MapWindowPoints (HWND_DESKTOP, hwndParent, (LPPOINT)&rcBuddy, 2);
518 if (dwStyle & TBS_VERT) {
519 x = (infoPtr->rcChannel.right + infoPtr->rcChannel.left) / 2 -
520 (rcBuddy.right - rcBuddy.left) / 2 + rcSelf.left;
521 y = rcSelf.bottom;
523 else {
524 x = rcSelf.right;
525 y = (infoPtr->rcChannel.bottom + infoPtr->rcChannel.top) / 2 -
526 (rcBuddy.bottom - rcBuddy.top) / 2 + rcSelf.top;
528 SetWindowPos (infoPtr->hwndBuddyRB, 0, x, y, 0, 0,
529 SWP_NOZORDER | SWP_NOSIZE);
534 static LRESULT
535 TRACKBAR_ClearSel (HWND hwnd, WPARAM wParam, LPARAM lParam)
537 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
539 infoPtr->nSelMin = 0;
540 infoPtr->nSelMax = 0;
541 infoPtr->flags |= TB_SELECTIONCHANGED;
543 if ((BOOL)wParam)
544 InvalidateRect (hwnd, NULL, FALSE);
546 return 0;
550 static LRESULT
551 TRACKBAR_ClearTics (HWND hwnd, WPARAM wParam, LPARAM lParam)
553 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
555 if (infoPtr->tics) {
556 COMCTL32_Free (infoPtr->tics);
557 infoPtr->tics = NULL;
558 infoPtr->uNumTics = 0;
561 if (wParam)
562 InvalidateRect (hwnd, NULL, FALSE);
564 return 0;
568 static LRESULT
569 TRACKBAR_GetBuddy (HWND hwnd, WPARAM wParam, LPARAM lParam)
571 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
573 if (wParam) /* buddy is left or above */
574 return (LRESULT)infoPtr->hwndBuddyLA;
576 /* buddy is right or below */
577 return (LRESULT) infoPtr->hwndBuddyRB;
581 static LRESULT
582 TRACKBAR_GetChannelRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
584 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
585 LPRECT lprc = (LPRECT)lParam;
587 if (lprc == NULL)
588 return 0;
590 lprc->left = infoPtr->rcChannel.left;
591 lprc->right = infoPtr->rcChannel.right;
592 lprc->bottom = infoPtr->rcChannel.bottom;
593 lprc->top = infoPtr->rcChannel.top;
595 return 0;
599 static LRESULT
600 TRACKBAR_GetLineSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
602 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
604 return infoPtr->nLineSize;
608 static LRESULT
609 TRACKBAR_GetNumTics (HWND hwnd, WPARAM wParam, LPARAM lParam)
611 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
613 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_NOTICKS)
614 return 0;
616 return infoPtr->uNumTics+2;
620 static LRESULT
621 TRACKBAR_GetPageSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
623 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
625 return infoPtr->nPageSize;
629 static LRESULT
630 TRACKBAR_GetPos (HWND hwnd, WPARAM wParam, LPARAM lParam)
632 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
634 return infoPtr->nPos;
638 static LRESULT
639 TRACKBAR_GetRangeMax (HWND hwnd, WPARAM wParam, LPARAM lParam)
641 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
643 return infoPtr->nRangeMax;
647 static LRESULT
648 TRACKBAR_GetRangeMin (HWND hwnd, WPARAM wParam, LPARAM lParam)
650 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
652 return infoPtr->nRangeMin;
656 static LRESULT
657 TRACKBAR_GetSelEnd (HWND hwnd, WPARAM wParam, LPARAM lParam)
659 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
661 return infoPtr->nSelMax;
665 static LRESULT
666 TRACKBAR_GetSelStart (HWND hwnd, WPARAM wParam, LPARAM lParam)
668 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
670 return infoPtr->nSelMin;
674 static LRESULT
675 TRACKBAR_GetThumbLength (HWND hwnd, WPARAM wParam, LPARAM lParam)
677 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
679 return infoPtr->uThumbLen;
682 static LRESULT
683 TRACKBAR_GetPTics (HWND hwnd)
685 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
687 return (LRESULT) infoPtr->tics;
690 static LRESULT
691 TRACKBAR_GetThumbRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
693 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
694 LPRECT lprc = (LPRECT)lParam;
696 if (lprc == NULL)
697 return 0;
699 lprc->left = infoPtr->rcThumb.left;
700 lprc->right = infoPtr->rcThumb.right;
701 lprc->bottom = infoPtr->rcThumb.bottom;
702 lprc->top = infoPtr->rcThumb.top;
704 return 0;
708 static LRESULT
709 TRACKBAR_GetTic (HWND hwnd, WPARAM wParam, LPARAM lParam)
711 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
712 INT iTic;
714 iTic=(INT) wParam;
715 if ((iTic<0) || (iTic>infoPtr->uNumTics))
716 return -1;
718 return (LRESULT) infoPtr->tics[iTic];
723 static LRESULT
724 TRACKBAR_GetTicPos (HWND hwnd, WPARAM wParam, LPARAM lParam)
726 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
727 INT iTic, range, width, pos;
730 iTic=(INT ) wParam;
731 if ((iTic<0) || (iTic>infoPtr->uNumTics))
732 return -1;
734 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
735 width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
736 pos=infoPtr->rcChannel.left + (width * infoPtr->tics[iTic]) / range;
739 return (LRESULT) pos;
743 static LRESULT
744 TRACKBAR_GetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
746 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
748 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_TOOLTIPS)
749 return (LRESULT)infoPtr->hwndToolTip;
750 return 0;
754 /* case TBM_GETUNICODEFORMAT: */
757 static LRESULT
758 TRACKBAR_SetBuddy (HWND hwnd, WPARAM wParam, LPARAM lParam)
760 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
761 HWND hwndTemp;
763 if (wParam) {
764 /* buddy is left or above */
765 hwndTemp = infoPtr->hwndBuddyLA;
766 infoPtr->hwndBuddyLA = (HWND)lParam;
768 FIXME("move buddy!\n");
770 else {
771 /* buddy is right or below */
772 hwndTemp = infoPtr->hwndBuddyRB;
773 infoPtr->hwndBuddyRB = (HWND)lParam;
775 FIXME("move buddy!\n");
778 TRACKBAR_AlignBuddies (hwnd, infoPtr);
780 return (LRESULT)hwndTemp;
784 static LRESULT
785 TRACKBAR_SetLineSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
787 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
788 INT nTemp = infoPtr->nLineSize;
790 infoPtr->nLineSize = (INT)lParam;
792 return nTemp;
796 static LRESULT
797 TRACKBAR_SetPageSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
799 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
800 INT nTemp = infoPtr->nPageSize;
802 infoPtr->nPageSize = (INT)lParam;
804 return nTemp;
808 static LRESULT
809 TRACKBAR_SetPos (HWND hwnd, WPARAM wParam, LPARAM lParam)
811 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
813 infoPtr->nPos = (INT)LOWORD(lParam);
815 if (infoPtr->nPos < infoPtr->nRangeMin)
816 infoPtr->nPos = infoPtr->nRangeMin;
818 if (infoPtr->nPos > infoPtr->nRangeMax)
819 infoPtr->nPos = infoPtr->nRangeMax;
820 infoPtr->flags |= TB_THUMBPOSCHANGED;
822 if (wParam)
823 InvalidateRect (hwnd, NULL, FALSE);
825 return 0;
829 static LRESULT
830 TRACKBAR_SetRange (HWND hwnd, WPARAM wParam, LPARAM lParam)
832 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
833 infoPtr->nRangeMin = (INT)LOWORD(lParam);
834 infoPtr->nRangeMax = (INT)HIWORD(lParam);
836 if (infoPtr->nPos < infoPtr->nRangeMin) {
837 infoPtr->nPos = infoPtr->nRangeMin;
838 infoPtr->flags |=TB_THUMBPOSCHANGED;
841 if (infoPtr->nPos > infoPtr->nRangeMax) {
842 infoPtr->nPos = infoPtr->nRangeMax;
843 infoPtr->flags |=TB_THUMBPOSCHANGED;
846 infoPtr->nPageSize=(infoPtr->nRangeMax - infoPtr->nRangeMin)/5;
847 if (infoPtr->nPageSize == 0)
848 infoPtr->nPageSize = 1;
849 TRACKBAR_RecalculateTics (infoPtr);
851 if (wParam)
852 InvalidateRect (hwnd, NULL, FALSE);
854 return 0;
858 static LRESULT
859 TRACKBAR_SetRangeMax (HWND hwnd, WPARAM wParam, LPARAM lParam)
861 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
863 infoPtr->nRangeMax = (INT)lParam;
864 if (infoPtr->nPos > infoPtr->nRangeMax) {
865 infoPtr->nPos = infoPtr->nRangeMax;
866 infoPtr->flags |=TB_THUMBPOSCHANGED;
869 infoPtr->nPageSize=(infoPtr->nRangeMax - infoPtr->nRangeMin)/5;
870 if (infoPtr->nPageSize == 0)
871 infoPtr->nPageSize = 1;
872 TRACKBAR_RecalculateTics (infoPtr);
874 if (wParam)
875 InvalidateRect (hwnd, NULL, FALSE);
877 return 0;
881 static LRESULT
882 TRACKBAR_SetRangeMin (HWND hwnd, WPARAM wParam, LPARAM lParam)
884 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
886 infoPtr->nRangeMin = (INT)lParam;
887 if (infoPtr->nPos < infoPtr->nRangeMin) {
888 infoPtr->nPos = infoPtr->nRangeMin;
889 infoPtr->flags |=TB_THUMBPOSCHANGED;
892 infoPtr->nPageSize=(infoPtr->nRangeMax - infoPtr->nRangeMin)/5;
893 if (infoPtr->nPageSize == 0)
894 infoPtr->nPageSize = 1;
895 TRACKBAR_RecalculateTics (infoPtr);
897 if (wParam)
898 InvalidateRect (hwnd, NULL, FALSE);
900 return 0;
904 static LRESULT
905 TRACKBAR_SetTicFreq (HWND hwnd, WPARAM wParam)
907 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
909 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_AUTOTICKS)
910 infoPtr->uTicFreq=(UINT) wParam;
912 TRACKBAR_RecalculateTics (infoPtr);
914 InvalidateRect (hwnd, NULL, FALSE);
916 return 0;
920 static LRESULT
921 TRACKBAR_SetSel (HWND hwnd, WPARAM wParam, LPARAM lParam)
923 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
925 infoPtr->nSelMin = (INT)LOWORD(lParam);
926 infoPtr->nSelMax = (INT)HIWORD(lParam);
927 infoPtr->flags |=TB_SELECTIONCHANGED;
929 if (!GetWindowLongA (hwnd, GWL_STYLE) & TBS_ENABLESELRANGE)
930 return 0;
932 if (infoPtr->nSelMin < infoPtr->nRangeMin)
933 infoPtr->nSelMin = infoPtr->nRangeMin;
934 if (infoPtr->nSelMax > infoPtr->nRangeMax)
935 infoPtr->nSelMax = infoPtr->nRangeMax;
937 if (wParam)
938 InvalidateRect (hwnd, NULL, FALSE);
941 return 0;
945 static LRESULT
946 TRACKBAR_SetSelEnd (HWND hwnd, WPARAM wParam, LPARAM lParam)
948 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
950 if (!GetWindowLongA (hwnd, GWL_STYLE) & TBS_ENABLESELRANGE)
951 return 0;
953 infoPtr->nSelMax = (INT)lParam;
954 infoPtr->flags |= TB_SELECTIONCHANGED;
956 if (infoPtr->nSelMax > infoPtr->nRangeMax)
957 infoPtr->nSelMax = infoPtr->nRangeMax;
959 if (wParam)
960 InvalidateRect (hwnd, NULL, FALSE);
962 return 0;
966 static LRESULT
967 TRACKBAR_SetSelStart (HWND hwnd, WPARAM wParam, LPARAM lParam)
969 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
971 if (!GetWindowLongA (hwnd, GWL_STYLE) & TBS_ENABLESELRANGE)
972 return 0;
974 infoPtr->nSelMin = (INT)lParam;
975 infoPtr->flags |=TB_SELECTIONCHANGED;
977 if (infoPtr->nSelMin < infoPtr->nRangeMin)
978 infoPtr->nSelMin = infoPtr->nRangeMin;
980 if (wParam)
981 InvalidateRect (hwnd, NULL, FALSE);
983 return 0;
987 static LRESULT
988 TRACKBAR_SetThumbLength (HWND hwnd, WPARAM wParam, LPARAM lParam)
990 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
992 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_FIXEDLENGTH)
993 infoPtr->uThumbLen = (UINT)wParam;
995 infoPtr->flags |= TB_THUMBSIZECHANGED;
997 InvalidateRect (hwnd, NULL, FALSE);
999 return 0;
1003 static LRESULT
1004 TRACKBAR_SetTic (HWND hwnd, WPARAM wParam, LPARAM lParam)
1006 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1007 INT nPos = (INT)lParam;
1009 if ((nPos < infoPtr->nRangeMin) || (nPos> infoPtr->nRangeMax))
1010 return FALSE;
1012 infoPtr->uNumTics++;
1013 infoPtr->tics=COMCTL32_ReAlloc( infoPtr->tics,
1014 (infoPtr->uNumTics)*sizeof (DWORD));
1015 infoPtr->tics[infoPtr->uNumTics-1]=nPos;
1017 InvalidateRect (hwnd, NULL, FALSE);
1019 return TRUE;
1023 static LRESULT
1024 TRACKBAR_SetTipSide (HWND hwnd, WPARAM wParam, LPARAM lParam)
1026 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1027 INT fTemp = infoPtr->fLocation;
1029 infoPtr->fLocation = (INT)wParam;
1031 return fTemp;
1035 static LRESULT
1036 TRACKBAR_SetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
1038 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1040 infoPtr->hwndToolTip = (HWND)wParam;
1042 return 0;
1046 /* case TBM_SETUNICODEFORMAT: */
1049 static LRESULT
1050 TRACKBAR_InitializeThumb (HWND hwnd)
1052 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1054 infoPtr->uThumbLen = 23; /* initial thumb length */
1056 TRACKBAR_CalcChannel (hwnd,infoPtr);
1057 TRACKBAR_CalcThumb (hwnd, infoPtr);
1058 infoPtr->flags &= ~TB_SELECTIONCHANGED;
1060 return 0;
1064 static LRESULT
1065 TRACKBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
1067 TRACKBAR_INFO *infoPtr;
1069 infoPtr = (TRACKBAR_INFO *)COMCTL32_Alloc (sizeof(TRACKBAR_INFO));
1070 SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
1072 /* set default values */
1073 infoPtr->nRangeMin = 0;
1074 infoPtr->nRangeMax = 100;
1075 infoPtr->nLineSize = 1;
1076 infoPtr->nPageSize = 20;
1077 infoPtr->nSelMin = 0;
1078 infoPtr->nSelMax = 0;
1079 infoPtr->nPos = 0;
1081 infoPtr->uNumTics = 0; /* start and end tic are not included in count*/
1082 infoPtr->uTicFreq = 1;
1083 infoPtr->tics = NULL;
1084 infoPtr->clrBk = GetSysColor (COLOR_BACKGROUND);
1085 infoPtr->hwndNotify = GetParent (hwnd);
1087 TRACKBAR_InitializeThumb (hwnd);
1089 /* Create tooltip control */
1090 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_TOOLTIPS) {
1091 TTTOOLINFOA ti;
1093 infoPtr->hwndToolTip =
1094 CreateWindowExA (0, TOOLTIPS_CLASSA, NULL, 0,
1095 CW_USEDEFAULT, CW_USEDEFAULT,
1096 CW_USEDEFAULT, CW_USEDEFAULT,
1097 hwnd, 0, 0, 0);
1099 /* Send NM_TOOLTIPSCREATED notification */
1100 if (infoPtr->hwndToolTip) {
1101 NMTOOLTIPSCREATED nmttc;
1103 nmttc.hdr.hwndFrom = hwnd;
1104 nmttc.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1105 nmttc.hdr.code = NM_TOOLTIPSCREATED;
1106 nmttc.hwndToolTips = infoPtr->hwndToolTip;
1108 SendMessageA (GetParent (hwnd), WM_NOTIFY,
1109 (WPARAM)nmttc.hdr.idFrom, (LPARAM)&nmttc);
1112 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
1113 ti.cbSize = sizeof(TTTOOLINFOA);
1114 ti.uFlags = TTF_IDISHWND | TTF_TRACK;
1115 ti.hwnd = hwnd;
1116 ti.uId = 0;
1117 ti.lpszText = "Test"; /* LPSTR_TEXTCALLBACK */
1118 SetRectEmpty (&ti.rect);
1120 SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA, 0, (LPARAM)&ti);
1123 return 0;
1127 static LRESULT
1128 TRACKBAR_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
1130 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1132 /* delete tooltip control */
1133 if (infoPtr->hwndToolTip)
1134 DestroyWindow (infoPtr->hwndToolTip);
1136 COMCTL32_Free (infoPtr);
1137 return 0;
1141 static LRESULT
1142 TRACKBAR_KillFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
1144 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1146 TRACE("\n");
1148 infoPtr->bFocus = FALSE;
1149 infoPtr->flags &= ~TB_DRAG_MODE;
1151 InvalidateRect (hwnd, NULL, FALSE);
1153 return 0;
1157 static LRESULT
1158 TRACKBAR_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
1160 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1161 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1162 int clickPlace,prevPos,vertical;
1163 DOUBLE clickPos;
1165 SetFocus (hwnd);
1167 vertical = dwStyle & TBS_VERT;
1168 if (vertical)
1169 clickPlace=(INT)HIWORD(lParam);
1170 else
1171 clickPlace=(INT)LOWORD(lParam);
1173 if ((vertical &&
1174 (clickPlace>infoPtr->rcThumb.top) &&
1175 (clickPlace<infoPtr->rcThumb.bottom)) ||
1176 (!vertical &&
1177 (clickPlace>infoPtr->rcThumb.left) &&
1178 (clickPlace<infoPtr->rcThumb.right))) {
1179 infoPtr->flags |= TB_DRAG_MODE;
1180 if (dwStyle & TBS_TOOLTIPS) { /* enable tooltip */
1181 TTTOOLINFOA ti;
1182 POINT pt;
1184 GetCursorPos (&pt);
1185 SendMessageA (infoPtr->hwndToolTip, TTM_TRACKPOSITION, 0,
1186 (LPARAM)MAKELPARAM(pt.x, pt.y));
1188 ti.cbSize = sizeof(TTTOOLINFOA);
1189 ti.uId = 0;
1190 ti.hwnd = (UINT)hwnd;
1192 infoPtr->flags |= TB_SHOW_TOOLTIP;
1193 SetCapture (hwnd);
1194 SendMessageA (infoPtr->hwndToolTip, TTM_TRACKACTIVATE,
1195 (WPARAM)TRUE, (LPARAM)&ti);
1197 return 0;
1200 clickPos = TRACKBAR_ConvertPlaceToPosition (infoPtr, clickPlace, vertical);
1201 prevPos = infoPtr->nPos;
1203 if (clickPos > prevPos) { /* similar to VK_NEXT */
1204 infoPtr->nPos += infoPtr->nPageSize;
1205 if (infoPtr->nPos > infoPtr->nRangeMax)
1206 infoPtr->nPos = infoPtr->nRangeMax;
1207 TRACKBAR_SendNotify (hwnd, TB_PAGEUP);
1208 } else {
1209 infoPtr->nPos -= infoPtr->nPageSize; /* similar to VK_PRIOR */
1210 if (infoPtr->nPos < infoPtr->nRangeMin)
1211 infoPtr->nPos = infoPtr->nRangeMin;
1212 TRACKBAR_SendNotify (hwnd, TB_PAGEDOWN);
1215 if (prevPos!=infoPtr->nPos) {
1216 infoPtr->flags |= TB_THUMBPOSCHANGED;
1217 InvalidateRect (hwnd, NULL, FALSE);
1220 return 0;
1224 static LRESULT
1225 TRACKBAR_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
1227 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1229 TRACKBAR_SendNotify (hwnd, TB_ENDTRACK);
1231 if (infoPtr->flags & TB_DRAG_MODE)
1233 infoPtr->flags &= ~TB_DRAG_MODE;
1234 ReleaseCapture ();
1237 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_TOOLTIPS) { /* disable tooltip */
1238 TTTOOLINFOA ti;
1240 ti.cbSize = sizeof(TTTOOLINFOA);
1241 ti.uId = 0;
1242 ti.hwnd = (UINT)hwnd;
1244 infoPtr->flags &= ~TB_SHOW_TOOLTIP;
1245 SendMessageA (infoPtr->hwndToolTip, TTM_TRACKACTIVATE,
1246 (WPARAM)FALSE, (LPARAM)&ti);
1249 InvalidateRect (hwnd, NULL, FALSE);
1251 return 0;
1255 static LRESULT
1256 TRACKBAR_CaptureChanged (HWND hwnd, WPARAM wParam, LPARAM lParam)
1258 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1260 if (infoPtr->flags & TB_DRAGPOSVALID) {
1261 infoPtr->nPos=infoPtr->dragPos;
1262 InvalidateRect (hwnd, NULL, FALSE);
1265 infoPtr->flags &= ~ TB_DRAGPOSVALID;
1267 TRACKBAR_SendNotify (hwnd, TB_ENDTRACK);
1268 return 0;
1272 static LRESULT
1273 TRACKBAR_Paint (HWND hwnd, WPARAM wParam)
1275 HDC hdc;
1276 PAINTSTRUCT ps;
1278 hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
1279 TRACKBAR_Refresh (hwnd, hdc);
1280 if(!wParam)
1281 EndPaint (hwnd, &ps);
1282 return 0;
1286 static LRESULT
1287 TRACKBAR_SetFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
1289 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1291 TRACE("\n");
1292 infoPtr->bFocus = TRUE;
1294 InvalidateRect (hwnd, NULL, FALSE);
1296 return 0;
1300 static LRESULT
1301 TRACKBAR_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
1303 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1305 TRACKBAR_CalcChannel (hwnd, infoPtr);
1306 TRACKBAR_AlignBuddies (hwnd, infoPtr);
1308 return 0;
1312 static BOOL
1313 TRACKBAR_SendNotify (HWND hwnd, UINT code)
1315 TRACE("%x\n",code);
1317 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_VERT)
1318 return (BOOL) SendMessageA (GetParent (hwnd),
1319 WM_VSCROLL, (WPARAM)code, (LPARAM)hwnd);
1321 return (BOOL) SendMessageA (GetParent (hwnd),
1322 WM_HSCROLL, (WPARAM)code, (LPARAM)hwnd);
1326 static LRESULT
1327 TRACKBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
1329 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1330 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1331 SHORT clickPlace;
1332 DOUBLE dragPos;
1333 char buf[80];
1335 TRACE("%x\n",wParam);
1337 if (dwStyle & TBS_VERT)
1338 clickPlace=(SHORT)HIWORD(lParam);
1339 else
1340 clickPlace=(SHORT)LOWORD(lParam);
1342 if (!(infoPtr->flags & TB_DRAG_MODE))
1343 return TRUE;
1345 SetCapture (hwnd);
1346 dragPos = TRACKBAR_ConvertPlaceToPosition (infoPtr, clickPlace,
1347 dwStyle & TBS_VERT);
1348 if (dragPos > ((INT)dragPos) + 0.5)
1349 infoPtr->dragPos = dragPos + 1;
1350 else
1351 infoPtr->dragPos = dragPos;
1353 infoPtr->flags |= TB_DRAGPOSVALID;
1354 TRACKBAR_SendNotify (hwnd, TB_THUMBTRACK | (infoPtr->nPos>>16));
1356 if (infoPtr->flags & TB_SHOW_TOOLTIP) {
1357 POINT pt;
1358 TTTOOLINFOA ti;
1360 ti.cbSize = sizeof(TTTOOLINFOA);
1361 ti.hwnd = hwnd;
1362 ti.uId = 0;
1363 ti.hinst=0;
1364 sprintf (buf,"%d",infoPtr->nPos);
1365 ti.lpszText = (LPSTR) buf;
1366 GetCursorPos (&pt);
1368 if (dwStyle & TBS_VERT) {
1369 SendMessageA (infoPtr->hwndToolTip, TTM_TRACKPOSITION,
1370 0, (LPARAM)MAKELPARAM(pt.x+5, pt.y+15));
1371 } else {
1372 SendMessageA (infoPtr->hwndToolTip, TTM_TRACKPOSITION,
1373 0, (LPARAM)MAKELPARAM(pt.x+15, pt.y+5));
1375 SendMessageA (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTA,
1376 0, (LPARAM)&ti);
1379 InvalidateRect (hwnd, NULL, FALSE);
1380 UpdateWindow (hwnd);
1382 return TRUE;
1386 static LRESULT
1387 TRACKBAR_KeyDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
1389 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1390 INT pos;
1392 TRACE("%x\n",wParam);
1394 pos=infoPtr->nPos;
1395 switch (wParam) {
1396 case VK_LEFT:
1397 case VK_UP:
1398 if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
1399 infoPtr->nPos -= infoPtr->nLineSize;
1400 if (infoPtr->nPos < infoPtr->nRangeMin)
1401 infoPtr->nPos = infoPtr->nRangeMin;
1402 TRACKBAR_SendNotify (hwnd, TB_LINEUP);
1403 break;
1404 case VK_RIGHT:
1405 case VK_DOWN:
1406 if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
1407 infoPtr->nPos += infoPtr->nLineSize;
1408 if (infoPtr->nPos > infoPtr->nRangeMax)
1409 infoPtr->nPos = infoPtr->nRangeMax;
1410 TRACKBAR_SendNotify (hwnd, TB_LINEDOWN);
1411 break;
1412 case VK_NEXT:
1413 if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
1414 infoPtr->nPos += infoPtr->nPageSize;
1415 if (infoPtr->nPos > infoPtr->nRangeMax)
1416 infoPtr->nPos = infoPtr->nRangeMax;
1417 TRACKBAR_SendNotify (hwnd, TB_PAGEUP);
1418 break;
1419 case VK_PRIOR:
1420 if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
1421 infoPtr->nPos -= infoPtr->nPageSize;
1422 if (infoPtr->nPos < infoPtr->nRangeMin)
1423 infoPtr->nPos = infoPtr->nRangeMin;
1424 TRACKBAR_SendNotify (hwnd, TB_PAGEDOWN);
1425 break;
1426 case VK_HOME:
1427 if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
1428 infoPtr->nPos = infoPtr->nRangeMin;
1429 TRACKBAR_SendNotify (hwnd, TB_TOP);
1430 break;
1431 case VK_END:
1432 if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
1433 infoPtr->nPos = infoPtr->nRangeMax;
1434 TRACKBAR_SendNotify (hwnd, TB_BOTTOM);
1435 break;
1438 if (pos!=infoPtr->nPos) {
1439 infoPtr->flags |=TB_THUMBPOSCHANGED;
1440 InvalidateRect (hwnd, NULL, FALSE);
1443 return TRUE;
1447 static LRESULT
1448 TRACKBAR_KeyUp (HWND hwnd, WPARAM wParam)
1450 switch (wParam) {
1451 case VK_LEFT:
1452 case VK_UP:
1453 case VK_RIGHT:
1454 case VK_DOWN:
1455 case VK_NEXT:
1456 case VK_PRIOR:
1457 case VK_HOME:
1458 case VK_END:
1459 TRACKBAR_SendNotify (hwnd, TB_ENDTRACK);
1461 return TRUE;
1465 static LRESULT WINAPI
1466 TRACKBAR_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1468 switch (uMsg)
1470 case TBM_CLEARSEL:
1471 return TRACKBAR_ClearSel (hwnd, wParam, lParam);
1473 case TBM_CLEARTICS:
1474 return TRACKBAR_ClearTics (hwnd, wParam, lParam);
1476 case TBM_GETBUDDY:
1477 return TRACKBAR_GetBuddy (hwnd, wParam, lParam);
1479 case TBM_GETCHANNELRECT:
1480 return TRACKBAR_GetChannelRect (hwnd, wParam, lParam);
1482 case TBM_GETLINESIZE:
1483 return TRACKBAR_GetLineSize (hwnd, wParam, lParam);
1485 case TBM_GETNUMTICS:
1486 return TRACKBAR_GetNumTics (hwnd, wParam, lParam);
1488 case TBM_GETPAGESIZE:
1489 return TRACKBAR_GetPageSize (hwnd, wParam, lParam);
1491 case TBM_GETPOS:
1492 return TRACKBAR_GetPos (hwnd, wParam, lParam);
1494 case TBM_GETPTICS:
1495 return TRACKBAR_GetPTics (hwnd);
1497 case TBM_GETRANGEMAX:
1498 return TRACKBAR_GetRangeMax (hwnd, wParam, lParam);
1500 case TBM_GETRANGEMIN:
1501 return TRACKBAR_GetRangeMin (hwnd, wParam, lParam);
1503 case TBM_GETSELEND:
1504 return TRACKBAR_GetSelEnd (hwnd, wParam, lParam);
1506 case TBM_GETSELSTART:
1507 return TRACKBAR_GetSelStart (hwnd, wParam, lParam);
1509 case TBM_GETTHUMBLENGTH:
1510 return TRACKBAR_GetThumbLength (hwnd, wParam, lParam);
1512 case TBM_GETTHUMBRECT:
1513 return TRACKBAR_GetThumbRect (hwnd, wParam, lParam);
1515 case TBM_GETTIC:
1516 return TRACKBAR_GetTic (hwnd, wParam, lParam);
1518 case TBM_GETTICPOS:
1519 return TRACKBAR_GetTicPos (hwnd, wParam, lParam);
1521 case TBM_GETTOOLTIPS:
1522 return TRACKBAR_GetToolTips (hwnd, wParam, lParam);
1524 /* case TBM_GETUNICODEFORMAT: */
1526 case TBM_SETBUDDY:
1527 return TRACKBAR_SetBuddy (hwnd, wParam, lParam);
1529 case TBM_SETLINESIZE:
1530 return TRACKBAR_SetLineSize (hwnd, wParam, lParam);
1532 case TBM_SETPAGESIZE:
1533 return TRACKBAR_SetPageSize (hwnd, wParam, lParam);
1535 case TBM_SETPOS:
1536 return TRACKBAR_SetPos (hwnd, wParam, lParam);
1538 case TBM_SETRANGE:
1539 return TRACKBAR_SetRange (hwnd, wParam, lParam);
1541 case TBM_SETRANGEMAX:
1542 return TRACKBAR_SetRangeMax (hwnd, wParam, lParam);
1544 case TBM_SETRANGEMIN:
1545 return TRACKBAR_SetRangeMin (hwnd, wParam, lParam);
1547 case TBM_SETSEL:
1548 return TRACKBAR_SetSel (hwnd, wParam, lParam);
1550 case TBM_SETSELEND:
1551 return TRACKBAR_SetSelEnd (hwnd, wParam, lParam);
1553 case TBM_SETSELSTART:
1554 return TRACKBAR_SetSelStart (hwnd, wParam, lParam);
1556 case TBM_SETTHUMBLENGTH:
1557 return TRACKBAR_SetThumbLength (hwnd, wParam, lParam);
1559 case TBM_SETTIC:
1560 return TRACKBAR_SetTic (hwnd, wParam, lParam);
1562 case TBM_SETTICFREQ:
1563 return TRACKBAR_SetTicFreq (hwnd, wParam);
1565 case TBM_SETTIPSIDE:
1566 return TRACKBAR_SetTipSide (hwnd, wParam, lParam);
1568 case TBM_SETTOOLTIPS:
1569 return TRACKBAR_SetToolTips (hwnd, wParam, lParam);
1571 /* case TBM_SETUNICODEFORMAT: */
1574 case WM_CAPTURECHANGED:
1575 return TRACKBAR_CaptureChanged (hwnd, wParam, lParam);
1577 case WM_CREATE:
1578 return TRACKBAR_Create (hwnd, wParam, lParam);
1580 case WM_DESTROY:
1581 return TRACKBAR_Destroy (hwnd, wParam, lParam);
1583 /* case WM_ENABLE: */
1585 /* case WM_ERASEBKGND: */
1586 /* return 0; */
1588 case WM_GETDLGCODE:
1589 return DLGC_WANTARROWS;
1591 case WM_KEYDOWN:
1592 return TRACKBAR_KeyDown (hwnd, wParam, lParam);
1594 case WM_KEYUP:
1595 return TRACKBAR_KeyUp (hwnd, wParam);
1597 case WM_KILLFOCUS:
1598 return TRACKBAR_KillFocus (hwnd, wParam, lParam);
1600 case WM_LBUTTONDOWN:
1601 return TRACKBAR_LButtonDown (hwnd, wParam, lParam);
1603 case WM_LBUTTONUP:
1604 return TRACKBAR_LButtonUp (hwnd, wParam, lParam);
1606 case WM_MOUSEMOVE:
1607 return TRACKBAR_MouseMove (hwnd, wParam, lParam);
1609 case WM_PAINT:
1610 return TRACKBAR_Paint (hwnd, wParam);
1612 case WM_SETFOCUS:
1613 return TRACKBAR_SetFocus (hwnd, wParam, lParam);
1615 case WM_SIZE:
1616 return TRACKBAR_Size (hwnd, wParam, lParam);
1618 case WM_WININICHANGE:
1619 return TRACKBAR_InitializeThumb (hwnd);
1621 default:
1622 if (uMsg >= WM_USER)
1623 ERR("unknown msg %04x wp=%08x lp=%08lx\n",
1624 uMsg, wParam, lParam);
1625 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
1627 return 0;
1631 VOID
1632 TRACKBAR_Register (void)
1634 WNDCLASSA wndClass;
1636 if (GlobalFindAtomA (TRACKBAR_CLASSA)) return;
1638 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
1639 wndClass.style = CS_GLOBALCLASS;
1640 wndClass.lpfnWndProc = (WNDPROC)TRACKBAR_WindowProc;
1641 wndClass.cbClsExtra = 0;
1642 wndClass.cbWndExtra = sizeof(TRACKBAR_INFO *);
1643 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
1644 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
1645 wndClass.lpszClassName = TRACKBAR_CLASSA;
1647 RegisterClassA (&wndClass);
1651 VOID
1652 TRACKBAR_Unregister (void)
1654 if (GlobalFindAtomA (TRACKBAR_CLASSA))
1655 UnregisterClassA (TRACKBAR_CLASSA, (HINSTANCE)NULL);