ReactOS 0.4.15-dev-7958-gcd0bb1a
updown.c
Go to the documentation of this file.
1/*
2 * Updown control
3 *
4 * Copyright 1997, 2002 Dimitrie O. Paun
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include <stdlib.h>
22#include <string.h>
23#include <stdarg.h>
24#include <stdio.h>
25
26#include "windef.h"
27#include "winbase.h"
28#include "wingdi.h"
29#include "winuser.h"
30#include "winnls.h"
31#include "commctrl.h"
32#include "comctl32.h"
33#include "uxtheme.h"
34#include "vssym32.h"
35#include "wine/heap.h"
36#include "wine/unicode.h"
37#include "wine/debug.h"
38
40
41typedef struct
42{
43 HWND Self; /* Handle to this up-down control */
44 HWND Notify; /* Handle to the parent window */
45 DWORD dwStyle; /* The GWL_STYLE for this window */
46 UINT AccelCount; /* Number of elements in AccelVect */
47 UDACCEL* AccelVect; /* Vector containing AccelCount elements */
48 INT AccelIndex; /* Current accel index, -1 if not accel'ing */
49 INT Base; /* Base to display nr in the buddy window */
50 INT CurVal; /* Current up-down value */
51 INT MinVal; /* Minimum up-down value */
52 INT MaxVal; /* Maximum up-down value */
53 HWND Buddy; /* Handle to the buddy window */
54 INT BuddyType; /* Remembers the buddy type BUDDY_TYPE_* */
55 INT Flags; /* Internal Flags FLAG_* */
56 BOOL UnicodeFormat; /* Marks the use of Unicode internally */
58
59/* Control configuration constants */
60
61#define INITIAL_DELAY 500 /* initial timer until auto-inc kicks in */
62#define AUTOPRESS_DELAY 250 /* time to keep arrow pressed on KEY_DOWN */
63#define REPEAT_DELAY 50 /* delay between auto-increments */
64
65#define DEFAULT_WIDTH 16 /* default width of the ctrl */
66#define DEFAULT_XSEP 0 /* default separation between buddy and ctrl */
67#define DEFAULT_ADDTOP 0 /* amount to extend above the buddy window */
68#define DEFAULT_ADDBOT 0 /* amount to extend below the buddy window */
69#define DEFAULT_BUDDYBORDER 2 /* Width/height of the buddy border */
70#define DEFAULT_BUDDYSPACER 2 /* Spacer between the buddy and the ctrl */
71#define DEFAULT_BUDDYBORDER_THEMED 1 /* buddy border when theming is enabled */
72#define DEFAULT_BUDDYSPACER_THEMED 0 /* buddy spacer when theming is enabled */
73
74/* Work constants */
75
76#define FLAG_INCR 0x01
77#define FLAG_DECR 0x02
78#define FLAG_MOUSEIN 0x04
79#define FLAG_PRESSED 0x08
80#define FLAG_BUDDYINT 0x10 /* UDS_SETBUDDYINT was set on creation */
81#define FLAG_ARROW (FLAG_INCR | FLAG_DECR)
82
83#define BUDDY_TYPE_UNKNOWN 0
84#define BUDDY_TYPE_LISTBOX 1
85#define BUDDY_TYPE_EDIT 2
86
87#define TIMER_AUTOREPEAT 1
88#define TIMER_ACCEL 2
89#define TIMER_AUTOPRESS 3
90
91#define UPDOWN_GetInfoPtr(hwnd) ((UPDOWN_INFO *)GetWindowLongPtrW (hwnd,0))
92
93/* id used for SetWindowSubclass */
94#define BUDDY_SUBCLASSID 1
95
96static void UPDOWN_DoAction (UPDOWN_INFO *infoPtr, int delta, int action);
97
98/***********************************************************************
99 * UPDOWN_IsBuddyEdit
100 * Tests if our buddy is an edit control.
101 */
102static inline BOOL UPDOWN_IsBuddyEdit(const UPDOWN_INFO *infoPtr)
103{
104 return infoPtr->BuddyType == BUDDY_TYPE_EDIT;
105}
106
107/***********************************************************************
108 * UPDOWN_IsBuddyListbox
109 * Tests if our buddy is a listbox control.
110 */
111static inline BOOL UPDOWN_IsBuddyListbox(const UPDOWN_INFO *infoPtr)
112{
113 return infoPtr->BuddyType == BUDDY_TYPE_LISTBOX;
114}
115
116/***********************************************************************
117 * UPDOWN_InBounds
118 * Tests if a given value 'val' is between the Min&Max limits
119 */
120static BOOL UPDOWN_InBounds(const UPDOWN_INFO *infoPtr, int val)
121{
122 if(infoPtr->MaxVal > infoPtr->MinVal)
123 return (infoPtr->MinVal <= val) && (val <= infoPtr->MaxVal);
124 else
125 return (infoPtr->MaxVal <= val) && (val <= infoPtr->MinVal);
126}
127
128/***********************************************************************
129 * UPDOWN_OffsetVal
130 * Change the current value by delta.
131 * It returns TRUE is the value was changed successfully, or FALSE
132 * if the value was not changed, as it would go out of bounds.
133 */
134static BOOL UPDOWN_OffsetVal(UPDOWN_INFO *infoPtr, int delta)
135{
136 /* check if we can do the modification first */
137 if(!UPDOWN_InBounds (infoPtr, infoPtr->CurVal+delta)) {
138 if (infoPtr->dwStyle & UDS_WRAP) {
139 delta += (delta < 0 ? -1 : 1) *
140 (infoPtr->MaxVal < infoPtr->MinVal ? -1 : 1) *
141 (infoPtr->MinVal - infoPtr->MaxVal) +
142 (delta < 0 ? 1 : -1);
143 } else if ((infoPtr->MaxVal > infoPtr->MinVal && infoPtr->CurVal+delta > infoPtr->MaxVal)
144 || (infoPtr->MaxVal < infoPtr->MinVal && infoPtr->CurVal+delta < infoPtr->MaxVal)) {
145 delta = infoPtr->MaxVal - infoPtr->CurVal;
146 } else {
147 delta = infoPtr->MinVal - infoPtr->CurVal;
148 }
149 }
150
151 infoPtr->CurVal += delta;
152 return delta != 0;
153}
154
155/***********************************************************************
156 * UPDOWN_HasBuddyBorder
157 *
158 * When we have a buddy set and that we are aligned on our buddy, we
159 * want to draw a sunken edge to make like we are part of that control.
160 */
162{
163 return ( ((infoPtr->dwStyle & (UDS_ALIGNLEFT | UDS_ALIGNRIGHT)) != 0) &&
164 UPDOWN_IsBuddyEdit(infoPtr) );
165}
166
167/***********************************************************************
168 * UPDOWN_GetArrowRect
169 * wndPtr - pointer to the up-down wnd
170 * rect - will hold the rectangle
171 * arrow - FLAG_INCR to get the "increment" rect (up or right)
172 * FLAG_DECR to get the "decrement" rect (down or left)
173 * If both flags are present, the envelope is returned.
174 */
175static void UPDOWN_GetArrowRect (const UPDOWN_INFO* infoPtr, RECT *rect, int arrow)
176{
177 HTHEME theme = GetWindowTheme (infoPtr->Self);
179 const int spacer = theme ? DEFAULT_BUDDYSPACER_THEMED : DEFAULT_BUDDYSPACER;
180 GetClientRect (infoPtr->Self, rect);
181
182 /*
183 * Make sure we calculate the rectangle to fit even if we draw the
184 * border.
185 */
186 if (UPDOWN_HasBuddyBorder(infoPtr)) {
187 if (infoPtr->dwStyle & UDS_ALIGNLEFT)
188 rect->left += border;
189 else
190 rect->right -= border;
191
192 InflateRect(rect, 0, -border);
193 }
194
195 /* now figure out if we need a space away from the buddy */
196 if (IsWindow(infoPtr->Buddy) ) {
197 if (infoPtr->dwStyle & UDS_ALIGNLEFT) rect->right -= spacer;
198 else if (infoPtr->dwStyle & UDS_ALIGNRIGHT) rect->left += spacer;
199 }
200
201 /*
202 * We're calculating the midpoint to figure-out where the
203 * separation between the buttons will lay. We make sure that we
204 * round the uneven numbers by adding 1.
205 */
206 if (infoPtr->dwStyle & UDS_HORZ) {
207 int len = rect->right - rect->left + 1; /* compute the width */
208 if (arrow & FLAG_INCR)
209 rect->left = rect->left + len/2;
210 if (arrow & FLAG_DECR)
211 rect->right = rect->left + len/2 - (theme ? 0 : 1);
212 } else {
213 int len = rect->bottom - rect->top + 1; /* compute the height */
214 if (arrow & FLAG_INCR)
215 rect->bottom = rect->top + len/2 - (theme ? 0 : 1);
216 if (arrow & FLAG_DECR)
217 rect->top = rect->top + len/2;
218 }
219}
220
221/***********************************************************************
222 * UPDOWN_GetArrowFromPoint
223 * Returns the rectagle (for the up or down arrow) that contains pt.
224 * If it returns the up rect, it returns FLAG_INCR.
225 * If it returns the down rect, it returns FLAG_DECR.
226 */
228{
230 if(PtInRect(rect, pt)) return FLAG_INCR;
231
233 if(PtInRect(rect, pt)) return FLAG_DECR;
234
235 return 0;
236}
237
238
239/***********************************************************************
240 * UPDOWN_GetThousandSep
241 * Returns the thousand sep. If an error occurs, it returns ','.
242 */
244{
245 WCHAR sep[2];
246
248 sep[0] = ',';
249
250 return sep[0];
251}
252
253/***********************************************************************
254 * UPDOWN_GetBuddyInt
255 * Tries to read the pos from the buddy window and if it succeeds,
256 * it stores it in the control's CurVal
257 * returns:
258 * TRUE - if it read the integer from the buddy successfully
259 * FALSE - if an error occurred
260 */
262{
263 WCHAR txt[20], sep, *src, *dst;
264 int newVal;
265
266 if (!((infoPtr->Flags & FLAG_BUDDYINT) && IsWindow(infoPtr->Buddy)))
267 return FALSE;
268
269 /*if the buddy is a list window, we must set curr index */
270 if (UPDOWN_IsBuddyListbox(infoPtr)) {
271 newVal = SendMessageW(infoPtr->Buddy, LB_GETCARETINDEX, 0, 0);
272 if(newVal < 0) return FALSE;
273 } else {
274 /* we have a regular window, so will get the text */
275 /* note that a zero-length string is a legitimate value for 'txt',
276 * and ought to result in a successful conversion to '0'. */
277 if (GetWindowTextW(infoPtr->Buddy, txt, ARRAY_SIZE(txt)) < 0)
278 return FALSE;
279
280 sep = UPDOWN_GetThousandSep();
281
282 /* now get rid of the separators */
283 for(src = dst = txt; *src; src++)
284 if(*src != sep) *dst++ = *src;
285 *dst = 0;
286
287 /* try to convert the number and validate it */
288 newVal = strtolW(txt, &src, infoPtr->Base);
289 if(*src || !UPDOWN_InBounds (infoPtr, newVal)) return FALSE;
290 }
291
292 TRACE("new value(%d) from buddy (old=%d)\n", newVal, infoPtr->CurVal);
293 infoPtr->CurVal = newVal;
294 return TRUE;
295}
296
297
298/***********************************************************************
299 * UPDOWN_SetBuddyInt
300 * Tries to set the pos to the buddy window based on current pos
301 * returns:
302 * TRUE - if it set the caption of the buddy successfully
303 * FALSE - if an error occurred
304 */
305static BOOL UPDOWN_SetBuddyInt (const UPDOWN_INFO *infoPtr)
306{
307 static const WCHAR fmt_hex[] = { '0', 'x', '%', '0', '4', 'X', 0 };
308 static const WCHAR fmt_dec_oct[] = { '%', 'd', '\0' };
309 const WCHAR *fmt;
310 WCHAR txt[20], txt_old[20] = { 0 };
311 int len;
312
313 if (!((infoPtr->Flags & FLAG_BUDDYINT) && IsWindow(infoPtr->Buddy)))
314 return FALSE;
315
316 TRACE("set new value(%d) to buddy.\n", infoPtr->CurVal);
317
318 /*if the buddy is a list window, we must set curr index */
319 if (UPDOWN_IsBuddyListbox(infoPtr)) {
320 return SendMessageW(infoPtr->Buddy, LB_SETCURSEL, infoPtr->CurVal, 0) != LB_ERR;
321 }
322
323 /* Regular window, so set caption to the number */
324 fmt = (infoPtr->Base == 16) ? fmt_hex : fmt_dec_oct;
325 len = wsprintfW(txt, fmt, infoPtr->CurVal);
326
327
328 /* Do thousands separation if necessary */
329 if ((infoPtr->Base == 10) && !(infoPtr->dwStyle & UDS_NOTHOUSANDS) && (len > 3)) {
330 WCHAR tmp[ARRAY_SIZE(txt)], *src = tmp, *dst = txt;
332 int start = len % 3;
333
334 memcpy(tmp, txt, sizeof(txt));
335 if (start == 0) start = 3;
336 dst += start;
337 src += start;
338 for (len=0; *src; len++) {
339 if (len % 3 == 0) *dst++ = sep;
340 *dst++ = *src++;
341 }
342 *dst = 0;
343 }
344
345 /* if nothing changed exit earlier */
346 GetWindowTextW(infoPtr->Buddy, txt_old, ARRAY_SIZE(txt_old));
347 if (lstrcmpiW(txt_old, txt) == 0) return FALSE;
348
349 return SetWindowTextW(infoPtr->Buddy, txt);
350}
351
352/***********************************************************************
353 * UPDOWN_DrawBuddyBackground
354 *
355 * Draw buddy background for visual integration.
356 */
358{
359 RECT br, r;
360 HTHEME buddyTheme = GetWindowTheme (infoPtr->Buddy);
361 if (!buddyTheme) return FALSE;
362
363 GetWindowRect (infoPtr->Buddy, &br);
364 MapWindowPoints (NULL, infoPtr->Self, (POINT*)&br, 2);
365 GetClientRect (infoPtr->Self, &r);
366
367 if (infoPtr->dwStyle & UDS_ALIGNLEFT)
368 br.left = r.left;
369 else if (infoPtr->dwStyle & UDS_ALIGNRIGHT)
370 br.right = r.right;
371 /* FIXME: take disabled etc. into account */
372 DrawThemeBackground (buddyTheme, hdc, 0, 0, &br, NULL);
373 return TRUE;
374}
375
376/***********************************************************************
377 * UPDOWN_Draw
378 *
379 * Draw the arrows. The background need not be erased.
380 */
381static LRESULT UPDOWN_Draw (const UPDOWN_INFO *infoPtr, HDC hdc)
382{
383 BOOL uPressed, uHot, dPressed, dHot;
384 RECT rect;
385 HTHEME theme = GetWindowTheme (infoPtr->Self);
386 int uPart = 0, uState = 0, dPart = 0, dState = 0;
387 BOOL needBuddyBg = FALSE;
388
389 uPressed = (infoPtr->Flags & FLAG_PRESSED) && (infoPtr->Flags & FLAG_INCR);
390 uHot = (infoPtr->Flags & FLAG_INCR) && (infoPtr->Flags & FLAG_MOUSEIN);
391 dPressed = (infoPtr->Flags & FLAG_PRESSED) && (infoPtr->Flags & FLAG_DECR);
392 dHot = (infoPtr->Flags & FLAG_DECR) && (infoPtr->Flags & FLAG_MOUSEIN);
393 if (theme) {
394 uPart = (infoPtr->dwStyle & UDS_HORZ) ? SPNP_UPHORZ : SPNP_UP;
395 uState = (infoPtr->dwStyle & WS_DISABLED) ? DNS_DISABLED
396 : (uPressed ? DNS_PRESSED : (uHot ? DNS_HOT : DNS_NORMAL));
397 dPart = (infoPtr->dwStyle & UDS_HORZ) ? SPNP_DOWNHORZ : SPNP_DOWN;
398 dState = (infoPtr->dwStyle & WS_DISABLED) ? DNS_DISABLED
399 : (dPressed ? DNS_PRESSED : (dHot ? DNS_HOT : DNS_NORMAL));
400 needBuddyBg = IsWindow (infoPtr->Buddy)
401 && (IsThemeBackgroundPartiallyTransparent (theme, uPart, uState)
402 || IsThemeBackgroundPartiallyTransparent (theme, dPart, dState));
403 }
404
405 /* Draw the common border between ourselves and our buddy */
406 if (UPDOWN_HasBuddyBorder(infoPtr) || needBuddyBg) {
407 if (!theme || !UPDOWN_DrawBuddyBackground (infoPtr, hdc)) {
408 GetClientRect(infoPtr->Self, &rect);
410 BF_BOTTOM | BF_TOP |
411 (infoPtr->dwStyle & UDS_ALIGNLEFT ? BF_LEFT : BF_RIGHT));
412 }
413 }
414
415 /* Draw the incr button */
417 if (theme) {
418 DrawThemeBackground(theme, hdc, uPart, uState, &rect, NULL);
419 } else {
422 ((infoPtr->dwStyle & UDS_HOTTRACK) && uHot ? DFCS_HOT : 0) |
423 (uPressed ? DFCS_PUSHED : 0) |
424 (infoPtr->dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0) );
425 }
426
427 /* Draw the decr button */
429 if (theme) {
430 DrawThemeBackground(theme, hdc, dPart, dState, &rect, NULL);
431 } else {
434 ((infoPtr->dwStyle & UDS_HOTTRACK) && dHot ? DFCS_HOT : 0) |
435 (dPressed ? DFCS_PUSHED : 0) |
436 (infoPtr->dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0) );
437 }
438
439 return 0;
440}
441
442/***********************************************************************
443 * UPDOWN_Paint
444 *
445 * Asynchronous drawing (must ONLY be used in WM_PAINT).
446 * Calls UPDOWN_Draw.
447 */
448static LRESULT UPDOWN_Paint (const UPDOWN_INFO *infoPtr, HDC hdc)
449{
450 PAINTSTRUCT ps;
451 if (hdc) return UPDOWN_Draw (infoPtr, hdc);
452 hdc = BeginPaint (infoPtr->Self, &ps);
453 UPDOWN_Draw (infoPtr, hdc);
454 EndPaint (infoPtr->Self, &ps);
455 return 0;
456}
457
458/***********************************************************************
459 * UPDOWN_KeyPressed
460 *
461 * Handle key presses (up & down) when we have to do so
462 */
464{
465 int arrow, accel;
466
467 if (key == VK_UP) arrow = FLAG_INCR;
468 else if (key == VK_DOWN) arrow = FLAG_DECR;
469 else return 1;
470
471 UPDOWN_GetBuddyInt (infoPtr);
472 infoPtr->Flags &= ~FLAG_ARROW;
473 infoPtr->Flags |= FLAG_PRESSED | arrow;
474 InvalidateRect (infoPtr->Self, NULL, FALSE);
476 accel = (infoPtr->AccelCount && infoPtr->AccelVect) ? infoPtr->AccelVect[0].nInc : 1;
477 UPDOWN_DoAction (infoPtr, accel, arrow);
478 return 0;
479}
480
481static int UPDOWN_GetPos(UPDOWN_INFO *infoPtr, BOOL *err)
482{
483 BOOL succ = UPDOWN_GetBuddyInt(infoPtr);
484 int val = infoPtr->CurVal;
485
486 if(!UPDOWN_InBounds(infoPtr, val)) {
487 if((infoPtr->MinVal < infoPtr->MaxVal && val < infoPtr->MinVal)
488 || (infoPtr->MinVal > infoPtr->MaxVal && val > infoPtr->MinVal))
489 val = infoPtr->MinVal;
490 else
491 val = infoPtr->MaxVal;
492
493 succ = FALSE;
494 }
495
496 if(err) *err = !succ;
497 return val;
498}
499
500static int UPDOWN_SetPos(UPDOWN_INFO *infoPtr, int pos)
501{
502 int ret = infoPtr->CurVal;
503
504 if(!UPDOWN_InBounds(infoPtr, pos)) {
505 if((infoPtr->MinVal < infoPtr->MaxVal && pos < infoPtr->MinVal)
506 || (infoPtr->MinVal > infoPtr->MaxVal && pos > infoPtr->MinVal))
507 pos = infoPtr->MinVal;
508 else
509 pos = infoPtr->MaxVal;
510 }
511
512 infoPtr->CurVal = pos;
513 UPDOWN_SetBuddyInt(infoPtr);
514
515 if(!UPDOWN_InBounds(infoPtr, ret)) {
516 if((infoPtr->MinVal < infoPtr->MaxVal && ret < infoPtr->MinVal)
517 || (infoPtr->MinVal > infoPtr->MaxVal && ret > infoPtr->MinVal))
518 ret = infoPtr->MinVal;
519 else
520 ret = infoPtr->MaxVal;
521 }
522 return ret;
523}
524
525
526/***********************************************************************
527 * UPDOWN_SetRange
528 *
529 * Handle UDM_SETRANGE, UDM_SETRANGE32
530 *
531 * FIXME: handle Max == Min properly:
532 * - arrows should be disabled (without WS_DISABLED set),
533 * visually they can't be pressed and don't respond;
534 * - all input messages should still pass in.
535 */
537{
538 infoPtr->MaxVal = Max;
539 infoPtr->MinVal = Min;
540
541 TRACE("UpDown Ctrl new range(%d to %d), hwnd=%p\n",
542 infoPtr->MinVal, infoPtr->MaxVal, infoPtr->Self);
543
544 return 0;
545}
546
547/***********************************************************************
548 * UPDOWN_MouseWheel
549 *
550 * Handle mouse wheel scrolling
551 */
553{
554 int iWheelDelta = GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA;
555
556 if (wParam & (MK_SHIFT | MK_CONTROL))
557 return 0;
558
559 if (iWheelDelta != 0)
560 {
561 UPDOWN_GetBuddyInt(infoPtr);
562 UPDOWN_DoAction(infoPtr, abs(iWheelDelta), iWheelDelta > 0 ? FLAG_INCR : FLAG_DECR);
563 }
564
565 return 1;
566}
567
568
569/***********************************************************************
570 * UPDOWN_Buddy_SubclassProc used to handle messages sent to the buddy
571 * control.
572 */
573static LRESULT CALLBACK
575 UINT_PTR uId, DWORD_PTR ref_data)
576{
577 UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr((HWND)ref_data);
578
579 TRACE("hwnd=%p, uMsg=%04x, wParam=%08lx, lParam=%08lx\n",
580 hwnd, uMsg, wParam, lParam);
581
582 switch(uMsg)
583 {
584 case WM_KEYDOWN:
585 if (infoPtr)
586 {
587 UPDOWN_KeyPressed(infoPtr, (int)wParam);
588 if (wParam == VK_UP || wParam == VK_DOWN)
589 return 0;
590 }
591 break;
592
593 case WM_MOUSEWHEEL:
594 if (infoPtr)
595 UPDOWN_MouseWheel(infoPtr, (int)wParam);
596 break;
597
598 case WM_NCDESTROY:
600 break;
601 default:
602 break;
603 }
604
605 return DefSubclassProc(hwnd, uMsg, wParam, lParam);
606}
607
608static void UPDOWN_ResetSubclass (UPDOWN_INFO *infoPtr)
609{
611}
612
613/***********************************************************************
614 * UPDOWN_SetBuddy
615 *
616 * Sets bud as a new Buddy.
617 * Then, it should subclass the buddy
618 * If window has the UDS_ARROWKEYS, it subclasses the buddy window to
619 * process the UP/DOWN arrow keys.
620 * If window has the UDS_ALIGNLEFT or UDS_ALIGNRIGHT style
621 * the size/pos of the buddy and the control are adjusted accordingly.
622 */
623static HWND UPDOWN_SetBuddy (UPDOWN_INFO* infoPtr, HWND bud)
624{
625 RECT budRect; /* new coord for the buddy */
626 int x, width; /* new x position and width for the up-down */
627 WCHAR buddyClass[40];
628 HWND old_buddy;
629
630 TRACE("(hwnd=%p, bud=%p)\n", infoPtr->Self, bud);
631
632 old_buddy = infoPtr->Buddy;
633
634 UPDOWN_ResetSubclass (infoPtr);
635
636 if (!IsWindow(bud)) bud = NULL;
637
638 /* Store buddy window handle */
639 infoPtr->Buddy = bud;
640
641 if(bud) {
642 /* Store buddy window class type */
643 infoPtr->BuddyType = BUDDY_TYPE_UNKNOWN;
644 if (GetClassNameW(bud, buddyClass, ARRAY_SIZE(buddyClass))) {
645 if (lstrcmpiW(buddyClass, WC_EDITW) == 0)
646 infoPtr->BuddyType = BUDDY_TYPE_EDIT;
647 else if (lstrcmpiW(buddyClass, WC_LISTBOXW) == 0)
648 infoPtr->BuddyType = BUDDY_TYPE_LISTBOX;
649 }
650
651 if (infoPtr->dwStyle & UDS_ARROWKEYS)
653 (DWORD_PTR)infoPtr->Self);
654
655 /* Get the rect of the buddy relative to its parent */
656 GetWindowRect(infoPtr->Buddy, &budRect);
657 MapWindowPoints(HWND_DESKTOP, GetParent(infoPtr->Buddy), (POINT *)(&budRect.left), 2);
658
659 /* now do the positioning */
660 if (infoPtr->dwStyle & UDS_ALIGNLEFT) {
661 x = budRect.left;
662 budRect.left += DEFAULT_WIDTH + DEFAULT_XSEP;
663 } else if (infoPtr->dwStyle & UDS_ALIGNRIGHT) {
664 budRect.right -= DEFAULT_WIDTH + DEFAULT_XSEP;
665 x = budRect.right+DEFAULT_XSEP;
666 } else {
667 /* nothing to do */
668 return old_buddy;
669 }
670
671 /* first adjust the buddy to accommodate the up/down */
672 SetWindowPos(infoPtr->Buddy, 0, budRect.left, budRect.top,
673 budRect.right - budRect.left, budRect.bottom - budRect.top,
675
676 /* now position the up/down */
677 /* Since the UDS_ALIGN* flags were used, */
678 /* we will pick the position and size of the window. */
680
681 /*
682 * If the updown has a buddy border, it has to overlap with the buddy
683 * to look as if it is integrated with the buddy control.
684 * We nudge the control or change its size to overlap.
685 */
686 if (UPDOWN_HasBuddyBorder(infoPtr)) {
687 if(infoPtr->dwStyle & UDS_ALIGNLEFT)
689 else
691 }
692
693 SetWindowPos(infoPtr->Self, 0, x,
694 budRect.top - DEFAULT_ADDTOP, width,
695 budRect.bottom - budRect.top + DEFAULT_ADDTOP + DEFAULT_ADDBOT,
697 } else if (!(infoPtr->dwStyle & UDS_HORZ) && old_buddy != NULL) {
698 RECT rect;
699 GetWindowRect(infoPtr->Self, &rect);
701 SetWindowPos(infoPtr->Self, 0, rect.left, rect.top, DEFAULT_WIDTH, rect.bottom - rect.top,
703 }
704
705 return old_buddy;
706}
707
708/***********************************************************************
709 * UPDOWN_DoAction
710 *
711 * This function increments/decrements the CurVal by the
712 * 'delta' amount according to the 'action' flag which can be a
713 * combination of FLAG_INCR and FLAG_DECR
714 * It notifies the parent as required.
715 * It handles wrapping and non-wrapping correctly.
716 * It is assumed that delta>0
717 */
718static void UPDOWN_DoAction (UPDOWN_INFO *infoPtr, int delta, int action)
719{
721
722 TRACE("%d by %d\n", action, delta);
723
724 /* check if we can do the modification first */
725 delta *= (action & FLAG_INCR ? 1 : -1) * (infoPtr->MaxVal < infoPtr->MinVal ? -1 : 1);
726 if ( (action & FLAG_INCR) && (action & FLAG_DECR) ) delta = 0;
727
728 TRACE("current %d, delta: %d\n", infoPtr->CurVal, delta);
729
730 /* We must notify parent now to obtain permission */
731 ni.iPos = infoPtr->CurVal;
732 ni.iDelta = delta;
733 ni.hdr.hwndFrom = infoPtr->Self;
734 ni.hdr.idFrom = GetWindowLongPtrW (infoPtr->Self, GWLP_ID);
735 ni.hdr.code = UDN_DELTAPOS;
736 if (!SendMessageW(infoPtr->Notify, WM_NOTIFY, ni.hdr.idFrom, (LPARAM)&ni)) {
737 /* Parent said: OK to adjust */
738
739 /* Now adjust value with (maybe new) delta */
740 if (UPDOWN_OffsetVal (infoPtr, ni.iDelta)) {
741 TRACE("new %d, delta: %d\n", infoPtr->CurVal, ni.iDelta);
742
743 /* Now take care about our buddy */
744 UPDOWN_SetBuddyInt (infoPtr);
745 }
746 }
747
748 /* Also, notify it. This message is sent in any case. */
749 SendMessageW( infoPtr->Notify, (infoPtr->dwStyle & UDS_HORZ) ? WM_HSCROLL : WM_VSCROLL,
750 MAKELONG(SB_THUMBPOSITION, infoPtr->CurVal), (LPARAM)infoPtr->Self);
751}
752
753/***********************************************************************
754 * UPDOWN_IsEnabled
755 *
756 * Returns TRUE if it is enabled as well as its buddy (if any)
757 * FALSE otherwise
758 */
759static BOOL UPDOWN_IsEnabled (const UPDOWN_INFO *infoPtr)
760{
761 if (!IsWindowEnabled(infoPtr->Self))
762 return FALSE;
763 if(infoPtr->Buddy)
764 return IsWindowEnabled(infoPtr->Buddy);
765 return TRUE;
766}
767
768/***********************************************************************
769 * UPDOWN_CancelMode
770 *
771 * Deletes any timers, releases the mouse and does redraw if necessary.
772 * If the control is not in "capture" mode, it does nothing.
773 * If the control was not in cancel mode, it returns FALSE.
774 * If the control was in cancel mode, it returns TRUE.
775 */
777{
778 if (!(infoPtr->Flags & FLAG_PRESSED)) return FALSE;
779
780 KillTimer (infoPtr->Self, TIMER_AUTOREPEAT);
781 KillTimer (infoPtr->Self, TIMER_ACCEL);
782 KillTimer (infoPtr->Self, TIMER_AUTOPRESS);
783
784 if (GetCapture() == infoPtr->Self)
786
787 infoPtr->Flags &= ~FLAG_PRESSED;
788 InvalidateRect (infoPtr->Self, NULL, FALSE);
789
790 return TRUE;
791}
792
793/***********************************************************************
794 * UPDOWN_HandleMouseEvent
795 *
796 * Handle a mouse event for the updown.
797 * 'pt' is the location of the mouse event in client or
798 * windows coordinates.
799 */
801{
802 POINT pt = { x, y };
803 RECT rect;
804 int temp, arrow;
805 TRACKMOUSEEVENT tme;
806
807 TRACE("msg %04x point %s\n", msg, wine_dbgstr_point(&pt));
808
809 switch(msg)
810 {
811 case WM_LBUTTONDOWN: /* Initialise mouse tracking */
812
813 /* If the buddy is an edit, will set focus to it */
814 if (UPDOWN_IsBuddyEdit(infoPtr)) SetFocus(infoPtr->Buddy);
815
816 /* Now see which one is the 'active' arrow */
817 arrow = UPDOWN_GetArrowFromPoint (infoPtr, &rect, pt);
818
819 /* Update the flags if we are in/out */
820 infoPtr->Flags &= ~(FLAG_MOUSEIN | FLAG_ARROW);
821 if (arrow)
822 infoPtr->Flags |= FLAG_MOUSEIN | arrow;
823 else
824 if (infoPtr->AccelIndex != -1) infoPtr->AccelIndex = 0;
825
826 if (infoPtr->Flags & FLAG_ARROW) {
827
828 /* Update the CurVal if necessary */
829 UPDOWN_GetBuddyInt (infoPtr);
830
831 /* Set up the correct flags */
832 infoPtr->Flags |= FLAG_PRESSED;
833
834 /* repaint the control */
835 InvalidateRect (infoPtr->Self, NULL, FALSE);
836
837 /* process the click */
838 temp = (infoPtr->AccelCount && infoPtr->AccelVect) ? infoPtr->AccelVect[0].nInc : 1;
839 UPDOWN_DoAction (infoPtr, temp, infoPtr->Flags & FLAG_ARROW);
840
841 /* now capture all mouse messages */
842 SetCapture (infoPtr->Self);
843
844 /* and startup the first timer */
846 }
847 break;
848
849 case WM_MOUSEMOVE:
850 /* save the flags to see if any got modified */
851 temp = infoPtr->Flags;
852
853 /* Now see which one is the 'active' arrow */
854 arrow = UPDOWN_GetArrowFromPoint (infoPtr, &rect, pt);
855
856 /* Update the flags if we are in/out */
857 infoPtr->Flags &= ~(FLAG_MOUSEIN | FLAG_ARROW);
858 if(arrow) {
859 infoPtr->Flags |= FLAG_MOUSEIN | arrow;
860 } else {
861 if(infoPtr->AccelIndex != -1) infoPtr->AccelIndex = 0;
862 }
863
864 /* If state changed, redraw the control */
865 if(temp != infoPtr->Flags)
866 InvalidateRect (infoPtr->Self, NULL, FALSE);
867
868 /* Set up tracking so the mousein flags can be reset when the
869 * mouse leaves the control */
870 tme.cbSize = sizeof( tme );
871 tme.dwFlags = TME_LEAVE;
872 tme.hwndTrack = infoPtr->Self;
873 TrackMouseEvent (&tme);
874
875 break;
876 case WM_MOUSELEAVE:
877 infoPtr->Flags &= ~(FLAG_MOUSEIN | FLAG_ARROW);
878 InvalidateRect (infoPtr->Self, NULL, FALSE);
879 break;
880
881 default:
882 ERR("Impossible case (msg=%x)!\n", msg);
883 }
884
885}
886
887/***********************************************************************
888 * UpDownWndProc
889 */
891{
893 static const WCHAR themeClass[] = {'S','p','i','n',0};
894 HTHEME theme;
895
896 TRACE("hwnd=%p msg=%04x wparam=%08lx lparam=%08lx\n", hwnd, message, wParam, lParam);
897
898 if (!infoPtr && (message != WM_CREATE))
900
901 switch(message)
902 {
903 case WM_CREATE:
904 {
906
907 infoPtr = heap_alloc_zero(sizeof(*infoPtr));
908 SetWindowLongPtrW (hwnd, 0, (DWORD_PTR)infoPtr);
909
910 /* initialize the info struct */
911 infoPtr->Self = hwnd;
912 infoPtr->Notify = pcs->hwndParent;
913 infoPtr->dwStyle = pcs->style;
914 infoPtr->AccelCount = 0;
915 infoPtr->AccelVect = 0;
916 infoPtr->AccelIndex = -1;
917 infoPtr->CurVal = 0;
918 infoPtr->MinVal = 100;
919 infoPtr->MaxVal = 0;
920 infoPtr->Base = 10; /* Default to base 10 */
921 infoPtr->Buddy = 0; /* No buddy window yet */
922 infoPtr->Flags = (infoPtr->dwStyle & UDS_SETBUDDYINT) ? FLAG_BUDDYINT : 0;
923
924 SetWindowLongW (hwnd, GWL_STYLE, infoPtr->dwStyle & ~WS_BORDER);
925 if (!(infoPtr->dwStyle & UDS_HORZ))
926 SetWindowPos (hwnd, NULL, 0, 0, DEFAULT_WIDTH, pcs->cy,
928
929 /* Do we pick the buddy win ourselves? */
930 if (infoPtr->dwStyle & UDS_AUTOBUDDY)
932
934
935 TRACE("UpDown Ctrl creation, hwnd=%p\n", hwnd);
936 }
937 break;
938
939 case WM_DESTROY:
940 heap_free (infoPtr->AccelVect);
941 UPDOWN_ResetSubclass (infoPtr);
942 heap_free (infoPtr);
943 SetWindowLongPtrW (hwnd, 0, 0);
944 theme = GetWindowTheme (hwnd);
945 CloseThemeData (theme);
946 TRACE("UpDown Ctrl destruction, hwnd=%p\n", hwnd);
947 break;
948
949 case WM_ENABLE:
950 if (wParam) {
951 infoPtr->dwStyle &= ~WS_DISABLED;
952 } else {
953 infoPtr->dwStyle |= WS_DISABLED;
954 UPDOWN_CancelMode (infoPtr);
955 }
956 InvalidateRect (infoPtr->Self, NULL, FALSE);
957 break;
958
959 case WM_STYLECHANGED:
960 if (wParam == GWL_STYLE) {
961 infoPtr->dwStyle = ((LPSTYLESTRUCT)lParam)->styleNew;
962 InvalidateRect (infoPtr->Self, NULL, FALSE);
963 }
964 break;
965
966 case WM_THEMECHANGED:
967 theme = GetWindowTheme (hwnd);
968 CloseThemeData (theme);
971 break;
972
973 case WM_TIMER:
974 /* is this the auto-press timer? */
975 if(wParam == TIMER_AUTOPRESS) {
977 infoPtr->Flags &= ~(FLAG_PRESSED | FLAG_ARROW);
978 InvalidateRect(infoPtr->Self, NULL, FALSE);
979 }
980
981 /* if initial timer, kill it and start the repeat timer */
982 if(wParam == TIMER_AUTOREPEAT) {
983 INT delay;
984
986 /* if no accel info given, used default timer */
987 if(infoPtr->AccelCount==0 || infoPtr->AccelVect==0) {
988 infoPtr->AccelIndex = -1;
989 delay = REPEAT_DELAY;
990 } else {
991 infoPtr->AccelIndex = 0; /* otherwise, use it */
992 delay = infoPtr->AccelVect[infoPtr->AccelIndex].nSec * 1000 + 1;
993 }
994 SetTimer(hwnd, TIMER_ACCEL, delay, 0);
995 }
996
997 /* now, if the mouse is above us, do the thing...*/
998 if(infoPtr->Flags & FLAG_MOUSEIN) {
999 int temp;
1000
1001 temp = infoPtr->AccelIndex == -1 ? 1 : infoPtr->AccelVect[infoPtr->AccelIndex].nInc;
1002 UPDOWN_DoAction(infoPtr, temp, infoPtr->Flags & FLAG_ARROW);
1003
1004 if(infoPtr->AccelIndex != -1 && infoPtr->AccelIndex < infoPtr->AccelCount-1) {
1006 infoPtr->AccelIndex++; /* move to the next accel info */
1007 temp = infoPtr->AccelVect[infoPtr->AccelIndex].nSec * 1000 + 1;
1008 /* make sure we have at least 1ms intervals */
1010 }
1011 }
1012 break;
1013
1014 case WM_CANCELMODE:
1015 return UPDOWN_CancelMode (infoPtr);
1016
1017 case WM_LBUTTONUP:
1018 if (GetCapture() != infoPtr->Self) break;
1019
1020 if ( (infoPtr->Flags & FLAG_MOUSEIN) &&
1021 (infoPtr->Flags & FLAG_ARROW) ) {
1022
1023 SendMessageW( infoPtr->Notify,
1024 (infoPtr->dwStyle & UDS_HORZ) ? WM_HSCROLL : WM_VSCROLL,
1025 MAKELONG(SB_ENDSCROLL, infoPtr->CurVal),
1026 (LPARAM)hwnd);
1027 if (UPDOWN_IsBuddyEdit(infoPtr))
1028 SendMessageW(infoPtr->Buddy, EM_SETSEL, 0, MAKELONG(0, -1));
1029 }
1030 UPDOWN_CancelMode(infoPtr);
1031 break;
1032
1033 case WM_LBUTTONDOWN:
1034 case WM_MOUSEMOVE:
1035 case WM_MOUSELEAVE:
1036 if(UPDOWN_IsEnabled(infoPtr))
1038 break;
1039
1040 case WM_MOUSEWHEEL:
1041 UPDOWN_MouseWheel(infoPtr, wParam);
1042 break;
1043
1044 case WM_KEYDOWN:
1045 if((infoPtr->dwStyle & UDS_ARROWKEYS) && UPDOWN_IsEnabled(infoPtr))
1046 return UPDOWN_KeyPressed(infoPtr, (int)wParam);
1047 break;
1048
1049 case WM_PRINTCLIENT:
1050 case WM_PAINT:
1051 return UPDOWN_Paint (infoPtr, (HDC)wParam);
1052
1053 case UDM_GETACCEL:
1054 if (wParam==0 && lParam==0) return infoPtr->AccelCount;
1055 if (wParam && lParam) {
1056 int temp = min(infoPtr->AccelCount, wParam);
1057 memcpy((void *)lParam, infoPtr->AccelVect, temp*sizeof(UDACCEL));
1058 return temp;
1059 }
1060 return 0;
1061
1062 case UDM_SETACCEL:
1063 {
1064 TRACE("UDM_SETACCEL\n");
1065
1066 if(infoPtr->AccelVect) {
1067 heap_free (infoPtr->AccelVect);
1068 infoPtr->AccelCount = 0;
1069 infoPtr->AccelVect = 0;
1070 }
1071 if(wParam==0) return TRUE;
1072 infoPtr->AccelVect = heap_alloc(wParam*sizeof(UDACCEL));
1073 if(!infoPtr->AccelVect) return FALSE;
1074 memcpy(infoPtr->AccelVect, (void*)lParam, wParam*sizeof(UDACCEL));
1075 infoPtr->AccelCount = wParam;
1076
1077 if (TRACE_ON(updown))
1078 {
1079 UINT i;
1080
1081 for (i = 0; i < wParam; i++)
1082 TRACE("%u: nSec %u nInc %u\n", i,
1083 infoPtr->AccelVect[i].nSec, infoPtr->AccelVect[i].nInc);
1084 }
1085
1086 return TRUE;
1087 }
1088 case UDM_GETBASE:
1089 return infoPtr->Base;
1090
1091 case UDM_SETBASE:
1092 TRACE("UpDown Ctrl new base(%ld), hwnd=%p\n", wParam, hwnd);
1093 if (wParam==10 || wParam==16) {
1094 WPARAM old_base = infoPtr->Base;
1095 infoPtr->Base = wParam;
1096
1097 if (old_base != infoPtr->Base)
1098 UPDOWN_SetBuddyInt(infoPtr);
1099
1100 return old_base;
1101 }
1102 break;
1103
1104 case UDM_GETBUDDY:
1105 return (LRESULT)infoPtr->Buddy;
1106
1107 case UDM_SETBUDDY:
1108 return (LRESULT)UPDOWN_SetBuddy (infoPtr, (HWND)wParam);
1109
1110 case UDM_GETPOS:
1111 {
1112 BOOL err;
1113 int pos;
1114
1115 pos = UPDOWN_GetPos(infoPtr, &err);
1116 return MAKELONG(pos, err);
1117 }
1118 case UDM_SETPOS:
1119 {
1120 return UPDOWN_SetPos(infoPtr, (short)LOWORD(lParam));
1121 }
1122 case UDM_GETRANGE:
1123 return MAKELONG(infoPtr->MaxVal, infoPtr->MinVal);
1124
1125 case UDM_SETRANGE:
1126 /* we must have:
1127 UD_MINVAL <= Max <= UD_MAXVAL
1128 UD_MINVAL <= Min <= UD_MAXVAL
1129 |Max-Min| <= UD_MAXVAL */
1130 UPDOWN_SetRange(infoPtr, (short)lParam, (short)HIWORD(lParam));
1131 break;
1132
1133 case UDM_GETRANGE32:
1134 if (wParam) *(LPINT)wParam = infoPtr->MinVal;
1135 if (lParam) *(LPINT)lParam = infoPtr->MaxVal;
1136 break;
1137
1138 case UDM_SETRANGE32:
1139 UPDOWN_SetRange(infoPtr, (INT)lParam, (INT)wParam);
1140 break;
1141
1142 case UDM_GETPOS32:
1143 {
1144 return UPDOWN_GetPos(infoPtr, (BOOL*)lParam);
1145 }
1146 case UDM_SETPOS32:
1147 {
1148 return UPDOWN_SetPos(infoPtr, (int)lParam);
1149 }
1151 /* we lie a bit here, we're always using Unicode internally */
1152 return infoPtr->UnicodeFormat;
1153
1155 {
1156 /* do we really need to honour this flag? */
1157 int temp = infoPtr->UnicodeFormat;
1158 infoPtr->UnicodeFormat = (BOOL)wParam;
1159 return temp;
1160 }
1161 default:
1163 ERR("unknown msg %04x wp=%04lx lp=%08lx\n", message, wParam, lParam);
1165 }
1166
1167 return 0;
1168}
1169
1170/***********************************************************************
1171 * UPDOWN_Register [Internal]
1172 *
1173 * Registers the updown window class.
1174 */
1176{
1177 WNDCLASSW wndClass;
1178
1179 ZeroMemory( &wndClass, sizeof( WNDCLASSW ) );
1181 wndClass.lpfnWndProc = UpDownWindowProc;
1182 wndClass.cbClsExtra = 0;
1183 wndClass.cbWndExtra = sizeof(UPDOWN_INFO*);
1184 wndClass.hCursor = LoadCursorW( 0, (LPWSTR)IDC_ARROW );
1185 wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
1186 wndClass.lpszClassName = UPDOWN_CLASSW;
1187
1188 RegisterClassW( &wndClass );
1189}
1190
1191
1192/***********************************************************************
1193 * UPDOWN_Unregister [Internal]
1194 *
1195 * Unregisters the updown window class.
1196 */
1198{
1200}
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
static const char * wine_dbgstr_point(const POINT *ppt)
Definition: atltest.h:138
#define msg(x)
Definition: auth_time.c:54
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ARRAY_SIZE(A)
Definition: main.h:33
#define ERR(fmt,...)
Definition: debug.h:110
#define Max(a, b)
Definition: cdprocs.h:78
#define Min(a, b)
Definition: cdprocs.h:74
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
BOOL COMCTL32_IsReflectedMessage(UINT uMsg) DECLSPEC_HIDDEN
Definition: commctrl.c:1748
BOOL WINAPI SetWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR uIDSubclass, DWORD_PTR dwRef)
Definition: commctrl.c:1261
BOOL WINAPI RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR uID)
Definition: commctrl.c:1390
LRESULT WINAPI DefSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: commctrl.c:1496
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static const WCHAR themeClass[]
Definition: header.c:115
static WCHAR UPDOWN_GetThousandSep(void)
Definition: updown.c:243
static void UPDOWN_DoAction(UPDOWN_INFO *infoPtr, int delta, int action)
Definition: updown.c:718
#define FLAG_BUDDYINT
Definition: updown.c:80
#define TIMER_AUTOREPEAT
Definition: updown.c:87
static void UPDOWN_HandleMouseEvent(UPDOWN_INFO *infoPtr, UINT msg, INT x, INT y)
Definition: updown.c:800
#define BUDDY_TYPE_UNKNOWN
Definition: updown.c:83
static BOOL UPDOWN_DrawBuddyBackground(const UPDOWN_INFO *infoPtr, HDC hdc)
Definition: updown.c:357
static LRESULT CALLBACK UPDOWN_Buddy_SubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uId, DWORD_PTR ref_data)
Definition: updown.c:574
#define DEFAULT_BUDDYBORDER_THEMED
Definition: updown.c:71
#define FLAG_PRESSED
Definition: updown.c:79
#define DEFAULT_XSEP
Definition: updown.c:66
static int UPDOWN_SetPos(UPDOWN_INFO *infoPtr, int pos)
Definition: updown.c:500
#define REPEAT_DELAY
Definition: updown.c:63
#define TIMER_ACCEL
Definition: updown.c:88
static void UPDOWN_ResetSubclass(UPDOWN_INFO *infoPtr)
Definition: updown.c:608
#define DEFAULT_BUDDYSPACER_THEMED
Definition: updown.c:72
static BOOL UPDOWN_CancelMode(UPDOWN_INFO *infoPtr)
Definition: updown.c:776
#define TIMER_AUTOPRESS
Definition: updown.c:89
#define DEFAULT_ADDBOT
Definition: updown.c:68
static INT UPDOWN_GetArrowFromPoint(const UPDOWN_INFO *infoPtr, RECT *rect, POINT pt)
Definition: updown.c:227
static HWND UPDOWN_SetBuddy(UPDOWN_INFO *infoPtr, HWND bud)
Definition: updown.c:623
static LRESULT UPDOWN_Draw(const UPDOWN_INFO *infoPtr, HDC hdc)
Definition: updown.c:381
#define FLAG_DECR
Definition: updown.c:77
#define INITIAL_DELAY
Definition: updown.c:61
static BOOL UPDOWN_GetBuddyInt(UPDOWN_INFO *infoPtr)
Definition: updown.c:261
#define BUDDY_TYPE_EDIT
Definition: updown.c:85
static BOOL UPDOWN_IsBuddyListbox(const UPDOWN_INFO *infoPtr)
Definition: updown.c:111
void UPDOWN_Unregister(void)
Definition: updown.c:1197
#define DEFAULT_ADDTOP
Definition: updown.c:67
static void UPDOWN_GetArrowRect(const UPDOWN_INFO *infoPtr, RECT *rect, int arrow)
Definition: updown.c:175
#define DEFAULT_WIDTH
Definition: updown.c:65
#define FLAG_ARROW
Definition: updown.c:81
static LRESULT UPDOWN_KeyPressed(UPDOWN_INFO *infoPtr, int key)
Definition: updown.c:463
#define DEFAULT_BUDDYBORDER
Definition: updown.c:69
#define AUTOPRESS_DELAY
Definition: updown.c:62
static int UPDOWN_GetPos(UPDOWN_INFO *infoPtr, BOOL *err)
Definition: updown.c:481
static BOOL UPDOWN_IsEnabled(const UPDOWN_INFO *infoPtr)
Definition: updown.c:759
void UPDOWN_Register(void)
Definition: updown.c:1175
static LRESULT UPDOWN_Paint(const UPDOWN_INFO *infoPtr, HDC hdc)
Definition: updown.c:448
static BOOL UPDOWN_HasBuddyBorder(const UPDOWN_INFO *infoPtr)
Definition: updown.c:161
#define DEFAULT_BUDDYSPACER
Definition: updown.c:70
#define FLAG_INCR
Definition: updown.c:76
static BOOL UPDOWN_InBounds(const UPDOWN_INFO *infoPtr, int val)
Definition: updown.c:120
static BOOL UPDOWN_OffsetVal(UPDOWN_INFO *infoPtr, int delta)
Definition: updown.c:134
#define BUDDY_SUBCLASSID
Definition: updown.c:94
static LRESULT UPDOWN_SetRange(UPDOWN_INFO *infoPtr, INT Max, INT Min)
Definition: updown.c:536
static BOOL UPDOWN_IsBuddyEdit(const UPDOWN_INFO *infoPtr)
Definition: updown.c:102
static LRESULT UPDOWN_MouseWheel(UPDOWN_INFO *infoPtr, WPARAM wParam)
Definition: updown.c:552
#define UPDOWN_GetInfoPtr(hwnd)
Definition: updown.c:91
#define FLAG_MOUSEIN
Definition: updown.c:78
static LRESULT WINAPI UpDownWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: updown.c:890
#define BUDDY_TYPE_LISTBOX
Definition: updown.c:84
static BOOL UPDOWN_SetBuddyInt(const UPDOWN_INFO *infoPtr)
Definition: updown.c:305
#define TRACE_ON(x)
Definition: compat.h:75
#define CALLBACK
Definition: compat.h:35
const WCHAR * action
Definition: action.c:7479
HRESULT WINAPI DrawThemeBackground(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect)
Definition: draw.c:128
BOOL WINAPI IsThemeBackgroundPartiallyTransparent(HTHEME hTheme, int iPartId, int iStateId)
Definition: draw.c:1883
HTHEME WINAPI OpenThemeData(HWND hwnd, LPCWSTR classlist)
Definition: system.c:835
HTHEME WINAPI GetWindowTheme(HWND hwnd)
Definition: system.c:851
HRESULT WINAPI CloseThemeData(HTHEME hTheme)
Definition: system.c:950
#define pt(x, y)
Definition: drawing.c:79
#define WM_APP
Definition: eventvwr.h:73
#define abs(i)
Definition: fconv.c:206
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
static struct netconfig_info ni
Definition: getnetconfig.c:158
GLint GLint GLsizei GLsizei GLsizei GLint border
Definition: gl.h:1546
GLuint start
Definition: gl.h:1545
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLint GLint GLsizei width
Definition: gl.h:1546
GLenum src
Definition: glext.h:6340
GLenum GLenum dst
Definition: glext.h:6340
GLuint GLfloat * val
Definition: glext.h:7180
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: lang.c:1108
if(dx< 0)
Definition: linetemp.h:194
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
HDC hdc
Definition: main.c:9
static HDC
Definition: imagelist.c:92
static HTHEME(WINAPI *pOpenThemeDataEx)(HWND
#define min(a, b)
Definition: monoChain.cc:55
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
unsigned int UINT
Definition: ndis.h:50
#define BOOL
Definition: nt_native.h:43
#define LOCALE_USER_DEFAULT
#define LOWORD(l)
Definition: pedump.c:82
#define WS_BORDER
Definition: pedump.c:625
short SHORT
Definition: pedump.c:59
#define WS_DISABLED
Definition: pedump.c:621
#define INT
Definition: polytest.cpp:20
#define UPDOWN_CLASSW
Definition: commctrl.h:2119
#define TME_LEAVE
Definition: commctrl.h:4981
#define UDM_SETACCEL
Definition: commctrl.h:2147
#define UDM_GETBUDDY
Definition: commctrl.h:2146
#define UDS_AUTOBUDDY
Definition: commctrl.h:2135
#define UDS_ALIGNLEFT
Definition: commctrl.h:2134
#define UDS_SETBUDDYINT
Definition: commctrl.h:2132
#define WC_EDITW
Definition: commctrl.h:4687
#define UDM_SETPOS
Definition: commctrl.h:2143
#define UDS_HOTTRACK
Definition: commctrl.h:2139
#define NM_UPDOWN
Definition: commctrl.h:2160
#define UDM_GETUNICODEFORMAT
Definition: commctrl.h:2154
#define UDM_GETACCEL
Definition: commctrl.h:2148
#define UDS_NOTHOUSANDS
Definition: commctrl.h:2138
#define UDM_SETRANGE
Definition: commctrl.h:2141
#define UDM_GETRANGE
Definition: commctrl.h:2142
#define UDS_ARROWKEYS
Definition: commctrl.h:2136
#define UDS_WRAP
Definition: commctrl.h:2131
#define UDM_SETBASE
Definition: commctrl.h:2149
#define WM_MOUSELEAVE
Definition: commctrl.h:4975
#define UDM_GETBASE
Definition: commctrl.h:2150
#define UDM_SETBUDDY
Definition: commctrl.h:2145
#define UDS_HORZ
Definition: commctrl.h:2137
#define UDM_SETUNICODEFORMAT
Definition: commctrl.h:2153
#define UDM_GETRANGE32
Definition: commctrl.h:2152
#define UDM_SETRANGE32
Definition: commctrl.h:2151
#define UDM_GETPOS
Definition: commctrl.h:2144
#define UDM_GETPOS32
Definition: commctrl.h:2156
#define UDN_DELTAPOS
Definition: commctrl.h:2169
#define UDS_ALIGNRIGHT
Definition: commctrl.h:2133
#define WC_LISTBOXW
Definition: commctrl.h:4711
#define UDM_SETPOS32
Definition: commctrl.h:2155
#define strtolW(s, e, b)
Definition: unicode.h:33
#define err(...)
#define WM_PRINTCLIENT
Definition: richedit.h:70
#define WM_NOTIFY
Definition: richedit.h:61
static calc_node_t temp
Definition: rpn_ieee.c:38
#define TRACE(s)
Definition: solgame.cpp:4
& rect
Definition: startmenu.cpp:1413
HWND Self
Definition: updown.c:43
UINT AccelCount
Definition: updown.c:46
HWND Buddy
Definition: updown.c:53
INT MaxVal
Definition: updown.c:52
DWORD dwStyle
Definition: updown.c:45
HWND Notify
Definition: updown.c:44
UDACCEL * AccelVect
Definition: updown.c:47
INT AccelIndex
Definition: updown.c:48
INT MinVal
Definition: updown.c:51
BOOL UnicodeFormat
Definition: updown.c:56
INT Base
Definition: updown.c:49
INT Flags
Definition: updown.c:55
INT BuddyType
Definition: updown.c:54
INT CurVal
Definition: updown.c:50
UINT nInc
Definition: commctrl.h:2125
UINT nSec
Definition: commctrl.h:2124
LPCWSTR lpszClassName
Definition: winuser.h:3185
HBRUSH hbrBackground
Definition: winuser.h:3183
int cbClsExtra
Definition: winuser.h:3178
UINT style
Definition: winuser.h:3176
WNDPROC lpfnWndProc
Definition: winuser.h:3177
int cbWndExtra
Definition: winuser.h:3179
HCURSOR hCursor
Definition: winuser.h:3182
Definition: dsound.c:943
Definition: copy.c:22
Definition: tftpd.h:60
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306
#define WHEEL_DELTA
Definition: treelist.c:99
#define WM_MOUSEWHEEL
Definition: treelist.c:96
uint32_t DWORD_PTR
Definition: typedefs.h:65
int32_t INT
Definition: typedefs.h:58
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define HIWORD(l)
Definition: typedefs.h:247
@ SPNP_UPHORZ
Definition: vsstyle.h:1151
@ SPNP_DOWNHORZ
Definition: vsstyle.h:1152
@ SPNP_DOWN
Definition: vsstyle.h:1150
@ SPNP_UP
Definition: vsstyle.h:1149
@ DNS_DISABLED
Definition: vsstyle.h:1168
@ DNS_NORMAL
Definition: vsstyle.h:1165
@ DNS_HOT
Definition: vsstyle.h:1166
@ DNS_PRESSED
Definition: vsstyle.h:1167
int ret
int WINAPI GetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount)
Definition: window.c:1412
#define ZeroMemory
Definition: winbase.h:1712
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
int * LPINT
Definition: windef.h:178
#define WINAPI
Definition: msvc.h:6
#define LOCALE_STHOUSAND
Definition: winnls.h:43
#define WM_PAINT
Definition: winuser.h:1620
#define LB_ERR
Definition: winuser.h:2432
HWND WINAPI SetCapture(_In_ HWND hWnd)
#define CS_VREDRAW
Definition: winuser.h:658
BOOL WINAPI IsWindow(_In_opt_ HWND)
#define MK_SHIFT
Definition: winuser.h:2369
#define SWP_NOACTIVATE
Definition: winuser.h:1242
#define DFC_SCROLL
Definition: winuser.h:475
#define GetWindowLongPtrW
Definition: winuser.h:4829
#define WM_ENABLE
Definition: winuser.h:1615
#define WM_HSCROLL
Definition: winuser.h:1743
#define SWP_FRAMECHANGED
Definition: winuser.h:1240
#define EDGE_SUNKEN
Definition: winuser.h:451
BOOL WINAPI ReleaseCapture(void)
Definition: message.c:2890
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define WM_VSCROLL
Definition: winuser.h:1744
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
#define WM_CREATE
Definition: winuser.h:1608
BOOL WINAPI DrawFrameControl(_In_ HDC, _Inout_ LPRECT, _In_ UINT, _In_ UINT)
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
LONG WINAPI SetWindowLongW(_In_ HWND, _In_ int, _In_ LONG)
#define WM_CANCELMODE
Definition: winuser.h:1635
#define SWP_NOMOVE
Definition: winuser.h:1244
#define CS_HREDRAW
Definition: winuser.h:653
#define DFCS_INACTIVE
Definition: winuser.h:502
ATOM WINAPI RegisterClassW(_In_ CONST WNDCLASSW *)
#define BF_LEFT
Definition: winuser.h:454
#define IDC_ARROW
Definition: winuser.h:687
#define VK_UP
Definition: winuser.h:2225
#define WM_MOUSEMOVE
Definition: winuser.h:1775
HWND WINAPI GetCapture(void)
Definition: message.c:2881
BOOL WINAPI TrackMouseEvent(_Inout_ LPTRACKMOUSEEVENT)
#define BF_BOTTOM
Definition: winuser.h:457
#define WM_LBUTTONDOWN
Definition: winuser.h:1776
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2105
#define DFCS_SCROLLUP
Definition: winuser.h:489
int WINAPI MapWindowPoints(_In_opt_ HWND hWndFrom, _In_opt_ HWND hWndTo, _Inout_updates_(cPoints) LPPOINT lpPoints, _In_ UINT cPoints)
UINT_PTR WINAPI SetTimer(_In_opt_ HWND, _In_ UINT_PTR, _In_ UINT, _In_opt_ TIMERPROC)
#define HWND_DESKTOP
Definition: winuser.h:1209
BOOL WINAPI SetWindowTextW(_In_ HWND, _In_opt_ LPCWSTR)
struct tagSTYLESTRUCT * LPSTYLESTRUCT
BOOL WINAPI PtInRect(_In_ LPCRECT, _In_ POINT)
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
BOOL WINAPI DrawEdge(_In_ HDC, _Inout_ LPRECT, _In_ UINT, _In_ UINT)
HWND WINAPI SetFocus(_In_opt_ HWND)
#define MK_CONTROL
Definition: winuser.h:2370
#define BF_TOP
Definition: winuser.h:455
#define WM_TIMER
Definition: winuser.h:1742
BOOL WINAPI EndPaint(_In_ HWND, _In_ const PAINTSTRUCT *)
#define BF_RIGHT
Definition: winuser.h:456
#define EM_SETSEL
Definition: winuser.h:2018
#define WM_LBUTTONUP
Definition: winuser.h:1777
BOOL WINAPI IsWindowEnabled(_In_ HWND)
HWND WINAPI GetParent(_In_ HWND)
#define CS_GLOBALCLASS
Definition: winuser.h:652
HWND WINAPI GetWindow(_In_ HWND, _In_ UINT)
#define WM_NCDESTROY
Definition: winuser.h:1684
int WINAPI GetClassNameW(_In_ HWND hWnd, _Out_writes_to_(nMaxCount, return) LPWSTR lpClassName, _In_ int nMaxCount)
#define VK_DOWN
Definition: winuser.h:2227
#define LB_GETCARETINDEX
Definition: winuser.h:2037
#define GWLP_ID
Definition: winuser.h:860
#define SWP_NOOWNERZORDER
Definition: winuser.h:1249
#define WM_USER
Definition: winuser.h:1895
#define SB_ENDSCROLL
Definition: winuser.h:574
#define GW_HWNDPREV
Definition: winuser.h:762
#define WM_DESTROY
Definition: winuser.h:1609
BOOL WINAPI UnregisterClassW(_In_ LPCWSTR, HINSTANCE)
#define LB_SETCURSEL
Definition: winuser.h:2063
#define WM_KEYDOWN
Definition: winuser.h:1715
#define DFCS_SCROLLLEFT
Definition: winuser.h:491
#define DFCS_SCROLLRIGHT
Definition: winuser.h:492
BOOL WINAPI InvalidateRect(_In_opt_ HWND, _In_opt_ LPCRECT, _In_ BOOL)
#define DFCS_SCROLLDOWN
Definition: winuser.h:490
#define SWP_NOZORDER
Definition: winuser.h:1247
HDC WINAPI BeginPaint(_In_ HWND, _Out_ LPPAINTSTRUCT)
BOOL WINAPI KillTimer(_In_opt_ HWND, _In_ UINT_PTR)
#define SetWindowLongPtrW
Definition: winuser.h:5346
BOOL WINAPI InflateRect(_Inout_ LPRECT, _In_ int, _In_ int)
#define GWL_STYLE
Definition: winuser.h:852
#define DFCS_PUSHED
Definition: winuser.h:503
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define COLOR_BTNFACE
Definition: winuser.h:928
#define SB_THUMBPOSITION
Definition: winuser.h:572
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184