UpDown Ctrl
Dimitrie O. Paun
dpaun at rogers.com
Thu Mar 28 00:50:17 CST 2002
I had this in my tree/head for a long time now,
so I guess it's time to let it lose.
Note that I am using the new KMail 1.4 from KDE 3.0rc3,
and as such, I don't know how well it behaves with
inline patches. Hope it does not mangle them. If it does,
please let me know.
ChangeLog:
-- updown unicodification
-- better/cleaner buddy handling
-- few bugs fixed
-- more testing
-- consistent indentation
Patch:
Index: dlls/comctl32/updown.c
===================================================================
RCS file: /var/cvs/wine/dlls/comctl32/updown.c,v
retrieving revision 1.36
diff -u -r1.36 updown.c
--- dlls/comctl32/updown.c 9 Mar 2002 23:29:34 -0000 1.36
+++ dlls/comctl32/updown.c 28 Mar 2002 06:25:19 -0000
@@ -17,22 +17,6 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * TODO:
- * - I think I do not handle correctly the WS_BORDER style.
- * (Should be fixed. <ekohl at abo.rhein-zeitung.de>)
- *
- * Testing:
- * Not much. The following have not been tested at all:
- * - horizontal arrows
- * - listbox as buddy window
- * - acceleration
- * - base 16
- * - integers with thousand separators.
- * (fixed bugs. <noel at macadamian.com>)
- *
- * Even though the above list seems rather large, the control seems to
- * behave very well so I am confident it does work in most (all) of the
- * untested cases.
*/
#include <stdlib.h>
@@ -45,31 +29,30 @@
#include "winuser.h"
#include "commctrl.h"
#include "winnls.h"
+#include "ntddk.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(updown);
-#define UPDOWN_BUDDYCLASSNAMELEN 40
-
typedef struct
{
- HWND Self; /* Handle to this up-down control */
- UINT AccelCount; /* Number of elements in AccelVect */
- UDACCEL* AccelVect; /* Vector containing AccelCount elements */
- INT AccelIndex; /* Current accel index, -1 if not accelerating */
- INT Base; /* Base to display nr in the buddy window */
- INT CurVal; /* Current up-down value */
- INT MinVal; /* Minimum up-down value */
- INT MaxVal; /* Maximum up-down value */
- HWND Buddy; /* Handle to the buddy window */
- CHAR szBuddyClass[UPDOWN_BUDDYCLASSNAMELEN]; /* Buddy window class name */
- INT Flags; /* Internal Flags FLAG_* */
+ HWND Self; /* Handle to this up-down control */
+ UINT AccelCount; /* Number of elements in AccelVect */
+ UDACCEL* AccelVect; /* Vector containing AccelCount elements */
+ INT AccelIndex; /* Current accel index, -1 if not accel'ing */
+ INT Base; /* Base to display nr in the buddy window */
+ INT CurVal; /* Current up-down value */
+ INT MinVal; /* Minimum up-down value */
+ INT MaxVal; /* Maximum up-down value */
+ HWND Buddy; /* Handle to the buddy window */
+ int BuddyType; /* Remembers the buddy type BUDDY_TYPE_* */
+ INT Flags; /* Internal Flags FLAG_* */
} UPDOWN_INFO;
/* Control configuration constants */
-#define INITIAL_DELAY 500 /* initial timer until auto-increment kicks in */
-#define REPEAT_DELAY 50 /* delay between auto-increments */
+#define INITIAL_DELAY 500 /* initial timer until auto-inc kicks in */
+#define REPEAT_DELAY 50 /* delay between auto-increments */
#define DEFAULT_WIDTH 14 /* default width of the ctrl */
#define DEFAULT_XSEP 0 /* default separation between buddy and crtl */
@@ -85,6 +68,10 @@
#define FLAG_MOUSEIN 0x04
#define FLAG_CLICKED (FLAG_INCR | FLAG_DECR)
+#define BUDDY_TYPE_UNKNOWN 0
+#define BUDDY_TYPE_LISTBOX 1
+#define BUDDY_TYPE_EDIT 2
+
#define TIMERID1 1
#define TIMERID2 2
#define BUDDY_UPDOWN_HWND "buddyUpDownHWND"
@@ -95,59 +82,75 @@
"(%04x): wp=%04x lp=%08lx\n", msg, wParam, lParam);
#define UPDOWN_GetInfoPtr(hwnd) ((UPDOWN_INFO *)GetWindowLongA (hwnd,0))
+#define COUNT_OF(a) (sizeof(a)/sizeof(a[0]))
static LRESULT CALLBACK
UPDOWN_Buddy_SubclassProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
/***********************************************************************
+ * UPDOWN_IsBuddyEdit
+ * Tests if our buddy is an edit control.
+ */
+static inline BOOL UPDOWN_IsBuddyEdit(UPDOWN_INFO *infoPtr)
+{
+ return infoPtr->BuddyType == BUDDY_TYPE_EDIT;
+}
+
+/***********************************************************************
+ * UPDOWN_IsBuddyListbox
+ * Tests if our buddy is a listbox control.
+ */
+static inline BOOL UPDOWN_IsBuddyListbox(UPDOWN_INFO *infoPtr)
+{
+ return infoPtr->BuddyType == BUDDY_TYPE_LISTBOX;
+}
+
+/***********************************************************************
* UPDOWN_InBounds
* Tests if a given value 'val' is between the Min&Max limits
*/
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->MaxVal > infoPtr->MinVal)
+ return (infoPtr->MinVal <= val) && (val <= infoPtr->MaxVal);
+ else
+ return (infoPtr->MaxVal <= val) && (val <= infoPtr->MinVal);
}
/***********************************************************************
* UPDOWN_OffsetVal
- * Tests if we can change the current value by delta. If so, it changes
- * it and returns TRUE. Else, it leaves it unchanged and returns FALSE.
+ * Change the current value by delta.
+ * It returns TRUE is the value was changed successfuly, or FALSE
+ * if the value was not changed, as it would go out of bounds.
*/
static BOOL UPDOWN_OffsetVal(UPDOWN_INFO *infoPtr, int delta)
{
- /* check if we can do the modification first */
- if(!UPDOWN_InBounds (infoPtr, infoPtr->CurVal+delta)){
- if (GetWindowLongW (infoPtr->Self, GWL_STYLE) & UDS_WRAP)
- {
- delta += (delta < 0 ? -1 : 1) *
- (infoPtr->MaxVal < infoPtr->MinVal ? -1 : 1) *
- (infoPtr->MinVal - infoPtr->MaxVal) +
- (delta < 0 ? 1 : -1);
+ /* check if we can do the modification first */
+ if(!UPDOWN_InBounds (infoPtr, infoPtr->CurVal+delta)) {
+ if (GetWindowLongW (infoPtr->Self, GWL_STYLE) & UDS_WRAP) {
+ delta += (delta < 0 ? -1 : 1) *
+ (infoPtr->MaxVal < infoPtr->MinVal ? -1 : 1) *
+ (infoPtr->MinVal - infoPtr->MaxVal) +
+ (delta < 0 ? 1 : -1);
+ } else return FALSE;
}
- else
- return FALSE;
- }
- infoPtr->CurVal += delta;
- return TRUE;
+ infoPtr->CurVal += delta;
+ return TRUE;
}
/***********************************************************************
- * UPDOWN_HasBuddyBorder [Internal]
+ * UPDOWN_HasBuddyBorder
*
* When we have a buddy set and that we are aligned on our buddy, we
* want to draw a sunken edge to make like we are part of that control.
*/
static BOOL UPDOWN_HasBuddyBorder(UPDOWN_INFO* infoPtr)
{
- DWORD dwStyle = GetWindowLongW (infoPtr->Self, GWL_STYLE);
+ DWORD dwStyle = GetWindowLongW (infoPtr->Self, GWL_STYLE);
- return ( ((dwStyle & (UDS_ALIGNLEFT | UDS_ALIGNRIGHT)) != 0) &&
- (SendMessageW(infoPtr->Self, UDM_GETBUDDY, 0, 0) != 0) &&
- (lstrcmpiA(infoPtr->szBuddyClass, "EDIT") == 0 ) );
+ return ( ((dwStyle & (UDS_ALIGNLEFT | UDS_ALIGNRIGHT)) != 0) &&
+ UPDOWN_IsBuddyEdit(infoPtr) );
}
/***********************************************************************
@@ -159,42 +162,42 @@
*/
static void UPDOWN_GetArrowRect (UPDOWN_INFO* infoPtr, RECT *rect, BOOL incr)
{
- DWORD dwStyle = GetWindowLongW (infoPtr->Self, GWL_STYLE);
- int len; /* will hold the width or height */
+ DWORD dwStyle = GetWindowLongW (infoPtr->Self, GWL_STYLE);
+ int len; /* will hold the width or height */
- GetClientRect (infoPtr->Self, rect);
+ GetClientRect (infoPtr->Self, rect);
- /*
- * Make sure we calculate the rectangle to fit even if we draw the
- * border.
- */
- if (UPDOWN_HasBuddyBorder(infoPtr)) {
- if (dwStyle & UDS_ALIGNLEFT)
- rect->left += DEFAULT_BUDDYBORDER;
- else
- rect->right -= DEFAULT_BUDDYBORDER;
+ /*
+ * Make sure we calculate the rectangle to fit even if we draw the
+ * border.
+ */
+ if (UPDOWN_HasBuddyBorder(infoPtr)) {
+ if (dwStyle & UDS_ALIGNLEFT)
+ rect->left += DEFAULT_BUDDYBORDER;
+ else
+ rect->right -= DEFAULT_BUDDYBORDER;
- InflateRect(rect, 0, -DEFAULT_BUDDYBORDER);
- }
+ InflateRect(rect, 0, -DEFAULT_BUDDYBORDER);
+ }
- /*
- * We're calculating the midpoint to figure-out where the
- * separation between the buttons will lay. We make sure that we
- * round the uneven numbers by adding 1.
- */
- if (dwStyle & UDS_HORZ) {
- len = rect->right - rect->left + 1; /* compute the width */
- if (incr)
- rect->left = rect->left + len/2;
- else
- rect->right = rect->left + len/2;
- } else {
- len = rect->bottom - rect->top + 1; /* compute the height */
- if (incr)
- rect->bottom = rect->top + len/2;
- else
- rect->top = rect->top + len/2;
- }
+ /*
+ * We're calculating the midpoint to figure-out where the
+ * separation between the buttons will lay. We make sure that we
+ * round the uneven numbers by adding 1.
+ */
+ if (dwStyle & UDS_HORZ) {
+ len = rect->right - rect->left + 1; /* compute the width */
+ if (incr)
+ rect->left = rect->left + len/2;
+ else
+ rect->right = rect->left + len/2;
+ } else {
+ len = rect->bottom - rect->top + 1; /* compute the height */
+ if (incr)
+ rect->bottom = rect->top + len/2;
+ else
+ rect->top = rect->top + len/2;
+ }
}
/***********************************************************************
@@ -205,11 +208,11 @@
*/
static BOOL UPDOWN_GetArrowFromPoint (UPDOWN_INFO* infoPtr, RECT *rect, POINT pt)
{
- UPDOWN_GetArrowRect (infoPtr, rect, TRUE);
- if(PtInRect(rect, pt)) return TRUE;
+ UPDOWN_GetArrowRect (infoPtr, rect, TRUE);
+ if(PtInRect(rect, pt)) return TRUE;
- UPDOWN_GetArrowRect (infoPtr, rect, FALSE);
- return FALSE;
+ UPDOWN_GetArrowRect (infoPtr, rect, FALSE);
+ return FALSE;
}
@@ -217,14 +220,14 @@
* UPDOWN_GetThousandSep
* Returns the thousand sep. If an error occurs, it returns ','.
*/
-static CHAR UPDOWN_GetThousandSep()
+static WCHAR UPDOWN_GetThousandSep()
{
- CHAR sep[2];
+ WCHAR sep[2];
- if(GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, sep, 2) != 1)
- return ',';
+ if(GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, sep, 2) != 1)
+ sep[0] = ',';
- return sep[0];
+ return sep[0];
}
/***********************************************************************
@@ -237,40 +240,35 @@
*/
static BOOL UPDOWN_GetBuddyInt (UPDOWN_INFO *infoPtr)
{
- char txt[20], sep, *src, *dst;
- int newVal;
+ WCHAR txt[20], sep, *src, *dst;
+ int newVal;
- if (!IsWindow(infoPtr->Buddy))
- return FALSE;
+ if (!IsWindow(infoPtr->Buddy))
+ return FALSE;
- /*if the buddy is a list window, we must set curr index */
- if (!lstrcmpA (infoPtr->szBuddyClass, "ListBox")){
- newVal = SendMessageA(infoPtr->Buddy, LB_GETCARETINDEX, 0, 0);
- if(newVal < 0)
- return FALSE;
- }
- else{
- /* we have a regular window, so will get the text */
- if (!GetWindowTextA(infoPtr->Buddy, txt, sizeof(txt)))
- return FALSE;
-
- sep = UPDOWN_GetThousandSep();
-
- /* now get rid of the separators */
- for(src = dst = txt; *src; src++)
- if(*src != sep) *dst++ = *src;
- *dst = 0;
-
- /* try to convert the number and validate it */
- newVal = strtol(txt, &src, infoPtr->Base);
- if(*src || !UPDOWN_InBounds (infoPtr, newVal))
- return FALSE;
+ /*if the buddy is a list window, we must set curr index */
+ if (UPDOWN_IsBuddyListbox(infoPtr)) {
+ newVal = SendMessageW(infoPtr->Buddy, LB_GETCARETINDEX, 0, 0);
+ if(newVal < 0) return FALSE;
+ } else {
+ /* we have a regular window, so will get the text */
+ if (!GetWindowTextW(infoPtr->Buddy, txt, COUNT_OF(txt))) return FALSE;
- TRACE("new value(%d) from buddy (old=%d)\n", newVal, infoPtr->CurVal);
- }
+ sep = UPDOWN_GetThousandSep();
+
+ /* now get rid of the separators */
+ for(src = dst = txt; *src; src++)
+ if(*src != sep) *dst++ = *src;
+ *dst = 0;
+
+ /* try to convert the number and validate it */
+ newVal = wcstol(txt, &src, infoPtr->Base);
+ if(*src || !UPDOWN_InBounds (infoPtr, newVal)) return FALSE;
+ }
- infoPtr->CurVal = newVal;
- return TRUE;
+ TRACE("new value(%d) from buddy (old=%d)\n", newVal, infoPtr->CurVal);
+ infoPtr->CurVal = newVal;
+ return TRUE;
}
@@ -283,112 +281,110 @@
*/
static BOOL UPDOWN_SetBuddyInt (UPDOWN_INFO *infoPtr)
{
- char txt1[20], sep;
- int len;
+ WCHAR fmt[3] = { '%', 'd', '\0' };
+ WCHAR txt[20];
+ int len;
- if (!IsWindow(infoPtr->Buddy))
- return FALSE;
+ if (!IsWindow(infoPtr->Buddy)) return FALSE;
- TRACE("set new value(%d) to buddy.\n", infoPtr->CurVal);
+ TRACE("set new value(%d) to buddy.\n", infoPtr->CurVal);
- /*if the buddy is a list window, we must set curr index */
- if(!lstrcmpA (infoPtr->szBuddyClass, "ListBox")){
- SendMessageA(infoPtr->Buddy, LB_SETCURSEL, infoPtr->CurVal, 0);
- }
- else{ /* Regular window, so set caption to the number */
- len = sprintf(txt1, (infoPtr->Base==16) ? "%X" : "%d", infoPtr->CurVal);
+ /*if the buddy is a list window, we must set curr index */
+ if (UPDOWN_IsBuddyListbox(infoPtr)) {
+ return SendMessageW(infoPtr->Buddy, LB_SETCURSEL, infoPtr->CurVal, 0) != LB_ERR;
+ }
+
+ /* Regular window, so set caption to the number */
+ if (infoPtr->Base == 16) fmt[1] = 'X';
+ len = swprintf(txt, fmt, infoPtr->CurVal);
- sep = UPDOWN_GetThousandSep();
/* Do thousands seperation if necessary */
- if (!(GetWindowLongA (infoPtr->Self, GWL_STYLE) & UDS_NOTHOUSANDS) && (len > 3)) {
- char txt2[20], *src = txt1, *dst = txt2;
- if(len % 3 > 0) {
- lstrcpynA (dst, src, len%3 + 1); /* need to include the null */
- dst += len%3;
- src += len%3;
- }
- for(len=0; *src; len++) {
- if(len%3==0) *dst++ = sep;
- *dst++ = *src++;
- }
- *dst = 0; /* null terminate it */
- strcpy(txt1, txt2); /* move it to the proper place */
+ if (!(GetWindowLongW (infoPtr->Self, GWL_STYLE) & UDS_NOTHOUSANDS) && (len > 3)) {
+ WCHAR tmp[COUNT_OF(txt)], *src = tmp, *dst = txt;
+ WCHAR sep = UPDOWN_GetThousandSep();
+ int start = len % 3;
+
+ memcpy(tmp, txt, sizeof(txt));
+ if (start == 0) start = 3;
+ dst += start;
+ src += start;
+ for (len=0; *src; len++) {
+ if (len % 3 == 0) *dst++ = sep;
+ *dst++ = *src++;
+ }
+ *dst = 0;
}
- SetWindowTextA(infoPtr->Buddy, txt1);
- }
-
- return TRUE;
+
+ return SetWindowTextW(infoPtr->Buddy, txt);
}
/***********************************************************************
- * UPDOWN_DrawBuddyBorder [Internal]
+ * UPDOWN_DrawBuddyBorder
*
* When we have a buddy set and that we are aligned on our buddy, we
* want to draw a sunken edge to make like we are part of that control.
*/
static void UPDOWN_DrawBuddyBorder (UPDOWN_INFO *infoPtr, HDC hdc)
{
- DWORD dwStyle = GetWindowLongA (infoPtr->Self, GWL_STYLE);
- RECT clientRect;
+ DWORD dwStyle = GetWindowLongW (infoPtr->Self, GWL_STYLE);
+ RECT clientRect;
- GetClientRect(infoPtr->Self, &clientRect);
+ GetClientRect(infoPtr->Self, &clientRect);
- if (dwStyle & UDS_ALIGNLEFT)
- DrawEdge(hdc, &clientRect, EDGE_SUNKEN, BF_BOTTOM | BF_LEFT | BF_TOP);
- else
- DrawEdge(hdc, &clientRect, EDGE_SUNKEN, BF_BOTTOM | BF_RIGHT | BF_TOP);
+ if (dwStyle & UDS_ALIGNLEFT)
+ DrawEdge(hdc, &clientRect, EDGE_SUNKEN, BF_BOTTOM | BF_LEFT | BF_TOP);
+ else
+ DrawEdge(hdc, &clientRect, EDGE_SUNKEN, BF_BOTTOM | BF_RIGHT | BF_TOP);
}
/***********************************************************************
- * UPDOWN_Draw [Internal]
+ * UPDOWN_Draw
*
* Draw the arrows. The background need not be erased.
*/
static void UPDOWN_Draw (UPDOWN_INFO *infoPtr, HDC hdc)
{
- DWORD dwStyle = GetWindowLongA (infoPtr->Self, GWL_STYLE);
- BOOL prssed;
- RECT rect;
-
- /*
- * Draw the common border between ourselves and our buddy.
- */
- if (UPDOWN_HasBuddyBorder(infoPtr))
- UPDOWN_DrawBuddyBorder(infoPtr, hdc);
+ DWORD dwStyle = GetWindowLongW (infoPtr->Self, GWL_STYLE);
+ BOOL prssed;
+ RECT rect;
+
+ /* Draw the common border between ourselves and our buddy */
+ if (UPDOWN_HasBuddyBorder(infoPtr))
+ UPDOWN_DrawBuddyBorder(infoPtr, hdc);
- /* Draw the incr button */
- UPDOWN_GetArrowRect (infoPtr, &rect, TRUE);
- prssed = (infoPtr->Flags & FLAG_INCR) && (infoPtr->Flags & FLAG_MOUSEIN);
- DrawFrameControl(hdc, &rect, DFC_SCROLL,
+ /* Draw the incr button */
+ UPDOWN_GetArrowRect (infoPtr, &rect, TRUE);
+ prssed = (infoPtr->Flags & FLAG_INCR) && (infoPtr->Flags & FLAG_MOUSEIN);
+ DrawFrameControl(hdc, &rect, DFC_SCROLL,
(dwStyle & UDS_HORZ ? DFCS_SCROLLRIGHT : DFCS_SCROLLUP) |
(prssed ? DFCS_PUSHED : 0) |
(dwStyle&WS_DISABLED ? DFCS_INACTIVE : 0) );
- /* Draw the space between the buttons */
- rect.top = rect.bottom; rect.bottom++;
- DrawEdge(hdc, &rect, 0, BF_MIDDLE);
+ /* Draw the space between the buttons */
+ rect.top = rect.bottom; rect.bottom++;
+ DrawEdge(hdc, &rect, 0, BF_MIDDLE);
- /* Draw the decr button */
- UPDOWN_GetArrowRect(infoPtr, &rect, FALSE);
- prssed = (infoPtr->Flags & FLAG_DECR) && (infoPtr->Flags & FLAG_MOUSEIN);
- DrawFrameControl(hdc, &rect, DFC_SCROLL,
+ /* Draw the decr button */
+ UPDOWN_GetArrowRect(infoPtr, &rect, FALSE);
+ prssed = (infoPtr->Flags & FLAG_DECR) && (infoPtr->Flags & FLAG_MOUSEIN);
+ DrawFrameControl(hdc, &rect, DFC_SCROLL,
(dwStyle & UDS_HORZ ? DFCS_SCROLLLEFT : DFCS_SCROLLDOWN) |
(prssed ? DFCS_PUSHED : 0) |
(dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0) );
}
/***********************************************************************
- * UPDOWN_Refresh [Internal]
+ * UPDOWN_Refresh
*
* Synchronous drawing (must NOT be used in WM_PAINT).
* Calls UPDOWN_Draw.
*/
static void UPDOWN_Refresh (UPDOWN_INFO *infoPtr)
{
- HDC hdc = GetDC (infoPtr->Self);
- UPDOWN_Draw (infoPtr, hdc);
- ReleaseDC (infoPtr->Self, hdc);
+ HDC hdc = GetDC(infoPtr->Self);
+ UPDOWN_Draw(infoPtr, hdc);
+ ReleaseDC(infoPtr->Self, hdc);
}
@@ -401,13 +397,13 @@
static void UPDOWN_Paint (UPDOWN_INFO *infoPtr, HDC hdc)
{
if (hdc) {
- UPDOWN_Draw (infoPtr, hdc);
+ UPDOWN_Draw (infoPtr, hdc);
} else {
- PAINTSTRUCT ps;
+ PAINTSTRUCT ps;
- hdc = BeginPaint (infoPtr->Self, &ps);
- UPDOWN_Draw (infoPtr, hdc);
- EndPaint (infoPtr->Self, &ps);
+ hdc = BeginPaint (infoPtr->Self, &ps);
+ UPDOWN_Draw (infoPtr, hdc);
+ EndPaint (infoPtr->Self, &ps);
}
}
@@ -423,93 +419,89 @@
*/
static BOOL UPDOWN_SetBuddy (UPDOWN_INFO* infoPtr, HWND bud)
{
- DWORD dwStyle = GetWindowLongA (infoPtr->Self, GWL_STYLE);
- RECT budRect; /* new coord for the buddy */
- int x,width; /* new x position and width for the up-down */
- WNDPROC baseWndProc, currWndProc;
+ DWORD dwStyle = GetWindowLongW (infoPtr->Self, GWL_STYLE);
+ RECT budRect; /* new coord for the buddy */
+ int x, width; /* new x position and width for the up-down */
+ WNDPROC baseWndProc, currWndProc;
+ CHAR buddyClass[40];
- /* Is it a valid bud? */
- if(!IsWindow(bud)) return FALSE;
+ /* Is it a valid bud? */
+ if(!IsWindow(bud)) return FALSE;
- /* there is already a body assigned */
- if ( infoPtr->Buddy )
- RemovePropA(infoPtr->Buddy, BUDDY_UPDOWN_HWND);
-
- /* Store buddy window handle */
- infoPtr->Buddy = bud;
-
- /* keep upDown ctrl hwnd in a buddy property */
- SetPropA( bud, BUDDY_UPDOWN_HWND, infoPtr->Self);
-
- /* Store buddy window clas name */
- memset(infoPtr->szBuddyClass, 0, UPDOWN_BUDDYCLASSNAMELEN);
- GetClassNameA (bud, infoPtr->szBuddyClass, UPDOWN_BUDDYCLASSNAMELEN-1);
-
- if(dwStyle & UDS_ARROWKEYS){
- /* Note that I don't clear the BUDDY_SUPERCLASS_WNDPROC property
- when we reset the upDown ctrl buddy to another buddy because it is not
- good to break the window proc chain. */
-
- currWndProc = (WNDPROC) GetWindowLongA(bud, GWL_WNDPROC);
- if (currWndProc != UPDOWN_Buddy_SubclassProc)
- {
- // replace the buddy's WndProc with ours
- baseWndProc = (WNDPROC)SetWindowLongA(bud, GWL_WNDPROC,
- (LPARAM)UPDOWN_Buddy_SubclassProc);
- // and save the base class' WndProc
- SetPropA(bud, BUDDY_SUPERCLASS_WNDPROC, (HANDLE)baseWndProc);
+ TRACE("(hwnd=%04x, bud=%04x)\n", infoPtr->Self, bud);
+
+ /* there is already a body assigned */
+ if (infoPtr->Buddy) RemovePropA(infoPtr->Buddy, BUDDY_UPDOWN_HWND);
+
+ /* Store buddy window handle */
+ infoPtr->Buddy = bud;
+
+ /* keep upDown ctrl hwnd in a buddy property */
+ SetPropA( bud, BUDDY_UPDOWN_HWND, infoPtr->Self);
+
+ /* Store buddy window class type */
+ infoPtr->BuddyType = BUDDY_TYPE_UNKNOWN;
+ if (GetClassNameA(bud, buddyClass, COUNT_OF(buddyClass))) {
+ if (lstrcmpiA(buddyClass, "Edit") == 0)
+ infoPtr->BuddyType = BUDDY_TYPE_EDIT;
+ else if (lstrcmpiA(buddyClass, "Listbox") == 0)
+ infoPtr->BuddyType = BUDDY_TYPE_LISTBOX;
+ }
+
+ if(dwStyle & UDS_ARROWKEYS){
+ /* Note that I don't clear the BUDDY_SUPERCLASS_WNDPROC property
+ when we reset the upDown ctrl buddy to another buddy because it is not
+ good to break the window proc chain. */
+ currWndProc = (WNDPROC) GetWindowLongW(bud, GWL_WNDPROC);
+ if (currWndProc != UPDOWN_Buddy_SubclassProc) {
+ baseWndProc = (WNDPROC)SetWindowLongW(bud, GWL_WNDPROC, (LPARAM)UPDOWN_Buddy_SubclassProc);
+ SetPropA(bud, BUDDY_SUPERCLASS_WNDPROC, (HANDLE)baseWndProc);
}
- // else
- // its already been subclassed, don't overwrite BUDDY_SUPERCLASS_WNDPROC
- }
-
- /* Get the rect of the buddy relative to its parent */
- GetWindowRect(infoPtr->Buddy, &budRect);
- MapWindowPoints(HWND_DESKTOP, GetParent(infoPtr->Buddy),
- (POINT *)(&budRect.left), 2);
-
- /* now do the positioning */
- if (dwStyle & UDS_ALIGNLEFT) {
- x = budRect.left;
- budRect.left += DEFAULT_WIDTH+DEFAULT_XSEP;
- }
- else if (dwStyle & UDS_ALIGNRIGHT){
- budRect.right -= DEFAULT_WIDTH+DEFAULT_XSEP;
- x = budRect.right+DEFAULT_XSEP;
- }
- else {
- x = budRect.right+DEFAULT_XSEP;
- }
-
- /* first adjust the buddy to accomodate the up/down */
- SetWindowPos(infoPtr->Buddy, 0, budRect.left, budRect.top,
- budRect.right - budRect.left, budRect.bottom - budRect.top,
- SWP_NOACTIVATE|SWP_NOZORDER);
-
- /* now position the up/down */
- /* Since the UDS_ALIGN* flags were used, */
- /* we will pick the position and size of the window. */
- width = DEFAULT_WIDTH;
-
- /*
- * If the updown has a buddy border, it has to overlap with the buddy
- * to look as if it is integrated with the buddy control.
- * We nudge the control or change it size to overlap.
- */
- if (UPDOWN_HasBuddyBorder(infoPtr))
- {
- if(dwStyle & UDS_ALIGNLEFT)
- width+=DEFAULT_BUDDYBORDER;
- else
- x-=DEFAULT_BUDDYBORDER;
- }
+ }
+
+ /* Get the rect of the buddy relative to its parent */
+ GetWindowRect(infoPtr->Buddy, &budRect);
+ MapWindowPoints(HWND_DESKTOP, GetParent(infoPtr->Buddy), (POINT *)(&budRect.left), 2);
+
+ /* now do the positioning */
+ if (dwStyle & UDS_ALIGNLEFT) {
+ x = budRect.left;
+ budRect.left += DEFAULT_WIDTH + DEFAULT_XSEP;
+ } else if (dwStyle & UDS_ALIGNRIGHT) {
+ budRect.right -= DEFAULT_WIDTH + DEFAULT_XSEP;
+ x = budRect.right+DEFAULT_XSEP;
+ } else {
+ x = budRect.right+DEFAULT_XSEP;
+ }
- SetWindowPos (infoPtr->Self, infoPtr->Buddy,
- x, budRect.top-DEFAULT_ADDTOP,
- width, (budRect.bottom-budRect.top)+DEFAULT_ADDTOP+DEFAULT_ADDBOT,
- SWP_NOACTIVATE);
+ /* first adjust the buddy to accomodate the up/down */
+ SetWindowPos(infoPtr->Buddy, 0, budRect.left, budRect.top,
+ budRect.right - budRect.left, budRect.bottom - budRect.top,
+ SWP_NOACTIVATE|SWP_NOZORDER);
+
+ /* now position the up/down */
+ /* Since the UDS_ALIGN* flags were used, */
+ /* we will pick the position and size of the window. */
+ width = DEFAULT_WIDTH;
+
+ /*
+ * If the updown has a buddy border, it has to overlap with the buddy
+ * to look as if it is integrated with the buddy control.
+ * We nudge the control or change it size to overlap.
+ */
+ if (UPDOWN_HasBuddyBorder(infoPtr)) {
+ if(dwStyle & UDS_ALIGNLEFT)
+ width += DEFAULT_BUDDYBORDER;
+ else
+ x -= DEFAULT_BUDDYBORDER;
+ }
- return TRUE;
+ SetWindowPos(infoPtr->Self, infoPtr->Buddy, x,
+ budRect.top - DEFAULT_ADDTOP, width,
+ budRect.bottom - budRect.top + DEFAULT_ADDTOP + DEFAULT_ADDBOT,
+ SWP_NOACTIVATE);
+
+ return TRUE;
}
/***********************************************************************
@@ -523,39 +515,35 @@
*/
static void UPDOWN_DoAction (UPDOWN_INFO *infoPtr, int delta, BOOL incr)
{
- DWORD dwStyle = GetWindowLongA (infoPtr->Self, GWL_STYLE);
- NM_UPDOWN ni;
+ DWORD dwStyle = GetWindowLongW (infoPtr->Self, GWL_STYLE);
+ NM_UPDOWN ni;
- TRACE("%s by %d\n", incr ? "inc" : "dec", delta);
+ TRACE("%s by %d\n", incr ? "inc" : "dec", delta);
- /* check if we can do the modification first */
- delta *= (incr ? 1 : -1) * (infoPtr->MaxVal < infoPtr->MinVal ? -1 : 1);
+ /* check if we can do the modification first */
+ delta *= (incr ? 1 : -1) * (infoPtr->MaxVal < infoPtr->MinVal ? -1 : 1);
- /* We must notify parent now to obtain permission */
- ni.iPos = infoPtr->CurVal;
- ni.iDelta = delta;
- ni.hdr.hwndFrom = infoPtr->Self;
- ni.hdr.idFrom = GetWindowLongA (infoPtr->Self, GWL_ID);
- ni.hdr.code = UDN_DELTAPOS;
- if (!SendMessageA(GetParent (infoPtr->Self), WM_NOTIFY,
- (WPARAM)ni.hdr.idFrom, (LPARAM)&ni))
- {
- /* Parent said: OK to adjust */
-
- /* Now adjust value with (maybe new) delta */
- if (UPDOWN_OffsetVal (infoPtr, ni.iDelta))
- {
- /* Now take care about our buddy */
- if(infoPtr->Buddy && IsWindow(infoPtr->Buddy)
- && (dwStyle & UDS_SETBUDDYINT) )
- UPDOWN_SetBuddyInt (infoPtr);
- }
- }
+ /* We must notify parent now to obtain permission */
+ ni.iPos = infoPtr->CurVal;
+ ni.iDelta = delta;
+ ni.hdr.hwndFrom = infoPtr->Self;
+ ni.hdr.idFrom = GetWindowLongW (infoPtr->Self, GWL_ID);
+ ni.hdr.code = UDN_DELTAPOS;
+ if (!SendMessageW(GetParent (infoPtr->Self), WM_NOTIFY,
+ (WPARAM)ni.hdr.idFrom, (LPARAM)&ni)) {
+ /* Parent said: OK to adjust */
+
+ /* Now adjust value with (maybe new) delta */
+ if (UPDOWN_OffsetVal (infoPtr, ni.iDelta)) {
+ /* Now take care about our buddy */
+ if (dwStyle & UDS_SETBUDDYINT) UPDOWN_SetBuddyInt (infoPtr);
+ }
+ }
- /* Also, notify it. This message is sent in any case. */
- SendMessageA (GetParent (infoPtr->Self),
- dwStyle & UDS_HORZ ? WM_HSCROLL : WM_VSCROLL,
- MAKELONG(SB_THUMBPOSITION, infoPtr->CurVal), infoPtr->Self);
+ /* Also, notify it. This message is sent in any case. */
+ SendMessageW( GetParent(infoPtr->Self),
+ dwStyle & UDS_HORZ ? WM_HSCROLL : WM_VSCROLL,
+ MAKELONG(SB_THUMBPOSITION, infoPtr->CurVal), infoPtr->Self);
}
/***********************************************************************
@@ -566,11 +554,11 @@
*/
static BOOL UPDOWN_IsEnabled (UPDOWN_INFO *infoPtr)
{
- if(GetWindowLongA (infoPtr->Self, GWL_STYLE) & WS_DISABLED)
- return FALSE;
- if(infoPtr->Buddy)
- return IsWindowEnabled(infoPtr->Buddy);
- return TRUE;
+ if(GetWindowLongW (infoPtr->Self, GWL_STYLE) & WS_DISABLED)
+ return FALSE;
+ if(infoPtr->Buddy)
+ return IsWindowEnabled(infoPtr->Buddy);
+ return TRUE;
}
/***********************************************************************
@@ -583,20 +571,18 @@
*/
static BOOL UPDOWN_CancelMode (UPDOWN_INFO *infoPtr)
{
- /* if not in 'capture' mode, do nothing */
- if(!(infoPtr->Flags & FLAG_CLICKED))
- return FALSE;
+ /* if not in 'capture' mode, do nothing */
+ if(!(infoPtr->Flags & FLAG_CLICKED)) return FALSE;
- KillTimer (infoPtr->Self, TIMERID1); /* kill all possible timers */
- KillTimer (infoPtr->Self, TIMERID2);
+ KillTimer (infoPtr->Self, TIMERID1); /* kill all possible timers */
+ KillTimer (infoPtr->Self, TIMERID2);
- if (GetCapture() == infoPtr->Self) /* let the mouse go */
- ReleaseCapture(); /* if we still have it */
-
- infoPtr->Flags = 0; /* get rid of any flags */
- UPDOWN_Refresh (infoPtr); /* redraw the control just in case */
+ if (GetCapture() == infoPtr->Self) ReleaseCapture();
+
+ infoPtr->Flags = 0; /* get rid of any flags */
+ UPDOWN_Refresh (infoPtr); /* redraw the control just in case */
- return TRUE;
+ return TRUE;
}
/***********************************************************************
@@ -608,75 +594,69 @@
*/
static void UPDOWN_HandleMouseEvent (UPDOWN_INFO *infoPtr, UINT msg, POINT pt)
{
- DWORD dwStyle = GetWindowLongA (infoPtr->Self, GWL_STYLE);
- RECT rect;
- int temp;
+ DWORD dwStyle = GetWindowLongW (infoPtr->Self, GWL_STYLE);
+ RECT rect;
+ int temp;
- switch(msg)
+ switch(msg)
{
- case WM_LBUTTONDOWN: /* Initialise mouse tracking */
- /* If we are already in the 'clicked' mode, then nothing to do */
- if(infoPtr->Flags & FLAG_CLICKED)
- return;
-
- /* If the buddy is an edit, will set focus to it */
- if (!lstrcmpA (infoPtr->szBuddyClass, "Edit"))
- SetFocus(infoPtr->Buddy);
-
- /* Now see which one is the 'active' arrow */
- temp = UPDOWN_GetArrowFromPoint (infoPtr, &rect, pt);
-
- /* Update the CurVal if necessary */
- if (dwStyle & UDS_SETBUDDYINT)
- UPDOWN_GetBuddyInt (infoPtr);
+ case WM_LBUTTONDOWN: /* Initialise mouse tracking */
+ /* If we are already in the 'clicked' mode, then nothing to do */
+ if(infoPtr->Flags & FLAG_CLICKED) return;
+
+ /* If the buddy is an edit, will set focus to it */
+ if (UPDOWN_IsBuddyEdit(infoPtr)) SetFocus(infoPtr->Buddy);
+
+ /* Now see which one is the 'active' arrow */
+ temp = UPDOWN_GetArrowFromPoint (infoPtr, &rect, pt);
+
+ /* Update the CurVal if necessary */
+ if (dwStyle & UDS_SETBUDDYINT) UPDOWN_GetBuddyInt (infoPtr);
- /* Set up the correct flags */
- infoPtr->Flags = 0;
- infoPtr->Flags |= temp ? FLAG_INCR : FLAG_DECR;
- infoPtr->Flags |= FLAG_MOUSEIN;
+ /* Set up the correct flags */
+ infoPtr->Flags = FLAG_MOUSEIN | (temp ? FLAG_INCR : FLAG_DECR);
- /* repaint the control */
- UPDOWN_Refresh (infoPtr);
+ /* repaint the control */
+ UPDOWN_Refresh (infoPtr);
- /* process the click */
- UPDOWN_DoAction (infoPtr, 1, infoPtr->Flags & FLAG_INCR);
+ /* process the click */
+ UPDOWN_DoAction (infoPtr, 1, infoPtr->Flags & FLAG_INCR);
- /* now capture all mouse messages */
- SetCapture (infoPtr->Self);
+ /* now capture all mouse messages */
+ SetCapture (infoPtr->Self);
- /* and startup the first timer */
- SetTimer(infoPtr->Self, TIMERID1, INITIAL_DELAY, 0);
- break;
-
- case WM_MOUSEMOVE:
- /* If we are not in the 'clicked' mode, then nothing to do */
- if(!(infoPtr->Flags & FLAG_CLICKED))
- return;
-
- /* save the flags to see if any got modified */
- temp = infoPtr->Flags;
-
- /* Now get the 'active' arrow rectangle */
- if (infoPtr->Flags & FLAG_INCR)
- UPDOWN_GetArrowRect (infoPtr, &rect, TRUE);
- else
- UPDOWN_GetArrowRect (infoPtr, &rect, FALSE);
-
- /* Update the flags if we are in/out */
- if(PtInRect(&rect, pt))
- infoPtr->Flags |= FLAG_MOUSEIN;
- else{
- infoPtr->Flags &= ~FLAG_MOUSEIN;
- if(infoPtr->AccelIndex != -1) /* if we have accel info */
- infoPtr->AccelIndex = 0; /* reset it */
- }
- /* If state changed, redraw the control */
- if(temp != infoPtr->Flags)
- UPDOWN_Refresh (infoPtr);
- break;
+ /* and startup the first timer */
+ SetTimer(infoPtr->Self, TIMERID1, INITIAL_DELAY, 0);
+ break;
+
+ case WM_MOUSEMOVE:
+ /* If we are not in the 'clicked' mode, then nothing to do */
+ if(!(infoPtr->Flags & FLAG_CLICKED)) return;
+
+ /* save the flags to see if any got modified */
+ temp = infoPtr->Flags;
+
+ /* Now get the 'active' arrow rectangle */
+ if (infoPtr->Flags & FLAG_INCR)
+ UPDOWN_GetArrowRect (infoPtr, &rect, TRUE);
+ else
+ UPDOWN_GetArrowRect (infoPtr, &rect, FALSE);
+
+ /* Update the flags if we are in/out */
+ if(PtInRect(&rect, pt)) {
+ infoPtr->Flags |= FLAG_MOUSEIN;
+ } else {
+ infoPtr->Flags &= ~FLAG_MOUSEIN;
+ /* reset acceleration */
+ if(infoPtr->AccelIndex != -1) infoPtr->AccelIndex = 0;
+ }
+
+ /* If state changed, redraw the control */
+ if(temp != infoPtr->Flags) UPDOWN_Refresh (infoPtr);
+ break;
- default:
- ERR("Impossible case!\n");
+ default:
+ ERR("Impossible case (msg=%x)!\n", msg);
}
}
@@ -687,266 +667,244 @@
static LRESULT WINAPI UpDownWindowProc(HWND hwnd, UINT message, WPARAM wParam,
LPARAM lParam)
{
- UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr (hwnd);
- DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
- int temp;
- if (!infoPtr && (message != WM_CREATE) && (message != WM_NCCREATE))
- return DefWindowProcA (hwnd, message, wParam, lParam);
- switch(message)
+ UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr (hwnd);
+ DWORD dwStyle = GetWindowLongW (hwnd, GWL_STYLE);
+ int temp;
+
+ if (!infoPtr && (message != WM_CREATE) && (message != WM_NCCREATE))
+ return DefWindowProcW (hwnd, message, wParam, lParam);
+
+ switch(message)
{
- case WM_NCCREATE:
- /* get rid of border, if any */
- SetWindowLongA (hwnd, GWL_STYLE, dwStyle & ~WS_BORDER);
- return TRUE;
-
- case WM_CREATE:
- infoPtr = (UPDOWN_INFO*)COMCTL32_Alloc (sizeof(UPDOWN_INFO));
- SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
-
- /* initialize the info struct */
- infoPtr->Self = hwnd;
- infoPtr->AccelCount = 0;
- infoPtr->AccelVect = 0;
- infoPtr->AccelIndex = -1;
- infoPtr->CurVal = 0;
- infoPtr->MinVal = 0;
- infoPtr->MaxVal = 9999;
- infoPtr->Base = 10; /* Default to base 10 */
- infoPtr->Buddy = 0; /* No buddy window yet */
- infoPtr->Flags = 0; /* And no flags */
-
- /* Do we pick the buddy win ourselves? */
- if (dwStyle & UDS_AUTOBUDDY)
- UPDOWN_SetBuddy (infoPtr, GetWindow (hwnd, GW_HWNDPREV));
+ case WM_NCCREATE:
+ /* get rid of border, if any */
+ SetWindowLongW (hwnd, GWL_STYLE, dwStyle & ~WS_BORDER);
+ return TRUE;
+
+ case WM_CREATE:
+ infoPtr = (UPDOWN_INFO*)COMCTL32_Alloc (sizeof(UPDOWN_INFO));
+ SetWindowLongW (hwnd, 0, (DWORD)infoPtr);
+
+ /* initialize the info struct */
+ infoPtr->Self = hwnd;
+ infoPtr->AccelCount = 0;
+ infoPtr->AccelVect = 0;
+ infoPtr->AccelIndex = -1;
+ infoPtr->CurVal = 0;
+ infoPtr->MinVal = 0;
+ infoPtr->MaxVal = 9999;
+ infoPtr->Base = 10; /* Default to base 10 */
+ infoPtr->Buddy = 0; /* No buddy window yet */
+ infoPtr->Flags = 0; /* And no flags */
+
+ /* Do we pick the buddy win ourselves? */
+ if (dwStyle & UDS_AUTOBUDDY)
+ UPDOWN_SetBuddy (infoPtr, GetWindow (hwnd, GW_HWNDPREV));
- TRACE("UpDown Ctrl creation, hwnd=%04x\n", hwnd);
- break;
+ TRACE("UpDown Ctrl creation, hwnd=%04x\n", hwnd);
+ break;
- case WM_DESTROY:
- if(infoPtr->AccelVect)
- COMCTL32_Free (infoPtr->AccelVect);
-
- if ( IsWindow(infoPtr->Buddy) ) /* Cleanup */
- RemovePropA(infoPtr->Buddy, BUDDY_UPDOWN_HWND);
-
- COMCTL32_Free (infoPtr);
- SetWindowLongA (hwnd, 0, 0);
- TRACE("UpDown Ctrl destruction, hwnd=%04x\n", hwnd);
- break;
-
- case WM_ENABLE:
- if (dwStyle & WS_DISABLED)
- UPDOWN_CancelMode (infoPtr);
-
- UPDOWN_Refresh (infoPtr);
- break;
-
- case WM_TIMER:
- /* if initial timer, kill it and start the repeat timer */
- if(wParam == TIMERID1){
- KillTimer(hwnd, TIMERID1);
- /* if no accel info given, used default timer */
- if(infoPtr->AccelCount==0 || infoPtr->AccelVect==0){
- infoPtr->AccelIndex = -1;
- temp = REPEAT_DELAY;
- }
- else{
- infoPtr->AccelIndex = 0; /* otherwise, use it */
- temp = infoPtr->AccelVect[infoPtr->AccelIndex].nSec * 1000 + 1;
- }
- SetTimer(hwnd, TIMERID2, temp, 0);
- }
+ case WM_DESTROY:
+ if(infoPtr->AccelVect) COMCTL32_Free (infoPtr->AccelVect);
- /* now, if the mouse is above us, do the thing...*/
- if(infoPtr->Flags & FLAG_MOUSEIN){
- temp = infoPtr->AccelIndex == -1 ? 1 : infoPtr->AccelVect[infoPtr->AccelIndex].nInc;
- UPDOWN_DoAction(infoPtr, temp, infoPtr->Flags & FLAG_INCR);
+ if(infoPtr->Buddy) RemovePropA(infoPtr->Buddy, BUDDY_UPDOWN_HWND);
+
+ COMCTL32_Free (infoPtr);
+ SetWindowLongW (hwnd, 0, 0);
+ TRACE("UpDown Ctrl destruction, hwnd=%04x\n", hwnd);
+ break;
- if(infoPtr->AccelIndex != -1 && infoPtr->AccelIndex < infoPtr->AccelCount-1){
- KillTimer(hwnd, TIMERID2);
- infoPtr->AccelIndex++; /* move to the next accel info */
- temp = infoPtr->AccelVect[infoPtr->AccelIndex].nSec * 1000 + 1;
- /* make sure we have at least 1ms intervals */
- SetTimer(hwnd, TIMERID2, temp, 0);
- }
- }
- break;
+ case WM_ENABLE:
+ if (dwStyle & WS_DISABLED) UPDOWN_CancelMode (infoPtr);
- case WM_CANCELMODE:
- UPDOWN_CancelMode (infoPtr);
- break;
-
- case WM_LBUTTONUP:
- if(!UPDOWN_CancelMode(infoPtr))
- break;
-
- SendMessageA(GetParent(hwnd), dwStyle & UDS_HORZ ? WM_HSCROLL : WM_VSCROLL,
- MAKELONG(SB_ENDSCROLL, infoPtr->CurVal), hwnd);
-
- /*If we released the mouse and our buddy is an edit */
- /* we must select all text in it. */
- if (!lstrcmpA (infoPtr->szBuddyClass, "Edit"))
- SendMessageA(infoPtr->Buddy, EM_SETSEL, 0, MAKELONG(0, -1));
- break;
+ UPDOWN_Refresh (infoPtr);
+ break;
+
+ case WM_TIMER:
+ /* if initial timer, kill it and start the repeat timer */
+ if(wParam == TIMERID1) {
+ KillTimer(hwnd, TIMERID1);
+ /* if no accel info given, used default timer */
+ if(infoPtr->AccelCount==0 || infoPtr->AccelVect==0) {
+ infoPtr->AccelIndex = -1;
+ temp = REPEAT_DELAY;
+ } else {
+ infoPtr->AccelIndex = 0; /* otherwise, use it */
+ temp = infoPtr->AccelVect[infoPtr->AccelIndex].nSec * 1000 + 1;
+ }
+ SetTimer(hwnd, TIMERID2, temp, 0);
+ }
+
+ /* now, if the mouse is above us, do the thing...*/
+ if(infoPtr->Flags & FLAG_MOUSEIN) {
+ temp = infoPtr->AccelIndex == -1 ? 1 : infoPtr->AccelVect[infoPtr->AccelIndex].nInc;
+ UPDOWN_DoAction(infoPtr, temp, infoPtr->Flags & FLAG_INCR);
+
+ if(infoPtr->AccelIndex != -1 && infoPtr->AccelIndex < infoPtr->AccelCount-1) {
+ KillTimer(hwnd, TIMERID2);
+ infoPtr->AccelIndex++; /* move to the next accel info */
+ temp = infoPtr->AccelVect[infoPtr->AccelIndex].nSec * 1000 + 1;
+ /* make sure we have at least 1ms intervals */
+ SetTimer(hwnd, TIMERID2, temp, 0);
+ }
+ }
+ break;
+
+ case WM_CANCELMODE:
+ return UPDOWN_CancelMode (infoPtr);
+
+ case WM_LBUTTONUP:
+ if(!UPDOWN_CancelMode(infoPtr)) break;
+
+ SendMessageW( GetParent(hwnd),
+ dwStyle & UDS_HORZ ? WM_HSCROLL : WM_VSCROLL,
+ MAKELONG(SB_ENDSCROLL, infoPtr->CurVal), hwnd);
+
+ /*If we released the mouse and our buddy is an edit */
+ /* we must select all text in it. */
+ if (UPDOWN_IsBuddyEdit(infoPtr))
+ SendMessageW(infoPtr->Buddy, EM_SETSEL, 0, MAKELONG(0, -1));
+ break;
- case WM_LBUTTONDOWN:
- case WM_MOUSEMOVE:
- if(UPDOWN_IsEnabled(infoPtr)){
- POINT pt;
- pt.x = SLOWORD(lParam);
- pt.y = SHIWORD(lParam);
- UPDOWN_HandleMouseEvent (infoPtr, message, pt );
- }
- break;
-
- case WM_KEYDOWN:
- if((dwStyle & UDS_ARROWKEYS) && UPDOWN_IsEnabled(infoPtr)){
- switch(wParam){
- case VK_UP:
- case VK_DOWN:
- UPDOWN_GetBuddyInt (infoPtr);
- /* FIXME: Paint the according button pressed for some time, like win95 does*/
- UPDOWN_DoAction (infoPtr, 1, wParam==VK_UP);
- break;
- }
- }
- break;
+ case WM_LBUTTONDOWN:
+ case WM_MOUSEMOVE:
+ if(UPDOWN_IsEnabled(infoPtr)){
+ POINT pt;
+ pt.x = SLOWORD(lParam);
+ pt.y = SHIWORD(lParam);
+ UPDOWN_HandleMouseEvent (infoPtr, message, pt );
+ }
+ break;
+
+ case WM_KEYDOWN:
+ if((dwStyle & UDS_ARROWKEYS) && UPDOWN_IsEnabled(infoPtr)) {
+ switch(wParam){
+ case VK_UP:
+ case VK_DOWN:
+ UPDOWN_GetBuddyInt (infoPtr);
+ /* FIXME: Paint the according button pressed for some time, like win95 does*/
+ UPDOWN_DoAction (infoPtr, 1, wParam==VK_UP);
+ break;
+ }
+ }
+ break;
- case WM_PAINT:
- UPDOWN_Paint (infoPtr, (HDC)wParam);
- break;
+ case WM_PAINT:
+ UPDOWN_Paint (infoPtr, (HDC)wParam);
+ break;
- case UDM_GETACCEL:
- if (wParam==0 && lParam==0) /*if both zero, */
- return infoPtr->AccelCount; /*just return the accel count*/
- if (wParam || lParam){
- UNKNOWN_PARAM(UDM_GETACCEL, wParam, lParam);
- return 0;
- }
- temp = min(infoPtr->AccelCount, wParam);
- memcpy((void *)lParam, infoPtr->AccelVect, temp*sizeof(UDACCEL));
- return temp;
-
- case UDM_SETACCEL:
- TRACE("UpDown Ctrl new accel info, hwnd=%04x\n", hwnd);
- if(infoPtr->AccelVect){
- COMCTL32_Free (infoPtr->AccelVect);
- infoPtr->AccelCount = 0;
- infoPtr->AccelVect = 0;
- }
- if(wParam==0)
- return TRUE;
- infoPtr->AccelVect = COMCTL32_Alloc (wParam*sizeof(UDACCEL));
- if(infoPtr->AccelVect==0)
- return FALSE;
- memcpy(infoPtr->AccelVect, (void*)lParam, wParam*sizeof(UDACCEL));
- return TRUE;
-
- case UDM_GETBASE:
- if (wParam || lParam)
- UNKNOWN_PARAM(UDM_GETBASE, wParam, lParam);
- return infoPtr->Base;
-
- case UDM_SETBASE:
- TRACE("UpDown Ctrl new base(%d), hwnd=%04x\n", wParam, hwnd);
- if ( !(wParam==10 || wParam==16) || lParam)
- UNKNOWN_PARAM(UDM_SETBASE, wParam, lParam);
- if (wParam==10 || wParam==16){
- temp = infoPtr->Base;
- infoPtr->Base = wParam;
- return temp; /* return the prev base */
- }
- break;
-
- case UDM_GETBUDDY:
- if (wParam || lParam)
- UNKNOWN_PARAM(UDM_GETBUDDY, wParam, lParam);
- return infoPtr->Buddy;
-
- case UDM_SETBUDDY:
- if (lParam)
- UNKNOWN_PARAM(UDM_SETBUDDY, wParam, lParam);
- temp = infoPtr->Buddy;
- UPDOWN_SetBuddy (infoPtr, wParam);
- TRACE("UpDown Ctrl new buddy(%04x), hwnd=%04x\n", infoPtr->Buddy, hwnd);
- return temp;
-
- case UDM_GETPOS:
- if (wParam || lParam)
- UNKNOWN_PARAM(UDM_GETPOS, wParam, lParam);
- temp = UPDOWN_GetBuddyInt (infoPtr);
- return MAKELONG(infoPtr->CurVal, temp ? 0 : 1);
-
- case UDM_SETPOS:
- if (wParam || HIWORD(lParam))
- UNKNOWN_PARAM(UDM_GETPOS, wParam, lParam);
- temp = SLOWORD(lParam);
- TRACE("UpDown Ctrl new value(%d), hwnd=%04x\n", temp, hwnd);
- if(!UPDOWN_InBounds(infoPtr, temp)){
- if(temp < infoPtr->MinVal)
- temp = infoPtr->MinVal;
- if(temp > infoPtr->MaxVal)
- temp = infoPtr->MaxVal;
- }
- wParam = infoPtr->CurVal; /* save prev value */
- infoPtr->CurVal = temp; /* set the new value */
- if(dwStyle & UDS_SETBUDDYINT)
- UPDOWN_SetBuddyInt (infoPtr);
- return wParam; /* return prev value */
+ case UDM_GETACCEL:
+ if (wParam==0 && lParam==0) return infoPtr->AccelCount;
+ if (wParam && lParam) {
+ temp = min(infoPtr->AccelCount, wParam);
+ memcpy((void *)lParam, infoPtr->AccelVect, temp*sizeof(UDACCEL));
+ return temp;
+ }
+ UNKNOWN_PARAM(UDM_GETACCEL, wParam, lParam);
+ return 0;
+
+ case UDM_SETACCEL:
+ TRACE("UpDown Ctrl new accel info, hwnd=%04x\n", hwnd);
+ if(infoPtr->AccelVect) {
+ COMCTL32_Free (infoPtr->AccelVect);
+ infoPtr->AccelCount = 0;
+ infoPtr->AccelVect = 0;
+ }
+ if(wParam==0) return TRUE;
+ infoPtr->AccelVect = COMCTL32_Alloc (wParam*sizeof(UDACCEL));
+ if(infoPtr->AccelVect == 0) return FALSE;
+ memcpy(infoPtr->AccelVect, (void*)lParam, wParam*sizeof(UDACCEL));
+ return TRUE;
+
+ case UDM_GETBASE:
+ if (wParam || lParam) UNKNOWN_PARAM(UDM_GETBASE, wParam, lParam);
+ return infoPtr->Base;
+
+ case UDM_SETBASE:
+ TRACE("UpDown Ctrl new base(%d), hwnd=%04x\n", wParam, hwnd);
+ if ( !(wParam==10 || wParam==16) || lParam)
+ UNKNOWN_PARAM(UDM_SETBASE, wParam, lParam);
+ if (wParam==10 || wParam==16) {
+ temp = infoPtr->Base;
+ infoPtr->Base = wParam;
+ return temp;
+ }
+ break;
+
+ case UDM_GETBUDDY:
+ if (wParam || lParam) UNKNOWN_PARAM(UDM_GETBUDDY, wParam, lParam);
+ return infoPtr->Buddy;
+
+ case UDM_SETBUDDY:
+ if (lParam) UNKNOWN_PARAM(UDM_SETBUDDY, wParam, lParam);
+ temp = infoPtr->Buddy;
+ UPDOWN_SetBuddy (infoPtr, wParam);
+ return temp;
+
+ case UDM_GETPOS:
+ if (wParam || lParam) UNKNOWN_PARAM(UDM_GETPOS, wParam, lParam);
+ temp = UPDOWN_GetBuddyInt (infoPtr);
+ return MAKELONG(infoPtr->CurVal, temp ? 0 : 1);
+
+ case UDM_SETPOS:
+ if (wParam || HIWORD(lParam)) UNKNOWN_PARAM(UDM_GETPOS, wParam, lParam);
+ temp = SLOWORD(lParam);
+ TRACE("UpDown Ctrl new value(%d), hwnd=%04x\n", temp, hwnd);
+ if(!UPDOWN_InBounds(infoPtr, temp)) {
+ if(temp < infoPtr->MinVal) temp = infoPtr->MinVal;
+ if(temp > infoPtr->MaxVal) temp = infoPtr->MaxVal;
+ }
+ wParam = infoPtr->CurVal; /* save prev value */
+ infoPtr->CurVal = temp; /* set the new value */
+ if(dwStyle & UDS_SETBUDDYINT) UPDOWN_SetBuddyInt (infoPtr);
+ return wParam; /* return prev value */
- case UDM_GETRANGE:
- if (wParam || lParam)
- UNKNOWN_PARAM(UDM_GETRANGE, wParam, lParam);
- return MAKELONG(infoPtr->MaxVal, infoPtr->MinVal);
-
- case UDM_SETRANGE:
- if (wParam)
- UNKNOWN_PARAM(UDM_SETRANGE, wParam, lParam); /* we must have: */
- infoPtr->MaxVal = SLOWORD(lParam); /* UD_MINVAL <= Max <= UD_MAXVAL */
- infoPtr->MinVal = SHIWORD(lParam); /* UD_MINVAL <= Min <= UD_MAXVAL */
- /* |Max-Min| <= UD_MAXVAL */
- TRACE("UpDown Ctrl new range(%d to %d), hwnd=%04x\n",
- infoPtr->MinVal, infoPtr->MaxVal, hwnd);
- break;
-
- case UDM_GETRANGE32:
- if (wParam)
- *(LPINT)wParam = infoPtr->MinVal;
- if (lParam)
- *(LPINT)lParam = infoPtr->MaxVal;
- break;
-
- case UDM_SETRANGE32:
- infoPtr->MinVal = (INT)wParam;
- infoPtr->MaxVal = (INT)lParam;
- if (infoPtr->MaxVal <= infoPtr->MinVal)
- infoPtr->MaxVal = infoPtr->MinVal + 1;
- TRACE("UpDown Ctrl new range(%d to %d), hwnd=%04x\n",
- infoPtr->MinVal, infoPtr->MaxVal, hwnd);
- break;
-
- case UDM_GETPOS32:
- if ((LPBOOL)lParam != NULL)
- *((LPBOOL)lParam) = TRUE;
- return infoPtr->CurVal;
-
- case UDM_SETPOS32:
- if(!UPDOWN_InBounds(infoPtr, (int)lParam)){
- if((int)lParam < infoPtr->MinVal)
- lParam = infoPtr->MinVal;
- if((int)lParam > infoPtr->MaxVal)
- lParam = infoPtr->MaxVal;
- }
- temp = infoPtr->CurVal; /* save prev value */
- infoPtr->CurVal = (int)lParam; /* set the new value */
- if(dwStyle & UDS_SETBUDDYINT)
- UPDOWN_SetBuddyInt (infoPtr);
- return temp; /* return prev value */
-
- default:
- if (message >= WM_USER)
- ERR("unknown msg %04x wp=%04x lp=%08lx\n", message, wParam, lParam);
- return DefWindowProcA (hwnd, message, wParam, lParam);
+ case UDM_GETRANGE:
+ if (wParam || lParam) UNKNOWN_PARAM(UDM_GETRANGE, wParam, lParam);
+ return MAKELONG(infoPtr->MaxVal, infoPtr->MinVal);
+
+ case UDM_SETRANGE:
+ if (wParam) UNKNOWN_PARAM(UDM_SETRANGE, wParam, lParam);
+ /* we must have: */
+ infoPtr->MaxVal = SLOWORD(lParam); /* UD_MINVAL <= Max <= UD_MAXVAL */
+ infoPtr->MinVal = SHIWORD(lParam); /* UD_MINVAL <= Min <= UD_MAXVAL */
+ /* |Max-Min| <= UD_MAXVAL */
+ TRACE("UpDown Ctrl new range(%d to %d), hwnd=%04x\n",
+ infoPtr->MinVal, infoPtr->MaxVal, hwnd);
+ break;
+
+ case UDM_GETRANGE32:
+ if (wParam) *(LPINT)wParam = infoPtr->MinVal;
+ if (lParam) *(LPINT)lParam = infoPtr->MaxVal;
+ break;
+
+ case UDM_SETRANGE32:
+ infoPtr->MinVal = (INT)wParam;
+ infoPtr->MaxVal = (INT)lParam;
+ if (infoPtr->MaxVal <= infoPtr->MinVal)
+ infoPtr->MaxVal = infoPtr->MinVal + 1;
+ TRACE("UpDown Ctrl new range(%d to %d), hwnd=%04x\n",
+ infoPtr->MinVal, infoPtr->MaxVal, hwnd);
+ break;
+
+ case UDM_GETPOS32:
+ if ((LPBOOL)lParam != NULL) *((LPBOOL)lParam) = TRUE;
+ return infoPtr->CurVal;
+
+ case UDM_SETPOS32:
+ if(!UPDOWN_InBounds(infoPtr, (int)lParam)) {
+ if((int)lParam < infoPtr->MinVal) lParam = infoPtr->MinVal;
+ if((int)lParam > infoPtr->MaxVal) lParam = infoPtr->MaxVal;
+ }
+ temp = infoPtr->CurVal; /* save prev value */
+ infoPtr->CurVal = (int)lParam; /* set the new value */
+ if(dwStyle & UDS_SETBUDDYINT) UPDOWN_SetBuddyInt (infoPtr);
+ return temp; /* return prev value */
+
+ default:
+ if (message >= WM_USER)
+ ERR("unknown msg %04x wp=%04x lp=%08lx\n", message, wParam, lParam);
+ return DefWindowProcW (hwnd, message, wParam, lParam);
}
return 0;
@@ -956,44 +914,31 @@
* UPDOWN_Buddy_SubclassProc used to handle messages sent to the buddy
* control.
*/
-LRESULT CALLBACK
-UPDOWN_Buddy_SubclassProc (
- HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam)
-{
- WNDPROC superClassWndProc = (WNDPROC)GetPropA(hwnd, BUDDY_SUPERCLASS_WNDPROC);
- TRACE("hwnd=%04x, wndProc=%d, uMsg=%04x, wParam=%d, lParam=%d\n",
- hwnd, (INT)superClassWndProc, uMsg, wParam, (UINT)lParam);
-
- switch (uMsg)
- {
- case WM_KEYDOWN:
- {
- if ( ((int)wParam == VK_UP ) || ((int)wParam == VK_DOWN ) )
- {
- HWND upDownHwnd = GetPropA(hwnd, BUDDY_UPDOWN_HWND);
- UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(upDownHwnd);
+LRESULT CALLBACK UPDOWN_Buddy_SubclassProc(HWND hwnd, UINT uMsg,
+ WPARAM wParam, LPARAM lParam)
+{
+ WNDPROC superClassWndProc = (WNDPROC)GetPropA(hwnd, BUDDY_SUPERCLASS_WNDPROC);
+ TRACE("hwnd=%04x, wndProc=%d, uMsg=%04x, wParam=%d, lParam=%d\n",
+ hwnd, (INT)superClassWndProc, uMsg, wParam, (UINT)lParam);
+
+ switch (uMsg) {
+ case WM_KEYDOWN:
+ if ( ((int)wParam == VK_UP ) || ((int)wParam == VK_DOWN ) ) {
+ HWND upDownHwnd = GetPropA(hwnd, BUDDY_UPDOWN_HWND);
+ UPDOWN_INFO *infoPtr = UPDOWN_GetInfoPtr(upDownHwnd);
- if (!lstrcmpA (infoPtr->szBuddyClass, "ListBox"))
- {
- /* if the buddy is a list window, we must update curr index */
- INT oldVal = SendMessageA(hwnd, LB_GETCURSEL, 0, 0);
- SendMessageA(hwnd, LB_SETCURSEL, oldVal+1, 0);
- }
- else
- {
- UPDOWN_GetBuddyInt(infoPtr);
- UPDOWN_DoAction(infoPtr, 1, wParam==VK_UP);
- }
-
- break;
- }
- /* else Fall Through */
+ if (UPDOWN_IsBuddyListbox(infoPtr)) {
+ INT oldVal = SendMessageW(hwnd, LB_GETCURSEL, 0, 0);
+ SendMessageW(hwnd, LB_SETCURSEL, oldVal+1, 0);
+ } else {
+ UPDOWN_GetBuddyInt(infoPtr);
+ UPDOWN_DoAction(infoPtr, 1, wParam==VK_UP);
+ }
+ }
+ break;
+ /* else Fall Through */
}
- }
- return CallWindowProcA( superClassWndProc, hwnd, uMsg, wParam, lParam);
+ return CallWindowProcW( superClassWndProc, hwnd, uMsg, wParam, lParam);
}
/***********************************************************************
@@ -1005,18 +950,18 @@
VOID
UPDOWN_Register(void)
{
- WNDCLASSA wndClass;
+ WNDCLASSW wndClass;
- ZeroMemory( &wndClass, sizeof( WNDCLASSA ) );
+ ZeroMemory( &wndClass, sizeof( WNDCLASSW ) );
wndClass.style = CS_GLOBALCLASS | CS_VREDRAW;
wndClass.lpfnWndProc = (WNDPROC)UpDownWindowProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = sizeof(UPDOWN_INFO*);
- wndClass.hCursor = LoadCursorA( 0, IDC_ARROWA );
+ wndClass.hCursor = LoadCursorW( 0, IDC_ARROWW );
wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
- wndClass.lpszClassName = UPDOWN_CLASSA;
+ wndClass.lpszClassName = UPDOWN_CLASSW;
- RegisterClassA( &wndClass );
+ RegisterClassW( &wndClass );
}
@@ -1029,6 +974,6 @@
VOID
UPDOWN_Unregister (void)
{
- UnregisterClassA (UPDOWN_CLASSA, (HINSTANCE)NULL);
+ UnregisterClassW (UPDOWN_CLASSW, (HINSTANCE)NULL);
}
More information about the wine-patches
mailing list