Got rid of the Wine internal lstrcpy* functions and of winestring.h.
[wine/gsoc_dplay.git] / dlls / comctl32 / trackbar.c
blob5b117671c7b2c8630e0823640f7f63c023f3766b
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 * - handle dragging slider better
11 * - better tic handling.
12 * - more notifications.
16 /* known bugs:
18 -TBM_SETRANGEMAX & TBM_SETRANGEMIN should only change the view of the
19 trackbar, not the actual amount of tics in the list.
20 -TBM_GETTIC & TBM_GETTICPOS shouldn't rely on infoPtr->tics being sorted.
24 #include <stdio.h>
26 #include "winbase.h"
27 #include "commctrl.h"
28 #include "debugtools.h"
30 DEFAULT_DEBUG_CHANNEL(trackbar);
32 typedef struct
34 INT nRangeMin;
35 INT nRangeMax;
36 INT nLineSize;
37 INT nPageSize;
38 INT nSelMin;
39 INT nSelMax;
40 INT nPos;
41 UINT uThumbLen;
42 UINT uNumTics;
43 UINT uTicFreq;
44 HWND hwndNotify;
45 HWND hwndToolTip;
46 HWND hwndBuddyLA;
47 HWND hwndBuddyRB;
48 INT fLocation;
49 COLORREF clrBk;
50 INT flags;
51 BOOL bFocus;
52 RECT rcChannel;
53 RECT rcSelection;
54 RECT rcThumb;
55 INT dragPos;
56 LPLONG tics;
57 } TRACKBAR_INFO;
59 /* #define TB_REFRESH_TIMER 1 */
60 /* #define TB_REFRESH_DELAY 1 */
62 #define TRACKBAR_GetInfoPtr(wndPtr) ((TRACKBAR_INFO *)GetWindowLongA (hwnd,0))
65 /* Used by TRACKBAR_Refresh to find out which parts of the control
66 need to be recalculated */
68 #define TB_THUMBPOSCHANGED 1
69 #define TB_THUMBSIZECHANGED 2
70 #define TB_THUMBCHANGED (TB_THUMBPOSCHANGED | TB_THUMBPOSCHANGED)
71 #define TB_SELECTIONCHANGED 4
72 #define TB_DRAG_MODE 16 /* we're dragging the slider */
73 #define TB_DRAGPOSVALID 32 /* current Position is in dragPos */
74 #define TB_SHOW_TOOLTIP 64 /* tooltip-style enabled and tooltip on */
76 /* helper defines for TRACKBAR_DrawTic */
77 #define TIC_LEFTEDGE 0x20
78 #define TIC_RIGHTEDGE 0x40
79 #define TIC_EDGE (TIC_LEFTEDGE | TIC_RIGHTEDGE)
80 #define TIC_SELECTIONMARKMAX 0x80
81 #define TIC_SELECTIONMARKMIN 0x100
82 #define TIC_SELECTIONMARK (TIC_SELECTIONMARKMAX | TIC_SELECTIONMARKMIN)
84 static BOOL TRACKBAR_SendNotify (HWND hwnd, UINT code);
86 static void TRACKBAR_RecalculateTics (TRACKBAR_INFO *infoPtr)
88 int i,tic,nrTics;
90 if (infoPtr->uTicFreq && infoPtr->nRangeMax >= infoPtr->nRangeMin)
91 nrTics=(infoPtr->nRangeMax - infoPtr->nRangeMin)/infoPtr->uTicFreq;
92 else {
93 nrTics=0;
94 COMCTL32_Free (infoPtr->tics);
95 infoPtr->tics=NULL;
96 infoPtr->uNumTics=0;
97 return;
100 if (nrTics!=infoPtr->uNumTics) {
101 infoPtr->tics=COMCTL32_ReAlloc (infoPtr->tics,
102 (nrTics+1)*sizeof (DWORD));
103 infoPtr->uNumTics=nrTics;
105 infoPtr->uNumTics=nrTics;
106 tic=infoPtr->nRangeMin+infoPtr->uTicFreq;
107 for (i=0; i<nrTics; i++,tic+=infoPtr->uTicFreq)
108 infoPtr->tics[i]=tic;
112 /* converts from physical (mouse) position to logical position
113 (in range of trackbar) */
115 static inline DOUBLE
116 TRACKBAR_ConvertPlaceToPosition (TRACKBAR_INFO *infoPtr, int place,
117 int vertical)
119 double range,width,pos;
121 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
122 if (vertical) {
123 width=infoPtr->rcChannel.bottom - infoPtr->rcChannel.top;
124 pos=(range*(place - infoPtr->rcChannel.top)) / width;
125 } else {
126 width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
127 pos=(range*(place - infoPtr->rcChannel.left)) / width;
129 pos+=infoPtr->nRangeMin;
130 if (pos > infoPtr->nRangeMax)
131 pos = infoPtr->nRangeMax;
132 else if (pos < infoPtr->nRangeMin)
133 pos = infoPtr->nRangeMin;
135 TRACE("%.2f\n",pos);
136 return pos;
140 static VOID
141 TRACKBAR_CalcChannel (HWND hwnd, TRACKBAR_INFO *infoPtr)
143 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
144 INT cyChannel,offsettop,offsetedge;
145 RECT lpRect,*channel = & infoPtr->rcChannel;
147 GetClientRect (hwnd, &lpRect);
149 if (dwStyle & TBS_ENABLESELRANGE)
150 cyChannel = ((int)(infoPtr->uThumbLen/4.5)+1)*3;
151 else
152 cyChannel = 4;
154 offsettop = (int)(infoPtr->uThumbLen/4.5);
155 offsetedge = (int)(infoPtr->uThumbLen/4.5) + 3;
157 if (dwStyle & TBS_VERT) {
158 channel->top = lpRect.top + offsetedge;
159 channel->bottom = lpRect.bottom - offsetedge;
161 if (dwStyle & (TBS_BOTH | TBS_LEFT)) {
162 channel->left = lpRect.left + offsettop + 8 ;
163 channel->right = channel->left + cyChannel;
165 else { /* TBS_RIGHT */
166 channel->left = lpRect.left + offsettop;
167 channel->right = channel->left + cyChannel;
170 else {
171 channel->left = lpRect.left + offsetedge;
172 channel->right = lpRect.right - offsetedge;
174 if (dwStyle & (TBS_BOTH|TBS_TOP)) {
175 channel->top = lpRect.top + offsettop + 8 ;
176 channel->bottom = channel->top + cyChannel;
178 else { /* TBS_BOTTOM */
179 channel->top = lpRect.top + offsettop;
180 channel->bottom = channel->top + cyChannel;
185 static VOID
186 TRACKBAR_CalcThumb (HWND hwnd, TRACKBAR_INFO *infoPtr)
188 RECT *thumb;
189 int range, width, thumbdepth;
190 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
192 thumb=&infoPtr->rcThumb;
193 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
194 thumbdepth = ((INT)((FLOAT)infoPtr->uThumbLen / 4.5) * 2) + 2;
196 if (!range) return; /* FIXME: may this happen? */
198 if (dwStyle & TBS_VERT)
200 width=infoPtr->rcChannel.bottom - infoPtr->rcChannel.top;
202 if (dwStyle & (TBS_BOTH | TBS_LEFT))
203 thumb->left = 10;
204 else
205 thumb-> left =2;
206 thumb->right = thumb -> left + infoPtr->uThumbLen;
207 thumb->top = infoPtr->rcChannel.top +
208 (width*(infoPtr->nPos - infoPtr->nRangeMin))/range -
209 thumbdepth/2;
210 thumb->bottom = thumb->top + thumbdepth;
212 else
214 width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
216 thumb->left = infoPtr->rcChannel.left +
217 (width*(infoPtr->nPos - infoPtr->nRangeMin))/range -
218 thumbdepth/2;
219 thumb->right = thumb->left + thumbdepth;
220 if (dwStyle & (TBS_BOTH | TBS_TOP))
221 thumb->top = 10;
222 else
223 thumb->top = 2;
224 thumb->bottom = thumb -> top + infoPtr->uThumbLen;
228 static VOID
229 TRACKBAR_CalcSelection (HWND hwnd, TRACKBAR_INFO *infoPtr)
231 RECT *selection;
232 int range, width;
234 selection= & infoPtr->rcSelection;
235 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
236 width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
238 if (range <= 0)
239 SetRectEmpty (selection);
240 else
241 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_VERT) {
242 selection->left = infoPtr->rcChannel.left +
243 (width*infoPtr->nSelMin)/range;
244 selection->right = infoPtr->rcChannel.left +
245 (width*infoPtr->nSelMax)/range;
246 selection->top = infoPtr->rcChannel.top + 2;
247 selection->bottom = infoPtr->rcChannel.bottom - 2;
248 } else {
249 selection->top = infoPtr->rcChannel.top +
250 (width*infoPtr->nSelMin)/range;
251 selection->bottom = infoPtr->rcChannel.top +
252 (width*infoPtr->nSelMax)/range;
253 selection->left = infoPtr->rcChannel.left + 2;
254 selection->right = infoPtr->rcChannel.right - 2;
258 /* Trackbar drawing code. I like my spaghetti done milanese. */
260 /* ticPos is in tic-units, not in pixels */
262 static VOID
263 TRACKBAR_DrawHorizTic (TRACKBAR_INFO *infoPtr, HDC hdc, LONG ticPos,
264 int flags, COLORREF clrTic)
266 RECT rcChannel=infoPtr->rcChannel;
267 int x,y,width,range,side;
269 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
270 width=rcChannel.right - rcChannel.left;
272 if (flags & TBS_TOP) {
273 y=rcChannel.top-2;
274 side=-1;
275 } else {
276 y=rcChannel.bottom+2;
277 side=1;
280 if (flags & TIC_SELECTIONMARK) {
281 if (flags & TIC_SELECTIONMARKMIN)
282 x=rcChannel.left + (width*(ticPos - infoPtr->nRangeMin))/range - 1;
283 else
284 x=rcChannel.left + (width*(ticPos - infoPtr->nRangeMin))/range + 1;
286 SetPixel (hdc, x,y+6*side, clrTic);
287 SetPixel (hdc, x,y+7*side, clrTic);
288 return;
291 if ((ticPos>infoPtr->nRangeMin) && (ticPos<infoPtr->nRangeMax)) {
292 x=rcChannel.left + (width*(ticPos - infoPtr->nRangeMin))/range;
293 SetPixel (hdc, x,y+5*side, clrTic);
294 SetPixel (hdc, x,y+6*side, clrTic);
295 SetPixel (hdc, x,y+7*side, clrTic);
298 if (flags & TIC_EDGE) {
299 if (flags & TIC_LEFTEDGE)
300 x=rcChannel.left;
301 else
302 x=rcChannel.right;
304 SetPixel (hdc, x,y+5*side, clrTic);
305 SetPixel (hdc, x,y+6*side, clrTic);
306 SetPixel (hdc, x,y+7*side, clrTic);
307 SetPixel (hdc, x,y+8*side, clrTic);
312 static VOID
313 TRACKBAR_DrawVertTic (TRACKBAR_INFO *infoPtr, HDC hdc, LONG ticPos,
314 int flags, COLORREF clrTic)
316 RECT rcChannel=infoPtr->rcChannel;
317 int x,y,width,range,side;
319 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
320 width=rcChannel.bottom - rcChannel.top;
322 if (flags & TBS_TOP) {
323 x=rcChannel.left-2;
324 side=-1;
325 } else {
326 x=rcChannel.right+2;
327 side=1;
331 if (flags & TIC_SELECTIONMARK) {
332 if (flags & TIC_SELECTIONMARKMIN)
333 y=rcChannel.top + (width*(ticPos - infoPtr->nRangeMin))/range - 1;
334 else
335 y=rcChannel.top + (width*(ticPos - infoPtr->nRangeMin))/range + 1;
337 SetPixel (hdc, x+6*side, y, clrTic);
338 SetPixel (hdc, x+7*side, y, clrTic);
339 return;
342 if ((ticPos>infoPtr->nRangeMin) && (ticPos<infoPtr->nRangeMax)) {
343 y=rcChannel.top + (width*(ticPos - infoPtr->nRangeMin))/range;
344 SetPixel (hdc, x+5*side, y, clrTic);
345 SetPixel (hdc, x+6*side, y, clrTic);
346 SetPixel (hdc, x+7*side, y, clrTic);
349 if (flags & TIC_EDGE) {
350 if (flags & TIC_LEFTEDGE)
351 y=rcChannel.top;
352 else
353 y=rcChannel.bottom;
355 SetPixel (hdc, x+5*side, y, clrTic);
356 SetPixel (hdc, x+6*side, y, clrTic);
357 SetPixel (hdc, x+7*side, y, clrTic);
358 SetPixel (hdc, x+8*side, y, clrTic);
364 static VOID
365 TRACKBAR_DrawTics (TRACKBAR_INFO *infoPtr, HDC hdc, LONG ticPos,
366 int flags, COLORREF clrTic)
369 if (flags & TBS_VERT) {
370 if ((flags & TBS_TOP) || (flags & TBS_BOTH))
371 TRACKBAR_DrawVertTic (infoPtr, hdc, ticPos,
372 flags | TBS_TOP , clrTic);
373 if (!(flags & TBS_TOP) || (flags & TBS_BOTH))
374 TRACKBAR_DrawVertTic (infoPtr, hdc, ticPos, flags, clrTic);
375 return;
378 if ((flags & TBS_TOP) || (flags & TBS_BOTH))
379 TRACKBAR_DrawHorizTic (infoPtr, hdc, ticPos, flags | TBS_TOP , clrTic);
381 if (!(flags & TBS_TOP) || (flags & TBS_BOTH))
382 TRACKBAR_DrawHorizTic (infoPtr, hdc, ticPos, flags, clrTic);
386 static VOID
387 TRACKBAR_DrawThumb(TRACKBAR_INFO *infoPtr, HDC hdc, DWORD dwStyle)
389 HBRUSH oldbr,hbr = GetSysColorBrush(COLOR_BTNFACE);
390 HPEN oldpen=(HPEN)NULL,hpn;
391 RECT thumb = infoPtr->rcThumb;
392 int BlackUntil=3;
393 int PointCount=6;
394 POINT points[6];
396 static INT PointDepth = 4;
398 oldbr = SelectObject (hdc, hbr);
399 SetPolyFillMode (hdc,WINDING);
401 if (dwStyle & TBS_BOTH)
403 points[0].x=thumb.right;
404 points[0].y=thumb.top;
405 points[1].x=thumb.right;
406 points[1].y=thumb.bottom;
407 points[2].x=thumb.left;
408 points[2].y=thumb.bottom;
409 points[3].x=thumb.left;
410 points[3].y=thumb.top;
411 points[4].x=points[0].x;
412 points[4].y=points[0].y;
413 PointCount = 5;
414 BlackUntil = 3;
416 else
418 if (dwStyle & TBS_VERT)
420 if (dwStyle & TBS_LEFT)
422 points[0].x=thumb.right;
423 points[0].y=thumb.top;
424 points[1].x=thumb.right;
425 points[1].y=thumb.bottom;
426 points[2].x=thumb.left + PointDepth;
427 points[2].y=thumb.bottom;
428 points[3].x=thumb.left;
429 points[3].y=(thumb.bottom - thumb.top) / 2 + thumb.top;
430 points[4].x=thumb.left + PointDepth;
431 points[4].y=thumb.top;
432 points[5].x=points[0].x;
433 points[5].y=points[0].y;
434 BlackUntil = 4;
436 else
438 points[0].x=thumb.right;
439 points[0].y=(thumb.bottom - thumb.top) / 2 + thumb.top;
440 points[1].x=thumb.right - PointDepth;
441 points[1].y=thumb.bottom;
442 points[2].x=thumb.left;
443 points[2].y=thumb.bottom;
444 points[3].x=thumb.left;
445 points[3].y=thumb.top;
446 points[4].x=thumb.right - PointDepth;
447 points[4].y=thumb.top;
448 points[5].x=points[0].x;
449 points[5].y=points[0].y;
452 else
454 if (dwStyle & TBS_TOP)
456 points[0].x=(thumb.right - thumb.left) / 2 + thumb.left ;
457 points[0].y=thumb.top;
458 points[1].x=thumb.right;
459 points[1].y=thumb.top + PointDepth;
460 points[2].x=thumb.right;
461 points[2].y=thumb.bottom;
462 points[3].x=thumb.left;
463 points[3].y=thumb.bottom;
464 points[4].x=thumb.left;
465 points[4].y=thumb.top + PointDepth;
466 points[5].x=points[0].x;
467 points[5].y=points[0].y;
468 BlackUntil = 4;
470 else
472 points[0].x=thumb.right;
473 points[0].y=thumb.top;
474 points[1].x=thumb.right;
475 points[1].y=thumb.bottom - PointDepth;
476 points[2].x=(thumb.right - thumb.left) / 2 + thumb.left ;
477 points[2].y=thumb.bottom;
478 points[3].x=thumb.left;
479 points[3].y=thumb.bottom - PointDepth;
480 points[4].x=thumb.left;
481 points[4].y=thumb.top;
482 points[5].x=points[0].x;
483 points[5].y=points[0].y;
490 * Fill the shape
492 Polygon (hdc, points, PointCount);
495 * Draw the edge
497 hpn = GetStockObject(BLACK_PEN);
498 oldpen = SelectObject(hdc,hpn);
501 * Black part
503 Polyline(hdc,points,BlackUntil);
505 SelectObject(hdc,oldpen);
506 hpn = GetStockObject(WHITE_PEN);
507 SelectObject(hdc,hpn);
510 * White Part
512 Polyline(hdc,&points[BlackUntil-1],PointCount+1-BlackUntil);
515 * restore the brush and pen
517 SelectObject(hdc,oldbr);
518 if (oldpen)
519 SelectObject(hdc,oldpen);
522 static VOID
523 TRACKBAR_Refresh (HWND hwnd, HDC hdc)
525 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
526 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
527 RECT rcClient, rcChannel, rcSelection;
528 HBRUSH hBrush;
529 int i;
531 GetClientRect (hwnd, &rcClient);
532 hBrush = CreateSolidBrush (infoPtr->clrBk);
533 FillRect (hdc, &rcClient, hBrush);
534 DeleteObject (hBrush);
536 if (infoPtr->flags & TB_DRAGPOSVALID) {
537 infoPtr->nPos=infoPtr->dragPos;
538 infoPtr->flags |= TB_THUMBPOSCHANGED;
541 if (infoPtr->flags & TB_THUMBCHANGED) {
542 TRACKBAR_CalcThumb (hwnd, infoPtr);
543 if (infoPtr->flags & TB_THUMBSIZECHANGED)
544 TRACKBAR_CalcChannel (hwnd, infoPtr);
546 if (infoPtr->flags & TB_SELECTIONCHANGED)
547 TRACKBAR_CalcSelection (hwnd, infoPtr);
548 infoPtr->flags &= ~ (TB_THUMBCHANGED | TB_SELECTIONCHANGED |
549 TB_DRAGPOSVALID);
551 /* draw channel */
553 rcChannel = infoPtr->rcChannel;
554 rcSelection= infoPtr->rcSelection;
555 DrawEdge (hdc, &rcChannel, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
557 if (dwStyle & TBS_ENABLESELRANGE) { /* fill the channel */
558 HBRUSH hbr = CreateSolidBrush (RGB(255,255,255));
559 FillRect (hdc, &rcChannel, hbr);
560 if (((dwStyle & TBS_VERT) &&
561 (rcSelection.left!=rcSelection.right)) ||
562 ((!(dwStyle & TBS_VERT)) &&
563 (rcSelection.left!=rcSelection.right))) {
564 hbr=CreateSolidBrush (COLOR_HIGHLIGHT);
565 FillRect (hdc, &rcSelection, hbr);
567 DeleteObject (hbr);
571 /* draw tics */
573 if (!(dwStyle & TBS_NOTICKS)) {
574 int ticFlags = dwStyle & 0x0f;
575 COLORREF clrTic=GetSysColor (COLOR_3DDKSHADOW);
577 for (i=0; i<infoPtr->uNumTics; i++)
578 TRACKBAR_DrawTics (infoPtr, hdc, infoPtr->tics[i],
579 ticFlags, clrTic);
581 TRACKBAR_DrawTics (infoPtr, hdc, 0, ticFlags | TIC_LEFTEDGE, clrTic);
582 TRACKBAR_DrawTics (infoPtr, hdc, 0, ticFlags | TIC_RIGHTEDGE, clrTic);
584 if ((dwStyle & TBS_ENABLESELRANGE) &&
585 (rcSelection.left!=rcSelection.right)) {
586 TRACKBAR_DrawTics (infoPtr, hdc, infoPtr->nSelMin,
587 ticFlags | TIC_SELECTIONMARKMIN, clrTic);
588 TRACKBAR_DrawTics (infoPtr, hdc, infoPtr->nSelMax,
589 ticFlags | TIC_SELECTIONMARKMAX, clrTic);
593 /* draw thumb */
595 if (!(dwStyle & TBS_NOTHUMB))
597 TRACKBAR_DrawThumb(infoPtr,hdc,dwStyle);
600 if (infoPtr->bFocus)
601 DrawFocusRect (hdc, &rcClient);
605 static VOID
606 TRACKBAR_AlignBuddies (HWND hwnd, TRACKBAR_INFO *infoPtr)
608 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
609 HWND hwndParent = GetParent (hwnd);
610 RECT rcSelf, rcBuddy;
611 INT x, y;
613 GetWindowRect (hwnd, &rcSelf);
614 MapWindowPoints (HWND_DESKTOP, hwndParent, (LPPOINT)&rcSelf, 2);
616 /* align buddy left or above */
617 if (infoPtr->hwndBuddyLA) {
618 GetWindowRect (infoPtr->hwndBuddyLA, &rcBuddy);
619 MapWindowPoints (HWND_DESKTOP, hwndParent, (LPPOINT)&rcBuddy, 2);
621 if (dwStyle & TBS_VERT) {
622 x = (infoPtr->rcChannel.right + infoPtr->rcChannel.left) / 2 -
623 (rcBuddy.right - rcBuddy.left) / 2 + rcSelf.left;
624 y = rcSelf.top - (rcBuddy.bottom - rcBuddy.top);
626 else {
627 x = rcSelf.left - (rcBuddy.right - rcBuddy.left);
628 y = (infoPtr->rcChannel.bottom + infoPtr->rcChannel.top) / 2 -
629 (rcBuddy.bottom - rcBuddy.top) / 2 + rcSelf.top;
632 SetWindowPos (infoPtr->hwndBuddyLA, 0, x, y, 0, 0,
633 SWP_NOZORDER | SWP_NOSIZE);
637 /* align buddy right or below */
638 if (infoPtr->hwndBuddyRB) {
639 GetWindowRect (infoPtr->hwndBuddyRB, &rcBuddy);
640 MapWindowPoints (HWND_DESKTOP, hwndParent, (LPPOINT)&rcBuddy, 2);
642 if (dwStyle & TBS_VERT) {
643 x = (infoPtr->rcChannel.right + infoPtr->rcChannel.left) / 2 -
644 (rcBuddy.right - rcBuddy.left) / 2 + rcSelf.left;
645 y = rcSelf.bottom;
647 else {
648 x = rcSelf.right;
649 y = (infoPtr->rcChannel.bottom + infoPtr->rcChannel.top) / 2 -
650 (rcBuddy.bottom - rcBuddy.top) / 2 + rcSelf.top;
652 SetWindowPos (infoPtr->hwndBuddyRB, 0, x, y, 0, 0,
653 SWP_NOZORDER | SWP_NOSIZE);
658 static LRESULT
659 TRACKBAR_ClearSel (HWND hwnd, WPARAM wParam, LPARAM lParam)
661 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
663 infoPtr->nSelMin = 0;
664 infoPtr->nSelMax = 0;
665 infoPtr->flags |= TB_SELECTIONCHANGED;
667 if ((BOOL)wParam)
668 InvalidateRect (hwnd, NULL, FALSE);
670 return 0;
674 static LRESULT
675 TRACKBAR_ClearTics (HWND hwnd, WPARAM wParam, LPARAM lParam)
677 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
679 if (infoPtr->tics) {
680 COMCTL32_Free (infoPtr->tics);
681 infoPtr->tics = NULL;
682 infoPtr->uNumTics = 0;
685 if (wParam)
686 InvalidateRect (hwnd, NULL, FALSE);
688 return 0;
692 static LRESULT
693 TRACKBAR_GetBuddy (HWND hwnd, WPARAM wParam, LPARAM lParam)
695 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
697 if (wParam) /* buddy is left or above */
698 return (LRESULT)infoPtr->hwndBuddyLA;
700 /* buddy is right or below */
701 return (LRESULT) infoPtr->hwndBuddyRB;
705 static LRESULT
706 TRACKBAR_GetChannelRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
708 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
709 LPRECT lprc = (LPRECT)lParam;
711 if (lprc == NULL)
712 return 0;
714 lprc->left = infoPtr->rcChannel.left;
715 lprc->right = infoPtr->rcChannel.right;
716 lprc->bottom = infoPtr->rcChannel.bottom;
717 lprc->top = infoPtr->rcChannel.top;
719 return 0;
723 static LRESULT
724 TRACKBAR_GetLineSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
726 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
728 return infoPtr->nLineSize;
732 static LRESULT
733 TRACKBAR_GetNumTics (HWND hwnd, WPARAM wParam, LPARAM lParam)
735 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
737 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_NOTICKS)
738 return 0;
740 return infoPtr->uNumTics+2;
744 static LRESULT
745 TRACKBAR_GetPageSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
747 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
749 return infoPtr->nPageSize;
753 static LRESULT
754 TRACKBAR_GetPos (HWND hwnd, WPARAM wParam, LPARAM lParam)
756 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
758 return infoPtr->nPos;
762 static LRESULT
763 TRACKBAR_GetRangeMax (HWND hwnd, WPARAM wParam, LPARAM lParam)
765 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
767 return infoPtr->nRangeMax;
771 static LRESULT
772 TRACKBAR_GetRangeMin (HWND hwnd, WPARAM wParam, LPARAM lParam)
774 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
776 return infoPtr->nRangeMin;
780 static LRESULT
781 TRACKBAR_GetSelEnd (HWND hwnd, WPARAM wParam, LPARAM lParam)
783 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
785 return infoPtr->nSelMax;
789 static LRESULT
790 TRACKBAR_GetSelStart (HWND hwnd, WPARAM wParam, LPARAM lParam)
792 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
794 return infoPtr->nSelMin;
798 static LRESULT
799 TRACKBAR_GetThumbLength (HWND hwnd, WPARAM wParam, LPARAM lParam)
801 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
803 return infoPtr->uThumbLen;
806 static LRESULT
807 TRACKBAR_GetPTics (HWND hwnd)
809 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
811 return (LRESULT) infoPtr->tics;
814 static LRESULT
815 TRACKBAR_GetThumbRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
817 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
818 LPRECT lprc = (LPRECT)lParam;
820 if (lprc == NULL)
821 return 0;
823 lprc->left = infoPtr->rcThumb.left;
824 lprc->right = infoPtr->rcThumb.right;
825 lprc->bottom = infoPtr->rcThumb.bottom;
826 lprc->top = infoPtr->rcThumb.top;
828 return 0;
832 static LRESULT
833 TRACKBAR_GetTic (HWND hwnd, WPARAM wParam, LPARAM lParam)
835 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
836 INT iTic;
838 iTic=(INT) wParam;
839 if ((iTic<0) || (iTic>infoPtr->uNumTics))
840 return -1;
842 return (LRESULT) infoPtr->tics[iTic];
847 static LRESULT
848 TRACKBAR_GetTicPos (HWND hwnd, WPARAM wParam, LPARAM lParam)
850 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
851 INT iTic, range, width, pos;
854 iTic=(INT ) wParam;
855 if ((iTic<0) || (iTic>infoPtr->uNumTics))
856 return -1;
858 range=infoPtr->nRangeMax - infoPtr->nRangeMin;
859 width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
860 pos=infoPtr->rcChannel.left + (width * infoPtr->tics[iTic]) / range;
863 return (LRESULT) pos;
867 static LRESULT
868 TRACKBAR_GetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
870 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
872 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_TOOLTIPS)
873 return (LRESULT)infoPtr->hwndToolTip;
874 return 0;
878 /* case TBM_GETUNICODEFORMAT: */
881 static LRESULT
882 TRACKBAR_SetBuddy (HWND hwnd, WPARAM wParam, LPARAM lParam)
884 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
885 HWND hwndTemp;
887 if (wParam) {
888 /* buddy is left or above */
889 hwndTemp = infoPtr->hwndBuddyLA;
890 infoPtr->hwndBuddyLA = (HWND)lParam;
892 FIXME("move buddy!\n");
894 else {
895 /* buddy is right or below */
896 hwndTemp = infoPtr->hwndBuddyRB;
897 infoPtr->hwndBuddyRB = (HWND)lParam;
899 FIXME("move buddy!\n");
902 TRACKBAR_AlignBuddies (hwnd, infoPtr);
904 return (LRESULT)hwndTemp;
908 static LRESULT
909 TRACKBAR_SetLineSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
911 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
912 INT nTemp = infoPtr->nLineSize;
914 infoPtr->nLineSize = (INT)lParam;
916 return nTemp;
920 static LRESULT
921 TRACKBAR_SetPageSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
923 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
924 INT nTemp = infoPtr->nPageSize;
926 infoPtr->nPageSize = (INT)lParam;
928 return nTemp;
932 static LRESULT
933 TRACKBAR_SetPos (HWND hwnd, WPARAM wParam, LPARAM lParam)
935 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
937 infoPtr->nPos = (INT)lParam;
939 if (infoPtr->nPos < infoPtr->nRangeMin)
940 infoPtr->nPos = infoPtr->nRangeMin;
942 if (infoPtr->nPos > infoPtr->nRangeMax)
943 infoPtr->nPos = infoPtr->nRangeMax;
944 infoPtr->flags |= TB_THUMBPOSCHANGED;
946 if (wParam)
947 InvalidateRect (hwnd, NULL, FALSE);
949 return 0;
953 static LRESULT
954 TRACKBAR_SetRange (HWND hwnd, WPARAM wParam, LPARAM lParam)
956 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
957 infoPtr->nRangeMin = (INT)LOWORD(lParam);
958 infoPtr->nRangeMax = (INT)HIWORD(lParam);
960 if (infoPtr->nPos < infoPtr->nRangeMin) {
961 infoPtr->nPos = infoPtr->nRangeMin;
962 infoPtr->flags |=TB_THUMBPOSCHANGED;
965 if (infoPtr->nPos > infoPtr->nRangeMax) {
966 infoPtr->nPos = infoPtr->nRangeMax;
967 infoPtr->flags |=TB_THUMBPOSCHANGED;
970 infoPtr->nPageSize=(infoPtr->nRangeMax - infoPtr->nRangeMin)/5;
971 if (infoPtr->nPageSize == 0)
972 infoPtr->nPageSize = 1;
973 TRACKBAR_RecalculateTics (infoPtr);
975 if (wParam)
976 InvalidateRect (hwnd, NULL, FALSE);
978 return 0;
982 static LRESULT
983 TRACKBAR_SetRangeMax (HWND hwnd, WPARAM wParam, LPARAM lParam)
985 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
987 infoPtr->nRangeMax = (INT)lParam;
988 if (infoPtr->nPos > infoPtr->nRangeMax) {
989 infoPtr->nPos = infoPtr->nRangeMax;
990 infoPtr->flags |=TB_THUMBPOSCHANGED;
993 infoPtr->nPageSize=(infoPtr->nRangeMax - infoPtr->nRangeMin)/5;
994 if (infoPtr->nPageSize == 0)
995 infoPtr->nPageSize = 1;
996 TRACKBAR_RecalculateTics (infoPtr);
998 if (wParam)
999 InvalidateRect (hwnd, NULL, FALSE);
1001 return 0;
1005 static LRESULT
1006 TRACKBAR_SetRangeMin (HWND hwnd, WPARAM wParam, LPARAM lParam)
1008 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1010 infoPtr->nRangeMin = (INT)lParam;
1011 if (infoPtr->nPos < infoPtr->nRangeMin) {
1012 infoPtr->nPos = infoPtr->nRangeMin;
1013 infoPtr->flags |=TB_THUMBPOSCHANGED;
1016 infoPtr->nPageSize=(infoPtr->nRangeMax - infoPtr->nRangeMin)/5;
1017 if (infoPtr->nPageSize == 0)
1018 infoPtr->nPageSize = 1;
1019 TRACKBAR_RecalculateTics (infoPtr);
1021 if (wParam)
1022 InvalidateRect (hwnd, NULL, FALSE);
1024 return 0;
1028 static LRESULT
1029 TRACKBAR_SetTicFreq (HWND hwnd, WPARAM wParam)
1031 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1033 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_AUTOTICKS)
1034 infoPtr->uTicFreq=(UINT) wParam;
1036 TRACKBAR_RecalculateTics (infoPtr);
1038 InvalidateRect (hwnd, NULL, FALSE);
1040 return 0;
1044 static LRESULT
1045 TRACKBAR_SetSel (HWND hwnd, WPARAM wParam, LPARAM lParam)
1047 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1049 infoPtr->nSelMin = (INT)LOWORD(lParam);
1050 infoPtr->nSelMax = (INT)HIWORD(lParam);
1051 infoPtr->flags |=TB_SELECTIONCHANGED;
1053 if (!GetWindowLongA (hwnd, GWL_STYLE) & TBS_ENABLESELRANGE)
1054 return 0;
1056 if (infoPtr->nSelMin < infoPtr->nRangeMin)
1057 infoPtr->nSelMin = infoPtr->nRangeMin;
1058 if (infoPtr->nSelMax > infoPtr->nRangeMax)
1059 infoPtr->nSelMax = infoPtr->nRangeMax;
1061 if (wParam)
1062 InvalidateRect (hwnd, NULL, FALSE);
1065 return 0;
1069 static LRESULT
1070 TRACKBAR_SetSelEnd (HWND hwnd, WPARAM wParam, LPARAM lParam)
1072 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1074 if (!GetWindowLongA (hwnd, GWL_STYLE) & TBS_ENABLESELRANGE)
1075 return 0;
1077 infoPtr->nSelMax = (INT)lParam;
1078 infoPtr->flags |= TB_SELECTIONCHANGED;
1080 if (infoPtr->nSelMax > infoPtr->nRangeMax)
1081 infoPtr->nSelMax = infoPtr->nRangeMax;
1083 if (wParam)
1084 InvalidateRect (hwnd, NULL, FALSE);
1086 return 0;
1090 static LRESULT
1091 TRACKBAR_SetSelStart (HWND hwnd, WPARAM wParam, LPARAM lParam)
1093 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1095 if (!GetWindowLongA (hwnd, GWL_STYLE) & TBS_ENABLESELRANGE)
1096 return 0;
1098 infoPtr->nSelMin = (INT)lParam;
1099 infoPtr->flags |=TB_SELECTIONCHANGED;
1101 if (infoPtr->nSelMin < infoPtr->nRangeMin)
1102 infoPtr->nSelMin = infoPtr->nRangeMin;
1104 if (wParam)
1105 InvalidateRect (hwnd, NULL, FALSE);
1107 return 0;
1111 static LRESULT
1112 TRACKBAR_SetThumbLength (HWND hwnd, WPARAM wParam, LPARAM lParam)
1114 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1116 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_FIXEDLENGTH)
1117 infoPtr->uThumbLen = (UINT)wParam;
1119 infoPtr->flags |= TB_THUMBSIZECHANGED;
1121 InvalidateRect (hwnd, NULL, FALSE);
1123 return 0;
1127 static LRESULT
1128 TRACKBAR_SetTic (HWND hwnd, WPARAM wParam, LPARAM lParam)
1130 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1131 INT nPos = (INT)lParam;
1133 if ((nPos < infoPtr->nRangeMin) || (nPos> infoPtr->nRangeMax))
1134 return FALSE;
1136 infoPtr->uNumTics++;
1137 infoPtr->tics=COMCTL32_ReAlloc( infoPtr->tics,
1138 (infoPtr->uNumTics)*sizeof (DWORD));
1139 infoPtr->tics[infoPtr->uNumTics-1]=nPos;
1141 InvalidateRect (hwnd, NULL, FALSE);
1143 return TRUE;
1147 static LRESULT
1148 TRACKBAR_SetTipSide (HWND hwnd, WPARAM wParam, LPARAM lParam)
1150 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1151 INT fTemp = infoPtr->fLocation;
1153 infoPtr->fLocation = (INT)wParam;
1155 return fTemp;
1159 static LRESULT
1160 TRACKBAR_SetToolTips (HWND hwnd, WPARAM wParam, LPARAM lParam)
1162 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1164 infoPtr->hwndToolTip = (HWND)wParam;
1166 return 0;
1170 /* case TBM_SETUNICODEFORMAT: */
1173 static LRESULT
1174 TRACKBAR_InitializeThumb (HWND hwnd)
1176 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1178 infoPtr->uThumbLen = 23; /* initial thumb length */
1180 TRACKBAR_CalcChannel (hwnd,infoPtr);
1181 TRACKBAR_CalcThumb (hwnd, infoPtr);
1182 infoPtr->flags &= ~TB_SELECTIONCHANGED;
1184 return 0;
1188 static LRESULT
1189 TRACKBAR_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
1191 TRACKBAR_INFO *infoPtr;
1193 infoPtr = (TRACKBAR_INFO *)COMCTL32_Alloc (sizeof(TRACKBAR_INFO));
1194 SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
1196 /* set default values */
1197 infoPtr->nRangeMin = 0;
1198 infoPtr->nRangeMax = 100;
1199 infoPtr->nLineSize = 1;
1200 infoPtr->nPageSize = 20;
1201 infoPtr->nSelMin = 0;
1202 infoPtr->nSelMax = 0;
1203 infoPtr->nPos = 0;
1205 infoPtr->uNumTics = 0; /* start and end tic are not included in count*/
1206 infoPtr->uTicFreq = 1;
1207 infoPtr->tics = NULL;
1208 infoPtr->clrBk = GetSysColor (COLOR_BTNFACE);
1209 infoPtr->hwndNotify = GetParent (hwnd);
1211 TRACKBAR_InitializeThumb (hwnd);
1213 /* Create tooltip control */
1214 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_TOOLTIPS) {
1215 TTTOOLINFOA ti;
1217 infoPtr->hwndToolTip =
1218 CreateWindowExA (0, TOOLTIPS_CLASSA, NULL, 0,
1219 CW_USEDEFAULT, CW_USEDEFAULT,
1220 CW_USEDEFAULT, CW_USEDEFAULT,
1221 hwnd, 0, 0, 0);
1223 /* Send NM_TOOLTIPSCREATED notification */
1224 if (infoPtr->hwndToolTip) {
1225 NMTOOLTIPSCREATED nmttc;
1227 nmttc.hdr.hwndFrom = hwnd;
1228 nmttc.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1229 nmttc.hdr.code = NM_TOOLTIPSCREATED;
1230 nmttc.hwndToolTips = infoPtr->hwndToolTip;
1232 SendMessageA (GetParent (hwnd), WM_NOTIFY,
1233 (WPARAM)nmttc.hdr.idFrom, (LPARAM)&nmttc);
1236 ZeroMemory (&ti, sizeof(TTTOOLINFOA));
1237 ti.cbSize = sizeof(TTTOOLINFOA);
1238 ti.uFlags = TTF_IDISHWND | TTF_TRACK;
1239 ti.hwnd = hwnd;
1240 ti.uId = 0;
1241 ti.lpszText = "Test"; /* LPSTR_TEXTCALLBACK */
1242 SetRectEmpty (&ti.rect);
1244 SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA, 0, (LPARAM)&ti);
1247 return 0;
1251 static LRESULT
1252 TRACKBAR_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
1254 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1256 /* delete tooltip control */
1257 if (infoPtr->hwndToolTip)
1258 DestroyWindow (infoPtr->hwndToolTip);
1260 COMCTL32_Free (infoPtr);
1261 SetWindowLongA (hwnd, 0, 0);
1262 return 0;
1266 static LRESULT
1267 TRACKBAR_KillFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
1269 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1271 TRACE("\n");
1273 infoPtr->bFocus = FALSE;
1274 infoPtr->flags &= ~TB_DRAG_MODE;
1276 InvalidateRect (hwnd, NULL, FALSE);
1278 return 0;
1282 static LRESULT
1283 TRACKBAR_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
1285 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1286 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1287 POINT clickPoint;
1289 SetFocus (hwnd);
1291 clickPoint.y = HIWORD(lParam);
1292 clickPoint.x = LOWORD(lParam);
1294 if (PtInRect(&(infoPtr->rcThumb),clickPoint))
1296 infoPtr->flags |= TB_DRAG_MODE;
1297 if (dwStyle & TBS_TOOLTIPS) { /* enable tooltip */
1298 TTTOOLINFOA ti;
1299 POINT pt;
1301 GetCursorPos (&pt);
1302 SendMessageA (infoPtr->hwndToolTip, TTM_TRACKPOSITION, 0,
1303 (LPARAM)MAKELPARAM(pt.x, pt.y));
1305 ti.cbSize = sizeof(TTTOOLINFOA);
1306 ti.uId = 0;
1307 ti.hwnd = (UINT)hwnd;
1309 infoPtr->flags |= TB_SHOW_TOOLTIP;
1310 SetCapture (hwnd);
1311 SendMessageA (infoPtr->hwndToolTip, TTM_TRACKACTIVATE,
1312 (WPARAM)TRUE, (LPARAM)&ti);
1314 return 0;
1316 else if (PtInRect(&(infoPtr->rcChannel),clickPoint))
1318 int clickPlace,prevPos,vertical;
1319 DOUBLE clickPos;
1321 vertical = (dwStyle & TBS_VERT) ? 1 : 0;
1322 if (vertical)
1323 clickPlace=(INT)HIWORD(lParam);
1324 else
1325 clickPlace=(INT)LOWORD(lParam);
1327 clickPos = TRACKBAR_ConvertPlaceToPosition(infoPtr, clickPlace,
1328 vertical);
1329 prevPos = infoPtr->nPos;
1330 if (clickPos > (int)prevPos)
1331 { /* similar to VK_NEXT */
1332 infoPtr->nPos += infoPtr->nPageSize;
1333 if (infoPtr->nPos > infoPtr->nRangeMax)
1334 infoPtr->nPos = infoPtr->nRangeMax;
1335 TRACKBAR_SendNotify (hwnd, TB_PAGEUP);
1337 else
1339 infoPtr->nPos -= infoPtr->nPageSize; /* similar to VK_PRIOR */
1340 if (infoPtr->nPos < infoPtr->nRangeMin)
1341 infoPtr->nPos = infoPtr->nRangeMin;
1342 TRACKBAR_SendNotify (hwnd, TB_PAGEDOWN);
1345 if (prevPos!=infoPtr->nPos) {
1346 infoPtr->flags |= TB_THUMBPOSCHANGED;
1347 InvalidateRect (hwnd, NULL, FALSE);
1351 return 0;
1355 static LRESULT
1356 TRACKBAR_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
1358 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1360 TRACKBAR_SendNotify (hwnd, TB_ENDTRACK);
1362 if (infoPtr->flags & TB_DRAG_MODE)
1364 infoPtr->flags &= ~TB_DRAG_MODE;
1365 ReleaseCapture ();
1368 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_TOOLTIPS) { /* disable tooltip */
1369 TTTOOLINFOA ti;
1371 ti.cbSize = sizeof(TTTOOLINFOA);
1372 ti.uId = 0;
1373 ti.hwnd = (UINT)hwnd;
1375 infoPtr->flags &= ~TB_SHOW_TOOLTIP;
1376 SendMessageA (infoPtr->hwndToolTip, TTM_TRACKACTIVATE,
1377 (WPARAM)FALSE, (LPARAM)&ti);
1380 InvalidateRect (hwnd, NULL, FALSE);
1382 return 0;
1386 static LRESULT
1387 TRACKBAR_CaptureChanged (HWND hwnd, WPARAM wParam, LPARAM lParam)
1389 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1391 if (infoPtr->flags & TB_DRAGPOSVALID) {
1392 infoPtr->nPos=infoPtr->dragPos;
1393 InvalidateRect (hwnd, NULL, FALSE);
1396 infoPtr->flags &= ~ TB_DRAGPOSVALID;
1398 TRACKBAR_SendNotify (hwnd, TB_ENDTRACK);
1399 return 0;
1403 static LRESULT
1404 TRACKBAR_Paint (HWND hwnd, WPARAM wParam)
1406 HDC hdc;
1407 PAINTSTRUCT ps;
1409 hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
1410 TRACKBAR_Refresh (hwnd, hdc);
1411 if(!wParam)
1412 EndPaint (hwnd, &ps);
1413 return 0;
1417 static LRESULT
1418 TRACKBAR_SetFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
1420 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1422 TRACE("\n");
1423 infoPtr->bFocus = TRUE;
1425 InvalidateRect (hwnd, NULL, FALSE);
1427 return 0;
1431 static LRESULT
1432 TRACKBAR_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
1434 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1436 TRACKBAR_CalcChannel (hwnd, infoPtr);
1437 TRACKBAR_AlignBuddies (hwnd, infoPtr);
1439 return 0;
1443 static BOOL
1444 TRACKBAR_SendNotify (HWND hwnd, UINT code)
1446 TRACE("%x\n",code);
1448 if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_VERT)
1449 return (BOOL) SendMessageA (GetParent (hwnd),
1450 WM_VSCROLL, (WPARAM)code, (LPARAM)hwnd);
1452 return (BOOL) SendMessageA (GetParent (hwnd),
1453 WM_HSCROLL, (WPARAM)code, (LPARAM)hwnd);
1457 static LRESULT
1458 TRACKBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
1460 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1461 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1462 SHORT clickPlace;
1463 DOUBLE dragPos;
1464 char buf[80];
1466 TRACE("%x\n",wParam);
1468 if (dwStyle & TBS_VERT)
1469 clickPlace=(SHORT)HIWORD(lParam);
1470 else
1471 clickPlace=(SHORT)LOWORD(lParam);
1473 if (!(infoPtr->flags & TB_DRAG_MODE))
1474 return TRUE;
1476 SetCapture (hwnd);
1477 dragPos = TRACKBAR_ConvertPlaceToPosition (infoPtr, clickPlace,
1478 dwStyle & TBS_VERT);
1479 if (dragPos > ((INT)dragPos) + 0.5)
1480 infoPtr->dragPos = dragPos + 1;
1481 else
1482 infoPtr->dragPos = dragPos;
1484 infoPtr->flags |= TB_DRAGPOSVALID;
1485 TRACKBAR_SendNotify (hwnd, TB_THUMBTRACK | (infoPtr->nPos<<16));
1487 if (infoPtr->flags & TB_SHOW_TOOLTIP) {
1488 POINT pt;
1489 TTTOOLINFOA ti;
1491 ti.cbSize = sizeof(TTTOOLINFOA);
1492 ti.hwnd = hwnd;
1493 ti.uId = 0;
1494 ti.hinst=0;
1495 sprintf (buf,"%d",infoPtr->nPos);
1496 ti.lpszText = (LPSTR) buf;
1497 GetCursorPos (&pt);
1499 if (dwStyle & TBS_VERT) {
1500 SendMessageA (infoPtr->hwndToolTip, TTM_TRACKPOSITION,
1501 0, (LPARAM)MAKELPARAM(pt.x+5, pt.y+15));
1502 } else {
1503 SendMessageA (infoPtr->hwndToolTip, TTM_TRACKPOSITION,
1504 0, (LPARAM)MAKELPARAM(pt.x+15, pt.y+5));
1506 SendMessageA (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTA,
1507 0, (LPARAM)&ti);
1510 InvalidateRect (hwnd, NULL, FALSE);
1511 UpdateWindow (hwnd);
1513 return TRUE;
1517 static LRESULT
1518 TRACKBAR_KeyDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
1520 TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
1521 INT pos;
1523 TRACE("%x\n",wParam);
1525 pos=infoPtr->nPos;
1526 switch (wParam) {
1527 case VK_LEFT:
1528 case VK_UP:
1529 if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
1530 infoPtr->nPos -= infoPtr->nLineSize;
1531 if (infoPtr->nPos < infoPtr->nRangeMin)
1532 infoPtr->nPos = infoPtr->nRangeMin;
1533 TRACKBAR_SendNotify (hwnd, TB_LINEUP);
1534 break;
1535 case VK_RIGHT:
1536 case VK_DOWN:
1537 if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
1538 infoPtr->nPos += infoPtr->nLineSize;
1539 if (infoPtr->nPos > infoPtr->nRangeMax)
1540 infoPtr->nPos = infoPtr->nRangeMax;
1541 TRACKBAR_SendNotify (hwnd, TB_LINEDOWN);
1542 break;
1543 case VK_NEXT:
1544 if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
1545 infoPtr->nPos += infoPtr->nPageSize;
1546 if (infoPtr->nPos > infoPtr->nRangeMax)
1547 infoPtr->nPos = infoPtr->nRangeMax;
1548 TRACKBAR_SendNotify (hwnd, TB_PAGEUP);
1549 break;
1550 case VK_PRIOR:
1551 if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
1552 infoPtr->nPos -= infoPtr->nPageSize;
1553 if (infoPtr->nPos < infoPtr->nRangeMin)
1554 infoPtr->nPos = infoPtr->nRangeMin;
1555 TRACKBAR_SendNotify (hwnd, TB_PAGEDOWN);
1556 break;
1557 case VK_HOME:
1558 if (infoPtr->nPos == infoPtr->nRangeMin) return FALSE;
1559 infoPtr->nPos = infoPtr->nRangeMin;
1560 TRACKBAR_SendNotify (hwnd, TB_TOP);
1561 break;
1562 case VK_END:
1563 if (infoPtr->nPos == infoPtr->nRangeMax) return FALSE;
1564 infoPtr->nPos = infoPtr->nRangeMax;
1565 TRACKBAR_SendNotify (hwnd, TB_BOTTOM);
1566 break;
1569 if (pos!=infoPtr->nPos) {
1570 infoPtr->flags |=TB_THUMBPOSCHANGED;
1571 InvalidateRect (hwnd, NULL, FALSE);
1574 return TRUE;
1578 static LRESULT
1579 TRACKBAR_KeyUp (HWND hwnd, WPARAM wParam)
1581 switch (wParam) {
1582 case VK_LEFT:
1583 case VK_UP:
1584 case VK_RIGHT:
1585 case VK_DOWN:
1586 case VK_NEXT:
1587 case VK_PRIOR:
1588 case VK_HOME:
1589 case VK_END:
1590 TRACKBAR_SendNotify (hwnd, TB_ENDTRACK);
1592 return TRUE;
1596 static LRESULT WINAPI
1597 TRACKBAR_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1599 TRACE("hwnd=%x msg=%x wparam=%x lparam=%lx\n", hwnd, uMsg, wParam, lParam);
1600 if (!TRACKBAR_GetInfoPtr (hwnd) && (uMsg != WM_CREATE))
1601 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
1602 switch (uMsg)
1604 case TBM_CLEARSEL:
1605 return TRACKBAR_ClearSel (hwnd, wParam, lParam);
1607 case TBM_CLEARTICS:
1608 return TRACKBAR_ClearTics (hwnd, wParam, lParam);
1610 case TBM_GETBUDDY:
1611 return TRACKBAR_GetBuddy (hwnd, wParam, lParam);
1613 case TBM_GETCHANNELRECT:
1614 return TRACKBAR_GetChannelRect (hwnd, wParam, lParam);
1616 case TBM_GETLINESIZE:
1617 return TRACKBAR_GetLineSize (hwnd, wParam, lParam);
1619 case TBM_GETNUMTICS:
1620 return TRACKBAR_GetNumTics (hwnd, wParam, lParam);
1622 case TBM_GETPAGESIZE:
1623 return TRACKBAR_GetPageSize (hwnd, wParam, lParam);
1625 case TBM_GETPOS:
1626 return TRACKBAR_GetPos (hwnd, wParam, lParam);
1628 case TBM_GETPTICS:
1629 return TRACKBAR_GetPTics (hwnd);
1631 case TBM_GETRANGEMAX:
1632 return TRACKBAR_GetRangeMax (hwnd, wParam, lParam);
1634 case TBM_GETRANGEMIN:
1635 return TRACKBAR_GetRangeMin (hwnd, wParam, lParam);
1637 case TBM_GETSELEND:
1638 return TRACKBAR_GetSelEnd (hwnd, wParam, lParam);
1640 case TBM_GETSELSTART:
1641 return TRACKBAR_GetSelStart (hwnd, wParam, lParam);
1643 case TBM_GETTHUMBLENGTH:
1644 return TRACKBAR_GetThumbLength (hwnd, wParam, lParam);
1646 case TBM_GETTHUMBRECT:
1647 return TRACKBAR_GetThumbRect (hwnd, wParam, lParam);
1649 case TBM_GETTIC:
1650 return TRACKBAR_GetTic (hwnd, wParam, lParam);
1652 case TBM_GETTICPOS:
1653 return TRACKBAR_GetTicPos (hwnd, wParam, lParam);
1655 case TBM_GETTOOLTIPS:
1656 return TRACKBAR_GetToolTips (hwnd, wParam, lParam);
1658 /* case TBM_GETUNICODEFORMAT: */
1660 case TBM_SETBUDDY:
1661 return TRACKBAR_SetBuddy (hwnd, wParam, lParam);
1663 case TBM_SETLINESIZE:
1664 return TRACKBAR_SetLineSize (hwnd, wParam, lParam);
1666 case TBM_SETPAGESIZE:
1667 return TRACKBAR_SetPageSize (hwnd, wParam, lParam);
1669 case TBM_SETPOS:
1670 return TRACKBAR_SetPos (hwnd, wParam, lParam);
1672 case TBM_SETRANGE:
1673 return TRACKBAR_SetRange (hwnd, wParam, lParam);
1675 case TBM_SETRANGEMAX:
1676 return TRACKBAR_SetRangeMax (hwnd, wParam, lParam);
1678 case TBM_SETRANGEMIN:
1679 return TRACKBAR_SetRangeMin (hwnd, wParam, lParam);
1681 case TBM_SETSEL:
1682 return TRACKBAR_SetSel (hwnd, wParam, lParam);
1684 case TBM_SETSELEND:
1685 return TRACKBAR_SetSelEnd (hwnd, wParam, lParam);
1687 case TBM_SETSELSTART:
1688 return TRACKBAR_SetSelStart (hwnd, wParam, lParam);
1690 case TBM_SETTHUMBLENGTH:
1691 return TRACKBAR_SetThumbLength (hwnd, wParam, lParam);
1693 case TBM_SETTIC:
1694 return TRACKBAR_SetTic (hwnd, wParam, lParam);
1696 case TBM_SETTICFREQ:
1697 return TRACKBAR_SetTicFreq (hwnd, wParam);
1699 case TBM_SETTIPSIDE:
1700 return TRACKBAR_SetTipSide (hwnd, wParam, lParam);
1702 case TBM_SETTOOLTIPS:
1703 return TRACKBAR_SetToolTips (hwnd, wParam, lParam);
1705 /* case TBM_SETUNICODEFORMAT: */
1708 case WM_CAPTURECHANGED:
1709 return TRACKBAR_CaptureChanged (hwnd, wParam, lParam);
1711 case WM_CREATE:
1712 return TRACKBAR_Create (hwnd, wParam, lParam);
1714 case WM_DESTROY:
1715 return TRACKBAR_Destroy (hwnd, wParam, lParam);
1717 /* case WM_ENABLE: */
1719 /* case WM_ERASEBKGND: */
1720 /* return 0; */
1722 case WM_GETDLGCODE:
1723 return DLGC_WANTARROWS;
1725 case WM_KEYDOWN:
1726 return TRACKBAR_KeyDown (hwnd, wParam, lParam);
1728 case WM_KEYUP:
1729 return TRACKBAR_KeyUp (hwnd, wParam);
1731 case WM_KILLFOCUS:
1732 return TRACKBAR_KillFocus (hwnd, wParam, lParam);
1734 case WM_LBUTTONDOWN:
1735 return TRACKBAR_LButtonDown (hwnd, wParam, lParam);
1737 case WM_LBUTTONUP:
1738 return TRACKBAR_LButtonUp (hwnd, wParam, lParam);
1740 case WM_MOUSEMOVE:
1741 return TRACKBAR_MouseMove (hwnd, wParam, lParam);
1743 case WM_PAINT:
1744 return TRACKBAR_Paint (hwnd, wParam);
1746 case WM_SETFOCUS:
1747 return TRACKBAR_SetFocus (hwnd, wParam, lParam);
1749 case WM_SIZE:
1750 return TRACKBAR_Size (hwnd, wParam, lParam);
1752 case WM_WININICHANGE:
1753 return TRACKBAR_InitializeThumb (hwnd);
1755 default:
1756 if (uMsg >= WM_USER)
1757 ERR("unknown msg %04x wp=%08x lp=%08lx\n",
1758 uMsg, wParam, lParam);
1759 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
1761 return 0;
1765 VOID
1766 TRACKBAR_Register (void)
1768 WNDCLASSA wndClass;
1770 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
1771 wndClass.style = CS_GLOBALCLASS;
1772 wndClass.lpfnWndProc = (WNDPROC)TRACKBAR_WindowProc;
1773 wndClass.cbClsExtra = 0;
1774 wndClass.cbWndExtra = sizeof(TRACKBAR_INFO *);
1775 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
1776 wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
1777 wndClass.lpszClassName = TRACKBAR_CLASSA;
1779 RegisterClassA (&wndClass);
1783 VOID
1784 TRACKBAR_Unregister (void)
1786 UnregisterClassA (TRACKBAR_CLASSA, (HINSTANCE)NULL);