ReactOS 0.4.16-dev-753-g705a985
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 <assert.h>
22#include <stdlib.h>
23#include <string.h>
24#include <stdarg.h>
25#include <stdio.h>
26
27#include "windef.h"
28#include "winbase.h"
29#include "wingdi.h"
30#include "winuser.h"
31#include "winnls.h"
32#include "commctrl.h"
33#include "comctl32.h"
34#include "uxtheme.h"
35#include "vssym32.h"
36#include "wine/heap.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 */
174static void UPDOWN_GetArrowRect (const UPDOWN_INFO* infoPtr, RECT *rect, unsigned int arrow)
175{
176 HTHEME theme = GetWindowTheme (infoPtr->Self);
178 const int spacer = theme ? DEFAULT_BUDDYSPACER_THEMED : DEFAULT_BUDDYSPACER;
179 int size;
180
181 assert(arrow && (arrow & (FLAG_INCR | FLAG_DECR)) != (FLAG_INCR | FLAG_DECR));
182
183 GetClientRect (infoPtr->Self, rect);
184
185 /*
186 * Make sure we calculate the rectangle to fit even if we draw the
187 * border.
188 */
189 if (UPDOWN_HasBuddyBorder(infoPtr)) {
190 if (infoPtr->dwStyle & UDS_ALIGNLEFT)
191 rect->left += border;
192 else
193 rect->right -= border;
194
195 InflateRect(rect, 0, -border);
196 }
197
198 /* now figure out if we need a space away from the buddy */
199 if (IsWindow(infoPtr->Buddy) ) {
200 if (infoPtr->dwStyle & UDS_ALIGNLEFT) rect->right -= spacer;
201 else if (infoPtr->dwStyle & UDS_ALIGNRIGHT) rect->left += spacer;
202 }
203
204 /*
205 * We're calculating the midpoint to figure-out where the
206 * separation between the buttons will lay.
207 */
208 if (infoPtr->dwStyle & UDS_HORZ) {
209 size = (rect->right - rect->left) / 2;
210 if (arrow & FLAG_INCR)
211 rect->left = rect->right - size;
212 else if (arrow & FLAG_DECR)
213 rect->right = rect->left + size;
214 } else {
215 size = (rect->bottom - rect->top) / 2;
216 if (arrow & FLAG_INCR)
217 rect->bottom = rect->top + size;
218 else if (arrow & FLAG_DECR)
219 rect->top = rect->bottom - size;
220 }
221}
222
223/***********************************************************************
224 * UPDOWN_GetArrowFromPoint
225 * Returns the rectagle (for the up or down arrow) that contains pt.
226 * If it returns the up rect, it returns FLAG_INCR.
227 * If it returns the down rect, it returns FLAG_DECR.
228 */
230{
232 if(PtInRect(rect, pt)) return FLAG_INCR;
233
235 if(PtInRect(rect, pt)) return FLAG_DECR;
236
237 return 0;
238}
239
240
241/***********************************************************************
242 * UPDOWN_GetThousandSep
243 * Returns the thousand sep. If an error occurs, it returns ','.
244 */
246{
247 WCHAR sep[2];
248
250 sep[0] = ',';
251
252 return sep[0];
253}
254
255/***********************************************************************
256 * UPDOWN_GetBuddyInt
257 * Tries to read the pos from the buddy window and if it succeeds,
258 * it stores it in the control's CurVal
259 * returns:
260 * TRUE - if it read the integer from the buddy successfully
261 * FALSE - if an error occurred
262 */
264{
265 WCHAR txt[20], sep, *src, *dst;
266 int newVal;
267
268 if (!((infoPtr->Flags & FLAG_BUDDYINT) && IsWindow(infoPtr->Buddy)))
269 return FALSE;
270
271 /*if the buddy is a list window, we must set curr index */
272 if (UPDOWN_IsBuddyListbox(infoPtr)) {
273 newVal = SendMessageW(infoPtr->Buddy, LB_GETCARETINDEX, 0, 0);
274 if(newVal < 0) return FALSE;
275 } else {
276 /* we have a regular window, so will get the text */
277 /* note that a zero-length string is a legitimate value for 'txt',
278 * and ought to result in a successful conversion to '0'. */
279 if (GetWindowTextW(infoPtr->Buddy, txt, ARRAY_SIZE(txt)) < 0)
280 return FALSE;
281
282 sep = UPDOWN_GetThousandSep();
283
284 /* now get rid of the separators */
285 for(src = dst = txt; *src; src++)
286 if(*src != sep) *dst++ = *src;
287 *dst = 0;
288
289 /* try to convert the number and validate it */
290 newVal = wcstol(txt, &src, infoPtr->Base);
291 if(*src || !UPDOWN_InBounds (infoPtr, newVal)) return FALSE;
292 }
293
294 TRACE("new value(%d) from buddy (old=%d)\n", newVal, infoPtr->CurVal);
295 infoPtr->CurVal = newVal;
296 return TRUE;
297}
298
299
300/***********************************************************************
301 * UPDOWN_SetBuddyInt
302 * Tries to set the pos to the buddy window based on current pos
303 * returns:
304 * TRUE - if it set the caption of the buddy successfully
305 * FALSE - if an error occurred
306 */
307static BOOL UPDOWN_SetBuddyInt (const UPDOWN_INFO *infoPtr)
308{
309 static const WCHAR fmt_hex[] = { '0', 'x', '%', '0', '4', 'X', 0 };
310 static const WCHAR fmt_dec_oct[] = { '%', 'd', '\0' };
311 const WCHAR *fmt;
312 WCHAR txt[20], txt_old[20] = { 0 };
313 int len;
314
315 if (!((infoPtr->Flags & FLAG_BUDDYINT) && IsWindow(infoPtr->Buddy)))
316 return FALSE;
317
318 TRACE("set new value(%d) to buddy.\n", infoPtr->CurVal);
319
320 /*if the buddy is a list window, we must set curr index */
321 if (UPDOWN_IsBuddyListbox(infoPtr)) {
322 return SendMessageW(infoPtr->Buddy, LB_SETCURSEL, infoPtr->CurVal, 0) != LB_ERR;
323 }
324
325 /* Regular window, so set caption to the number */
326 fmt = (infoPtr->Base == 16) ? fmt_hex : fmt_dec_oct;
327 len = wsprintfW(txt, fmt, infoPtr->CurVal);
328
329
330 /* Do thousands separation if necessary */
331 if ((infoPtr->Base == 10) && !(infoPtr->dwStyle & UDS_NOTHOUSANDS) && (len > 3)) {
332 WCHAR tmp[ARRAY_SIZE(txt)], *src = tmp, *dst = txt;
334 int start = len % 3;
335
336 memcpy(tmp, txt, sizeof(txt));
337 if (start == 0) start = 3;
338 dst += start;
339 src += start;
340 for (len=0; *src; len++) {
341 if (len % 3 == 0) *dst++ = sep;
342 *dst++ = *src++;
343 }
344 *dst = 0;
345 }
346
347 /* if nothing changed exit earlier */
348 GetWindowTextW(infoPtr->Buddy, txt_old, ARRAY_SIZE(txt_old));
349 if (lstrcmpiW(txt_old, txt) == 0) return FALSE;
350
351 return SetWindowTextW(infoPtr->Buddy, txt);
352}
353
354/***********************************************************************
355 * UPDOWN_DrawBuddyBackground
356 *
357 * Draw buddy background for visual integration.
358 */
360{
361 RECT br, r;
362 HTHEME buddyTheme = GetWindowTheme (infoPtr->Buddy);
363 if (!buddyTheme) return FALSE;
364
365 GetWindowRect (infoPtr->Buddy, &br);
366 MapWindowPoints (NULL, infoPtr->Self, (POINT*)&br, 2);
367 GetClientRect (infoPtr->Self, &r);
368
369 if (infoPtr->dwStyle & UDS_ALIGNLEFT)
370 br.left = r.left;
371 else if (infoPtr->dwStyle & UDS_ALIGNRIGHT)
372 br.right = r.right;
373 /* FIXME: take disabled etc. into account */
374 DrawThemeBackground (buddyTheme, hdc, 0, 0, &br, NULL);
375 return TRUE;
376}
377
378/***********************************************************************
379 * UPDOWN_Draw
380 *
381 * Draw the arrows. The background need not be erased.
382 */
383static LRESULT UPDOWN_Draw (const UPDOWN_INFO *infoPtr, HDC hdc)
384{
385 BOOL uPressed, uHot, dPressed, dHot;
386 RECT rect;
387 HTHEME theme = GetWindowTheme (infoPtr->Self);
388 int uPart = 0, uState = 0, dPart = 0, dState = 0;
389 BOOL needBuddyBg = FALSE;
390
391 uPressed = (infoPtr->Flags & FLAG_PRESSED) && (infoPtr->Flags & FLAG_INCR);
392 uHot = (infoPtr->Flags & FLAG_INCR) && (infoPtr->Flags & FLAG_MOUSEIN);
393 dPressed = (infoPtr->Flags & FLAG_PRESSED) && (infoPtr->Flags & FLAG_DECR);
394 dHot = (infoPtr->Flags & FLAG_DECR) && (infoPtr->Flags & FLAG_MOUSEIN);
395 if (theme) {
396 uPart = (infoPtr->dwStyle & UDS_HORZ) ? SPNP_UPHORZ : SPNP_UP;
397 uState = (infoPtr->dwStyle & WS_DISABLED) ? DNS_DISABLED
398 : (uPressed ? DNS_PRESSED : (uHot ? DNS_HOT : DNS_NORMAL));
399 dPart = (infoPtr->dwStyle & UDS_HORZ) ? SPNP_DOWNHORZ : SPNP_DOWN;
400 dState = (infoPtr->dwStyle & WS_DISABLED) ? DNS_DISABLED
401 : (dPressed ? DNS_PRESSED : (dHot ? DNS_HOT : DNS_NORMAL));
402 needBuddyBg = IsWindow (infoPtr->Buddy)
403 && (IsThemeBackgroundPartiallyTransparent (theme, uPart, uState)
404 || IsThemeBackgroundPartiallyTransparent (theme, dPart, dState));
405 }
406
407 /* Draw the common border between ourselves and our buddy */
408 if (UPDOWN_HasBuddyBorder(infoPtr) || needBuddyBg) {
409 if (!theme || !UPDOWN_DrawBuddyBackground (infoPtr, hdc)) {
410 GetClientRect(infoPtr->Self, &rect);
412 BF_BOTTOM | BF_TOP |
413 (infoPtr->dwStyle & UDS_ALIGNLEFT ? BF_LEFT : BF_RIGHT));
414 }
415 }
416
417 /* Draw the incr button */
419 if (theme) {
420 DrawThemeBackground(theme, hdc, uPart, uState, &rect, NULL);
421 } else {
424 ((infoPtr->dwStyle & UDS_HOTTRACK) && uHot ? DFCS_HOT : 0) |
425 (uPressed ? DFCS_PUSHED : 0) |
426 (infoPtr->dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0) );
427 }
428
429 /* Draw the decr button */
431 if (theme) {
432 DrawThemeBackground(theme, hdc, dPart, dState, &rect, NULL);
433 } else {
436 ((infoPtr->dwStyle & UDS_HOTTRACK) && dHot ? DFCS_HOT : 0) |
437 (dPressed ? DFCS_PUSHED : 0) |
438 (infoPtr->dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0) );
439 }
440
441 return 0;
442}
443
444/***********************************************************************
445 * UPDOWN_Paint
446 *
447 * Asynchronous drawing (must ONLY be used in WM_PAINT).
448 * Calls UPDOWN_Draw.
449 */
450static LRESULT UPDOWN_Paint (const UPDOWN_INFO *infoPtr, HDC hdc)
451{
452 PAINTSTRUCT ps;
453 if (hdc) return UPDOWN_Draw (infoPtr, hdc);
454 hdc = BeginPaint (infoPtr->Self, &ps);
455 UPDOWN_Draw (infoPtr, hdc);
456 EndPaint (infoPtr->Self, &ps);
457 return 0;
458}
459
460/***********************************************************************
461 * UPDOWN_KeyPressed
462 *
463 * Handle key presses (up & down) when we have to do so
464 */
466{
467 int arrow, accel;
468
469 if (key == VK_UP) arrow = FLAG_INCR;
470 else if (key == VK_DOWN) arrow = FLAG_DECR;
471 else return 1;
472
473 UPDOWN_GetBuddyInt (infoPtr);
474 infoPtr->Flags &= ~FLAG_ARROW;
475 infoPtr->Flags |= FLAG_PRESSED | arrow;
476 InvalidateRect (infoPtr->Self, NULL, FALSE);
478 accel = (infoPtr->AccelCount && infoPtr->AccelVect) ? infoPtr->AccelVect[0].nInc : 1;
479 UPDOWN_DoAction (infoPtr, accel, arrow);
480 return 0;
481}
482
483static int UPDOWN_GetPos(UPDOWN_INFO *infoPtr, BOOL *err)
484{
485 BOOL succ = UPDOWN_GetBuddyInt(infoPtr);
486 int val = infoPtr->CurVal;
487
488 if(!UPDOWN_InBounds(infoPtr, val)) {
489 if((infoPtr->MinVal < infoPtr->MaxVal && val < infoPtr->MinVal)
490 || (infoPtr->MinVal > infoPtr->MaxVal && val > infoPtr->MinVal))
491 val = infoPtr->MinVal;
492 else
493 val = infoPtr->MaxVal;
494
495 succ = FALSE;
496 }
497
498 if(err) *err = !succ;
499 return val;
500}
501
502static int UPDOWN_SetPos(UPDOWN_INFO *infoPtr, int pos)
503{
504 int ret = infoPtr->CurVal;
505
506 if(!UPDOWN_InBounds(infoPtr, pos)) {
507 if((infoPtr->MinVal < infoPtr->MaxVal && pos < infoPtr->MinVal)
508 || (infoPtr->MinVal > infoPtr->MaxVal && pos > infoPtr->MinVal))
509 pos = infoPtr->MinVal;
510 else
511 pos = infoPtr->MaxVal;
512 }
513
514 infoPtr->CurVal = pos;
515 UPDOWN_SetBuddyInt(infoPtr);
516
517 if(!UPDOWN_InBounds(infoPtr, ret)) {
518 if((infoPtr->MinVal < infoPtr->MaxVal && ret < infoPtr->MinVal)
519 || (infoPtr->MinVal > infoPtr->MaxVal && ret > infoPtr->MinVal))
520 ret = infoPtr->MinVal;
521 else
522 ret = infoPtr->MaxVal;
523 }
524 return ret;
525}
526
527
528/***********************************************************************
529 * UPDOWN_SetRange
530 *
531 * Handle UDM_SETRANGE, UDM_SETRANGE32
532 *
533 * FIXME: handle Max == Min properly:
534 * - arrows should be disabled (without WS_DISABLED set),
535 * visually they can't be pressed and don't respond;
536 * - all input messages should still pass in.
537 */
539{
540 infoPtr->MaxVal = Max;
541 infoPtr->MinVal = Min;
542
543 TRACE("UpDown Ctrl new range(%d to %d), hwnd=%p\n",
544 infoPtr->MinVal, infoPtr->MaxVal, infoPtr->Self);
545
546 return 0;
547}
548
549/***********************************************************************
550 * UPDOWN_MouseWheel
551 *
552 * Handle mouse wheel scrolling
553 */
555{
556 int iWheelDelta = GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA;
557
558 if (wParam & (MK_SHIFT | MK_CONTROL))
559 return 0;
560
561 if (iWheelDelta != 0)
562 {
563 UPDOWN_GetBuddyInt(infoPtr);
564 UPDOWN_DoAction(infoPtr, abs(iWheelDelta), iWheelDelta > 0 ? FLAG_INCR : FLAG_DECR);
565 }
566
567 return 1;
568}
569
570
571/***********************************************************************
572 * UPDOWN_Buddy_SubclassProc used to handle messages sent to the buddy
573 * control.
574 */
575static LRESULT CALLBACK
577 UINT_PTR uId, DWORD_PTR ref_data)
578{
579 UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr((HWND)ref_data);
580
581 TRACE("hwnd=%p, uMsg=%04x, wParam=%08lx, lParam=%08lx\n",
582 hwnd, uMsg, wParam, lParam);
583
584 switch(uMsg)
585 {
586 case WM_KEYDOWN:
587 if (infoPtr)
588 {
589 UPDOWN_KeyPressed(infoPtr, (int)wParam);
590 if (wParam == VK_UP || wParam == VK_DOWN)
591 return 0;
592 }
593 break;
594
595 case WM_MOUSEWHEEL:
596 if (infoPtr)
597 UPDOWN_MouseWheel(infoPtr, (int)wParam);
598 break;
599
600 case WM_NCDESTROY:
602 break;
603 default:
604 break;
605 }
606
607 return DefSubclassProc(hwnd, uMsg, wParam, lParam);
608}
609
610static void UPDOWN_ResetSubclass (UPDOWN_INFO *infoPtr)
611{
613}
614
615/***********************************************************************
616 * UPDOWN_SetBuddy
617 *
618 * Sets bud as a new Buddy.
619 * Then, it should subclass the buddy
620 * If window has the UDS_ARROWKEYS, it subclasses the buddy window to
621 * process the UP/DOWN arrow keys.
622 * If window has the UDS_ALIGNLEFT or UDS_ALIGNRIGHT style
623 * the size/pos of the buddy and the control are adjusted accordingly.
624 */
625static HWND UPDOWN_SetBuddy (UPDOWN_INFO* infoPtr, HWND bud)
626{
627 RECT budRect; /* new coord for the buddy */
628 int x, width; /* new x position and width for the up-down */
629 WCHAR buddyClass[40];
630 HWND old_buddy;
631
632 TRACE("(hwnd=%p, bud=%p)\n", infoPtr->Self, bud);
633
634 old_buddy = infoPtr->Buddy;
635
636 UPDOWN_ResetSubclass (infoPtr);
637
638 if (!IsWindow(bud)) bud = NULL;
639
640 /* Store buddy window handle */
641 infoPtr->Buddy = bud;
642
643 if(bud) {
644 /* Store buddy window class type */
645 infoPtr->BuddyType = BUDDY_TYPE_UNKNOWN;
646 if (GetClassNameW(bud, buddyClass, ARRAY_SIZE(buddyClass))) {
647 if (lstrcmpiW(buddyClass, WC_EDITW) == 0)
648 infoPtr->BuddyType = BUDDY_TYPE_EDIT;
649 else if (lstrcmpiW(buddyClass, WC_LISTBOXW) == 0)
650 infoPtr->BuddyType = BUDDY_TYPE_LISTBOX;
651 }
652
653 if (infoPtr->dwStyle & UDS_ARROWKEYS)
655 (DWORD_PTR)infoPtr->Self);
656
657 /* Get the rect of the buddy relative to its parent */
658 GetWindowRect(infoPtr->Buddy, &budRect);
659 MapWindowPoints(HWND_DESKTOP, GetParent(infoPtr->Buddy), (POINT *)(&budRect.left), 2);
660
661 /* now do the positioning */
662 if (infoPtr->dwStyle & UDS_ALIGNLEFT) {
663 x = budRect.left;
664 budRect.left += DEFAULT_WIDTH + DEFAULT_XSEP;
665 } else if (infoPtr->dwStyle & UDS_ALIGNRIGHT) {
666 budRect.right -= DEFAULT_WIDTH + DEFAULT_XSEP;
667 x = budRect.right+DEFAULT_XSEP;
668 } else {
669 /* nothing to do */
670 return old_buddy;
671 }
672
673 /* first adjust the buddy to accommodate the up/down */
674 SetWindowPos(infoPtr->Buddy, 0, budRect.left, budRect.top,
675 budRect.right - budRect.left, budRect.bottom - budRect.top,
677
678 /* now position the up/down */
679 /* Since the UDS_ALIGN* flags were used, */
680 /* we will pick the position and size of the window. */
682
683 /*
684 * If the updown has a buddy border, it has to overlap with the buddy
685 * to look as if it is integrated with the buddy control.
686 * We nudge the control or change its size to overlap.
687 */
688 if (UPDOWN_HasBuddyBorder(infoPtr)) {
689 if(infoPtr->dwStyle & UDS_ALIGNLEFT)
691 else
693 }
694
695 SetWindowPos(infoPtr->Self, 0, x,
696 budRect.top - DEFAULT_ADDTOP, width,
697 budRect.bottom - budRect.top + DEFAULT_ADDTOP + DEFAULT_ADDBOT,
699 } else if (!(infoPtr->dwStyle & UDS_HORZ) && old_buddy != NULL) {
700 RECT rect;
701 GetWindowRect(infoPtr->Self, &rect);
703 SetWindowPos(infoPtr->Self, 0, rect.left, rect.top, DEFAULT_WIDTH, rect.bottom - rect.top,
705 }
706
707 return old_buddy;
708}
709
710/***********************************************************************
711 * UPDOWN_DoAction
712 *
713 * This function increments/decrements the CurVal by the
714 * 'delta' amount according to the 'action' flag which can be a
715 * combination of FLAG_INCR and FLAG_DECR
716 * It notifies the parent as required.
717 * It handles wrapping and non-wrapping correctly.
718 * It is assumed that delta>0
719 */
720static void UPDOWN_DoAction (UPDOWN_INFO *infoPtr, int delta, int action)
721{
723
724 TRACE("%d by %d\n", action, delta);
725
726 /* check if we can do the modification first */
727 delta *= (action & FLAG_INCR ? 1 : -1) * (infoPtr->MaxVal < infoPtr->MinVal ? -1 : 1);
728 if ( (action & FLAG_INCR) && (action & FLAG_DECR) ) delta = 0;
729
730 TRACE("current %d, delta: %d\n", infoPtr->CurVal, delta);
731
732 /* We must notify parent now to obtain permission */
733 ni.iPos = infoPtr->CurVal;
734 ni.iDelta = delta;
735 ni.hdr.hwndFrom = infoPtr->Self;
736 ni.hdr.idFrom = GetWindowLongPtrW (infoPtr->Self, GWLP_ID);
737 ni.hdr.code = UDN_DELTAPOS;
738 if (!SendMessageW(infoPtr->Notify, WM_NOTIFY, ni.hdr.idFrom, (LPARAM)&ni)) {
739 /* Parent said: OK to adjust */
740
741 /* Now adjust value with (maybe new) delta */
742 if (UPDOWN_OffsetVal (infoPtr, ni.iDelta)) {
743 TRACE("new %d, delta: %d\n", infoPtr->CurVal, ni.iDelta);
744
745 /* Now take care about our buddy */
746 UPDOWN_SetBuddyInt (infoPtr);
747 }
748 }
749
750 /* Also, notify it. This message is sent in any case. */
751 SendMessageW( infoPtr->Notify, (infoPtr->dwStyle & UDS_HORZ) ? WM_HSCROLL : WM_VSCROLL,
752 MAKELONG(SB_THUMBPOSITION, infoPtr->CurVal), (LPARAM)infoPtr->Self);
753}
754
755/***********************************************************************
756 * UPDOWN_IsEnabled
757 *
758 * Returns TRUE if it is enabled as well as its buddy (if any)
759 * FALSE otherwise
760 */
761static BOOL UPDOWN_IsEnabled (const UPDOWN_INFO *infoPtr)
762{
763 if (!IsWindowEnabled(infoPtr->Self))
764 return FALSE;
765 if(infoPtr->Buddy)
766 return IsWindowEnabled(infoPtr->Buddy);
767 return TRUE;
768}
769
770/***********************************************************************
771 * UPDOWN_CancelMode
772 *
773 * Deletes any timers, releases the mouse and does redraw if necessary.
774 * If the control is not in "capture" mode, it does nothing.
775 * If the control was not in cancel mode, it returns FALSE.
776 * If the control was in cancel mode, it returns TRUE.
777 */
779{
780 if (!(infoPtr->Flags & FLAG_PRESSED)) return FALSE;
781
782 KillTimer (infoPtr->Self, TIMER_AUTOREPEAT);
783 KillTimer (infoPtr->Self, TIMER_ACCEL);
784 KillTimer (infoPtr->Self, TIMER_AUTOPRESS);
785
786 if (GetCapture() == infoPtr->Self)
788
789 infoPtr->Flags &= ~FLAG_PRESSED;
790 InvalidateRect (infoPtr->Self, NULL, FALSE);
791
792 return TRUE;
793}
794
795/***********************************************************************
796 * UPDOWN_HandleMouseEvent
797 *
798 * Handle a mouse event for the updown.
799 * 'pt' is the location of the mouse event in client or
800 * windows coordinates.
801 */
803{
804 POINT pt = { x, y };
805 RECT rect;
806 int temp, arrow;
807 TRACKMOUSEEVENT tme;
808
809 TRACE("msg %04x point %s\n", msg, wine_dbgstr_point(&pt));
810
811 switch(msg)
812 {
813 case WM_LBUTTONDOWN: /* Initialise mouse tracking */
814
815 /* If the buddy is an edit, will set focus to it */
816 if (UPDOWN_IsBuddyEdit(infoPtr)) SetFocus(infoPtr->Buddy);
817
818 /* Now see which one is the 'active' arrow */
819 arrow = UPDOWN_GetArrowFromPoint (infoPtr, &rect, pt);
820
821 /* Update the flags if we are in/out */
822 infoPtr->Flags &= ~(FLAG_MOUSEIN | FLAG_ARROW);
823 if (arrow)
824 infoPtr->Flags |= FLAG_MOUSEIN | arrow;
825 else
826 if (infoPtr->AccelIndex != -1) infoPtr->AccelIndex = 0;
827
828 if (infoPtr->Flags & FLAG_ARROW) {
829
830 /* Update the CurVal if necessary */
831 UPDOWN_GetBuddyInt (infoPtr);
832
833 /* Set up the correct flags */
834 infoPtr->Flags |= FLAG_PRESSED;
835
836 /* repaint the control */
837 InvalidateRect (infoPtr->Self, NULL, FALSE);
838
839 /* process the click */
840 temp = (infoPtr->AccelCount && infoPtr->AccelVect) ? infoPtr->AccelVect[0].nInc : 1;
841 UPDOWN_DoAction (infoPtr, temp, infoPtr->Flags & FLAG_ARROW);
842
843 /* now capture all mouse messages */
844 SetCapture (infoPtr->Self);
845
846 /* and startup the first timer */
848 }
849 break;
850
851 case WM_MOUSEMOVE:
852 /* save the flags to see if any got modified */
853 temp = infoPtr->Flags;
854
855 /* Now see which one is the 'active' arrow */
856 arrow = UPDOWN_GetArrowFromPoint (infoPtr, &rect, pt);
857
858 /* Update the flags if we are in/out */
859 infoPtr->Flags &= ~(FLAG_MOUSEIN | FLAG_ARROW);
860 if(arrow) {
861 infoPtr->Flags |= FLAG_MOUSEIN | arrow;
862 } else {
863 if(infoPtr->AccelIndex != -1) infoPtr->AccelIndex = 0;
864 }
865
866 /* If state changed, redraw the control */
867 if(temp != infoPtr->Flags)
868 InvalidateRect (infoPtr->Self, NULL, FALSE);
869
870 /* Set up tracking so the mousein flags can be reset when the
871 * mouse leaves the control */
872 tme.cbSize = sizeof( tme );
873 tme.dwFlags = TME_LEAVE;
874 tme.hwndTrack = infoPtr->Self;
875 TrackMouseEvent (&tme);
876
877 break;
878 case WM_MOUSELEAVE:
879 infoPtr->Flags &= ~(FLAG_MOUSEIN | FLAG_ARROW);
880 InvalidateRect (infoPtr->Self, NULL, FALSE);
881 break;
882
883 default:
884 ERR("Impossible case (msg=%x)!\n", msg);
885 }
886
887}
888
889/***********************************************************************
890 * UpDownWndProc
891 */
893{
895 static const WCHAR themeClass[] = {'S','p','i','n',0};
896 HTHEME theme;
897
898 TRACE("hwnd=%p msg=%04x wparam=%08lx lparam=%08lx\n", hwnd, message, wParam, lParam);
899
900 if (!infoPtr && (message != WM_CREATE))
902
903 switch(message)
904 {
905 case WM_CREATE:
906 {
908
909 infoPtr = heap_alloc_zero(sizeof(*infoPtr));
910 SetWindowLongPtrW (hwnd, 0, (DWORD_PTR)infoPtr);
911
912 /* initialize the info struct */
913 infoPtr->Self = hwnd;
914 infoPtr->Notify = pcs->hwndParent;
915 infoPtr->dwStyle = pcs->style;
916 infoPtr->AccelCount = 0;
917 infoPtr->AccelVect = 0;
918 infoPtr->AccelIndex = -1;
919 infoPtr->CurVal = 0;
920 infoPtr->MinVal = 100;
921 infoPtr->MaxVal = 0;
922 infoPtr->Base = 10; /* Default to base 10 */
923 infoPtr->Buddy = 0; /* No buddy window yet */
924 infoPtr->Flags = (infoPtr->dwStyle & UDS_SETBUDDYINT) ? FLAG_BUDDYINT : 0;
925
926 SetWindowLongW (hwnd, GWL_STYLE, infoPtr->dwStyle & ~WS_BORDER);
927 if (!(infoPtr->dwStyle & UDS_HORZ))
928 SetWindowPos (hwnd, NULL, 0, 0, DEFAULT_WIDTH, pcs->cy,
930
931 /* Do we pick the buddy win ourselves? */
932 if (infoPtr->dwStyle & UDS_AUTOBUDDY)
934
936
937 TRACE("UpDown Ctrl creation, hwnd=%p\n", hwnd);
938 }
939 break;
940
941 case WM_DESTROY:
942 heap_free (infoPtr->AccelVect);
943 UPDOWN_ResetSubclass (infoPtr);
944 heap_free (infoPtr);
945 SetWindowLongPtrW (hwnd, 0, 0);
946 theme = GetWindowTheme (hwnd);
947 CloseThemeData (theme);
948 TRACE("UpDown Ctrl destruction, hwnd=%p\n", hwnd);
949 break;
950
951 case WM_ENABLE:
952 if (wParam) {
953 infoPtr->dwStyle &= ~WS_DISABLED;
954 } else {
955 infoPtr->dwStyle |= WS_DISABLED;
956 UPDOWN_CancelMode (infoPtr);
957 }
958 InvalidateRect (infoPtr->Self, NULL, FALSE);
959 break;
960
961 case WM_STYLECHANGED:
962 if (wParam == GWL_STYLE) {
963 infoPtr->dwStyle = ((LPSTYLESTRUCT)lParam)->styleNew;
964 InvalidateRect (infoPtr->Self, NULL, FALSE);
965 }
966 break;
967
968 case WM_THEMECHANGED:
969 theme = GetWindowTheme (hwnd);
970 CloseThemeData (theme);
973 break;
974
975 case WM_TIMER:
976 /* is this the auto-press timer? */
977 if(wParam == TIMER_AUTOPRESS) {
979 infoPtr->Flags &= ~(FLAG_PRESSED | FLAG_ARROW);
980 InvalidateRect(infoPtr->Self, NULL, FALSE);
981 }
982
983 /* if initial timer, kill it and start the repeat timer */
984 if(wParam == TIMER_AUTOREPEAT) {
985 INT delay;
986
988 /* if no accel info given, used default timer */
989 if(infoPtr->AccelCount==0 || infoPtr->AccelVect==0) {
990 infoPtr->AccelIndex = -1;
991 delay = REPEAT_DELAY;
992 } else {
993 infoPtr->AccelIndex = 0; /* otherwise, use it */
994 delay = infoPtr->AccelVect[infoPtr->AccelIndex].nSec * 1000 + 1;
995 }
996 SetTimer(hwnd, TIMER_ACCEL, delay, 0);
997 }
998
999 /* now, if the mouse is above us, do the thing...*/
1000 if(infoPtr->Flags & FLAG_MOUSEIN) {
1001 int temp;
1002
1003 temp = infoPtr->AccelIndex == -1 ? 1 : infoPtr->AccelVect[infoPtr->AccelIndex].nInc;
1004 UPDOWN_DoAction(infoPtr, temp, infoPtr->Flags & FLAG_ARROW);
1005
1006 if(infoPtr->AccelIndex != -1 && infoPtr->AccelIndex < infoPtr->AccelCount-1) {
1008 infoPtr->AccelIndex++; /* move to the next accel info */
1009 temp = infoPtr->AccelVect[infoPtr->AccelIndex].nSec * 1000 + 1;
1010 /* make sure we have at least 1ms intervals */
1012 }
1013 }
1014 break;
1015
1016 case WM_CANCELMODE:
1017 return UPDOWN_CancelMode (infoPtr);
1018
1019 case WM_LBUTTONUP:
1020 if (GetCapture() != infoPtr->Self) break;
1021
1022 if ( (infoPtr->Flags & FLAG_MOUSEIN) &&
1023 (infoPtr->Flags & FLAG_ARROW) ) {
1024
1025 SendMessageW( infoPtr->Notify,
1026 (infoPtr->dwStyle & UDS_HORZ) ? WM_HSCROLL : WM_VSCROLL,
1027 MAKELONG(SB_ENDSCROLL, infoPtr->CurVal),
1028 (LPARAM)hwnd);
1029 if (UPDOWN_IsBuddyEdit(infoPtr))
1030 SendMessageW(infoPtr->Buddy, EM_SETSEL, 0, MAKELONG(0, -1));
1031 }
1032 UPDOWN_CancelMode(infoPtr);
1033 break;
1034
1035 case WM_LBUTTONDOWN:
1036 case WM_MOUSEMOVE:
1037 case WM_MOUSELEAVE:
1038 if(UPDOWN_IsEnabled(infoPtr))
1040 break;
1041
1042 case WM_MOUSEWHEEL:
1043 UPDOWN_MouseWheel(infoPtr, wParam);
1044 break;
1045
1046 case WM_KEYDOWN:
1047 if((infoPtr->dwStyle & UDS_ARROWKEYS) && UPDOWN_IsEnabled(infoPtr))
1048 return UPDOWN_KeyPressed(infoPtr, (int)wParam);
1049 break;
1050
1051 case WM_PRINTCLIENT:
1052 case WM_PAINT:
1053 return UPDOWN_Paint (infoPtr, (HDC)wParam);
1054
1055 case UDM_GETACCEL:
1056 if (wParam==0 && lParam==0) return infoPtr->AccelCount;
1057 if (wParam && lParam) {
1058 int temp = min(infoPtr->AccelCount, wParam);
1059 memcpy((void *)lParam, infoPtr->AccelVect, temp*sizeof(UDACCEL));
1060 return temp;
1061 }
1062 return 0;
1063
1064 case UDM_SETACCEL:
1065 {
1066 TRACE("UDM_SETACCEL\n");
1067
1068 if(infoPtr->AccelVect) {
1069 heap_free (infoPtr->AccelVect);
1070 infoPtr->AccelCount = 0;
1071 infoPtr->AccelVect = 0;
1072 }
1073 if(wParam==0) return TRUE;
1074 infoPtr->AccelVect = heap_alloc(wParam*sizeof(UDACCEL));
1075 if(!infoPtr->AccelVect) return FALSE;
1076 memcpy(infoPtr->AccelVect, (void*)lParam, wParam*sizeof(UDACCEL));
1077 infoPtr->AccelCount = wParam;
1078
1079 if (TRACE_ON(updown))
1080 {
1081 UINT i;
1082
1083 for (i = 0; i < wParam; i++)
1084 TRACE("%u: nSec %u nInc %u\n", i,
1085 infoPtr->AccelVect[i].nSec, infoPtr->AccelVect[i].nInc);
1086 }
1087
1088 return TRUE;
1089 }
1090 case UDM_GETBASE:
1091 return infoPtr->Base;
1092
1093 case UDM_SETBASE:
1094 TRACE("UpDown Ctrl new base(%ld), hwnd=%p\n", wParam, hwnd);
1095 if (wParam==10 || wParam==16) {
1096 WPARAM old_base = infoPtr->Base;
1097 infoPtr->Base = wParam;
1098
1099 if (old_base != infoPtr->Base)
1100 UPDOWN_SetBuddyInt(infoPtr);
1101
1102 return old_base;
1103 }
1104 break;
1105
1106 case UDM_GETBUDDY:
1107 return (LRESULT)infoPtr->Buddy;
1108
1109 case UDM_SETBUDDY:
1110 return (LRESULT)UPDOWN_SetBuddy (infoPtr, (HWND)wParam);
1111
1112 case UDM_GETPOS:
1113 {
1114 BOOL err;
1115 int pos;
1116
1117 pos = UPDOWN_GetPos(infoPtr, &err);
1118 return MAKELONG(pos, err);
1119 }
1120 case UDM_SETPOS:
1121 {
1122 return UPDOWN_SetPos(infoPtr, (short)LOWORD(lParam));
1123 }
1124 case UDM_GETRANGE:
1125 return MAKELONG(infoPtr->MaxVal, infoPtr->MinVal);
1126
1127 case UDM_SETRANGE:
1128 /* we must have:
1129 UD_MINVAL <= Max <= UD_MAXVAL
1130 UD_MINVAL <= Min <= UD_MAXVAL
1131 |Max-Min| <= UD_MAXVAL */
1132 UPDOWN_SetRange(infoPtr, (short)lParam, (short)HIWORD(lParam));
1133 break;
1134
1135 case UDM_GETRANGE32:
1136 if (wParam) *(LPINT)wParam = infoPtr->MinVal;
1137 if (lParam) *(LPINT)lParam = infoPtr->MaxVal;
1138 break;
1139
1140 case UDM_SETRANGE32:
1141 UPDOWN_SetRange(infoPtr, (INT)lParam, (INT)wParam);
1142 break;
1143
1144 case UDM_GETPOS32:
1145 {
1146 return UPDOWN_GetPos(infoPtr, (BOOL*)lParam);
1147 }
1148 case UDM_SETPOS32:
1149 {
1150 return UPDOWN_SetPos(infoPtr, (int)lParam);
1151 }
1153 /* we lie a bit here, we're always using Unicode internally */
1154 return infoPtr->UnicodeFormat;
1155
1157 {
1158 /* do we really need to honour this flag? */
1159 int temp = infoPtr->UnicodeFormat;
1160 infoPtr->UnicodeFormat = (BOOL)wParam;
1161 return temp;
1162 }
1163 default:
1165 ERR("unknown msg %04x wp=%04lx lp=%08lx\n", message, wParam, lParam);
1167 }
1168
1169 return 0;
1170}
1171
1172/***********************************************************************
1173 * UPDOWN_Register [Internal]
1174 *
1175 * Registers the updown window class.
1176 */
1178{
1179 WNDCLASSW wndClass;
1180
1181 ZeroMemory( &wndClass, sizeof( WNDCLASSW ) );
1183 wndClass.lpfnWndProc = UpDownWindowProc;
1184 wndClass.cbClsExtra = 0;
1185 wndClass.cbWndExtra = sizeof(UPDOWN_INFO*);
1186 wndClass.hCursor = LoadCursorW( 0, (LPWSTR)IDC_ARROW );
1187 wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
1188 wndClass.lpszClassName = UPDOWN_CLASSW;
1189
1190 RegisterClassW( &wndClass );
1191}
1192
1193
1194/***********************************************************************
1195 * UPDOWN_Unregister [Internal]
1196 *
1197 * Unregisters the updown window class.
1198 */
1200{
1202}
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:20
#define ERR(fmt,...)
Definition: precomp.h:57
#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:1755
BOOL WINAPI SetWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR uIDSubclass, DWORD_PTR dwRef)
Definition: commctrl.c:1268
BOOL WINAPI RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR uID)
Definition: commctrl.c:1397
LRESULT WINAPI DefSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: commctrl.c:1503
#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:114
static WCHAR UPDOWN_GetThousandSep(void)
Definition: updown.c:245
static void UPDOWN_DoAction(UPDOWN_INFO *infoPtr, int delta, int action)
Definition: updown.c:720
#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:802
#define BUDDY_TYPE_UNKNOWN
Definition: updown.c:83
static BOOL UPDOWN_DrawBuddyBackground(const UPDOWN_INFO *infoPtr, HDC hdc)
Definition: updown.c:359
static LRESULT CALLBACK UPDOWN_Buddy_SubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uId, DWORD_PTR ref_data)
Definition: updown.c:576
#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:502
#define REPEAT_DELAY
Definition: updown.c:63
#define TIMER_ACCEL
Definition: updown.c:88
static void UPDOWN_ResetSubclass(UPDOWN_INFO *infoPtr)
Definition: updown.c:610
#define DEFAULT_BUDDYSPACER_THEMED
Definition: updown.c:72
static BOOL UPDOWN_CancelMode(UPDOWN_INFO *infoPtr)
Definition: updown.c:778
#define TIMER_AUTOPRESS
Definition: updown.c:89
#define DEFAULT_ADDBOT
Definition: updown.c:68
static void UPDOWN_GetArrowRect(const UPDOWN_INFO *infoPtr, RECT *rect, unsigned int arrow)
Definition: updown.c:174
static INT UPDOWN_GetArrowFromPoint(const UPDOWN_INFO *infoPtr, RECT *rect, POINT pt)
Definition: updown.c:229
static HWND UPDOWN_SetBuddy(UPDOWN_INFO *infoPtr, HWND bud)
Definition: updown.c:625
static LRESULT UPDOWN_Draw(const UPDOWN_INFO *infoPtr, HDC hdc)
Definition: updown.c:383
#define FLAG_DECR
Definition: updown.c:77
#define INITIAL_DELAY
Definition: updown.c:61
static BOOL UPDOWN_GetBuddyInt(UPDOWN_INFO *infoPtr)
Definition: updown.c:263
#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:1199
#define DEFAULT_ADDTOP
Definition: updown.c:67
#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:465
#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:483
static BOOL UPDOWN_IsEnabled(const UPDOWN_INFO *infoPtr)
Definition: updown.c:761
void UPDOWN_Register(void)
Definition: updown.c:1177
static LRESULT UPDOWN_Paint(const UPDOWN_INFO *infoPtr, HDC hdc)
Definition: updown.c:450
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:538
static BOOL UPDOWN_IsBuddyEdit(const UPDOWN_INFO *infoPtr)
Definition: updown.c:102
static LRESULT UPDOWN_MouseWheel(UPDOWN_INFO *infoPtr, WPARAM wParam)
Definition: updown.c:554
#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:892
#define BUDDY_TYPE_LISTBOX
Definition: updown.c:84
static BOOL UPDOWN_SetBuddyInt(const UPDOWN_INFO *infoPtr)
Definition: updown.c:307
#define TRACE_ON(x)
Definition: compat.h:75
#define CALLBACK
Definition: compat.h:35
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4262
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: locale.c:1666
const WCHAR * action
Definition: action.c:7509
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:1927
HTHEME WINAPI OpenThemeData(HWND hwnd, LPCWSTR classlist)
Definition: system.c:850
HTHEME WINAPI GetWindowTheme(HWND hwnd)
Definition: system.c:866
HRESULT WINAPI CloseThemeData(HTHEME hTheme)
Definition: system.c:965
#define assert(x)
Definition: debug.h:53
#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
GLsizeiptr size
Definition: glext.h:5919
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
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
if(dx< 0)
Definition: linetemp.h:194
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
HDC hdc
Definition: main.c:9
static HDC
Definition: imagelist.c:88
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:2124
#define TME_LEAVE
Definition: commctrl.h:4986
#define UDM_SETACCEL
Definition: commctrl.h:2152
#define UDM_GETBUDDY
Definition: commctrl.h:2151
#define UDS_AUTOBUDDY
Definition: commctrl.h:2140
#define UDS_ALIGNLEFT
Definition: commctrl.h:2139
#define UDS_SETBUDDYINT
Definition: commctrl.h:2137
#define WC_EDITW
Definition: commctrl.h:4692
#define UDM_SETPOS
Definition: commctrl.h:2148
#define UDS_HOTTRACK
Definition: commctrl.h:2144
#define NM_UPDOWN
Definition: commctrl.h:2165
#define UDM_GETUNICODEFORMAT
Definition: commctrl.h:2159
#define UDM_GETACCEL
Definition: commctrl.h:2153
#define UDS_NOTHOUSANDS
Definition: commctrl.h:2143
#define UDM_SETRANGE
Definition: commctrl.h:2146
#define UDM_GETRANGE
Definition: commctrl.h:2147
#define UDS_ARROWKEYS
Definition: commctrl.h:2141
#define UDS_WRAP
Definition: commctrl.h:2136
#define UDM_SETBASE
Definition: commctrl.h:2154
#define WM_MOUSELEAVE
Definition: commctrl.h:4980
#define UDM_GETBASE
Definition: commctrl.h:2155
#define UDM_SETBUDDY
Definition: commctrl.h:2150
#define UDS_HORZ
Definition: commctrl.h:2142
#define UDM_SETUNICODEFORMAT
Definition: commctrl.h:2158
#define UDM_GETRANGE32
Definition: commctrl.h:2157
#define UDM_SETRANGE32
Definition: commctrl.h:2156
#define UDM_GETPOS
Definition: commctrl.h:2149
#define UDM_GETPOS32
Definition: commctrl.h:2161
#define UDN_DELTAPOS
Definition: commctrl.h:2174
#define UDS_ALIGNRIGHT
Definition: commctrl.h:2138
#define WC_LISTBOXW
Definition: commctrl.h:4716
#define UDM_SETPOS32
Definition: commctrl.h:2160
#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:2130
UINT nSec
Definition: commctrl.h:2129
LPCWSTR lpszClassName
Definition: winuser.h:3188
HBRUSH hbrBackground
Definition: winuser.h:3186
int cbClsExtra
Definition: winuser.h:3181
UINT style
Definition: winuser.h:3179
WNDPROC lpfnWndProc
Definition: winuser.h:3180
int cbWndExtra
Definition: winuser.h:3182
HCURSOR hCursor
Definition: winuser.h:3185
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:1394
#define ZeroMemory
Definition: winbase.h:1737
_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:45
#define WM_PAINT
Definition: winuser.h:1623
#define LB_ERR
Definition: winuser.h:2435
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:2372
#define SWP_NOACTIVATE
Definition: winuser.h:1245
#define DFC_SCROLL
Definition: winuser.h:475
#define GetWindowLongPtrW
Definition: winuser.h:4832
#define WM_ENABLE
Definition: winuser.h:1618
#define WM_HSCROLL
Definition: winuser.h:1746
#define SWP_FRAMECHANGED
Definition: winuser.h:1243
#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:1747
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
#define WM_CREATE
Definition: winuser.h:1611
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:1638
#define SWP_NOMOVE
Definition: winuser.h:1247
#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:2228
#define WM_MOUSEMOVE
Definition: winuser.h:1778
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:1779
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2191
#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:1212
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:2373
#define BF_TOP
Definition: winuser.h:455
#define WM_TIMER
Definition: winuser.h:1745
BOOL WINAPI EndPaint(_In_ HWND, _In_ const PAINTSTRUCT *)
#define BF_RIGHT
Definition: winuser.h:456
#define EM_SETSEL
Definition: winuser.h:2021
#define WM_LBUTTONUP
Definition: winuser.h:1780
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:1687
int WINAPI GetClassNameW(_In_ HWND hWnd, _Out_writes_to_(nMaxCount, return) LPWSTR lpClassName, _In_ int nMaxCount)
#define VK_DOWN
Definition: winuser.h:2230
#define LB_GETCARETINDEX
Definition: winuser.h:2040
#define GWLP_ID
Definition: winuser.h:863
#define SWP_NOOWNERZORDER
Definition: winuser.h:1252
#define WM_USER
Definition: winuser.h:1898
#define SB_ENDSCROLL
Definition: winuser.h:574
#define GW_HWNDPREV
Definition: winuser.h:765
#define WM_DESTROY
Definition: winuser.h:1612
BOOL WINAPI UnregisterClassW(_In_ LPCWSTR, HINSTANCE)
#define LB_SETCURSEL
Definition: winuser.h:2066
#define WM_KEYDOWN
Definition: winuser.h:1718
#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:1250
HDC WINAPI BeginPaint(_In_ HWND, _Out_ LPPAINTSTRUCT)
BOOL WINAPI KillTimer(_In_opt_ HWND, _In_ UINT_PTR)
#define SetWindowLongPtrW
Definition: winuser.h:5358
BOOL WINAPI InflateRect(_Inout_ LPRECT, _In_ int, _In_ int)
#define GWL_STYLE
Definition: winuser.h:855
#define DFCS_PUSHED
Definition: winuser.h:503
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define COLOR_BTNFACE
Definition: winuser.h:931
#define SB_THUMBPOSITION
Definition: winuser.h:572
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184