4 * Copyright 1997 Dimitrie O. Paun
7 * - subclass the buddy window (in UPDOWN_SetBuddy) to process the
9 * - I am not sure about the default values for the Min, Max, Pos
10 * (in the UPDOWN_INFO the fields: MinVal, MaxVal, CurVal)
11 * - I think I do not handle correctly the WS_BORDER style.
13 * Not much. The following have not been tested at all:
15 * - listbox as buddy window
18 * - UDS_ALIGNLEFT, ~UDS_WRAP
19 * - integers with thousand separators.
20 * Even though the above list seems rather large, the control seems to
21 * behave very well so I am confident it does work in most (all) of the
24 * I do not like the arrows yet, I'll work more on them later on.
33 #include "sysmetrics.h"
40 /* Control configuration constants */
42 #define INITIAL_DELAY 500 /* initial timer until auto-increment kicks in */
43 #define REPEAT_DELAY 50 /* delay between auto-increments */
45 #define DEFAULT_WIDTH 14 /* default width of the ctrl */
46 #define DEFAULT_XSEP 0 /* default separation between buddy and crtl */
47 #define DEFAULT_ADDTOP 0 /* amount to extend above the buddy window */
48 #define DEFAULT_ADDBOT 0 /* amount to extend below the buddy window */
53 #define FLAG_INCR 0x01
54 #define FLAG_DECR 0x02
55 #define FLAG_MOUSEIN 0x04
56 #define FLAG_CLICKED (FLAG_INCR | FLAG_DECR)
61 static int accelIndex
= -1;
63 #define UNKNOWN_PARAM(msg, wParam, lParam) dprintf_warn(updown, \
64 "UpDown Ctrl: Unknown parameter(s) for message " #msg \
65 "(%04x): wp=%04x lp=%08lx\n", msg, wParam, lParam);
67 #define UPDOWN_GetInfoPtr(wndPtr) ((UPDOWN_INFO *)wndPtr->wExtra)
69 /***********************************************************************
71 * Tests if a given value 'val' is between the Min&Max limits
73 static BOOL32
UPDOWN_InBounds(WND
*wndPtr
, int val
)
75 UPDOWN_INFO
*infoPtr
= UPDOWN_GetInfoPtr(wndPtr
);
77 if(infoPtr
->MaxVal
> infoPtr
->MinVal
)
78 return (infoPtr
->MinVal
<= val
) && (val
<= infoPtr
->MaxVal
);
80 return (infoPtr
->MaxVal
<= val
) && (val
<= infoPtr
->MinVal
);
83 /***********************************************************************
85 * Tests if we can change the current value by delta. If so, it changes
86 * it and returns TRUE. Else, it leaves it unchanged and returns FALSE.
88 static BOOL32
UPDOWN_OffsetVal(WND
*wndPtr
, int delta
)
90 UPDOWN_INFO
*infoPtr
= UPDOWN_GetInfoPtr(wndPtr
);
92 /* check if we can do the modification first */
93 if(!UPDOWN_InBounds(wndPtr
, infoPtr
->CurVal
+delta
)){
94 if(wndPtr
->dwStyle
& UDS_WRAP
)
95 delta
+= (delta
< 0 ? -1 : 1) *
96 (infoPtr
->MaxVal
< infoPtr
->MinVal
? -1 : 1) *
97 (infoPtr
->MinVal
- infoPtr
->MaxVal
) +
103 infoPtr
->CurVal
+= delta
;
107 /***********************************************************************
108 * UPDOWN_GetArrawRect
109 * wndPtr - pointer to the up-down wnd
110 * rect - will hold the rectangle
111 * incr - TRUE get the "increment" rect (up or right)
112 * FALSE get the "decrement" rect (down or left)
115 static void UPDOWN_GetArrowRect(WND
*wndPtr
, RECT32
*rect
, BOOL32 incr
)
117 int len
; /* will hold the width or height */
119 GetClientRect32(wndPtr
->hwndSelf
, rect
);
121 if (wndPtr
->dwStyle
& UDS_HORZ
) {
122 len
= rect
->right
- rect
->left
; /* compute the width */
124 rect
->left
= len
/2+1;
129 len
= rect
->bottom
- rect
->top
; /* compute the height */
131 rect
->bottom
= len
/2;
137 /***********************************************************************
138 * UPDOWN_GetArrowFromPoint
139 * Returns the rectagle (for the up or down arrow) that contains pt.
140 * If it returns the up rect, it returns TRUE.
141 * If it returns the down rect, it returns FALSE.
143 static int UPDOWN_GetArrowFromPoint(WND
*wndPtr
, RECT32
*rect
, POINT32 pt
)
145 UPDOWN_GetArrowRect(wndPtr
, rect
, TRUE
);
146 if(PtInRect32(rect
, pt
))
149 UPDOWN_GetArrowRect(wndPtr
, rect
, FALSE
);
154 /***********************************************************************
155 * UPDOWN_GetThousandSep
156 * Returns the thousand sep. If an error occurs, it returns ','.
158 static char UPDOWN_GetThousandSep()
162 if(GetLocaleInfo32A(LOCALE_USER_DEFAULT
, LOCALE_STHOUSAND
,
163 sep
, sizeof(sep
)) != 1)
169 /***********************************************************************
171 * Tries to read the pos from the buddy window and if it succeeds,
172 * it stores it in the control's CurVal
174 * TRUE - if it read the integer from the buddy successfully
175 * FALSE - if an error occured
177 static BOOL32
UPDOWN_GetBuddyInt(WND
*wndPtr
)
179 UPDOWN_INFO
*infoPtr
= UPDOWN_GetInfoPtr(wndPtr
);
180 char txt
[20], sep
, *src
, *dst
;
183 if (!IsWindow32(infoPtr
->Buddy
))
186 /*if the buddy is a list window, we must set curr index */
187 if(WIDGETS_IsControl32(WIN_FindWndPtr(infoPtr
->Buddy
), BIC32_LISTBOX
)){
188 newVal
= SendMessage32A(infoPtr
->Buddy
, LB_GETCARETINDEX32
, 0, 0);
193 /* we have a regural window, so will get the text */
194 if (!GetWindowText32A(infoPtr
->Buddy
, txt
, sizeof(txt
)))
197 sep
= UPDOWN_GetThousandSep();
199 /* now get rid of the separators */
200 for(src
= dst
= txt
; *src
; src
++)
205 /* try to convert the number and validate it */
206 newVal
= strtol(txt
, &src
, infoPtr
->Base
);
207 if(*src
|| !UPDOWN_InBounds(wndPtr
, newVal
))
210 dprintf_info(updown
, "UpDown Ctrl: new value(%d) read from buddy "
211 "(old=%d)\n", newVal
, infoPtr
->CurVal
);
214 infoPtr
->CurVal
= newVal
;
219 /***********************************************************************
221 * Tries to set the pos to the buddy window based on current pos
223 * TRUE - if it set the caption of the buddy successfully
224 * FALSE - if an error occured
226 static BOOL32
UPDOWN_SetBuddyInt(WND
*wndPtr
)
228 UPDOWN_INFO
*infoPtr
= UPDOWN_GetInfoPtr(wndPtr
);
232 if (!IsWindow32(infoPtr
->Buddy
))
235 dprintf_info(updown
, "UpDown Ctrl: set new value(%d) to buddy.\n",
238 /*if the buddy is a list window, we must set curr index */
239 if(WIDGETS_IsControl32(WIN_FindWndPtr(infoPtr
->Buddy
), BIC32_LISTBOX
)){
240 SendMessage32A(infoPtr
->Buddy
, LB_SETCURSEL32
, infoPtr
->CurVal
, 0);
242 else{ /* Regural window, so set caption to the number */
243 len
= sprintf(txt1
, (infoPtr
->Base
==16) ? "%X" : "%d", infoPtr
->CurVal
);
245 sep
= UPDOWN_GetThousandSep();
247 if (!(wndPtr
->dwStyle
& UDS_NOTHOUSANDS
)) {
248 char txt2
[20], *src
= txt1
, *dst
= txt2
;
250 strncpy(dst
, src
, len
%3);
254 for(len
=0; *src
; len
++,src
++){
259 *dst
= 0; /* null terminate it */
260 strcpy(txt1
, txt2
); /* move it to the proper place */
262 SetWindowText32A(infoPtr
->Buddy
, txt1
);
268 /***********************************************************************
270 * Draw the arrows. The background need not be erased.
272 static void UPDOWN_Paint(WND
*wndPtr
)
274 UPDOWN_INFO
*infoPtr
= UPDOWN_GetInfoPtr(wndPtr
);
280 /* start painting the button */
281 hdc
= BeginPaint32( wndPtr
->hwndSelf
, &ps
);
283 /* Draw the incr button */
284 UPDOWN_GetArrowRect(wndPtr
, &rect
, TRUE
);
285 prssed
= (infoPtr
->Flags
& FLAG_INCR
) && (infoPtr
->Flags
& FLAG_MOUSEIN
);
286 DrawFrameControl32(hdc
, &rect
, DFC_SCROLL
,
287 (wndPtr
->dwStyle
& UDS_HORZ
? DFCS_SCROLLLEFT
: DFCS_SCROLLUP
) |
288 (prssed
? DFCS_PUSHED
: 0) |
289 (wndPtr
->dwStyle
&WS_DISABLED
? DFCS_INACTIVE
: 0) );
291 /* Draw the space between the buttons */
292 rect
.top
= rect
.bottom
; rect
.bottom
++;
293 DrawEdge32(hdc
, &rect
, 0, BF_MIDDLE
);
295 /* Draw the decr button */
296 UPDOWN_GetArrowRect(wndPtr
, &rect
, FALSE
);
297 prssed
= (infoPtr
->Flags
& FLAG_DECR
) && (infoPtr
->Flags
& FLAG_MOUSEIN
);
298 DrawFrameControl32(hdc
, &rect
, DFC_SCROLL
,
299 (wndPtr
->dwStyle
& UDS_HORZ
? DFCS_SCROLLRIGHT
: DFCS_SCROLLDOWN
) |
300 (prssed
? DFCS_PUSHED
: 0) |
301 (wndPtr
->dwStyle
&WS_DISABLED
? DFCS_INACTIVE
: 0) );
305 EndPaint32( wndPtr
->hwndSelf
, &ps
);
308 /***********************************************************************
310 * Tests if 'hwndBud' is a valid window handle. If not, returns FALSE.
311 * Else, sets it as a new Buddy.
312 * Then, it should subclass the buddy
313 * If window has the UDS_ARROWKEYS, it subcalsses the buddy window to
314 * process the UP/DOWN arrow keys.
315 * If window has the UDS_ALIGNLEFT or UDS_ALIGNRIGHT style
316 * the size/pos of the buddy and the control are adjusted accordingly.
318 static BOOL32
UPDOWN_SetBuddy(WND
*wndPtr
, HWND32 hwndBud
)
320 UPDOWN_INFO
*infoPtr
= UPDOWN_GetInfoPtr(wndPtr
);
321 RECT32 budRect
; /* new coord for the buddy */
322 int x
; /* new x position and width for the up-down */
324 /* Is is a valid bud? */
325 if(!IsWindow32(hwndBud
))
328 if(wndPtr
->dwStyle
& UDS_ARROWKEYS
){
329 /* FIXME: we need to subclass the buddy to process the arrow keys. */
330 fprintf(stderr
, "UpDown Ctrl: we should subclass the buddy window!\n");
333 /* do we need to do any adjustments? */
334 if(!(wndPtr
->dwStyle
& (UDS_ALIGNLEFT
| UDS_ALIGNRIGHT
)))
337 /* Get the rect of the buddy relative to its parent */
338 GetWindowRect32(infoPtr
->Buddy
, &budRect
);
339 MapWindowPoints32(HWND_DESKTOP
, GetParent32(infoPtr
->Buddy
),
340 (POINT32
*)(&budRect
.left
), 2);
342 /* now do the positioning */
343 if(wndPtr
->dwStyle
& UDS_ALIGNRIGHT
){
344 budRect
.right
-= DEFAULT_WIDTH
+DEFAULT_XSEP
;
345 x
= budRect
.right
+DEFAULT_XSEP
;
347 else{ /* UDS_ALIGNLEFT */
349 budRect
.left
+= DEFAULT_WIDTH
+DEFAULT_XSEP
;
352 /* first adjust the buddy to accomodate the up/down */
353 SetWindowPos32(infoPtr
->Buddy
, 0, budRect
.left
, budRect
.top
,
354 budRect
.right
- budRect
.left
, budRect
.bottom
- budRect
.top
,
355 SWP_NOACTIVATE
|SWP_NOZORDER
);
357 /* now position the up/down */
358 /* Since the UDS_ALIGN* flags were used, */
359 /* we will pick the position and size of the window. */
360 SetWindowPos32(wndPtr
->hwndSelf
,0,x
,budRect
.top
-DEFAULT_ADDTOP
,DEFAULT_WIDTH
,
361 (budRect
.bottom
-budRect
.top
)+DEFAULT_ADDTOP
+DEFAULT_ADDBOT
,
362 SWP_NOACTIVATE
|SWP_NOZORDER
);
367 /***********************************************************************
370 * This function increments/decrements the CurVal by the
371 * 'delta' amount according to the 'incr' flag
372 * It notifies the parent as required.
373 * It handles wraping and non-wraping correctly.
374 * It is assumed that delta>0
376 static void UPDOWN_DoAction(WND
*wndPtr
, int delta
, BOOL32 incr
)
378 UPDOWN_INFO
*infoPtr
= UPDOWN_GetInfoPtr(wndPtr
);
379 int old_val
= infoPtr
->CurVal
;
382 dprintf_info(updown
, "UpDown Ctrl action: %s by %d\n",
383 incr
? "inc" : "dec", delta
);
385 /* check if we can do the modification first */
386 delta
*= (incr
? 1 : -1) * (infoPtr
->MaxVal
< infoPtr
->MinVal
? -1 : 1);
387 if(!UPDOWN_OffsetVal(wndPtr
, delta
))
390 /* so, if we can do the change, recompute delta and restore old value */
391 delta
= infoPtr
->CurVal
- old_val
;
392 infoPtr
->CurVal
= old_val
;
394 /* We must notify parent now to obtain permission */
395 ni
.iPos
= infoPtr
->CurVal
;
397 ni
.hdr
.hwndFrom
= wndPtr
->hwndSelf
;
398 ni
.hdr
.idFrom
= wndPtr
->wIDmenu
;
399 ni
.hdr
.code
= UDN_DELTAPOS
;
400 if(SendMessage32A(wndPtr
->parent
->hwndSelf
,
401 WM_NOTIFY
, wndPtr
->wIDmenu
, (LPARAM
)&ni
))
402 return; /* we are not allowed to change */
404 /* Now adjust value with (maybe new) delta */
405 if(!UPDOWN_OffsetVal(wndPtr
, ni
.iDelta
))
408 /* Now take care about our buddy */
409 if(!IsWindow32(infoPtr
->Buddy
))
410 return; /* Nothing else to do */
413 if(wndPtr
->dwStyle
& UDS_SETBUDDYINT
)
414 UPDOWN_SetBuddyInt(wndPtr
);
416 /* Also, notify it */
417 /* FIXME: do we need to send the notification only if
418 we do not have the UDS_SETBUDDYINT style set? */
419 SendMessage32A(infoPtr
->Buddy
,
420 wndPtr
->dwStyle
& UDS_HORZ
? WM_HSCROLL
: WM_VSCROLL
,
421 MAKELONG(incr
? SB_LINEUP
: SB_LINEDOWN
, infoPtr
->CurVal
),
425 /***********************************************************************
428 * Returns TRUE if it is enabled as well as its buddy (if any)
431 static BOOL32
UPDOWN_IsEnabled(WND
*wndPtr
)
433 UPDOWN_INFO
*infoPtr
= UPDOWN_GetInfoPtr(wndPtr
);
435 if(wndPtr
->dwStyle
& WS_DISABLED
)
437 return IsWindowEnabled32(infoPtr
->Buddy
);
440 /***********************************************************************
443 * Deletes any timers, releases the mouse and does redraw if necessary.
444 * If the control is not in "capture" mode, it does nothing.
445 * If the control was not in cancel mode, it returns FALSE.
446 * If the control was in cancel mode, it returns TRUE.
448 static BOOL32
UPDOWN_CancelMode(WND
*wndPtr
)
450 UPDOWN_INFO
*infoPtr
= UPDOWN_GetInfoPtr(wndPtr
);
452 /* if not in 'capture' mode, do nothing */
453 if(!(infoPtr
->Flags
& FLAG_CLICKED
))
456 KillTimer32(wndPtr
->hwndSelf
, TIMERID1
); /* kill all possible timers */
457 KillTimer32(wndPtr
->hwndSelf
, TIMERID2
);
459 if(GetCapture32() == wndPtr
->hwndSelf
) /* let the mouse go */
460 ReleaseCapture(); /* if we still have it */
462 infoPtr
->Flags
= 0; /* get rid of any flags */
463 UPDOWN_Paint(wndPtr
); /* redraw the control just in case */
468 /***********************************************************************
469 * UPDOWN_HandleMouseEvent
471 * Handle a mouse event for the updown.
472 * 'pt' is the location of the mouse event in client or
473 * windows coordinates.
475 static void UPDOWN_HandleMouseEvent(WND
*wndPtr
, UINT32 msg
, POINT32 pt
)
477 UPDOWN_INFO
*infoPtr
= UPDOWN_GetInfoPtr(wndPtr
);
483 case WM_LBUTTONDOWN
: /* Initialise mouse tracking */
484 /* If we are already in the 'clicked' mode, then nothing to do */
485 if(infoPtr
->Flags
& FLAG_CLICKED
)
488 /* If the buddy is an edit, will set focus to it */
489 if(WIDGETS_IsControl32(WIN_FindWndPtr(infoPtr
->Buddy
), BIC32_EDIT
))
490 SetFocus32(infoPtr
->Buddy
);
492 /* Now see which one is the 'active' arrow */
493 temp
= UPDOWN_GetArrowFromPoint(wndPtr
, &rect
, pt
);
495 /* Update the CurVal if necessary */
496 if(wndPtr
->dwStyle
& UDS_SETBUDDYINT
)
497 UPDOWN_GetBuddyInt(wndPtr
);
499 /* Before we proceed, see if we can spin... */
500 if(!(wndPtr
->dwStyle
& UDS_WRAP
))
501 if(( temp
&& infoPtr
->CurVal
==infoPtr
->MaxVal
) ||
502 (!temp
&& infoPtr
->CurVal
==infoPtr
->MinVal
))
505 /* Set up the correct flags */
507 infoPtr
->Flags
|= temp
? FLAG_INCR
: FLAG_DECR
;
508 infoPtr
->Flags
|= FLAG_MOUSEIN
;
510 /* repaint the control */
511 UPDOWN_Paint(wndPtr
);
513 /* process the click */
514 UPDOWN_DoAction(wndPtr
, 1, infoPtr
->Flags
& FLAG_INCR
);
516 /* now capture all mouse messages */
517 SetCapture32(wndPtr
->hwndSelf
);
519 /* and startup the first timer */
520 SetTimer32(wndPtr
->hwndSelf
, TIMERID1
, INITIAL_DELAY
, 0);
524 /* If we are not in the 'clicked' mode, then nothing to do */
525 if(!(infoPtr
->Flags
& FLAG_CLICKED
))
528 /* save the flags to see if any got modified */
529 temp
= infoPtr
->Flags
;
531 /* Now get the 'active' arrow rectangle */
532 if (infoPtr
->Flags
& FLAG_INCR
)
533 UPDOWN_GetArrowRect(wndPtr
, &rect
, TRUE
);
535 UPDOWN_GetArrowRect(wndPtr
, &rect
, FALSE
);
537 /* Update the flags if we are in/out */
538 if(PtInRect32(&rect
, pt
))
539 infoPtr
->Flags
|= FLAG_MOUSEIN
;
541 infoPtr
->Flags
&= ~FLAG_MOUSEIN
;
542 if(accelIndex
!= -1) /* if we have accel info */
543 accelIndex
= 0; /* reset it */
545 /* If state changed, redraw the control */
546 if(temp
!= infoPtr
->Flags
)
547 UPDOWN_Paint(wndPtr
);
551 fprintf(stderr
, "UpDown: Impossible case in proc "
552 "UPDOWN_HandleMouseEvent");
557 /***********************************************************************
560 LRESULT WINAPI
UpDownWindowProc(HWND32 hwnd
, UINT32 message
, WPARAM32 wParam
,
563 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
564 UPDOWN_INFO
*infoPtr
= UPDOWN_GetInfoPtr(wndPtr
);
570 /* get rid of border, if any */
571 wndPtr
->dwStyle
&= ~WS_BORDER
;
573 /* initialize the info struct */
574 infoPtr
->AccelCount
=0; infoPtr
->AccelVect
=0;
575 infoPtr
->CurVal
=0; infoPtr
->MinVal
=0; infoPtr
->MaxVal
=100; /*FIXME*/
576 infoPtr
->Base
= 10; /* Default to base 10 */
577 infoPtr
->Buddy
= 0; /* No buddy window yet */
578 infoPtr
->Flags
= 0; /* And no flags */
580 /* Do we pick the buddy win ourselves? */
581 if(wndPtr
->dwStyle
& UDS_AUTOBUDDY
)
582 UPDOWN_SetBuddy(wndPtr
, GetWindow32(wndPtr
->hwndSelf
, GW_HWNDPREV
));
584 dprintf_info(updown
, "UpDown Ctrl creation, hwnd=%04x\n", hwnd
);
588 if(infoPtr
->AccelVect
)
589 free(infoPtr
->AccelVect
);
590 dprintf_info(updown
, "UpDown Ctrl destruction, hwnd=%04x\n", hwnd
);
594 if(wndPtr
->dwStyle
& WS_DISABLED
)
595 UPDOWN_CancelMode(wndPtr
);
596 UPDOWN_Paint(wndPtr
);
600 /* if initial timer, kill it and start the repeat timer */
601 if(wParam
== TIMERID1
){
602 KillTimer32(hwnd
, TIMERID1
);
603 /* if no accel info given, used default timer */
604 if(infoPtr
->AccelCount
==0 || infoPtr
->AccelVect
==0){
609 accelIndex
= 0; /* otherwise, use it */
610 temp
= infoPtr
->AccelVect
[accelIndex
].nSec
* 1000 + 1;
612 SetTimer32(hwnd
, TIMERID2
, temp
, 0);
615 /* now, if the mouse is above us, do the thing...*/
616 if(infoPtr
->Flags
& FLAG_MOUSEIN
){
617 temp
= accelIndex
==-1 ? 1 : infoPtr
->AccelVect
[accelIndex
].nInc
;
618 UPDOWN_DoAction(wndPtr
, temp
, infoPtr
->Flags
& FLAG_INCR
);
620 if(accelIndex
!=-1 && accelIndex
< infoPtr
->AccelCount
-1){
621 KillTimer32(hwnd
, TIMERID2
);
622 accelIndex
++; /* move to the next accel info */
623 temp
= infoPtr
->AccelVect
[accelIndex
].nSec
* 1000 + 1;
624 /* make sure we have at least 1ms intervals */
625 SetTimer32(hwnd
, TIMERID2
, temp
, 0);
631 UPDOWN_CancelMode(wndPtr
);
635 if(!UPDOWN_CancelMode(wndPtr
))
637 /*If we released the mouse and our buddy is an edit */
638 /* we must select all text in it. */
639 if(WIDGETS_IsControl32(WIN_FindWndPtr(infoPtr
->Buddy
), BIC32_EDIT
))
640 SendMessage32A(infoPtr
->Buddy
, EM_SETSEL32
, 0, MAKELONG(0, -1));
645 if(UPDOWN_IsEnabled(wndPtr
)){
647 CONV_POINT16TO32( (POINT16
*)&lParam
, &pt
);
648 UPDOWN_HandleMouseEvent( wndPtr
, message
, pt
);
653 if((wndPtr
->dwStyle
& UDS_ARROWKEYS
) && UPDOWN_IsEnabled(wndPtr
)){
657 UPDOWN_GetBuddyInt(wndPtr
);
658 UPDOWN_DoAction(wndPtr
, 1, wParam
==VK_UP
);
665 UPDOWN_Paint(wndPtr
);
669 if (wParam
==0 && lParam
==0) /*if both zero, */
670 return infoPtr
->AccelCount
; /*just return the accel count*/
671 if (wParam
|| lParam
){
672 UNKNOWN_PARAM(UDM_GETACCEL
, wParam
, lParam
);
675 temp
= MIN(infoPtr
->AccelCount
, wParam
);
676 memcpy((void *)lParam
, infoPtr
->AccelVect
, temp
*sizeof(UDACCEL
));
680 dprintf_info(updown
, "UpDown Ctrl new accel info, hwnd=%04x\n", hwnd
);
681 if(infoPtr
->AccelVect
){
682 free(infoPtr
->AccelVect
);
683 infoPtr
->AccelCount
= 0;
684 infoPtr
->AccelVect
= 0;
688 infoPtr
->AccelVect
= malloc(wParam
*sizeof(UDACCEL
));
689 if(infoPtr
->AccelVect
==0)
691 memcpy(infoPtr
->AccelVect
, (void*)lParam
, wParam
*sizeof(UDACCEL
));
695 if (wParam
|| lParam
)
696 UNKNOWN_PARAM(UDM_GETBASE
, wParam
, lParam
);
697 return infoPtr
->Base
;
700 dprintf_info(updown
, "UpDown Ctrl new base(%d), hwnd=%04x\n",
702 if ( !(wParam
==10 || wParam
==16) || lParam
)
703 UNKNOWN_PARAM(UDM_SETBASE
, wParam
, lParam
);
704 if (wParam
==10 || wParam
==16){
705 temp
= infoPtr
->Base
;
706 infoPtr
->Base
= wParam
;
707 return temp
; /* return the prev base */
712 if (wParam
|| lParam
)
713 UNKNOWN_PARAM(UDM_GETBUDDY
, wParam
, lParam
);
714 return infoPtr
->Buddy
;
718 UNKNOWN_PARAM(UDM_SETBUDDY
, wParam
, lParam
);
719 temp
= infoPtr
->Buddy
;
720 infoPtr
->Buddy
= wParam
;
721 UPDOWN_SetBuddy(wndPtr
, wParam
);
722 dprintf_info(updown
, "UpDown Ctrl new buddy(%04x), hwnd=%04x\n",
723 infoPtr
->Buddy
, hwnd
);
727 if (wParam
|| lParam
)
728 UNKNOWN_PARAM(UDM_GETPOS
, wParam
, lParam
);
729 temp
= UPDOWN_GetBuddyInt(wndPtr
);
730 return MAKELONG(infoPtr
->CurVal
, temp
? 0 : 1);
733 if (wParam
|| HIWORD(lParam
))
734 UNKNOWN_PARAM(UDM_GETPOS
, wParam
, lParam
);
735 temp
= SLOWORD(lParam
);
736 dprintf_info(updown
, "UpDown Ctrl new value(%d), hwnd=%04x\n",
738 if(!UPDOWN_InBounds(wndPtr
, temp
)){
739 if(temp
< infoPtr
->MinVal
)
740 temp
= infoPtr
->MinVal
;
741 if(temp
> infoPtr
->MaxVal
)
742 temp
= infoPtr
->MaxVal
;
744 wParam
= infoPtr
->CurVal
; /* save prev value */
745 infoPtr
->CurVal
= temp
; /* set the new value */
746 if(wndPtr
->dwStyle
& UDS_SETBUDDYINT
)
747 UPDOWN_SetBuddyInt(wndPtr
);
748 return wParam
; /* return prev value */
751 if (wParam
|| lParam
)
752 UNKNOWN_PARAM(UDM_GETRANGE
, wParam
, lParam
);
753 return MAKELONG(infoPtr
->MaxVal
, infoPtr
->MinVal
);
757 UNKNOWN_PARAM(UDM_SETRANGE
, wParam
, lParam
); /* we must have: */
758 infoPtr
->MaxVal
= SLOWORD(lParam
); /* UD_MINVAL <= Max <= UD_MAXVAL */
759 infoPtr
->MinVal
= SHIWORD(lParam
); /* UD_MINVAL <= Min <= UD_MAXVAL */
760 /* |Max-Min| <= UD_MAXVAL */
761 dprintf_info(updown
, "UpDown Ctrl new range(%d to %d), hwnd=%04x\n",
762 infoPtr
->MinVal
, infoPtr
->MaxVal
, hwnd
);
766 if (message
>= WM_USER
)
767 fprintf( stderr
, "UpDown Ctrl: unknown msg %04x wp=%04x lp=%08lx\n",
768 message
, wParam
, lParam
);
769 return DefWindowProc32A( hwnd
, message
, wParam
, lParam
);