comctl32 updown base 16 bug fix
Leslie Choong
septikus at gmail.com
Sat Mar 24 14:52:40 CDT 2007
Hi There, this bug fix addresses the issue brought up here:
http://bugs.winehq.org/show_bug.cgi?id=7034
I have added tests to confirm the existence of the bug and that it has
been fixed.
Let me know of any changes you think are necessary.
-Leslie Choong
-------------- next part --------------
From 538f7ffdac284ff15daafa72c4209a24221768e8 Mon Sep 17 00:00:00 2001
From: U-SEPTIKUS\Leslie <septikus at gmail.com>
Date: Thu, 22 Mar 2007 20:22:03 -0800
Subject: [PATCH] comctl32: updown: Fixed Base 16 range handling bug
---
tests/updown.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
updown.c | 43 ++++++++++++++++++++++++++++++++++------
2 files changed, 96 insertions(+), 7 deletions(-)
diff --git a/dlls/comctl32/tests/updown.c b/dlls/comctl32/tests/updown.c
index a5781ee..2dfa61c 100644
--- a/dlls/comctl32/tests/updown.c
+++ b/dlls/comctl32/tests/updown.c
@@ -546,6 +546,65 @@ static void test_updown_unicode(void)
ok_sequence(sequences, UPDOWN_SEQ_INDEX, test_updown_unicode_seq, "test updown unicode", FALSE);
}
+static void test_set_base16_range_bug(void)
+{
+ int r;
+
+ /* Some messages are not checked as previous value set before function */
+ SendMessage(updown, UDM_SETBASE, 10 , 0);
+ r = SendMessage(updown, UDM_GETBASE, 0 , 0);
+ expect(10,r);
+
+ SendMessage(updown, UDM_SETRANGE, 0 , MAKELONG(10,-10) );
+ r = SendMessage(updown, UDM_GETRANGE, 0,0);
+ expect(MAKELONG(10,-10),r);
+
+ r = SendMessage(updown, UDM_SETBASE, 16 , 0);
+ expect(10,r);
+ r = SendMessage(updown, UDM_GETBASE, 0 , 0);
+ expect(16,r);
+
+ r = SendMessage(updown, UDM_GETRANGE, 0,0);
+ expect(MAKELONG(10,-10),r);
+
+ /* Test that the lower range is 0xA */
+ SendMessage(updown, UDM_SETPOS, 0,MAKELONG(10,0));
+ r = SendMessage(updown, UDM_GETPOS, 0,0);
+ expect(10,LOWORD(r));
+ expect(1,HIWORD(r));
+
+ r = SendMessage(updown, UDM_SETPOS, 0,MAKELONG(9,0));
+ expect(10,r);
+ r = SendMessage(updown, UDM_GETPOS, 0,0);
+ expect(10,LOWORD(r));
+ expect(1,HIWORD(r));
+
+ r = SendMessage(updown, UDM_SETPOS, 0,MAKELONG(11,0));
+ expect(10,r);
+ r = SendMessage(updown, UDM_GETPOS, 0,0);
+ expect(11,LOWORD(r));
+ expect(1,HIWORD(r));
+
+ /* Test that upper range is 0xFFF6 (-10 unsigned) */
+ r = SendMessage(updown, UDM_SETPOS, 0, MAKELONG(0xFFF6,0));
+ expect(11,r);
+ r = SendMessage(updown, UDM_GETPOS, 0,0);
+ expect(0xFFF6,LOWORD(r));
+ expect(1,HIWORD(r));
+
+ r = SendMessage(updown, UDM_SETPOS, 0, MAKELONG(0xFFF7,0));
+ expect(-10,r);
+ r = SendMessage(updown, UDM_GETPOS, 0,0);
+ expect(0xFFF6,LOWORD(r));
+ expect(1,HIWORD(r));
+
+ r = SendMessage(updown, UDM_SETPOS, 0, MAKELONG(0xFFF5,0));
+ expect(-10,r);
+ r = SendMessage(updown, UDM_GETPOS, 0,0);
+ expect(0xFFF5,LOWORD(r));
+ expect(1,HIWORD(r));
+}
+
static void test_create_updown_control(void)
{
CHAR text[MAX_PATH];
@@ -580,6 +639,7 @@ static void test_create_updown_control(void)
test_updown_buddy();
test_updown_base();
test_updown_unicode();
+ test_set_base16_range_bug();
}
START_TEST(updown)
diff --git a/dlls/comctl32/updown.c b/dlls/comctl32/updown.c
old mode 100644
new mode 100755
index 7fbe3c9..aec1e4a
--- a/dlls/comctl32/updown.c
+++ b/dlls/comctl32/updown.c
@@ -128,10 +128,20 @@ static inline BOOL UPDOWN_IsBuddyListbox(UPDOWN_INFO *infoPtr)
*/
static BOOL UPDOWN_InBounds(UPDOWN_INFO *infoPtr, int val)
{
- if(infoPtr->MaxVal > infoPtr->MinVal)
- return (infoPtr->MinVal <= val) && (val <= infoPtr->MaxVal);
- else
- return (infoPtr->MaxVal <= val) && (val <= infoPtr->MinVal);
+ if(infoPtr->Base == 10) {
+ if(infoPtr->MaxVal > infoPtr->MinVal)
+ return (infoPtr->MinVal <= val) && (val <= infoPtr->MaxVal);
+ else
+ return (infoPtr->MaxVal <= val) && (val <= infoPtr->MinVal);
+ } else { /* Base is 16 and must do unsigned integer comparison */
+ unsigned int uMinVal = (unsigned int) infoPtr->MinVal;
+ unsigned int uMaxVal = (unsigned int) infoPtr->MaxVal;
+ unsigned int uval = (unsigned int) val;
+ if(uMaxVal > uMinVal)
+ return (uMinVal <= uval) && (uval <= uMaxVal);
+ else
+ return (uMaxVal <= uval) && (uval <= uMinVal);
+ }
}
/***********************************************************************
@@ -616,7 +626,13 @@ static void UPDOWN_DoAction (UPDOWN_INFO *infoPtr, int delta, int action)
TRACE("%d by %d\n", action, delta);
/* check if we can do the modification first */
- delta *= (action & FLAG_INCR ? 1 : -1) * (infoPtr->MaxVal < infoPtr->MinVal ? -1 : 1);
+ if(infoPtr->Base == 10)
+ delta *= (action & FLAG_INCR ? 1 : -1) * (infoPtr->MaxVal < infoPtr->MinVal ? -1 : 1);
+ else {
+ unsigned int uMinVal = (unsigned int) infoPtr->MinVal;
+ unsigned int uMaxVal = (unsigned int) infoPtr->MaxVal;
+ delta *= (action & FLAG_INCR ? 1 : -1) * (uMaxVal < uMinVal ? -1 : 1);
+ }
if ( (action & FLAG_INCR) && (action & FLAG_DECR) ) delta = 0;
TRACE("current %d, delta: %d\n", infoPtr->CurVal, delta);
@@ -992,8 +1008,21 @@ static LRESULT WINAPI UpDownWindowProc(HWND hwnd, UINT message, WPARAM wParam, L
temp = (short)LOWORD(lParam);
TRACE("UpDown Ctrl new value(%d), hwnd=%p\n", temp, hwnd);
if(!UPDOWN_InBounds(infoPtr, temp)) {
- if(temp < infoPtr->MinVal) temp = infoPtr->MinVal;
- if(temp > infoPtr->MaxVal) temp = infoPtr->MaxVal;
+ if(infoPtr->Base == 10) {
+ if(temp < infoPtr->MinVal) temp = infoPtr->MinVal;
+ if(temp > infoPtr->MaxVal) temp = infoPtr->MaxVal;
+ } else { /* In Base 16 mode and must treat as unsigned */
+ unsigned int uMinVal = (unsigned int) infoPtr->MinVal;
+ unsigned int uMaxVal = (unsigned int) infoPtr->MaxVal;
+ unsigned int utemp = (unsigned int) temp;
+ if(uMaxVal > uMinVal) {
+ if(utemp < uMinVal) temp = infoPtr->MinVal;
+ if(utemp > uMaxVal) temp = infoPtr->MaxVal;
+ } else { /* Ranges are flopped so must flop comparison */
+ if(utemp > uMinVal) temp = infoPtr->MinVal;
+ if(utemp < uMaxVal) temp = infoPtr->MaxVal;
+ }
+ }
}
wParam = infoPtr->CurVal;
infoPtr->CurVal = temp;
More information about the wine-patches
mailing list