Various updown control fixes
Dmitry Timoshkov
dmitry at baikal.ru
Tue Nov 9 06:40:16 CST 2004
Hello,
this patch fixes several problems with updown control exposed by the app
I'm working on:
1. my app arranges buddy and updown control on its own and does not specify
neither UDS_ALIGNLEFT nor UDS_ALIGNRIGHT. Since the control does it in any
case buddy and updown control overlap.
2. my app subclasses updown control and simply does not forward WM_MOUSEMOVE
messages to it. Since WM_LBUTTONDOWN handler checks FLAG_MOUSEIN flag (which
is currently exclusively set in WM_MOUSEMOVE handler) it decides to do nothing.
3. and a couple of more obvious bugfixes.
Changelog:
Dmitry Timoshkov <dmitry at codeweavers.com>
- do not move updown control and buddy if an alignment was not requested
- in UDM_SETACCEL handler do not forget to update number of accelerators
- update arrows info in WM_LBUTTONDOWN as well as in WM_MOUSEMOVE
- use accelerators in WM_LBUTTONDOWN handler
diff -up cvs/hq/wine/dlls/comctl32/updown.c wine/dlls/comctl32/updown.c
--- cvs/hq/wine/dlls/comctl32/updown.c 2004-10-26 10:30:23.000000000 +0900
+++ wine/dlls/comctl32/updown.c 2004-11-09 20:12:03.000000000 +0800
@@ -428,8 +428,9 @@ static LRESULT CALLBACK
UPDOWN_Buddy_SubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
WNDPROC superClassWndProc = (WNDPROC)GetPropW(hwnd, BUDDY_SUPERCLASS_WNDPROC);
- TRACE("hwnd=%p, wndProc=%d, uMsg=%04x, wParam=%d, lParam=%d\n",
- hwnd, (INT)superClassWndProc, uMsg, wParam, (UINT)lParam);
+
+ TRACE("hwnd=%p, wndProc=%p, uMsg=%04x, wParam=%08x, lParam=%08lx\n",
+ hwnd, superClassWndProc, uMsg, wParam, lParam);
if (uMsg == WM_KEYDOWN) {
HWND upDownHwnd = GetPropW(hwnd, BUDDY_UPDOWN_HWND);
@@ -510,7 +511,8 @@ static HWND UPDOWN_SetBuddy (UPDOWN_INFO
budRect.right -= DEFAULT_WIDTH + DEFAULT_XSEP;
x = budRect.right+DEFAULT_XSEP;
} else {
- x = budRect.right+DEFAULT_XSEP;
+ /* nothing to do */
+ return ret;
}
/* first adjust the buddy to accommodate the up/down */
@@ -535,7 +537,7 @@ static HWND UPDOWN_SetBuddy (UPDOWN_INFO
x -= DEFAULT_BUDDYBORDER;
}
- SetWindowPos(infoPtr->Self, infoPtr->Buddy, x,
+ SetWindowPos(infoPtr->Self, 0, x,
budRect.top - DEFAULT_ADDTOP, width,
budRect.bottom - budRect.top + DEFAULT_ADDTOP + DEFAULT_ADDBOT,
SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOZORDER);
@@ -570,6 +572,8 @@ static void UPDOWN_DoAction (UPDOWN_INFO
delta *= (action & FLAG_INCR ? 1 : -1) * (infoPtr->MaxVal < infoPtr->MinVal ? -1 : 1);
if ( (action & FLAG_INCR) && (action & FLAG_DECR) ) delta = 0;
+ TRACE("current %d, delta: %d\n", infoPtr->CurVal, delta);
+
/* We must notify parent now to obtain permission */
ni.iPos = infoPtr->CurVal;
ni.iDelta = delta;
@@ -581,6 +585,8 @@ static void UPDOWN_DoAction (UPDOWN_INFO
/* Now adjust value with (maybe new) delta */
if (UPDOWN_OffsetVal (infoPtr, ni.iDelta)) {
+ TRACE("new %d, delta: %d\n", infoPtr->CurVal, ni.iDelta);
+
/* Now take care about our buddy */
if (dwStyle & UDS_SETBUDDYINT) UPDOWN_SetBuddyInt (infoPtr);
}
@@ -599,7 +605,7 @@ static void UPDOWN_DoAction (UPDOWN_INFO
*/
static BOOL UPDOWN_IsEnabled (UPDOWN_INFO *infoPtr)
{
- if(GetWindowLongW (infoPtr->Self, GWL_STYLE) & WS_DISABLED)
+ if (!IsWindowEnabled(infoPtr->Self))
return FALSE;
if(infoPtr->Buddy)
return IsWindowEnabled(infoPtr->Buddy);
@@ -651,16 +657,25 @@ static void UPDOWN_HandleMouseEvent (UPD
RECT rect;
int temp, arrow;
+ TRACE("msg %04x point %s\n", msg, wine_dbgstr_point(&pt));
+
switch(msg)
{
case WM_LBUTTONDOWN: /* Initialise mouse tracking */
- /* If we are inside an arrow, then nothing to do */
- if(!(infoPtr->Flags & FLAG_MOUSEIN)) 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 */
+ arrow = UPDOWN_GetArrowFromPoint (infoPtr, &rect, pt);
+
+ /* Update the flags if we are in/out */
+ infoPtr->Flags &= ~(FLAG_MOUSEIN | FLAG_ARROW);
+ if (arrow)
+ infoPtr->Flags |= FLAG_MOUSEIN | arrow;
+ else
+ if (infoPtr->AccelIndex != -1) infoPtr->AccelIndex = 0;
+
if (infoPtr->Flags & FLAG_ARROW) {
/* Update the CurVal if necessary */
@@ -673,7 +688,8 @@ static void UPDOWN_HandleMouseEvent (UPD
InvalidateRect (infoPtr->Self, NULL, FALSE);
/* process the click */
- UPDOWN_DoAction (infoPtr, 1, infoPtr->Flags & FLAG_ARROW);
+ temp = (infoPtr->AccelCount && infoPtr->AccelVect) ? infoPtr->AccelVect[0].nInc : 1;
+ UPDOWN_DoAction (infoPtr, temp, infoPtr->Flags & FLAG_ARROW);
/* now capture all mouse messages */
SetCapture (infoPtr->Self);
@@ -718,6 +734,8 @@ static LRESULT WINAPI UpDownWindowProc(H
DWORD dwStyle = GetWindowLongW (hwnd, GWL_STYLE);
int temp;
+ TRACE("hwnd=%p msg=%04x wparam=%08x lparam=%08lx\n", hwnd, message, wParam, lParam);
+
if (!infoPtr && (message != WM_CREATE))
return DefWindowProcW (hwnd, message, wParam, lParam);
@@ -843,7 +861,8 @@ static LRESULT WINAPI UpDownWindowProc(H
return 0;
case UDM_SETACCEL:
- TRACE("UpDown Ctrl new accel info, hwnd=%p\n", hwnd);
+ TRACE("UDM_SETACCEL\n");
+
if(infoPtr->AccelVect) {
Free (infoPtr->AccelVect);
infoPtr->AccelCount = 0;
@@ -853,6 +872,11 @@ static LRESULT WINAPI UpDownWindowProc(H
infoPtr->AccelVect = Alloc (wParam*sizeof(UDACCEL));
if(infoPtr->AccelVect == 0) return FALSE;
memcpy(infoPtr->AccelVect, (void*)lParam, wParam*sizeof(UDACCEL));
+ infoPtr->AccelCount = wParam;
+
+ for (temp = 0; temp < wParam; temp++)
+ TRACE("%d: nSec %u nInc %u\n", temp, infoPtr->AccelVect[temp].nSec, infoPtr->AccelVect[temp].nInc);
+
return TRUE;
case UDM_GETBASE:
diff -up cvs/hq/wine/windows/spy.c wine/windows/spy.c
--- cvs/hq/wine/windows/spy.c 2004-10-08 12:47:52.000000000 +0900
+++ wine/windows/spy.c 2004-11-09 20:10:33.000000000 +0800
@@ -1732,7 +1732,7 @@ static const SPY_NOTIFY spnfy_array[] =
SPNFY(TBN_GETINFOTIPW, NMTBGETINFOTIPW),
SPNFY(TBN_GETBUTTONINFOW, NMTOOLBARW),
/* Up/Down 0U-721U to 0U-740U */
- SPNFY(UDN_DELTAPOS, NMHDR),
+ SPNFY(UDN_DELTAPOS, NM_UPDOWN),
/* Month Calendar 0U-750U to 0U-759U */
/* ******************* WARNING ***************************** */
/* The following appear backwards but needs to be this way. */
More information about the wine-patches
mailing list