Commit | Line | Data |
---|---|---|
a0d77315 AJ |
1 | /* |
2 | * Trackbar control | |
3 | * | |
dcaf1377 MB |
4 | * Copyright 1998, 1999 Eric Kohl |
5 | * Copyright 1998, 1999 Alex Priem | |
6 | * Copyright 2002 Dimitrie O. Paun | |
a0d77315 | 7 | * |
0799c1a7 AJ |
8 | * This library is free software; you can redistribute it and/or |
9 | * modify it under the terms of the GNU Lesser General Public | |
10 | * License as published by the Free Software Foundation; either | |
11 | * version 2.1 of the License, or (at your option) any later version. | |
12 | * | |
13 | * This library is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 | * Lesser General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU Lesser General Public | |
19 | * License along with this library; if not, write to the Free Software | |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
a0d77315 | 21 | * |
da9bac4d DP |
22 | * NOTE |
23 | * | |
24 | * This code was audited for completeness against the documented features | |
25 | * of Comctl32.dll version 6.0 on Sep. 12, 2002, by Dimitrie O. Paun. | |
26 | * | |
27 | * Unless otherwise noted, we believe this code to be complete, as per | |
28 | * the specification mentioned above. | |
29 | * If you discover missing features, or bugs, please note them below. | |
30 | * | |
a0d77315 AJ |
31 | */ |
32 | ||
e37c6e18 | 33 | #include <stdarg.h> |
383da68c | 34 | #include <stdio.h> |
c514a781 | 35 | #include <stdlib.h> |
f4d5fefb | 36 | #include <string.h> |
d30dfd24 | 37 | |
e37c6e18 | 38 | #include "windef.h" |
3480e4a5 | 39 | #include "winbase.h" |
e37c6e18 AJ |
40 | #include "wingdi.h" |
41 | #include "winuser.h" | |
42 | #include "winnls.h" | |
a0d77315 | 43 | #include "commctrl.h" |
0799c1a7 | 44 | #include "wine/debug.h" |
a0d77315 | 45 | |
c514a781 DP |
46 | #include "comctl32.h" |
47 | ||
0799c1a7 | 48 | WINE_DEFAULT_DEBUG_CHANNEL(trackbar); |
b4b9fae6 | 49 | |
70c9e095 AJ |
50 | typedef struct |
51 | { | |
e4ddd2ac DP |
52 | HWND hwndSelf; |
53 | LONG lRangeMin; | |
54 | LONG lRangeMax; | |
55 | LONG lLineSize; | |
56 | LONG lPageSize; | |
57 | LONG lSelMin; | |
58 | LONG lSelMax; | |
59 | LONG lPos; | |
70c9e095 AJ |
60 | UINT uThumbLen; |
61 | UINT uNumTics; | |
e4ddd2ac | 62 | UINT uTicFreq; |
70c9e095 AJ |
63 | HWND hwndNotify; |
64 | HWND hwndToolTip; | |
65 | HWND hwndBuddyLA; | |
66 | HWND hwndBuddyRB; | |
67 | INT fLocation; | |
70c9e095 | 68 | INT flags; |
e4ddd2ac | 69 | BOOL bUnicode; |
d2b8e39b | 70 | BOOL bFocussed; |
70c9e095 AJ |
71 | RECT rcChannel; |
72 | RECT rcSelection; | |
73 | RECT rcThumb; | |
70c9e095 AJ |
74 | LPLONG tics; |
75 | } TRACKBAR_INFO; | |
76 | ||
c1e3cb8d DP |
77 | #define TB_REFRESH_TIMER 1 |
78 | #define TB_REFRESH_DELAY 500 | |
a0d77315 | 79 | |
0c6dd5b9 | 80 | #define TOOLTIP_OFFSET 2 /* distance from ctrl edge to tooltip */ |
a0d77315 | 81 | |
9a624916 | 82 | /* Used by TRACKBAR_Refresh to find out which parts of the control |
3d35e989 | 83 | need to be recalculated */ |
a0d77315 | 84 | |
9a624916 | 85 | #define TB_THUMBPOSCHANGED 1 |
3d35e989 | 86 | #define TB_THUMBSIZECHANGED 2 |
c514a781 | 87 | #define TB_THUMBCHANGED (TB_THUMBPOSCHANGED | TB_THUMBSIZECHANGED) |
3d35e989 | 88 | #define TB_SELECTIONCHANGED 4 |
d7174979 | 89 | #define TB_DRAG_MODE 8 /* we're dragging the slider */ |
c1e3cb8d DP |
90 | #define TB_AUTO_PAGE_LEFT 16 |
91 | #define TB_AUTO_PAGE_RIGHT 32 | |
92 | #define TB_AUTO_PAGE (TB_AUTO_PAGE_LEFT | TB_AUTO_PAGE_RIGHT) | |
a0d77315 | 93 | |
506115b8 | 94 | /* helper defines for TRACKBAR_DrawTic */ |
d7174979 | 95 | #define TIC_EDGE 0x20 |
3d35e989 LT |
96 | #define TIC_SELECTIONMARKMAX 0x80 |
97 | #define TIC_SELECTIONMARKMIN 0x100 | |
98 | #define TIC_SELECTIONMARK (TIC_SELECTIONMARKMAX | TIC_SELECTIONMARKMIN) | |
506115b8 | 99 | |
e54fdf21 | 100 | static inline int |
a63270f1 | 101 | notify_customdraw(TRACKBAR_INFO *infoPtr, NMCUSTOMDRAW *pnmcd, int stage) |
e54fdf21 DP |
102 | { |
103 | pnmcd->dwDrawStage = stage; | |
a63270f1 | 104 | return SendMessageW (infoPtr->hwndNotify, WM_NOTIFY, |
e54fdf21 DP |
105 | pnmcd->hdr.idFrom, (LPARAM)pnmcd); |
106 | } | |
107 | ||
a63270f1 HD |
108 | static LRESULT notify_hdr(TRACKBAR_INFO *infoPtr, INT code, LPNMHDR pnmh) |
109 | { | |
110 | LRESULT result; | |
111 | ||
112 | TRACE("(code=%d)\n", code); | |
113 | ||
114 | pnmh->hwndFrom = infoPtr->hwndSelf; | |
115 | pnmh->idFrom = GetWindowLongW(infoPtr->hwndSelf, GWL_ID); | |
116 | pnmh->code = code; | |
117 | result = SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, | |
118 | (WPARAM)pnmh->idFrom, (LPARAM)pnmh); | |
119 | ||
120 | TRACE(" <= %ld\n", result); | |
121 | ||
122 | return result; | |
123 | } | |
124 | ||
125 | static inline int notify(TRACKBAR_INFO *infoPtr, INT code) | |
126 | { | |
127 | NMHDR nmh; | |
128 | return notify_hdr(infoPtr, code, &nmh); | |
129 | } | |
130 | ||
131 | static BOOL | |
132 | notify_with_scroll (TRACKBAR_INFO *infoPtr, UINT code) | |
133 | { | |
134 | BOOL bVert = GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE) & TBS_VERT; | |
135 | ||
136 | TRACE("%x\n", code); | |
137 | ||
138 | return (BOOL) SendMessageW (infoPtr->hwndNotify, | |
139 | bVert ? WM_VSCROLL : WM_HSCROLL, | |
140 | (WPARAM)code, (LPARAM)infoPtr->hwndSelf); | |
141 | } | |
142 | ||
26ffb3cd | 143 | static void TRACKBAR_RecalculateTics (TRACKBAR_INFO *infoPtr) |
d30dfd24 | 144 | { |
c514a781 | 145 | int i, tic, nrTics; |
a0d77315 | 146 | |
e4ddd2ac DP |
147 | if (infoPtr->uTicFreq && infoPtr->lRangeMax >= infoPtr->lRangeMin) |
148 | nrTics=(infoPtr->lRangeMax - infoPtr->lRangeMin)/infoPtr->uTicFreq; | |
3d35e989 | 149 | else { |
c514a781 | 150 | nrTics = 0; |
7de279a7 | 151 | Free (infoPtr->tics); |
c514a781 DP |
152 | infoPtr->tics = NULL; |
153 | infoPtr->uNumTics = 0; | |
3d35e989 LT |
154 | return; |
155 | } | |
d30dfd24 | 156 | |
c514a781 | 157 | if (nrTics != infoPtr->uNumTics) { |
7de279a7 | 158 | infoPtr->tics=ReAlloc (infoPtr->tics, |
3d35e989 | 159 | (nrTics+1)*sizeof (DWORD)); |
c514a781 DP |
160 | if (!infoPtr->tics) { |
161 | infoPtr->uNumTics = 0; | |
a63270f1 | 162 | notify(infoPtr, NM_OUTOFMEMORY); |
c514a781 DP |
163 | return; |
164 | } | |
165 | infoPtr->uNumTics = nrTics; | |
d30dfd24 | 166 | } |
a0d77315 | 167 | |
c514a781 DP |
168 | tic = infoPtr->lRangeMin + infoPtr->uTicFreq; |
169 | for (i = 0; i < nrTics; i++, tic += infoPtr->uTicFreq) | |
170 | infoPtr->tics[i] = tic; | |
171 | } | |
a0d77315 | 172 | |
9a624916 | 173 | /* converts from physical (mouse) position to logical position |
ba211eeb | 174 | (in range of trackbar) */ |
d30dfd24 | 175 | |
c1e3cb8d | 176 | static inline LONG |
9a624916 VB |
177 | TRACKBAR_ConvertPlaceToPosition (TRACKBAR_INFO *infoPtr, int place, |
178 | int vertical) | |
d30dfd24 | 179 | { |
9ebf12c3 | 180 | double range, width, pos, offsetthumb; |
d30dfd24 | 181 | |
c1e3cb8d | 182 | range = infoPtr->lRangeMax - infoPtr->lRangeMin; |
506115b8 | 183 | if (vertical) { |
0d5aae1a DC |
184 | offsetthumb = (infoPtr->rcThumb.bottom - infoPtr->rcThumb.top)/2; |
185 | width = infoPtr->rcChannel.bottom - infoPtr->rcChannel.top - (offsetthumb * 2) - 1; | |
9ebf12c3 | 186 | pos = (range*(place - infoPtr->rcChannel.top - offsetthumb)) / width; |
3d35e989 | 187 | } else { |
0d5aae1a DC |
188 | offsetthumb = (infoPtr->rcThumb.right - infoPtr->rcThumb.left)/2; |
189 | width = infoPtr->rcChannel.right - infoPtr->rcChannel.left - (offsetthumb * 2) - 1; | |
9ebf12c3 | 190 | pos = (range*(place - infoPtr->rcChannel.left - offsetthumb)) / width; |
3d35e989 | 191 | } |
e4ddd2ac DP |
192 | pos += infoPtr->lRangeMin; |
193 | if (pos > infoPtr->lRangeMax) | |
194 | pos = infoPtr->lRangeMax; | |
195 | else if (pos < infoPtr->lRangeMin) | |
196 | pos = infoPtr->lRangeMin; | |
3d35e989 | 197 | |
e4ddd2ac | 198 | TRACE("%.2f\n", pos); |
c1e3cb8d DP |
199 | return (LONG)(pos + 0.5); |
200 | } | |
201 | ||
202 | ||
203 | /* return: 0> prev, 0 none, >0 next */ | |
204 | static LONG | |
205 | TRACKBAR_GetAutoPageDirection (TRACKBAR_INFO *infoPtr, POINT clickPoint) | |
206 | { | |
207 | DWORD dwStyle = GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE); | |
208 | RECT pageRect; | |
209 | ||
210 | if (dwStyle & TBS_VERT) { | |
211 | pageRect.top = infoPtr->rcChannel.top; | |
212 | pageRect.bottom = infoPtr->rcChannel.bottom; | |
213 | pageRect.left = infoPtr->rcThumb.left; | |
214 | pageRect.right = infoPtr->rcThumb.right; | |
215 | } else { | |
216 | pageRect.top = infoPtr->rcThumb.top; | |
217 | pageRect.bottom = infoPtr->rcThumb.bottom; | |
218 | pageRect.left = infoPtr->rcChannel.left; | |
219 | pageRect.right = infoPtr->rcChannel.right; | |
220 | } | |
221 | ||
222 | ||
223 | if (PtInRect(&pageRect, clickPoint)) | |
224 | { | |
225 | int clickPlace = (dwStyle & TBS_VERT) ? clickPoint.y : clickPoint.x; | |
226 | ||
227 | LONG clickPos = TRACKBAR_ConvertPlaceToPosition(infoPtr, clickPlace, | |
228 | dwStyle & TBS_VERT); | |
229 | return clickPos - infoPtr->lPos; | |
230 | } | |
231 | ||
232 | return 0; | |
233 | } | |
234 | ||
235 | static void inline | |
a63270f1 | 236 | TRACKBAR_PageDown (TRACKBAR_INFO *infoPtr) |
c1e3cb8d DP |
237 | { |
238 | if (infoPtr->lPos == infoPtr->lRangeMax) return; | |
239 | ||
240 | infoPtr->lPos += infoPtr->lPageSize; | |
241 | if (infoPtr->lPos > infoPtr->lRangeMax) | |
242 | infoPtr->lPos = infoPtr->lRangeMax; | |
a63270f1 | 243 | notify_with_scroll (infoPtr, TB_PAGEDOWN); |
d30dfd24 AJ |
244 | } |
245 | ||
ba211eeb | 246 | |
c1e3cb8d | 247 | static void inline |
a63270f1 | 248 | TRACKBAR_PageUp (TRACKBAR_INFO *infoPtr) |
c1e3cb8d DP |
249 | { |
250 | if (infoPtr->lPos == infoPtr->lRangeMin) return; | |
251 | ||
252 | infoPtr->lPos -= infoPtr->lPageSize; | |
253 | if (infoPtr->lPos < infoPtr->lRangeMin) | |
254 | infoPtr->lPos = infoPtr->lRangeMin; | |
a63270f1 HD |
255 | notify_with_scroll (infoPtr, TB_PAGEUP); |
256 | } | |
257 | ||
258 | static void inline TRACKBAR_LineUp(TRACKBAR_INFO *infoPtr) | |
259 | { | |
260 | if (infoPtr->lPos == infoPtr->lRangeMin) return; | |
261 | infoPtr->lPos -= infoPtr->lLineSize; | |
262 | if (infoPtr->lPos < infoPtr->lRangeMin) | |
263 | infoPtr->lPos = infoPtr->lRangeMin; | |
264 | notify_with_scroll (infoPtr, TB_LINEUP); | |
265 | } | |
266 | ||
267 | static void inline TRACKBAR_LineDown(TRACKBAR_INFO *infoPtr) | |
268 | { | |
269 | if (infoPtr->lPos == infoPtr->lRangeMax) return; | |
270 | infoPtr->lPos += infoPtr->lLineSize; | |
271 | if (infoPtr->lPos > infoPtr->lRangeMax) | |
272 | infoPtr->lPos = infoPtr->lRangeMax; | |
273 | notify_with_scroll (infoPtr, TB_LINEDOWN); | |
c1e3cb8d DP |
274 | } |
275 | ||
e4ddd2ac DP |
276 | static void |
277 | TRACKBAR_CalcChannel (TRACKBAR_INFO *infoPtr) | |
a0d77315 | 278 | { |
e4ddd2ac | 279 | DWORD dwStyle = GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE); |
c514a781 DP |
280 | INT cyChannel, offsetthumb, offsetedge; |
281 | RECT lpRect, *channel = & infoPtr->rcChannel; | |
d30dfd24 | 282 | |
e4ddd2ac | 283 | GetClientRect (infoPtr->hwndSelf, &lpRect); |
a0d77315 | 284 | |
9ebf12c3 | 285 | offsetthumb = infoPtr->uThumbLen / 4; |
c514a781 | 286 | offsetedge = offsetthumb + 3; |
0d5aae1a | 287 | cyChannel = (dwStyle & TBS_ENABLESELRANGE) ? offsetthumb*3 : 4; |
cad17ff7 | 288 | if (dwStyle & TBS_VERT) { |
f64a59f2 AS |
289 | channel->top = lpRect.top + offsetedge; |
290 | channel->bottom = lpRect.bottom - offsetedge; | |
0d5aae1a DC |
291 | if (dwStyle & TBS_ENABLESELRANGE) |
292 | channel->left = lpRect.left + ((infoPtr->uThumbLen - cyChannel + 2) / 2); | |
293 | else | |
294 | channel->left = lpRect.left + (infoPtr->uThumbLen / 2) - 1; | |
9ebf12c3 DC |
295 | if (dwStyle & TBS_BOTH) { |
296 | if (dwStyle & TBS_NOTICKS) | |
297 | channel->left += 1; | |
298 | else | |
299 | channel->left += 9; | |
300 | } | |
301 | else if (dwStyle & TBS_TOP) { | |
302 | if (dwStyle & TBS_NOTICKS) | |
303 | channel->left += 2; | |
304 | else | |
305 | channel->left += 10; | |
306 | } | |
c514a781 DP |
307 | channel->right = channel->left + cyChannel; |
308 | } else { | |
f64a59f2 AS |
309 | channel->left = lpRect.left + offsetedge; |
310 | channel->right = lpRect.right - offsetedge; | |
0d5aae1a DC |
311 | if (dwStyle & TBS_ENABLESELRANGE) |
312 | channel->top = lpRect.top + ((infoPtr->uThumbLen - cyChannel + 2) / 2); | |
313 | else | |
314 | channel->top = lpRect.top + (infoPtr->uThumbLen / 2) - 1; | |
9ebf12c3 DC |
315 | if (dwStyle & TBS_BOTH) { |
316 | if (dwStyle & TBS_NOTICKS) | |
317 | channel->top += 1; | |
318 | else | |
319 | channel->top += 9; | |
320 | } | |
321 | else if (dwStyle & TBS_TOP) { | |
322 | if (dwStyle & TBS_NOTICKS) | |
323 | channel->top += 2; | |
324 | else | |
325 | channel->top += 10; | |
326 | } | |
c514a781 | 327 | channel->bottom = channel->top + cyChannel; |
3d35e989 | 328 | } |
d30dfd24 AJ |
329 | } |
330 | ||
e4ddd2ac | 331 | static void |
c514a781 | 332 | TRACKBAR_CalcThumb (TRACKBAR_INFO *infoPtr, LONG lPos, RECT *thumb) |
d30dfd24 | 333 | { |
9ebf12c3 | 334 | int range, width, height, thumbwidth; |
e4ddd2ac | 335 | DWORD dwStyle = GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE); |
dcaf1377 | 336 | RECT lpRect; |
9a624916 | 337 | |
d2b8e39b | 338 | range = infoPtr->lRangeMax - infoPtr->lRangeMin; |
9ebf12c3 | 339 | thumbwidth = (infoPtr->uThumbLen / 2) | 1; |
f64a59f2 | 340 | |
e4ddd2ac | 341 | if (!range) range = 1; |
f64a59f2 | 342 | |
dcaf1377 | 343 | GetClientRect(infoPtr->hwndSelf, &lpRect); |
9a624916 | 344 | if (dwStyle & TBS_VERT) |
f64a59f2 | 345 | { |
0d5aae1a | 346 | height = infoPtr->rcChannel.bottom - infoPtr->rcChannel.top - thumbwidth; |
d30dfd24 | 347 | |
9ebf12c3 DC |
348 | if ((dwStyle & (TBS_BOTH | TBS_LEFT)) && !(dwStyle & TBS_NOTICKS)) |
349 | thumb->left = 10; | |
f64a59f2 | 350 | else |
e4ddd2ac | 351 | thumb->left = 2; |
9ebf12c3 | 352 | thumb->right = thumb->left + infoPtr->uThumbLen; |
f64a59f2 | 353 | thumb->top = infoPtr->rcChannel.top + |
9ebf12c3 DC |
354 | (height*(lPos - infoPtr->lRangeMin))/range; |
355 | thumb->bottom = thumb->top + thumbwidth; | |
9a624916 VB |
356 | } |
357 | else | |
f64a59f2 | 358 | { |
0d5aae1a | 359 | width = infoPtr->rcChannel.right - infoPtr->rcChannel.left - thumbwidth; |
f64a59f2 AS |
360 | |
361 | thumb->left = infoPtr->rcChannel.left + | |
9ebf12c3 DC |
362 | (width*(lPos - infoPtr->lRangeMin))/range; |
363 | thumb->right = thumb->left + thumbwidth; | |
364 | if ((dwStyle & (TBS_BOTH | TBS_TOP)) && !(dwStyle & TBS_NOTICKS)) | |
365 | thumb->top = 10; | |
f64a59f2 | 366 | else |
dcaf1377 | 367 | thumb->top = 2; |
9ebf12c3 | 368 | thumb->bottom = thumb->top + infoPtr->uThumbLen; |
3d35e989 | 369 | } |
d30dfd24 AJ |
370 | } |
371 | ||
c514a781 DP |
372 | inline static void |
373 | TRACKBAR_UpdateThumb (TRACKBAR_INFO *infoPtr) | |
374 | { | |
375 | TRACKBAR_CalcThumb(infoPtr, infoPtr->lPos, &infoPtr->rcThumb); | |
376 | } | |
377 | ||
0c6dd5b9 DP |
378 | static inline void |
379 | TRACKBAR_InvalidateAll(TRACKBAR_INFO * infoPtr) | |
380 | { | |
381 | InvalidateRect(infoPtr->hwndSelf, NULL, FALSE); | |
382 | } | |
383 | ||
c514a781 | 384 | static void |
e54fdf21 DP |
385 | TRACKBAR_InvalidateThumb (TRACKBAR_INFO *infoPtr, LONG thumbPos) |
386 | { | |
387 | RECT rcThumb; | |
388 | ||
389 | TRACKBAR_CalcThumb(infoPtr, thumbPos, &rcThumb); | |
390 | InflateRect(&rcThumb, 1, 1); | |
391 | InvalidateRect(infoPtr->hwndSelf, &rcThumb, FALSE); | |
392 | } | |
393 | ||
394 | static inline void | |
c514a781 DP |
395 | TRACKBAR_InvalidateThumbMove (TRACKBAR_INFO *infoPtr, LONG oldPos, LONG newPos) |
396 | { | |
e54fdf21 DP |
397 | TRACKBAR_InvalidateThumb (infoPtr, oldPos); |
398 | if (newPos != oldPos) | |
399 | TRACKBAR_InvalidateThumb (infoPtr, newPos); | |
c514a781 DP |
400 | } |
401 | ||
d7174979 DP |
402 | static BOOL inline |
403 | TRACKBAR_HasSelection (TRACKBAR_INFO *infoPtr) | |
404 | { | |
405 | return infoPtr->lSelMin != infoPtr->lSelMax; | |
406 | } | |
407 | ||
e4ddd2ac DP |
408 | static void |
409 | TRACKBAR_CalcSelection (TRACKBAR_INFO *infoPtr) | |
d30dfd24 | 410 | { |
d7174979 DP |
411 | RECT *selection = &infoPtr->rcSelection; |
412 | int range = infoPtr->lRangeMax - infoPtr->lRangeMin; | |
0d5aae1a | 413 | int offsetthumb, height, width; |
3d35e989 | 414 | |
d7174979 | 415 | if (range <= 0) { |
3d35e989 | 416 | SetRectEmpty (selection); |
d7174979 | 417 | } else { |
e4ddd2ac | 418 | if (GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE) & TBS_VERT) { |
0d5aae1a DC |
419 | offsetthumb = (infoPtr->rcThumb.bottom - infoPtr->rcThumb.top)/2; |
420 | height = infoPtr->rcChannel.bottom - infoPtr->rcChannel.top - offsetthumb*2; | |
421 | selection->top = infoPtr->rcChannel.top + offsetthumb + | |
d7174979 | 422 | (height*infoPtr->lSelMin)/range; |
0d5aae1a | 423 | selection->bottom = infoPtr->rcChannel.top + offsetthumb + |
d7174979 DP |
424 | (height*infoPtr->lSelMax)/range; |
425 | selection->left = infoPtr->rcChannel.left + 3; | |
426 | selection->right = infoPtr->rcChannel.right - 3; | |
427 | } else { | |
0d5aae1a DC |
428 | offsetthumb = (infoPtr->rcThumb.right - infoPtr->rcThumb.left)/2; |
429 | width = infoPtr->rcChannel.right - infoPtr->rcChannel.left - offsetthumb*2; | |
430 | selection->left = infoPtr->rcChannel.left + offsetthumb + | |
e4ddd2ac | 431 | (width*infoPtr->lSelMin)/range; |
0d5aae1a | 432 | selection->right = infoPtr->rcChannel.left + offsetthumb + |
e4ddd2ac | 433 | (width*infoPtr->lSelMax)/range; |
d7174979 DP |
434 | selection->top = infoPtr->rcChannel.top + 3; |
435 | selection->bottom = infoPtr->rcChannel.bottom - 3; | |
3d35e989 | 436 | } |
d7174979 DP |
437 | } |
438 | ||
0fd521fe | 439 | TRACE("selection[left=%ld, top=%ld, right=%ld, bottom=%ld]\n", |
d7174979 | 440 | selection->left, selection->top, selection->right, selection->bottom); |
d30dfd24 AJ |
441 | } |
442 | ||
c1e3cb8d DP |
443 | static BOOL |
444 | TRACKBAR_AutoPage (TRACKBAR_INFO *infoPtr, POINT clickPoint) | |
445 | { | |
446 | LONG dir = TRACKBAR_GetAutoPageDirection(infoPtr, clickPoint); | |
447 | LONG prevPos = infoPtr->lPos; | |
448 | ||
449 | TRACE("x=%ld, y=%ld, dir=%ld\n", clickPoint.x, clickPoint.y, dir); | |
450 | ||
451 | if (dir > 0 && (infoPtr->flags & TB_AUTO_PAGE_RIGHT)) | |
c1e3cb8d | 452 | TRACKBAR_PageDown(infoPtr); |
a63270f1 HD |
453 | else if (dir < 0 && (infoPtr->flags & TB_AUTO_PAGE_LEFT)) |
454 | TRACKBAR_PageUp(infoPtr); | |
c1e3cb8d DP |
455 | else return FALSE; |
456 | ||
457 | infoPtr->flags |= TB_THUMBPOSCHANGED; | |
458 | TRACKBAR_InvalidateThumbMove (infoPtr, prevPos, infoPtr->lPos); | |
459 | ||
460 | return TRUE; | |
461 | } | |
462 | ||
506115b8 AP |
463 | /* Trackbar drawing code. I like my spaghetti done milanese. */ |
464 | ||
e54fdf21 DP |
465 | static void |
466 | TRACKBAR_DrawChannel (TRACKBAR_INFO *infoPtr, HDC hdc, DWORD dwStyle) | |
467 | { | |
468 | RECT rcChannel = infoPtr->rcChannel; | |
469 | ||
470 | DrawEdge (hdc, &rcChannel, EDGE_SUNKEN, BF_RECT | BF_ADJUST); | |
471 | if (dwStyle & TBS_ENABLESELRANGE) { /* fill the channel */ | |
472 | FillRect (hdc, &rcChannel, GetStockObject(WHITE_BRUSH)); | |
473 | if (TRACKBAR_HasSelection(infoPtr)) | |
474 | FillRect (hdc, &infoPtr->rcSelection, GetSysColorBrush(COLOR_HIGHLIGHT)); | |
475 | } | |
476 | } | |
506115b8 | 477 | |
e4ddd2ac | 478 | static void |
e54fdf21 | 479 | TRACKBAR_DrawOneTic (TRACKBAR_INFO *infoPtr, HDC hdc, LONG ticPos, int flags) |
506115b8 | 480 | { |
9ebf12c3 DC |
481 | int x, y, ox, oy, range, side, indent = 0, len = 3; |
482 | int offsetthumb; | |
d7174979 | 483 | RECT rcTics; |
c514a781 | 484 | |
d7174979 | 485 | if (flags & TBS_VERT) { |
0d5aae1a | 486 | offsetthumb = (infoPtr->rcThumb.bottom - infoPtr->rcThumb.top)/2; |
9ebf12c3 DC |
487 | rcTics.left = infoPtr->rcThumb.left - 2; |
488 | rcTics.right = infoPtr->rcThumb.right + 2; | |
0d5aae1a | 489 | rcTics.top = infoPtr->rcChannel.top + offsetthumb + 1; |
9ebf12c3 | 490 | rcTics.bottom = infoPtr->rcChannel.bottom - offsetthumb; |
3d35e989 | 491 | } else { |
0d5aae1a DC |
492 | offsetthumb = (infoPtr->rcThumb.right - infoPtr->rcThumb.left)/2; |
493 | rcTics.left = infoPtr->rcChannel.left + offsetthumb + 1; | |
9ebf12c3 DC |
494 | rcTics.right = infoPtr->rcChannel.right - offsetthumb; |
495 | rcTics.top = infoPtr->rcThumb.top - 2; | |
496 | rcTics.bottom = infoPtr->rcThumb.bottom + 2; | |
3d35e989 | 497 | } |
506115b8 | 498 | |
d7174979 DP |
499 | if (flags & (TBS_TOP | TBS_LEFT)) { |
500 | x = rcTics.left; | |
501 | y = rcTics.top; | |
502 | side = -1; | |
3d35e989 | 503 | } else { |
d7174979 DP |
504 | x = rcTics.right; |
505 | y = rcTics.bottom; | |
506 | side = 1; | |
3d35e989 | 507 | } |
506115b8 | 508 | |
d7174979 | 509 | range = infoPtr->lRangeMax - infoPtr->lRangeMin; |
76707020 | 510 | if (range <= 0) |
2cf92565 | 511 | range = 1; /* to avoid division by zero */ |
506115b8 | 512 | |
3d35e989 | 513 | if (flags & TIC_SELECTIONMARK) { |
d7174979 DP |
514 | indent = (flags & TIC_SELECTIONMARKMIN) ? -1 : 1; |
515 | } else if (flags & TIC_EDGE) { | |
516 | len++; | |
3d35e989 | 517 | } |
506115b8 | 518 | |
d7174979 | 519 | if (flags & TBS_VERT) { |
d2b8e39b | 520 | int height = rcTics.bottom - rcTics.top; |
d7174979 | 521 | y = rcTics.top + (height*(ticPos - infoPtr->lRangeMin))/range; |
d7174979 DP |
522 | } else { |
523 | int width = rcTics.right - rcTics.left; | |
524 | x = rcTics.left + (width*(ticPos - infoPtr->lRangeMin))/range; | |
3d35e989 | 525 | } |
506115b8 | 526 | |
0c6dd5b9 DP |
527 | ox = x; |
528 | oy = y; | |
529 | MoveToEx(hdc, x, y, 0); | |
530 | if (flags & TBS_VERT) x += len * side; | |
531 | else y += len * side; | |
532 | LineTo(hdc, x, y); | |
533 | ||
d7174979 DP |
534 | if (flags & TIC_SELECTIONMARK) { |
535 | if (flags & TBS_VERT) { | |
0c6dd5b9 | 536 | x -= side; |
d7174979 | 537 | } else { |
0c6dd5b9 | 538 | y -= side; |
d7174979 | 539 | } |
0c6dd5b9 DP |
540 | MoveToEx(hdc, x, y, 0); |
541 | if (flags & TBS_VERT) { | |
542 | y += 2 * indent; | |
543 | } else { | |
544 | x += 2 * indent; | |
545 | } | |
546 | ||
547 | LineTo(hdc, x, y); | |
548 | LineTo(hdc, ox, oy); | |
d7174979 | 549 | } |
506115b8 AP |
550 | } |
551 | ||
552 | ||
e54fdf21 DP |
553 | static inline void |
554 | TRACKBAR_DrawTic (TRACKBAR_INFO *infoPtr, HDC hdc, LONG ticPos, int flags) | |
506115b8 | 555 | { |
d7174979 | 556 | if ((flags & (TBS_LEFT | TBS_TOP)) || (flags & TBS_BOTH)) |
e54fdf21 | 557 | TRACKBAR_DrawOneTic (infoPtr, hdc, ticPos, flags | TBS_LEFT); |
506115b8 | 558 | |
d7174979 | 559 | if (!(flags & (TBS_LEFT | TBS_TOP)) || (flags & TBS_BOTH)) |
9ebf12c3 | 560 | TRACKBAR_DrawOneTic (infoPtr, hdc, ticPos, flags & ~TBS_LEFT); |
e54fdf21 DP |
561 | } |
562 | ||
563 | static void | |
564 | TRACKBAR_DrawTics (TRACKBAR_INFO *infoPtr, HDC hdc, DWORD dwStyle) | |
565 | { | |
566 | int i, ticFlags = dwStyle & 0x0f; | |
567 | LOGPEN ticPen = { PS_SOLID, {1, 0}, GetSysColor (COLOR_3DDKSHADOW) }; | |
568 | HPEN hOldPen, hTicPen; | |
569 | ||
570 | /* create the pen to draw the tics with */ | |
571 | hTicPen = CreatePenIndirect(&ticPen); | |
572 | hOldPen = hTicPen ? SelectObject(hdc, hTicPen) : 0; | |
573 | ||
574 | /* actually draw the tics */ | |
575 | for (i=0; i<infoPtr->uNumTics; i++) | |
576 | TRACKBAR_DrawTic (infoPtr, hdc, infoPtr->tics[i], ticFlags); | |
577 | ||
578 | TRACKBAR_DrawTic (infoPtr, hdc, infoPtr->lRangeMin, ticFlags | TIC_EDGE); | |
579 | TRACKBAR_DrawTic (infoPtr, hdc, infoPtr->lRangeMax, ticFlags | TIC_EDGE); | |
580 | ||
581 | if ((dwStyle & TBS_ENABLESELRANGE) && TRACKBAR_HasSelection(infoPtr)) { | |
582 | TRACKBAR_DrawTic (infoPtr, hdc, infoPtr->lSelMin, | |
583 | ticFlags | TIC_SELECTIONMARKMIN); | |
584 | TRACKBAR_DrawTic (infoPtr, hdc, infoPtr->lSelMax, | |
585 | ticFlags | TIC_SELECTIONMARKMAX); | |
586 | } | |
587 | ||
588 | /* clean up the pen, if we created one */ | |
589 | if (hTicPen) { | |
590 | SelectObject(hdc, hOldPen); | |
591 | DeleteObject(hTicPen); | |
592 | } | |
506115b8 AP |
593 | } |
594 | ||
e4ddd2ac | 595 | static void |
f64a59f2 AS |
596 | TRACKBAR_DrawThumb(TRACKBAR_INFO *infoPtr, HDC hdc, DWORD dwStyle) |
597 | { | |
0c6dd5b9 DP |
598 | HBRUSH oldbr; |
599 | HPEN oldpen; | |
f64a59f2 | 600 | RECT thumb = infoPtr->rcThumb; |
0c6dd5b9 DP |
601 | int BlackUntil = 3; |
602 | int PointCount = 6; | |
f64a59f2 | 603 | POINT points[6]; |
e54fdf21 | 604 | int fillClr; |
9ebf12c3 | 605 | int PointDepth; |
f64a59f2 | 606 | |
e54fdf21 DP |
607 | fillClr = infoPtr->flags & TB_DRAG_MODE ? COLOR_BTNHILIGHT : COLOR_BTNFACE; |
608 | oldbr = SelectObject (hdc, GetSysColorBrush(fillClr)); | |
c1e3cb8d | 609 | SetPolyFillMode (hdc, WINDING); |
9a624916 VB |
610 | |
611 | if (dwStyle & TBS_BOTH) | |
f64a59f2 AS |
612 | { |
613 | points[0].x=thumb.right; | |
614 | points[0].y=thumb.top; | |
615 | points[1].x=thumb.right; | |
616 | points[1].y=thumb.bottom; | |
617 | points[2].x=thumb.left; | |
618 | points[2].y=thumb.bottom; | |
619 | points[3].x=thumb.left; | |
620 | points[3].y=thumb.top; | |
621 | points[4].x=points[0].x; | |
622 | points[4].y=points[0].y; | |
623 | PointCount = 5; | |
624 | BlackUntil = 3; | |
9a624916 VB |
625 | } |
626 | else | |
f64a59f2 AS |
627 | { |
628 | if (dwStyle & TBS_VERT) | |
629 | { | |
9ebf12c3 | 630 | PointDepth = (thumb.bottom - thumb.top) / 2; |
f64a59f2 AS |
631 | if (dwStyle & TBS_LEFT) |
632 | { | |
633 | points[0].x=thumb.right; | |
634 | points[0].y=thumb.top; | |
635 | points[1].x=thumb.right; | |
636 | points[1].y=thumb.bottom; | |
637 | points[2].x=thumb.left + PointDepth; | |
638 | points[2].y=thumb.bottom; | |
639 | points[3].x=thumb.left; | |
9ebf12c3 | 640 | points[3].y=(thumb.bottom - thumb.top) / 2 + thumb.top + 1; |
f64a59f2 AS |
641 | points[4].x=thumb.left + PointDepth; |
642 | points[4].y=thumb.top; | |
643 | points[5].x=points[0].x; | |
644 | points[5].y=points[0].y; | |
645 | BlackUntil = 4; | |
646 | } | |
647 | else | |
648 | { | |
649 | points[0].x=thumb.right; | |
9ebf12c3 | 650 | points[0].y=(thumb.bottom - thumb.top) / 2 + thumb.top + 1; |
f64a59f2 AS |
651 | points[1].x=thumb.right - PointDepth; |
652 | points[1].y=thumb.bottom; | |
653 | points[2].x=thumb.left; | |
654 | points[2].y=thumb.bottom; | |
655 | points[3].x=thumb.left; | |
656 | points[3].y=thumb.top; | |
657 | points[4].x=thumb.right - PointDepth; | |
658 | points[4].y=thumb.top; | |
659 | points[5].x=points[0].x; | |
660 | points[5].y=points[0].y; | |
661 | } | |
662 | } | |
663 | else | |
664 | { | |
9ebf12c3 | 665 | PointDepth = (thumb.right - thumb.left) / 2; |
f64a59f2 AS |
666 | if (dwStyle & TBS_TOP) |
667 | { | |
9ebf12c3 | 668 | points[0].x=(thumb.right - thumb.left) / 2 + thumb.left + 1; |
f64a59f2 AS |
669 | points[0].y=thumb.top; |
670 | points[1].x=thumb.right; | |
671 | points[1].y=thumb.top + PointDepth; | |
672 | points[2].x=thumb.right; | |
9a624916 | 673 | points[2].y=thumb.bottom; |
f64a59f2 AS |
674 | points[3].x=thumb.left; |
675 | points[3].y=thumb.bottom; | |
676 | points[4].x=thumb.left; | |
677 | points[4].y=thumb.top + PointDepth; | |
678 | points[5].x=points[0].x; | |
679 | points[5].y=points[0].y; | |
680 | BlackUntil = 4; | |
681 | } | |
682 | else | |
683 | { | |
684 | points[0].x=thumb.right; | |
685 | points[0].y=thumb.top; | |
686 | points[1].x=thumb.right; | |
687 | points[1].y=thumb.bottom - PointDepth; | |
9ebf12c3 | 688 | points[2].x=(thumb.right - thumb.left) / 2 + thumb.left + 1; |
f64a59f2 AS |
689 | points[2].y=thumb.bottom; |
690 | points[3].x=thumb.left; | |
691 | points[3].y=thumb.bottom - PointDepth; | |
692 | points[4].x=thumb.left; | |
693 | points[4].y=thumb.top; | |
694 | points[5].x=points[0].x; | |
695 | points[5].y=points[0].y; | |
696 | } | |
697 | } | |
9a624916 | 698 | |
f64a59f2 AS |
699 | } |
700 | ||
0c6dd5b9 | 701 | /* Draw the thumb now */ |
f64a59f2 | 702 | Polygon (hdc, points, PointCount); |
0c6dd5b9 DP |
703 | oldpen = SelectObject(hdc, GetStockObject(BLACK_PEN)); |
704 | Polyline(hdc,points, BlackUntil); | |
705 | SelectObject(hdc, GetStockObject(WHITE_PEN)); | |
c1e3cb8d | 706 | Polyline(hdc, &points[BlackUntil-1], PointCount+1-BlackUntil); |
0c6dd5b9 DP |
707 | SelectObject(hdc, oldpen); |
708 | SelectObject(hdc, oldbr); | |
f64a59f2 | 709 | } |
506115b8 | 710 | |
c514a781 | 711 | |
d7174979 DP |
712 | static void inline |
713 | TRACKBAR_ActivateToolTip (TRACKBAR_INFO *infoPtr, BOOL fShow) | |
714 | { | |
715 | TTTOOLINFOW ti; | |
716 | ||
717 | if (!infoPtr->hwndToolTip) return; | |
718 | ||
719 | ZeroMemory(&ti, sizeof(ti)); | |
720 | ti.cbSize = sizeof(ti); | |
721 | ti.hwnd = infoPtr->hwndSelf; | |
722 | ||
723 | SendMessageW (infoPtr->hwndToolTip, TTM_TRACKACTIVATE, fShow, (LPARAM)&ti); | |
724 | } | |
725 | ||
726 | ||
e4ddd2ac | 727 | static void |
c514a781 | 728 | TRACKBAR_UpdateToolTip (TRACKBAR_INFO *infoPtr) |
d30dfd24 | 729 | { |
e4ddd2ac | 730 | DWORD dwStyle = GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE); |
52c08321 FG |
731 | WCHAR buf[80]; |
732 | static const WCHAR fmt[] = { '%', 'l', 'd', 0 }; | |
c514a781 DP |
733 | TTTOOLINFOW ti; |
734 | POINT pt; | |
0c6dd5b9 | 735 | RECT rcClient; |
c514a781 | 736 | LRESULT size; |
d30dfd24 | 737 | |
c514a781 | 738 | if (!infoPtr->hwndToolTip) return; |
d30dfd24 | 739 | |
c514a781 DP |
740 | ZeroMemory(&ti, sizeof(ti)); |
741 | ti.cbSize = sizeof(ti); | |
742 | ti.hwnd = infoPtr->hwndSelf; | |
743 | ti.uFlags = TTF_IDISHWND | TTF_TRACK | TTF_ABSOLUTE; | |
744 | ||
745 | wsprintfW (buf, fmt, infoPtr->lPos); | |
746 | ti.lpszText = buf; | |
747 | SendMessageW (infoPtr->hwndToolTip, TTM_UPDATETIPTEXTW, 0, (LPARAM)&ti); | |
748 | ||
0c6dd5b9 | 749 | GetClientRect (infoPtr->hwndSelf, &rcClient); |
d7174979 | 750 | size = SendMessageW (infoPtr->hwndToolTip, TTM_GETBUBBLESIZE, 0, (LPARAM)&ti); |
c514a781 | 751 | if (dwStyle & TBS_VERT) { |
d7174979 | 752 | if (infoPtr->fLocation == TBTS_LEFT) |
0c6dd5b9 | 753 | pt.x = 0 - LOWORD(size) - TOOLTIP_OFFSET; |
d7174979 | 754 | else |
0c6dd5b9 | 755 | pt.x = rcClient.right + TOOLTIP_OFFSET; |
c514a781 DP |
756 | pt.y = (infoPtr->rcThumb.top + infoPtr->rcThumb.bottom - HIWORD(size))/2; |
757 | } else { | |
d7174979 | 758 | if (infoPtr->fLocation == TBTS_TOP) |
0c6dd5b9 | 759 | pt.y = 0 - HIWORD(size) - TOOLTIP_OFFSET; |
d7174979 | 760 | else |
0c6dd5b9 | 761 | pt.y = rcClient.bottom + TOOLTIP_OFFSET; |
c514a781 | 762 | pt.x = (infoPtr->rcThumb.left + infoPtr->rcThumb.right - LOWORD(size))/2; |
506115b8 | 763 | } |
c514a781 DP |
764 | ClientToScreen(infoPtr->hwndSelf, &pt); |
765 | ||
766 | SendMessageW (infoPtr->hwndToolTip, TTM_TRACKPOSITION, | |
767 | 0, (LPARAM)MAKELPARAM(pt.x, pt.y)); | |
768 | } | |
769 | ||
770 | ||
771 | static void | |
0c6dd5b9 | 772 | TRACKBAR_Refresh (TRACKBAR_INFO *infoPtr, HDC hdcDst) |
c514a781 DP |
773 | { |
774 | DWORD dwStyle = GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE); | |
e54fdf21 | 775 | RECT rcClient; |
0c6dd5b9 DP |
776 | HDC hdc; |
777 | HBITMAP hOldBmp = 0, hOffScreenBmp = 0; | |
e54fdf21 DP |
778 | NMCUSTOMDRAW nmcd; |
779 | int gcdrf, icdrf; | |
9a624916 | 780 | |
3d35e989 | 781 | if (infoPtr->flags & TB_THUMBCHANGED) { |
c514a781 | 782 | TRACKBAR_UpdateThumb (infoPtr); |
9a624916 | 783 | if (infoPtr->flags & TB_THUMBSIZECHANGED) |
e4ddd2ac | 784 | TRACKBAR_CalcChannel (infoPtr); |
3d35e989 LT |
785 | } |
786 | if (infoPtr->flags & TB_SELECTIONCHANGED) | |
e4ddd2ac | 787 | TRACKBAR_CalcSelection (infoPtr); |
c514a781 | 788 | |
d7174979 | 789 | if (infoPtr->flags & TB_DRAG_MODE) |
c514a781 DP |
790 | TRACKBAR_UpdateToolTip (infoPtr); |
791 | ||
e54fdf21 DP |
792 | infoPtr->flags &= ~ (TB_THUMBCHANGED | TB_SELECTIONCHANGED); |
793 | ||
0c6dd5b9 DP |
794 | GetClientRect (infoPtr->hwndSelf, &rcClient); |
795 | ||
796 | /* try to render offscreen, if we fail, carrry onscreen */ | |
797 | hdc = CreateCompatibleDC(hdcDst); | |
798 | if (hdc) { | |
799 | hOffScreenBmp = CreateCompatibleBitmap(hdcDst, rcClient.right, rcClient.bottom); | |
800 | if (hOffScreenBmp) { | |
801 | hOldBmp = SelectObject(hdc, hOffScreenBmp); | |
802 | } else { | |
803 | DeleteObject(hdc); | |
804 | hdc = hdcDst; | |
805 | } | |
806 | } else { | |
807 | hdc = hdcDst; | |
808 | } | |
809 | ||
e54fdf21 DP |
810 | ZeroMemory(&nmcd, sizeof(nmcd)); |
811 | nmcd.hdr.hwndFrom = infoPtr->hwndSelf; | |
812 | nmcd.hdr.idFrom = GetWindowLongW (infoPtr->hwndSelf, GWL_ID); | |
813 | nmcd.hdr.code = NM_CUSTOMDRAW; | |
814 | nmcd.hdc = hdc; | |
d30dfd24 | 815 | |
e54fdf21 DP |
816 | /* start the paint cycle */ |
817 | nmcd.rc = rcClient; | |
a63270f1 | 818 | gcdrf = notify_customdraw(infoPtr, &nmcd, CDDS_PREPAINT); |
e54fdf21 DP |
819 | if (gcdrf & CDRF_SKIPDEFAULT) goto cleanup; |
820 | ||
0c6dd5b9 | 821 | /* Erase backbround */ |
e54fdf21 | 822 | if (gcdrf == CDRF_DODEFAULT || |
a63270f1 | 823 | notify_customdraw(infoPtr, &nmcd, CDDS_PREERASE) != CDRF_SKIPDEFAULT) { |
e54fdf21 DP |
824 | FillRect (hdc, &rcClient, GetSysColorBrush(COLOR_BTNFACE)); |
825 | if (gcdrf != CDRF_DODEFAULT) | |
a63270f1 | 826 | notify_customdraw(infoPtr, &nmcd, CDDS_POSTERASE); |
e54fdf21 | 827 | } |
0c6dd5b9 | 828 | |
d30dfd24 | 829 | /* draw channel */ |
e54fdf21 DP |
830 | if (gcdrf & CDRF_NOTIFYITEMDRAW) { |
831 | nmcd.dwItemSpec = TBCD_CHANNEL; | |
832 | nmcd.uItemState = CDIS_DEFAULT; | |
833 | nmcd.rc = infoPtr->rcChannel; | |
a63270f1 | 834 | icdrf = notify_customdraw(infoPtr, &nmcd, CDDS_ITEMPREPAINT); |
e54fdf21 DP |
835 | } else icdrf = CDRF_DODEFAULT; |
836 | if ( !(icdrf & CDRF_SKIPDEFAULT) ) { | |
837 | TRACKBAR_DrawChannel (infoPtr, hdc, dwStyle); | |
838 | if (icdrf & CDRF_NOTIFYPOSTPAINT) | |
a63270f1 | 839 | notify_customdraw(infoPtr, &nmcd, CDDS_ITEMPOSTPAINT); |
a0d77315 | 840 | } |
a0d77315 | 841 | |
d30dfd24 AJ |
842 | |
843 | /* draw tics */ | |
cad17ff7 | 844 | if (!(dwStyle & TBS_NOTICKS)) { |
e54fdf21 DP |
845 | if (gcdrf & CDRF_NOTIFYITEMDRAW) { |
846 | nmcd.dwItemSpec = TBCD_TICS; | |
847 | nmcd.uItemState = CDIS_DEFAULT; | |
848 | nmcd.rc = rcClient; | |
a63270f1 | 849 | icdrf = notify_customdraw(infoPtr, &nmcd, CDDS_ITEMPREPAINT); |
e54fdf21 DP |
850 | } else icdrf = CDRF_DODEFAULT; |
851 | if ( !(icdrf & CDRF_SKIPDEFAULT) ) { | |
852 | TRACKBAR_DrawTics (infoPtr, hdc, dwStyle); | |
853 | if (icdrf & CDRF_NOTIFYPOSTPAINT) | |
a63270f1 | 854 | notify_customdraw(infoPtr, &nmcd, CDDS_ITEMPOSTPAINT); |
e54fdf21 | 855 | } |
a0d77315 | 856 | } |
e54fdf21 | 857 | |
3d35e989 | 858 | /* draw thumb */ |
e54fdf21 DP |
859 | if (!(dwStyle & TBS_NOTHUMB)) { |
860 | if (gcdrf & CDRF_NOTIFYITEMDRAW) { | |
861 | nmcd.dwItemSpec = TBCD_THUMB; | |
862 | nmcd.uItemState = infoPtr->flags & TB_DRAG_MODE ? CDIS_HOT : CDIS_DEFAULT; | |
863 | nmcd.rc = infoPtr->rcThumb; | |
a63270f1 | 864 | icdrf = notify_customdraw(infoPtr, &nmcd, CDDS_ITEMPREPAINT); |
e54fdf21 DP |
865 | } else icdrf = CDRF_DODEFAULT; |
866 | if ( !(icdrf & CDRF_SKIPDEFAULT) ) { | |
867 | TRACKBAR_DrawThumb(infoPtr, hdc, dwStyle); | |
868 | if (icdrf & CDRF_NOTIFYPOSTPAINT) | |
a63270f1 | 869 | notify_customdraw(infoPtr, &nmcd, CDDS_ITEMPOSTPAINT); |
e54fdf21 DP |
870 | } |
871 | } | |
0c6dd5b9 | 872 | |
d2b8e39b MH |
873 | /* draw focus rectangle */ |
874 | if (infoPtr->bFocussed) { | |
875 | DrawFocusRect(hdc, &rcClient); | |
876 | } | |
877 | ||
e54fdf21 DP |
878 | /* finish up the painting */ |
879 | if (gcdrf & CDRF_NOTIFYPOSTPAINT) | |
a63270f1 | 880 | notify_customdraw(infoPtr, &nmcd, CDDS_POSTPAINT); |
e54fdf21 DP |
881 | |
882 | cleanup: | |
0c6dd5b9 DP |
883 | /* cleanup, if we rendered offscreen */ |
884 | if (hdc != hdcDst) { | |
885 | BitBlt(hdcDst, 0, 0, rcClient.right, rcClient.bottom, hdc, 0, 0, SRCCOPY); | |
886 | SelectObject(hdc, hOldBmp); | |
887 | DeleteObject(hOffScreenBmp); | |
888 | DeleteObject(hdc); | |
889 | } | |
a0d77315 AJ |
890 | } |
891 | ||
892 | ||
e4ddd2ac DP |
893 | static void |
894 | TRACKBAR_AlignBuddies (TRACKBAR_INFO *infoPtr) | |
a0d77315 | 895 | { |
e4ddd2ac DP |
896 | DWORD dwStyle = GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE); |
897 | HWND hwndParent = GetParent (infoPtr->hwndSelf); | |
a3960292 AJ |
898 | RECT rcSelf, rcBuddy; |
899 | INT x, y; | |
a0d77315 | 900 | |
e4ddd2ac | 901 | GetWindowRect (infoPtr->hwndSelf, &rcSelf); |
a3960292 | 902 | MapWindowPoints (HWND_DESKTOP, hwndParent, (LPPOINT)&rcSelf, 2); |
a0d77315 AJ |
903 | |
904 | /* align buddy left or above */ | |
905 | if (infoPtr->hwndBuddyLA) { | |
a3960292 AJ |
906 | GetWindowRect (infoPtr->hwndBuddyLA, &rcBuddy); |
907 | MapWindowPoints (HWND_DESKTOP, hwndParent, (LPPOINT)&rcBuddy, 2); | |
a0d77315 | 908 | |
cad17ff7 | 909 | if (dwStyle & TBS_VERT) { |
a0d77315 AJ |
910 | x = (infoPtr->rcChannel.right + infoPtr->rcChannel.left) / 2 - |
911 | (rcBuddy.right - rcBuddy.left) / 2 + rcSelf.left; | |
912 | y = rcSelf.top - (rcBuddy.bottom - rcBuddy.top); | |
913 | } | |
914 | else { | |
915 | x = rcSelf.left - (rcBuddy.right - rcBuddy.left); | |
916 | y = (infoPtr->rcChannel.bottom + infoPtr->rcChannel.top) / 2 - | |
917 | (rcBuddy.bottom - rcBuddy.top) / 2 + rcSelf.top; | |
918 | } | |
919 | ||
a3960292 | 920 | SetWindowPos (infoPtr->hwndBuddyLA, 0, x, y, 0, 0, |
3d35e989 | 921 | SWP_NOZORDER | SWP_NOSIZE); |
a0d77315 AJ |
922 | } |
923 | ||
924 | ||
925 | /* align buddy right or below */ | |
926 | if (infoPtr->hwndBuddyRB) { | |
a3960292 AJ |
927 | GetWindowRect (infoPtr->hwndBuddyRB, &rcBuddy); |
928 | MapWindowPoints (HWND_DESKTOP, hwndParent, (LPPOINT)&rcBuddy, 2); | |
a0d77315 | 929 | |
cad17ff7 | 930 | if (dwStyle & TBS_VERT) { |
a0d77315 AJ |
931 | x = (infoPtr->rcChannel.right + infoPtr->rcChannel.left) / 2 - |
932 | (rcBuddy.right - rcBuddy.left) / 2 + rcSelf.left; | |
933 | y = rcSelf.bottom; | |
934 | } | |
935 | else { | |
936 | x = rcSelf.right; | |
937 | y = (infoPtr->rcChannel.bottom + infoPtr->rcChannel.top) / 2 - | |
938 | (rcBuddy.bottom - rcBuddy.top) / 2 + rcSelf.top; | |
939 | } | |
a3960292 | 940 | SetWindowPos (infoPtr->hwndBuddyRB, 0, x, y, 0, 0, |
3d35e989 | 941 | SWP_NOZORDER | SWP_NOSIZE); |
a0d77315 AJ |
942 | } |
943 | } | |
944 | ||
945 | ||
946 | static LRESULT | |
e4ddd2ac | 947 | TRACKBAR_ClearSel (TRACKBAR_INFO *infoPtr, BOOL fRedraw) |
a0d77315 | 948 | { |
e4ddd2ac DP |
949 | infoPtr->lSelMin = 0; |
950 | infoPtr->lSelMax = 0; | |
3d35e989 | 951 | infoPtr->flags |= TB_SELECTIONCHANGED; |
a0d77315 | 952 | |
0c6dd5b9 | 953 | if (fRedraw) TRACKBAR_InvalidateAll(infoPtr); |
a0d77315 AJ |
954 | |
955 | return 0; | |
956 | } | |
957 | ||
958 | ||
959 | static LRESULT | |
e4ddd2ac | 960 | TRACKBAR_ClearTics (TRACKBAR_INFO *infoPtr, BOOL fRedraw) |
a0d77315 | 961 | { |
a0d77315 | 962 | if (infoPtr->tics) { |
7de279a7 | 963 | Free (infoPtr->tics); |
3d35e989 LT |
964 | infoPtr->tics = NULL; |
965 | infoPtr->uNumTics = 0; | |
a0d77315 AJ |
966 | } |
967 | ||
0c6dd5b9 | 968 | if (fRedraw) TRACKBAR_InvalidateAll(infoPtr); |
a0d77315 AJ |
969 | |
970 | return 0; | |
971 | } | |
972 | ||
973 | ||
e4ddd2ac DP |
974 | static LRESULT inline |
975 | TRACKBAR_GetChannelRect (TRACKBAR_INFO *infoPtr, LPRECT lprc) | |
a0d77315 | 976 | { |
e4ddd2ac | 977 | if (lprc == NULL) return 0; |
a0d77315 AJ |
978 | |
979 | lprc->left = infoPtr->rcChannel.left; | |
980 | lprc->right = infoPtr->rcChannel.right; | |
981 | lprc->bottom = infoPtr->rcChannel.bottom; | |
982 | lprc->top = infoPtr->rcChannel.top; | |
983 | ||
984 | return 0; | |
985 | } | |
986 | ||
987 | ||
e4ddd2ac DP |
988 | static LONG inline |
989 | TRACKBAR_GetNumTics (TRACKBAR_INFO *infoPtr) | |
a0d77315 | 990 | { |
e4ddd2ac | 991 | if (GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE) & TBS_NOTICKS) |
3d35e989 | 992 | return 0; |
a0d77315 | 993 | |
e4ddd2ac | 994 | return infoPtr->uNumTics + 2; |
a0d77315 AJ |
995 | } |
996 | ||
997 | ||
c514a781 DP |
998 | static int comp_tics(const void *ap, const void *bp) |
999 | { | |
1000 | DWORD a = *((DWORD *)ap); | |
1001 | DWORD b = *((DWORD *)bp); | |
1002 | ||
1003 | TRACE("(a=%ld, b=%ld)\n", a, b); | |
1004 | if (a < b) return -1; | |
1005 | if (a > b) return 1; | |
1006 | return 0; | |
1007 | } | |
1008 | ||
a0d77315 | 1009 | |
e4ddd2ac DP |
1010 | static LONG inline |
1011 | TRACKBAR_GetTic (TRACKBAR_INFO *infoPtr, INT iTic) | |
d30dfd24 | 1012 | { |
c514a781 | 1013 | if ((iTic < 0) || (iTic >= infoPtr->uNumTics) || !infoPtr->tics) |
d30dfd24 AJ |
1014 | return -1; |
1015 | ||
c514a781 | 1016 | qsort(infoPtr->tics, infoPtr->uNumTics, sizeof(DWORD), comp_tics); |
e4ddd2ac | 1017 | return infoPtr->tics[iTic]; |
d30dfd24 AJ |
1018 | } |
1019 | ||
1020 | ||
e4ddd2ac DP |
1021 | static LONG inline |
1022 | TRACKBAR_GetTicPos (TRACKBAR_INFO *infoPtr, INT iTic) | |
d30dfd24 | 1023 | { |
c514a781 | 1024 | LONG range, width, pos, tic; |
0d5aae1a | 1025 | int offsetthumb; |
d30dfd24 | 1026 | |
c514a781 | 1027 | if ((iTic < 0) || (iTic >= infoPtr->uNumTics) || !infoPtr->tics) |
d30dfd24 AJ |
1028 | return -1; |
1029 | ||
c514a781 | 1030 | tic = TRACKBAR_GetTic (infoPtr, iTic); |
e4ddd2ac | 1031 | range = infoPtr->lRangeMax - infoPtr->lRangeMin; |
76707020 | 1032 | if (range <= 0) range = 1; |
0d5aae1a DC |
1033 | offsetthumb = (infoPtr->rcThumb.right - infoPtr->rcThumb.left)/2; |
1034 | width = infoPtr->rcChannel.right - infoPtr->rcChannel.left - offsetthumb*2; | |
1035 | pos = infoPtr->rcChannel.left + offsetthumb + (width * tic) / range; | |
d30dfd24 | 1036 | |
e4ddd2ac | 1037 | return pos; |
d30dfd24 AJ |
1038 | } |
1039 | ||
3d35e989 | 1040 | |
e4ddd2ac DP |
1041 | static HWND |
1042 | TRACKBAR_SetBuddy (TRACKBAR_INFO *infoPtr, BOOL fLocation, HWND hwndBuddy) | |
a0d77315 | 1043 | { |
a3960292 | 1044 | HWND hwndTemp; |
a0d77315 | 1045 | |
e4ddd2ac | 1046 | if (fLocation) { |
a0d77315 AJ |
1047 | /* buddy is left or above */ |
1048 | hwndTemp = infoPtr->hwndBuddyLA; | |
e4ddd2ac | 1049 | infoPtr->hwndBuddyLA = hwndBuddy; |
a0d77315 AJ |
1050 | } |
1051 | else { | |
3d35e989 LT |
1052 | /* buddy is right or below */ |
1053 | hwndTemp = infoPtr->hwndBuddyRB; | |
e4ddd2ac | 1054 | infoPtr->hwndBuddyRB = hwndBuddy; |
a0d77315 AJ |
1055 | } |
1056 | ||
e4ddd2ac | 1057 | TRACKBAR_AlignBuddies (infoPtr); |
a0d77315 | 1058 | |
e4ddd2ac | 1059 | return hwndTemp; |
a0d77315 AJ |
1060 | } |
1061 | ||
1062 | ||
e4ddd2ac DP |
1063 | static LONG inline |
1064 | TRACKBAR_SetLineSize (TRACKBAR_INFO *infoPtr, LONG lLineSize) | |
a0d77315 | 1065 | { |
e4ddd2ac | 1066 | LONG lTemp = infoPtr->lLineSize; |
a0d77315 | 1067 | |
e4ddd2ac | 1068 | infoPtr->lLineSize = lLineSize; |
a0d77315 | 1069 | |
e4ddd2ac | 1070 | return lTemp; |
a0d77315 AJ |
1071 | } |
1072 | ||
1073 | ||
e4ddd2ac DP |
1074 | static LONG inline |
1075 | TRACKBAR_SetPageSize (TRACKBAR_INFO *infoPtr, LONG lPageSize) | |
a0d77315 | 1076 | { |
e4ddd2ac | 1077 | LONG lTemp = infoPtr->lPageSize; |
a0d77315 | 1078 | |
e4ddd2ac | 1079 | infoPtr->lPageSize = lPageSize; |
a0d77315 | 1080 | |
e4ddd2ac | 1081 | return lTemp; |
a0d77315 AJ |
1082 | } |
1083 | ||
1084 | ||
e4ddd2ac DP |
1085 | static LRESULT inline |
1086 | TRACKBAR_SetPos (TRACKBAR_INFO *infoPtr, BOOL fPosition, LONG lPosition) | |
a0d77315 | 1087 | { |
0c6dd5b9 | 1088 | LONG oldPos = infoPtr->lPos; |
e4ddd2ac | 1089 | infoPtr->lPos = lPosition; |
a0d77315 | 1090 | |
e4ddd2ac DP |
1091 | if (infoPtr->lPos < infoPtr->lRangeMin) |
1092 | infoPtr->lPos = infoPtr->lRangeMin; | |
a0d77315 | 1093 | |
e4ddd2ac DP |
1094 | if (infoPtr->lPos > infoPtr->lRangeMax) |
1095 | infoPtr->lPos = infoPtr->lRangeMax; | |
3d35e989 | 1096 | infoPtr->flags |= TB_THUMBPOSCHANGED; |
a0d77315 | 1097 | |
0c6dd5b9 | 1098 | if (fPosition) TRACKBAR_InvalidateThumbMove(infoPtr, oldPos, lPosition); |
a0d77315 AJ |
1099 | |
1100 | return 0; | |
1101 | } | |
1102 | ||
1103 | ||
e4ddd2ac DP |
1104 | static LRESULT inline |
1105 | TRACKBAR_SetRange (TRACKBAR_INFO *infoPtr, BOOL fRedraw, LONG lRange) | |
a0d77315 | 1106 | { |
c514a781 DP |
1107 | infoPtr->lRangeMin = (SHORT)LOWORD(lRange); |
1108 | infoPtr->lRangeMax = (SHORT)HIWORD(lRange); | |
a0d77315 | 1109 | |
e4ddd2ac DP |
1110 | if (infoPtr->lPos < infoPtr->lRangeMin) { |
1111 | infoPtr->lPos = infoPtr->lRangeMin; | |
c514a781 | 1112 | infoPtr->flags |= TB_THUMBPOSCHANGED; |
3d35e989 | 1113 | } |
a0d77315 | 1114 | |
e4ddd2ac DP |
1115 | if (infoPtr->lPos > infoPtr->lRangeMax) { |
1116 | infoPtr->lPos = infoPtr->lRangeMax; | |
c514a781 | 1117 | infoPtr->flags |= TB_THUMBPOSCHANGED; |
3d35e989 | 1118 | } |
d30dfd24 | 1119 | |
c514a781 DP |
1120 | infoPtr->lPageSize = (infoPtr->lRangeMax - infoPtr->lRangeMin) / 5; |
1121 | if (infoPtr->lPageSize == 0) infoPtr->lPageSize = 1; | |
a0d77315 | 1122 | |
0c6dd5b9 | 1123 | if (fRedraw) TRACKBAR_InvalidateAll(infoPtr); |
a0d77315 AJ |
1124 | |
1125 | return 0; | |
1126 | } | |
1127 | ||
1128 | ||
e4ddd2ac DP |
1129 | static LRESULT inline |
1130 | TRACKBAR_SetRangeMax (TRACKBAR_INFO *infoPtr, BOOL fRedraw, LONG lMax) | |
a0d77315 | 1131 | { |
e4ddd2ac DP |
1132 | infoPtr->lRangeMax = lMax; |
1133 | if (infoPtr->lPos > infoPtr->lRangeMax) { | |
1134 | infoPtr->lPos = infoPtr->lRangeMax; | |
c514a781 | 1135 | infoPtr->flags |= TB_THUMBPOSCHANGED; |
3d35e989 | 1136 | } |
d30dfd24 | 1137 | |
c514a781 DP |
1138 | infoPtr->lPageSize = (infoPtr->lRangeMax - infoPtr->lRangeMin) / 5; |
1139 | if (infoPtr->lPageSize == 0) infoPtr->lPageSize = 1; | |
a0d77315 | 1140 | |
0c6dd5b9 | 1141 | if (fRedraw) TRACKBAR_InvalidateAll(infoPtr); |
a0d77315 AJ |
1142 | |
1143 | return 0; | |
1144 | } | |
1145 | ||
1146 | ||
e4ddd2ac DP |
1147 | static LRESULT inline |
1148 | TRACKBAR_SetRangeMin (TRACKBAR_INFO *infoPtr, BOOL fRedraw, LONG lMin) | |
a0d77315 | 1149 | { |
e4ddd2ac DP |
1150 | infoPtr->lRangeMin = lMin; |
1151 | if (infoPtr->lPos < infoPtr->lRangeMin) { | |
1152 | infoPtr->lPos = infoPtr->lRangeMin; | |
c514a781 | 1153 | infoPtr->flags |= TB_THUMBPOSCHANGED; |
3d35e989 | 1154 | } |
d30dfd24 | 1155 | |
c514a781 DP |
1156 | infoPtr->lPageSize = (infoPtr->lRangeMax - infoPtr->lRangeMin) / 5; |
1157 | if (infoPtr->lPageSize == 0) infoPtr->lPageSize = 1; | |
a0d77315 | 1158 | |
0c6dd5b9 | 1159 | if (fRedraw) TRACKBAR_InvalidateAll(infoPtr); |
a0d77315 AJ |
1160 | |
1161 | return 0; | |
1162 | } | |
1163 | ||
3d35e989 | 1164 | |
e4ddd2ac DP |
1165 | static LRESULT inline |
1166 | TRACKBAR_SetSel (TRACKBAR_INFO *infoPtr, BOOL fRedraw, LONG lSel) | |
d30dfd24 | 1167 | { |
d7174979 DP |
1168 | if (!GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE) & TBS_ENABLESELRANGE) |
1169 | return 0; | |
1170 | ||
c514a781 DP |
1171 | infoPtr->lSelMin = (SHORT)LOWORD(lSel); |
1172 | infoPtr->lSelMax = (SHORT)HIWORD(lSel); | |
1173 | infoPtr->flags |= TB_SELECTIONCHANGED; | |
d30dfd24 | 1174 | |
e4ddd2ac DP |
1175 | if (infoPtr->lSelMin < infoPtr->lRangeMin) |
1176 | infoPtr->lSelMin = infoPtr->lRangeMin; | |
1177 | if (infoPtr->lSelMax > infoPtr->lRangeMax) | |
1178 | infoPtr->lSelMax = infoPtr->lRangeMax; | |
a0d77315 | 1179 | |
0c6dd5b9 | 1180 | if (fRedraw) TRACKBAR_InvalidateAll(infoPtr); |
a0d77315 AJ |
1181 | |
1182 | return 0; | |
1183 | } | |
1184 | ||
1185 | ||
e4ddd2ac DP |
1186 | static LRESULT inline |
1187 | TRACKBAR_SetSelEnd (TRACKBAR_INFO *infoPtr, BOOL fRedraw, LONG lEnd) | |
a0d77315 | 1188 | { |
e4ddd2ac | 1189 | if (!GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE) & TBS_ENABLESELRANGE) |
a0d77315 AJ |
1190 | return 0; |
1191 | ||
e4ddd2ac | 1192 | infoPtr->lSelMax = lEnd; |
3d35e989 | 1193 | infoPtr->flags |= TB_SELECTIONCHANGED; |
9a624916 | 1194 | |
e4ddd2ac DP |
1195 | if (infoPtr->lSelMax > infoPtr->lRangeMax) |
1196 | infoPtr->lSelMax = infoPtr->lRangeMax; | |
a0d77315 | 1197 | |
0c6dd5b9 | 1198 | if (fRedraw) TRACKBAR_InvalidateAll(infoPtr); |
a0d77315 AJ |
1199 | |
1200 | return 0; | |
1201 | } | |
1202 | ||
1203 | ||
e4ddd2ac DP |
1204 | static LRESULT inline |
1205 | TRACKBAR_SetSelStart (TRACKBAR_INFO *infoPtr, BOOL fRedraw, LONG lStart) | |
a0d77315 | 1206 | { |
e4ddd2ac | 1207 | if (!GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE) & TBS_ENABLESELRANGE) |
a0d77315 AJ |
1208 | return 0; |
1209 | ||
e4ddd2ac | 1210 | infoPtr->lSelMin = lStart; |
3d35e989 | 1211 | infoPtr->flags |=TB_SELECTIONCHANGED; |
cad17ff7 | 1212 | |
e4ddd2ac DP |
1213 | if (infoPtr->lSelMin < infoPtr->lRangeMin) |
1214 | infoPtr->lSelMin = infoPtr->lRangeMin; | |
a0d77315 | 1215 | |
0c6dd5b9 | 1216 | if (fRedraw) TRACKBAR_InvalidateAll(infoPtr); |
a0d77315 AJ |
1217 | |
1218 | return 0; | |
1219 | } | |
1220 | ||
1221 | ||
e4ddd2ac DP |
1222 | static LRESULT inline |
1223 | TRACKBAR_SetThumbLength (TRACKBAR_INFO *infoPtr, UINT iLength) | |
a0d77315 | 1224 | { |
d2b8e39b | 1225 | if (GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE) & TBS_FIXEDLENGTH) { |
e4ddd2ac | 1226 | infoPtr->uThumbLen = iLength; |
d2b8e39b MH |
1227 | infoPtr->flags |= TB_THUMBSIZECHANGED; |
1228 | InvalidateRect (infoPtr->hwndSelf, &infoPtr->rcThumb, FALSE); | |
1229 | } | |
cad17ff7 | 1230 | |
a0d77315 AJ |
1231 | return 0; |
1232 | } | |
1233 | ||
1234 | ||
e4ddd2ac DP |
1235 | static LRESULT inline |
1236 | TRACKBAR_SetTic (TRACKBAR_INFO *infoPtr, LONG lPos) | |
a0d77315 | 1237 | { |
c514a781 DP |
1238 | if (GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE) & TBS_AUTOTICKS) |
1239 | return FALSE; | |
1240 | ||
e4ddd2ac | 1241 | if ((lPos < infoPtr->lRangeMin) || (lPos> infoPtr->lRangeMax)) |
3d35e989 | 1242 | return FALSE; |
a0d77315 | 1243 | |
c514a781 DP |
1244 | TRACE("lPos=%ld\n", lPos); |
1245 | ||
3d35e989 | 1246 | infoPtr->uNumTics++; |
7de279a7 | 1247 | infoPtr->tics=ReAlloc( infoPtr->tics, |
3d35e989 | 1248 | (infoPtr->uNumTics)*sizeof (DWORD)); |
c514a781 DP |
1249 | if (!infoPtr->tics) { |
1250 | infoPtr->uNumTics = 0; | |
a63270f1 | 1251 | notify(infoPtr, NM_OUTOFMEMORY); |
c514a781 DP |
1252 | return FALSE; |
1253 | } | |
1254 | infoPtr->tics[infoPtr->uNumTics-1] = lPos; | |
a0d77315 | 1255 | |
0c6dd5b9 | 1256 | TRACKBAR_InvalidateAll(infoPtr); |
a0d77315 AJ |
1257 | |
1258 | return TRUE; | |
1259 | } | |
1260 | ||
1261 | ||
e4ddd2ac DP |
1262 | static LRESULT inline |
1263 | TRACKBAR_SetTicFreq (TRACKBAR_INFO *infoPtr, WORD wFreq) | |
1264 | { | |
c514a781 | 1265 | if (GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE) & TBS_AUTOTICKS) { |
e4ddd2ac | 1266 | infoPtr->uTicFreq = wFreq; |
c514a781 | 1267 | TRACKBAR_RecalculateTics (infoPtr); |
0c6dd5b9 | 1268 | TRACKBAR_InvalidateAll(infoPtr); |
c514a781 | 1269 | } |
e4ddd2ac DP |
1270 | |
1271 | return 0; | |
1272 | } | |
1273 | ||
1274 | ||
1275 | static INT inline | |
1276 | TRACKBAR_SetTipSide (TRACKBAR_INFO *infoPtr, INT fLocation) | |
a0d77315 | 1277 | { |
a3960292 | 1278 | INT fTemp = infoPtr->fLocation; |
a0d77315 | 1279 | |
e4ddd2ac | 1280 | infoPtr->fLocation = fLocation; |
9a624916 | 1281 | |
a0d77315 AJ |
1282 | return fTemp; |
1283 | } | |
1284 | ||
1285 | ||
e4ddd2ac DP |
1286 | static LRESULT inline |
1287 | TRACKBAR_SetToolTips (TRACKBAR_INFO *infoPtr, HWND hwndTT) | |
a0d77315 | 1288 | { |
e4ddd2ac | 1289 | infoPtr->hwndToolTip = hwndTT; |
a0d77315 AJ |
1290 | |
1291 | return 0; | |
1292 | } | |
1293 | ||
1294 | ||
e4ddd2ac DP |
1295 | static BOOL inline |
1296 | TRACKBAR_SetUnicodeFormat (TRACKBAR_INFO *infoPtr, BOOL fUnicode) | |
1297 | { | |
1298 | BOOL bTemp = infoPtr->bUnicode; | |
1299 | ||
1300 | infoPtr->bUnicode = fUnicode; | |
1301 | ||
1302 | return bTemp; | |
1303 | } | |
a0d77315 AJ |
1304 | |
1305 | ||
d30dfd24 | 1306 | static LRESULT |
e4ddd2ac | 1307 | TRACKBAR_InitializeThumb (TRACKBAR_INFO *infoPtr) |
d30dfd24 | 1308 | { |
d2b8e39b | 1309 | DWORD dwStyle = GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE); |
dcaf1377 | 1310 | RECT rect; |
9ebf12c3 | 1311 | int clientWidth, clientMetric; |
d2b8e39b MH |
1312 | |
1313 | /* initial thumb length */ | |
0d5aae1a | 1314 | clientMetric = (dwStyle & TBS_ENABLESELRANGE) ? 23 : 21; |
dcaf1377 | 1315 | GetClientRect(infoPtr->hwndSelf,&rect); |
d2b8e39b | 1316 | if (dwStyle & TBS_VERT) { |
9ebf12c3 | 1317 | clientWidth = rect.right - rect.left; |
d2b8e39b | 1318 | } else { |
9ebf12c3 | 1319 | clientWidth = rect.bottom - rect.top; |
d2b8e39b | 1320 | } |
0d5aae1a DC |
1321 | if (clientWidth >= clientMetric) |
1322 | infoPtr->uThumbLen = clientMetric; | |
9ebf12c3 DC |
1323 | else |
1324 | infoPtr->uThumbLen = clientWidth > 9 ? clientWidth - 6 : 4; | |
d30dfd24 | 1325 | |
e4ddd2ac | 1326 | TRACKBAR_CalcChannel (infoPtr); |
c514a781 | 1327 | TRACKBAR_UpdateThumb (infoPtr); |
3d35e989 | 1328 | infoPtr->flags &= ~TB_SELECTIONCHANGED; |
d30dfd24 | 1329 | |
3d35e989 | 1330 | return 0; |
d30dfd24 | 1331 | } |
a0d77315 AJ |
1332 | |
1333 | ||
1334 | static LRESULT | |
e4ddd2ac | 1335 | TRACKBAR_Create (HWND hwnd, LPCREATESTRUCTW lpcs) |
a0d77315 AJ |
1336 | { |
1337 | TRACKBAR_INFO *infoPtr; | |
c514a781 | 1338 | DWORD oldStyle, newStyle; |
a0d77315 | 1339 | |
7de279a7 | 1340 | infoPtr = (TRACKBAR_INFO *)Alloc (sizeof(TRACKBAR_INFO)); |
e4ddd2ac DP |
1341 | if (!infoPtr) return -1; |
1342 | SetWindowLongW (hwnd, 0, (DWORD)infoPtr); | |
a0d77315 | 1343 | |
cad17ff7 | 1344 | /* set default values */ |
e4ddd2ac DP |
1345 | infoPtr->hwndSelf = hwnd; |
1346 | infoPtr->lRangeMin = 0; | |
1347 | infoPtr->lRangeMax = 100; | |
1348 | infoPtr->lLineSize = 1; | |
1349 | infoPtr->lPageSize = 20; | |
1350 | infoPtr->lSelMin = 0; | |
1351 | infoPtr->lSelMax = 0; | |
1352 | infoPtr->lPos = 0; | |
d7174979 | 1353 | infoPtr->fLocation = -1; |
d30dfd24 | 1354 | infoPtr->uNumTics = 0; /* start and end tic are not included in count*/ |
3d35e989 | 1355 | infoPtr->uTicFreq = 1; |
e4ddd2ac | 1356 | infoPtr->tics = NULL; |
a63270f1 | 1357 | infoPtr->hwndNotify= lpcs->hwndParent; |
a0d77315 | 1358 | |
e4ddd2ac | 1359 | TRACKBAR_InitializeThumb (infoPtr); |
506115b8 | 1360 | |
c514a781 DP |
1361 | oldStyle = newStyle = GetWindowLongW (hwnd, GWL_STYLE); |
1362 | if (oldStyle & TBS_VERT) { | |
1363 | if (! (oldStyle & (TBS_LEFT | TBS_RIGHT | TBS_BOTH)) ) | |
1364 | newStyle |= TBS_RIGHT; | |
1365 | } else { | |
1366 | if (! (oldStyle & (TBS_TOP | TBS_BOTTOM | TBS_BOTH)) ) | |
1367 | newStyle |= TBS_BOTTOM; | |
1368 | } | |
1369 | if (newStyle != oldStyle) | |
1370 | SetWindowLongW (hwnd, GWL_STYLE, newStyle); | |
1371 | ||
cad17ff7 | 1372 | /* Create tooltip control */ |
c514a781 | 1373 | if (newStyle & TBS_TOOLTIPS) { |
506115b8 AP |
1374 | |
1375 | infoPtr->hwndToolTip = | |
e4ddd2ac | 1376 | CreateWindowExW (0, TOOLTIPS_CLASSW, NULL, 0, |
3d35e989 LT |
1377 | CW_USEDEFAULT, CW_USEDEFAULT, |
1378 | CW_USEDEFAULT, CW_USEDEFAULT, | |
1379 | hwnd, 0, 0, 0); | |
506115b8 | 1380 | |
d7174979 | 1381 | if (infoPtr->hwndToolTip) { |
5b44c77f | 1382 | TTTOOLINFOW ti; |
d7174979 DP |
1383 | ZeroMemory (&ti, sizeof(ti)); |
1384 | ti.cbSize = sizeof(ti); | |
1385 | ti.uFlags = TTF_IDISHWND | TTF_TRACK | TTF_ABSOLUTE; | |
1386 | ti.hwnd = hwnd; | |
506115b8 | 1387 | |
d7174979 DP |
1388 | SendMessageW (infoPtr->hwndToolTip, TTM_ADDTOOLW, 0, (LPARAM)&ti); |
1389 | } | |
3d35e989 | 1390 | } |
cad17ff7 | 1391 | |
a0d77315 AJ |
1392 | return 0; |
1393 | } | |
1394 | ||
1395 | ||
1396 | static LRESULT | |
e4ddd2ac | 1397 | TRACKBAR_Destroy (TRACKBAR_INFO *infoPtr) |
a0d77315 | 1398 | { |
3d35e989 | 1399 | /* delete tooltip control */ |
506115b8 | 1400 | if (infoPtr->hwndToolTip) |
a3960292 | 1401 | DestroyWindow (infoPtr->hwndToolTip); |
506115b8 | 1402 | |
7de279a7 | 1403 | Free (infoPtr); |
e4ddd2ac | 1404 | SetWindowLongW (infoPtr->hwndSelf, 0, 0); |
a0d77315 AJ |
1405 | return 0; |
1406 | } | |
1407 | ||
1408 | ||
1409 | static LRESULT | |
e4ddd2ac | 1410 | TRACKBAR_KillFocus (TRACKBAR_INFO *infoPtr, HWND hwndGetFocus) |
a0d77315 | 1411 | { |
a099a555 | 1412 | TRACE("\n"); |
d2b8e39b | 1413 | infoPtr->bFocussed = FALSE; |
0c6dd5b9 | 1414 | TRACKBAR_InvalidateAll(infoPtr); |
a0d77315 AJ |
1415 | |
1416 | return 0; | |
1417 | } | |
1418 | ||
a0d77315 | 1419 | static LRESULT |
d7174979 | 1420 | TRACKBAR_LButtonDown (TRACKBAR_INFO *infoPtr, DWORD fwKeys, POINTS pts) |
a0d77315 | 1421 | { |
d7174979 | 1422 | POINT clickPoint = { pts.x, pts.y }; |
a0d77315 | 1423 | |
d7174979 DP |
1424 | SetFocus(infoPtr->hwndSelf); |
1425 | ||
c1e3cb8d | 1426 | if (PtInRect(&infoPtr->rcThumb, clickPoint)) { |
3d35e989 | 1427 | infoPtr->flags |= TB_DRAG_MODE; |
c514a781 | 1428 | SetCapture (infoPtr->hwndSelf); |
d7174979 DP |
1429 | TRACKBAR_UpdateToolTip (infoPtr); |
1430 | TRACKBAR_ActivateToolTip (infoPtr, TRUE); | |
e54fdf21 | 1431 | TRACKBAR_InvalidateThumb(infoPtr, infoPtr->lPos); |
c514a781 | 1432 | } else { |
c1e3cb8d DP |
1433 | LONG dir = TRACKBAR_GetAutoPageDirection(infoPtr, clickPoint); |
1434 | if (dir == 0) return 0; | |
1435 | infoPtr->flags |= (dir < 0) ? TB_AUTO_PAGE_LEFT : TB_AUTO_PAGE_RIGHT; | |
1436 | TRACKBAR_AutoPage (infoPtr, clickPoint); | |
1437 | SetCapture (infoPtr->hwndSelf); | |
1438 | SetTimer(infoPtr->hwndSelf, TB_REFRESH_TIMER, TB_REFRESH_DELAY, 0); | |
3d35e989 | 1439 | } |
9a624916 | 1440 | |
d30dfd24 AJ |
1441 | return 0; |
1442 | } | |
1443 | ||
3d35e989 | 1444 | |
d30dfd24 | 1445 | static LRESULT |
d7174979 | 1446 | TRACKBAR_LButtonUp (TRACKBAR_INFO *infoPtr, DWORD fwKeys, POINTS pts) |
d30dfd24 | 1447 | { |
c1e3cb8d | 1448 | if (infoPtr->flags & TB_DRAG_MODE) { |
a63270f1 HD |
1449 | notify_with_scroll (infoPtr, TB_THUMBPOSITION | (infoPtr->lPos<<16)); |
1450 | notify_with_scroll (infoPtr, TB_ENDTRACK); | |
3d35e989 LT |
1451 | infoPtr->flags &= ~TB_DRAG_MODE; |
1452 | ReleaseCapture (); | |
a63270f1 | 1453 | notify(infoPtr, NM_RELEASEDCAPTURE); |
c1e3cb8d | 1454 | TRACKBAR_ActivateToolTip(infoPtr, FALSE); |
e54fdf21 | 1455 | TRACKBAR_InvalidateThumb(infoPtr, infoPtr->lPos); |
c1e3cb8d DP |
1456 | } |
1457 | if (infoPtr->flags & TB_AUTO_PAGE) { | |
1458 | KillTimer (infoPtr->hwndSelf, TB_REFRESH_TIMER); | |
1459 | infoPtr->flags &= ~TB_AUTO_PAGE; | |
a63270f1 | 1460 | notify_with_scroll (infoPtr, TB_ENDTRACK); |
c1e3cb8d | 1461 | ReleaseCapture (); |
a63270f1 | 1462 | notify(infoPtr, NM_RELEASEDCAPTURE); |
3d35e989 | 1463 | } |
9a624916 | 1464 | |
a0d77315 AJ |
1465 | return 0; |
1466 | } | |
1467 | ||
3d35e989 | 1468 | |
d30dfd24 | 1469 | static LRESULT |
e4ddd2ac | 1470 | TRACKBAR_CaptureChanged (TRACKBAR_INFO *infoPtr) |
d30dfd24 | 1471 | { |
a63270f1 | 1472 | notify_with_scroll (infoPtr, TB_ENDTRACK); |
3d35e989 | 1473 | return 0; |
d30dfd24 | 1474 | } |
a0d77315 | 1475 | |
3d35e989 | 1476 | |
a0d77315 | 1477 | static LRESULT |
e4ddd2ac | 1478 | TRACKBAR_Paint (TRACKBAR_INFO *infoPtr, HDC hdc) |
a0d77315 | 1479 | { |
e4ddd2ac DP |
1480 | if (hdc) { |
1481 | TRACKBAR_Refresh(infoPtr, hdc); | |
1482 | } else { | |
1483 | PAINTSTRUCT ps; | |
1484 | hdc = BeginPaint (infoPtr->hwndSelf, &ps); | |
1485 | TRACKBAR_Refresh (infoPtr, hdc); | |
1486 | EndPaint (infoPtr->hwndSelf, &ps); | |
1487 | } | |
a0d77315 | 1488 | |
a0d77315 AJ |
1489 | return 0; |
1490 | } | |
1491 | ||
1492 | ||
1493 | static LRESULT | |
e4ddd2ac | 1494 | TRACKBAR_SetFocus (TRACKBAR_INFO *infoPtr, HWND hwndLoseFocus) |
a0d77315 | 1495 | { |
a099a555 | 1496 | TRACE("\n"); |
d2b8e39b | 1497 | infoPtr->bFocussed = TRUE; |
0c6dd5b9 | 1498 | TRACKBAR_InvalidateAll(infoPtr); |
a0d77315 AJ |
1499 | |
1500 | return 0; | |
1501 | } | |
1502 | ||
1503 | ||
1504 | static LRESULT | |
e4ddd2ac | 1505 | TRACKBAR_Size (TRACKBAR_INFO *infoPtr, DWORD fwSizeType, INT nWidth, INT nHeight) |
a0d77315 | 1506 | { |
88c25c86 | 1507 | TRACKBAR_InitializeThumb (infoPtr); |
e4ddd2ac | 1508 | TRACKBAR_AlignBuddies (infoPtr); |
a0d77315 AJ |
1509 | |
1510 | return 0; | |
1511 | } | |
1512 | ||
1513 | ||
c1e3cb8d DP |
1514 | static LRESULT |
1515 | TRACKBAR_Timer (TRACKBAR_INFO *infoPtr, INT wTimerID, TIMERPROC *tmrpc) | |
1516 | { | |
1517 | if (infoPtr->flags & TB_AUTO_PAGE) { | |
1518 | POINT pt; | |
1519 | if (GetCursorPos(&pt)) | |
1520 | if (ScreenToClient(infoPtr->hwndSelf, &pt)) | |
1521 | TRACKBAR_AutoPage(infoPtr, pt); | |
1522 | } | |
1523 | return 0; | |
1524 | } | |
1525 | ||
1526 | ||
d30dfd24 | 1527 | static LRESULT |
d7174979 | 1528 | TRACKBAR_MouseMove (TRACKBAR_INFO *infoPtr, DWORD fwKeys, POINTS pts) |
d30dfd24 | 1529 | { |
e4ddd2ac | 1530 | DWORD dwStyle = GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE); |
d7174979 | 1531 | INT clickPlace = (dwStyle & TBS_VERT) ? pts.y : pts.x; |
1084a8ba | 1532 | LONG dragPos, oldPos = infoPtr->lPos; |
9a624916 | 1533 | |
d7174979 | 1534 | TRACE("(x=%d. y=%d)\n", pts.x, pts.y); |
506115b8 | 1535 | |
c1e3cb8d DP |
1536 | if (infoPtr->flags & TB_AUTO_PAGE) { |
1537 | POINT pt; | |
1538 | POINTSTOPOINT(pt, pts); | |
1539 | TRACKBAR_AutoPage (infoPtr, pt); | |
cad17ff7 | 1540 | return TRUE; |
c1e3cb8d DP |
1541 | } |
1542 | ||
1543 | if (!(infoPtr->flags & TB_DRAG_MODE)) return TRUE; | |
ba211eeb | 1544 | |
9a624916 | 1545 | dragPos = TRACKBAR_ConvertPlaceToPosition (infoPtr, clickPlace, |
3d35e989 | 1546 | dwStyle & TBS_VERT); |
c514a781 | 1547 | if (dragPos == oldPos) return TRUE; |
506115b8 | 1548 | |
c514a781 | 1549 | infoPtr->lPos = dragPos; |
e4ddd2ac | 1550 | |
c514a781 | 1551 | infoPtr->flags |= TB_THUMBPOSCHANGED; |
a63270f1 | 1552 | notify_with_scroll (infoPtr, TB_THUMBTRACK | (infoPtr->lPos<<16)); |
9a624916 | 1553 | |
506115b8 | 1554 | |
c514a781 | 1555 | TRACKBAR_InvalidateThumbMove(infoPtr, oldPos, dragPos); |
e4ddd2ac | 1556 | UpdateWindow (infoPtr->hwndSelf); |
ba211eeb | 1557 | |
3d35e989 | 1558 | return TRUE; |
d30dfd24 AJ |
1559 | } |
1560 | ||
e4ddd2ac DP |
1561 | static BOOL |
1562 | TRACKBAR_KeyDown (TRACKBAR_INFO *infoPtr, INT nVirtKey, DWORD lKeyData) | |
d30dfd24 | 1563 | { |
a63270f1 HD |
1564 | DWORD style = GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE); |
1565 | BOOL downIsLeft = style & TBS_DOWNISLEFT; | |
1566 | BOOL vert = style & TBS_VERT; | |
e4ddd2ac | 1567 | LONG pos = infoPtr->lPos; |
d30dfd24 | 1568 | |
e4ddd2ac | 1569 | TRACE("%x\n", nVirtKey); |
d30dfd24 | 1570 | |
e4ddd2ac | 1571 | switch (nVirtKey) { |
9a624916 | 1572 | case VK_UP: |
a63270f1 HD |
1573 | if (!vert && downIsLeft) TRACKBAR_LineDown(infoPtr); |
1574 | else TRACKBAR_LineUp(infoPtr); | |
1575 | break; | |
d7174979 | 1576 | case VK_LEFT: |
a63270f1 HD |
1577 | if (vert && downIsLeft) TRACKBAR_LineDown(infoPtr); |
1578 | else TRACKBAR_LineUp(infoPtr); | |
3d35e989 | 1579 | break; |
9a624916 | 1580 | case VK_DOWN: |
a63270f1 HD |
1581 | if (!vert && downIsLeft) TRACKBAR_LineUp(infoPtr); |
1582 | else TRACKBAR_LineDown(infoPtr); | |
1583 | break; | |
d7174979 | 1584 | case VK_RIGHT: |
a63270f1 HD |
1585 | if (vert && downIsLeft) TRACKBAR_LineUp(infoPtr); |
1586 | else TRACKBAR_LineDown(infoPtr); | |
3d35e989 LT |
1587 | break; |
1588 | case VK_NEXT: | |
a63270f1 HD |
1589 | if (!vert && downIsLeft) TRACKBAR_PageUp(infoPtr); |
1590 | else TRACKBAR_PageDown(infoPtr); | |
3d35e989 LT |
1591 | break; |
1592 | case VK_PRIOR: | |
a63270f1 HD |
1593 | if (!vert && downIsLeft) TRACKBAR_PageDown(infoPtr); |
1594 | else TRACKBAR_PageUp(infoPtr); | |
3d35e989 | 1595 | break; |
9a624916 | 1596 | case VK_HOME: |
e4ddd2ac DP |
1597 | if (infoPtr->lPos == infoPtr->lRangeMin) return FALSE; |
1598 | infoPtr->lPos = infoPtr->lRangeMin; | |
a63270f1 | 1599 | notify_with_scroll (infoPtr, TB_TOP); |
3d35e989 | 1600 | break; |
9a624916 | 1601 | case VK_END: |
e4ddd2ac DP |
1602 | if (infoPtr->lPos == infoPtr->lRangeMax) return FALSE; |
1603 | infoPtr->lPos = infoPtr->lRangeMax; | |
a63270f1 | 1604 | notify_with_scroll (infoPtr, TB_BOTTOM); |
3d35e989 LT |
1605 | break; |
1606 | } | |
d30dfd24 | 1607 | |
e4ddd2ac | 1608 | if (pos != infoPtr->lPos) { |
ba211eeb | 1609 | infoPtr->flags |=TB_THUMBPOSCHANGED; |
c514a781 | 1610 | TRACKBAR_InvalidateThumbMove (infoPtr, pos, infoPtr->lPos); |
3d35e989 | 1611 | } |
d30dfd24 | 1612 | |
3d35e989 | 1613 | return TRUE; |
d30dfd24 AJ |
1614 | } |
1615 | ||
3d35e989 | 1616 | |
e4ddd2ac DP |
1617 | static BOOL inline |
1618 | TRACKBAR_KeyUp (TRACKBAR_INFO *infoPtr, INT nVirtKey, DWORD lKeyData) | |
d30dfd24 | 1619 | { |
e4ddd2ac | 1620 | switch (nVirtKey) { |
3d35e989 | 1621 | case VK_LEFT: |
9a624916 | 1622 | case VK_UP: |
3d35e989 | 1623 | case VK_RIGHT: |
9a624916 | 1624 | case VK_DOWN: |
3d35e989 LT |
1625 | case VK_NEXT: |
1626 | case VK_PRIOR: | |
9a624916 | 1627 | case VK_HOME: |
3d35e989 | 1628 | case VK_END: |
a63270f1 | 1629 | notify_with_scroll (infoPtr, TB_ENDTRACK); |
3d35e989 LT |
1630 | } |
1631 | return TRUE; | |
ba211eeb AP |
1632 | } |
1633 | ||
1634 | ||
26ffb3cd | 1635 | static LRESULT WINAPI |
a3960292 | 1636 | TRACKBAR_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) |
a0d77315 | 1637 | { |
e4ddd2ac DP |
1638 | TRACKBAR_INFO *infoPtr = (TRACKBAR_INFO *)GetWindowLongW (hwnd, 0); |
1639 | ||
353529b2 | 1640 | TRACE("hwnd=%p msg=%x wparam=%x lparam=%lx\n", hwnd, uMsg, wParam, lParam); |
e4ddd2ac DP |
1641 | |
1642 | if (!infoPtr && (uMsg != WM_CREATE)) | |
1643 | return DefWindowProcW (hwnd, uMsg, wParam, lParam); | |
1644 | ||
a0d77315 AJ |
1645 | switch (uMsg) |
1646 | { | |
3d35e989 | 1647 | case TBM_CLEARSEL: |
e4ddd2ac | 1648 | return TRACKBAR_ClearSel (infoPtr, (BOOL)wParam); |
a0d77315 | 1649 | |
3d35e989 | 1650 | case TBM_CLEARTICS: |
e4ddd2ac | 1651 | return TRACKBAR_ClearTics (infoPtr, (BOOL)wParam); |
a0d77315 | 1652 | |
3d35e989 | 1653 | case TBM_GETBUDDY: |
f3d1893f | 1654 | return (LRESULT)(wParam ? infoPtr->hwndBuddyLA : infoPtr->hwndBuddyRB); |
a0d77315 | 1655 | |
3d35e989 | 1656 | case TBM_GETCHANNELRECT: |
e4ddd2ac | 1657 | return TRACKBAR_GetChannelRect (infoPtr, (LPRECT)lParam); |
a0d77315 | 1658 | |
3d35e989 | 1659 | case TBM_GETLINESIZE: |
d7174979 | 1660 | return infoPtr->lLineSize; |
a0d77315 | 1661 | |
3d35e989 | 1662 | case TBM_GETNUMTICS: |
e4ddd2ac | 1663 | return TRACKBAR_GetNumTics (infoPtr); |
a0d77315 | 1664 | |
3d35e989 | 1665 | case TBM_GETPAGESIZE: |
d7174979 | 1666 | return infoPtr->lPageSize; |
a0d77315 | 1667 | |
3d35e989 | 1668 | case TBM_GETPOS: |
d7174979 | 1669 | return infoPtr->lPos; |
a0d77315 | 1670 | |
3d35e989 | 1671 | case TBM_GETPTICS: |
d7174979 | 1672 | return (LRESULT)infoPtr->tics; |
a0d77315 | 1673 | |
3d35e989 | 1674 | case TBM_GETRANGEMAX: |
d7174979 | 1675 | return infoPtr->lRangeMax; |
a0d77315 | 1676 | |
3d35e989 | 1677 | case TBM_GETRANGEMIN: |
d7174979 | 1678 | return infoPtr->lRangeMin; |
a0d77315 | 1679 | |
3d35e989 | 1680 | case TBM_GETSELEND: |
d7174979 | 1681 | return infoPtr->lSelMax; |
a0d77315 | 1682 | |
3d35e989 | 1683 | case TBM_GETSELSTART: |
d7174979 | 1684 | return infoPtr->lSelMin; |
a0d77315 | 1685 | |
3d35e989 | 1686 | case TBM_GETTHUMBLENGTH: |
d7174979 | 1687 | return infoPtr->uThumbLen; |
a0d77315 | 1688 | |
3d35e989 | 1689 | case TBM_GETTHUMBRECT: |
d7174979 | 1690 | return CopyRect((LPRECT)lParam, &infoPtr->rcThumb); |
a0d77315 | 1691 | |
d30dfd24 | 1692 | case TBM_GETTIC: |
e4ddd2ac | 1693 | return TRACKBAR_GetTic (infoPtr, (INT)wParam); |
9a624916 | 1694 | |
d30dfd24 | 1695 | case TBM_GETTICPOS: |
e4ddd2ac | 1696 | return TRACKBAR_GetTicPos (infoPtr, (INT)wParam); |
9a624916 | 1697 | |
3d35e989 | 1698 | case TBM_GETTOOLTIPS: |
d7174979 | 1699 | return (LRESULT)infoPtr->hwndToolTip; |
a0d77315 | 1700 | |
e4ddd2ac | 1701 | case TBM_GETUNICODEFORMAT: |
d7174979 | 1702 | return infoPtr->bUnicode; |
a0d77315 | 1703 | |
3d35e989 | 1704 | case TBM_SETBUDDY: |
e4ddd2ac | 1705 | return (LRESULT) TRACKBAR_SetBuddy(infoPtr, (BOOL)wParam, (HWND)lParam); |
a0d77315 | 1706 | |
3d35e989 | 1707 | case TBM_SETLINESIZE: |
e4ddd2ac | 1708 | return TRACKBAR_SetLineSize (infoPtr, (LONG)lParam); |
a0d77315 | 1709 | |
3d35e989 | 1710 | case TBM_SETPAGESIZE: |
e4ddd2ac | 1711 | return TRACKBAR_SetPageSize (infoPtr, (LONG)lParam); |
a0d77315 | 1712 | |
3d35e989 | 1713 | case TBM_SETPOS: |
e4ddd2ac | 1714 | return TRACKBAR_SetPos (infoPtr, (BOOL)wParam, (LONG)lParam); |
a0d77315 | 1715 | |
3d35e989 | 1716 | case TBM_SETRANGE: |
e4ddd2ac | 1717 | return TRACKBAR_SetRange (infoPtr, (BOOL)wParam, (LONG)lParam); |
a0d77315 | 1718 | |
3d35e989 | 1719 | case TBM_SETRANGEMAX: |
e4ddd2ac | 1720 | return TRACKBAR_SetRangeMax (infoPtr, (BOOL)wParam, (LONG)lParam); |
a0d77315 | 1721 | |
3d35e989 | 1722 | case TBM_SETRANGEMIN: |
e4ddd2ac | 1723 | return TRACKBAR_SetRangeMin (infoPtr, (BOOL)wParam, (LONG)lParam); |
a0d77315 | 1724 | |
3d35e989 | 1725 | case TBM_SETSEL: |
e4ddd2ac | 1726 | return TRACKBAR_SetSel (infoPtr, (BOOL)wParam, (LONG)lParam); |
a0d77315 | 1727 | |
3d35e989 | 1728 | case TBM_SETSELEND: |
e4ddd2ac | 1729 | return TRACKBAR_SetSelEnd (infoPtr, (BOOL)wParam, (LONG)lParam); |
a0d77315 | 1730 | |
3d35e989 | 1731 | case TBM_SETSELSTART: |
e4ddd2ac | 1732 | return TRACKBAR_SetSelStart (infoPtr, (BOOL)wParam, (LONG)lParam); |
a0d77315 | 1733 | |
3d35e989 | 1734 | case TBM_SETTHUMBLENGTH: |
e4ddd2ac | 1735 | return TRACKBAR_SetThumbLength (infoPtr, (UINT)wParam); |
a0d77315 | 1736 | |
3d35e989 | 1737 | case TBM_SETTIC: |
e4ddd2ac | 1738 | return TRACKBAR_SetTic (infoPtr, (LONG)lParam); |
a0d77315 | 1739 | |
d30dfd24 | 1740 | case TBM_SETTICFREQ: |
e4ddd2ac | 1741 | return TRACKBAR_SetTicFreq (infoPtr, (WORD)wParam); |
a0d77315 | 1742 | |
3d35e989 | 1743 | case TBM_SETTIPSIDE: |
e4ddd2ac | 1744 | return TRACKBAR_SetTipSide (infoPtr, (INT)wParam); |
a0d77315 | 1745 | |
3d35e989 | 1746 | case TBM_SETTOOLTIPS: |
e4ddd2ac | 1747 | return TRACKBAR_SetToolTips (infoPtr, (HWND)wParam); |
a0d77315 | 1748 | |
e4ddd2ac DP |
1749 | case TBM_SETUNICODEFORMAT: |
1750 | return TRACKBAR_SetUnicodeFormat (infoPtr, (BOOL)wParam); | |
a0d77315 AJ |
1751 | |
1752 | ||
3d35e989 | 1753 | case WM_CAPTURECHANGED: |
e4ddd2ac | 1754 | return TRACKBAR_CaptureChanged (infoPtr); |
a0d77315 | 1755 | |
3d35e989 | 1756 | case WM_CREATE: |
e4ddd2ac | 1757 | return TRACKBAR_Create (hwnd, (LPCREATESTRUCTW)lParam); |
a0d77315 | 1758 | |
3d35e989 | 1759 | case WM_DESTROY: |
e4ddd2ac | 1760 | return TRACKBAR_Destroy (infoPtr); |
a0d77315 | 1761 | |
73458b03 | 1762 | /* case WM_ENABLE: */ |
a0d77315 | 1763 | |
c514a781 | 1764 | case WM_ERASEBKGND: |
0c6dd5b9 | 1765 | return 0; |
a0d77315 | 1766 | |
3d35e989 LT |
1767 | case WM_GETDLGCODE: |
1768 | return DLGC_WANTARROWS; | |
a0d77315 | 1769 | |
3d35e989 | 1770 | case WM_KEYDOWN: |
e4ddd2ac | 1771 | return TRACKBAR_KeyDown (infoPtr, (INT)wParam, (DWORD)lParam); |
9a624916 | 1772 | |
3d35e989 | 1773 | case WM_KEYUP: |
e4ddd2ac | 1774 | return TRACKBAR_KeyUp (infoPtr, (INT)wParam, (DWORD)lParam); |
a0d77315 | 1775 | |
3d35e989 | 1776 | case WM_KILLFOCUS: |
e4ddd2ac | 1777 | return TRACKBAR_KillFocus (infoPtr, (HWND)wParam); |
a0d77315 | 1778 | |
3d35e989 | 1779 | case WM_LBUTTONDOWN: |
d7174979 | 1780 | return TRACKBAR_LButtonDown (infoPtr, wParam, MAKEPOINTS(lParam)); |
a0d77315 | 1781 | |
3d35e989 | 1782 | case WM_LBUTTONUP: |
d7174979 | 1783 | return TRACKBAR_LButtonUp (infoPtr, wParam, MAKEPOINTS(lParam)); |
a0d77315 | 1784 | |
3d35e989 | 1785 | case WM_MOUSEMOVE: |
d7174979 | 1786 | return TRACKBAR_MouseMove (infoPtr, wParam, MAKEPOINTS(lParam)); |
a0d77315 | 1787 | |
3d35e989 | 1788 | case WM_PAINT: |
e4ddd2ac | 1789 | return TRACKBAR_Paint (infoPtr, (HDC)wParam); |
a0d77315 | 1790 | |
3d35e989 | 1791 | case WM_SETFOCUS: |
e4ddd2ac | 1792 | return TRACKBAR_SetFocus (infoPtr, (HWND)wParam); |
a0d77315 | 1793 | |
3d35e989 | 1794 | case WM_SIZE: |
e4ddd2ac DP |
1795 | return TRACKBAR_Size (infoPtr, wParam, LOWORD(lParam), HIWORD(lParam)); |
1796 | ||
c1e3cb8d DP |
1797 | case WM_TIMER: |
1798 | return TRACKBAR_Timer (infoPtr, (INT)wParam, (TIMERPROC *)lParam); | |
a0d77315 | 1799 | |
3d35e989 | 1800 | case WM_WININICHANGE: |
e4ddd2ac | 1801 | return TRACKBAR_InitializeThumb (infoPtr); |
a0d77315 | 1802 | |
3d35e989 | 1803 | default: |
23739a33 | 1804 | if ((uMsg >= WM_USER) && (uMsg < WM_APP)) |
e4ddd2ac DP |
1805 | ERR("unknown msg %04x wp=%08x lp=%08lx\n", uMsg, wParam, lParam); |
1806 | return DefWindowProcW (hwnd, uMsg, wParam, lParam); | |
a0d77315 AJ |
1807 | } |
1808 | return 0; | |
1809 | } | |
1810 | ||
1811 | ||
e4ddd2ac | 1812 | void TRACKBAR_Register (void) |
a0d77315 | 1813 | { |
e4ddd2ac | 1814 | WNDCLASSW wndClass; |
a0d77315 | 1815 | |
e4ddd2ac | 1816 | ZeroMemory (&wndClass, sizeof(WNDCLASSW)); |
a0d77315 | 1817 | wndClass.style = CS_GLOBALCLASS; |
a3960292 | 1818 | wndClass.lpfnWndProc = (WNDPROC)TRACKBAR_WindowProc; |
a0d77315 AJ |
1819 | wndClass.cbClsExtra = 0; |
1820 | wndClass.cbWndExtra = sizeof(TRACKBAR_INFO *); | |
cf52644a | 1821 | wndClass.hCursor = LoadCursorW (0, (LPWSTR)IDC_ARROW); |
a3960292 | 1822 | wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1); |
e4ddd2ac | 1823 | wndClass.lpszClassName = TRACKBAR_CLASSW; |
9a624916 | 1824 | |
e4ddd2ac | 1825 | RegisterClassW (&wndClass); |
a0d77315 | 1826 | } |
9d8e864b EK |
1827 | |
1828 | ||
e4ddd2ac | 1829 | void TRACKBAR_Unregister (void) |
9d8e864b | 1830 | { |
d2667a4c | 1831 | UnregisterClassW (TRACKBAR_CLASSW, NULL); |
9d8e864b | 1832 | } |