Hi Susan!
This patch addressed exactly some of the problems I was experiencing with my
app I am working on.
Unfortunately it introduces some other bugs like:
- the buttons being left in raised conditions, when the menu is open
- the button going back to normal when the mouse leaves the toolbar area
even though the menu is still open.
So I decided to take your patch and improve upon it, here is my result.
Fixed hot button issues, and made the toolbar mimic windows behavior more
correctly.
This is a replacement for Susan's patch.
Change log
dlls/comctl32/toolbar.c
Jason Mawdsley
Macadamian Technologies
PS Thanks for the patch Susan! ;-)
----- Original Message -----
From: "Susan Farley" <[EMAIL PROTECTED]>
To: "wine patches" <[EMAIL PROTECTED]>
Sent: Friday, October 20, 2000 10:55 AM
Subject: mouseleave on toolbar buttons
> In addition to not allowing tool buttons to appear highlighted
> (hot) when the enable flag is toggled, this patch corrects a
> problem that was introduced by my CaptureChanged handler a couple
> of weeks ago. Its purpose was to fix the condition where pressing
> a tool button then releasing it outside of the btn put it in a
> pressed state next time the mouse was moved over it. This is
> a better way of doing it.
>
> :) sue
>
>
> changelog:
> * newly dis/enabled btns cannot be hot
> * LButtonDown handlers for the app can cause the btn to lose
> capture, (e.g. btns that drop down menus) so instead of using
> WM_CAPTURECHANGED to reset nButtonDown for btns that have been
> pressed then released outside of the btn's area, do it in
> MouseLeave
Index: dlls/comctl32/toolbar.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/toolbar.c,v
retrieving revision 1.69
diff -u -r1.69 toolbar.c
--- dlls/comctl32/toolbar.c 2000/10/12 23:11:35 1.69
+++ dlls/comctl32/toolbar.c 2000/10/20 22:48:23
@@ -522,7 +522,7 @@
SelectObject (hdc, hOldFont);
ReleaseDC (0, hdc);
- TRACE("string size %ld x %ld!\n", lpSize->cx, lpSize->cy);
+ TRACE("string size %d x %d!\n", lpSize->cx, lpSize->cy);
}
static void
@@ -549,7 +549,7 @@
}
}
- TRACE("string size %ld x %ld!\n", lpSize->cx, lpSize->cy);
+ TRACE("string size %d x %d!\n", lpSize->cx, lpSize->cy);
}
/***********************************************************************
@@ -1938,6 +1938,7 @@
/* redraw the button only if the state of the button changed */
if(bState != (btnPtr->fsState & TBSTATE_ENABLED))
{
+ btnPtr->bHot = FALSE;
InvalidateRect(hwnd, &btnPtr->rect,
TOOLBAR_HasText(infoPtr, btnPtr));
}
@@ -3505,12 +3506,9 @@
pt.y = (INT)HIWORD(lParam);
nHit = TOOLBAR_InternalHitTest (hwnd, &pt);
- /* restore hot effect to hot button disabled by TOOLBAR_LButtonDown() */
- /* if the cursor is still inside of the toolbar */
- if((infoPtr->nHotItem >= 0) && (nHit != -1))
- infoPtr->buttons[infoPtr->nHotItem].bHot = TRUE;
-
if ((infoPtr->bCaptured) && (infoPtr->nButtonDown >= 0)) {
+ infoPtr->bCaptured = FALSE;
+ ReleaseCapture ();
btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
btnPtr->fsState &= ~TBSTATE_PRESSED;
@@ -3543,51 +3541,35 @@
TOOLBAR_HasText(infoPtr, &infoPtr->buttons[nOldIndex]));
}
- /*
- * now we can ReleaseCapture, which triggers CAPTURECHANGED msg,
- * that resets bCaptured and btn TBSTATE_PRESSED flags,
- * and obliterates nButtonDown and nOldHit (see TOOLBAR_CaptureChanged)
- */
- ReleaseCapture ();
+ infoPtr->nButtonDown = -1;
+ infoPtr->nOldHit = -1;
+ InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
+ btnPtr));
if (bSendMessage)
SendMessageA (GetParent(hwnd), WM_COMMAND,
MAKEWPARAM(btnPtr->idCommand, 0), (LPARAM)hwnd);
}
-
return 0;
}
static LRESULT
-TOOLBAR_CaptureChanged(HWND hwnd)
-{
- TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
- TBUTTON_INFO *btnPtr;
-
- infoPtr->bCaptured = FALSE;
-
- if (infoPtr->nButtonDown >= 0)
- {
- btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
- btnPtr->fsState &= ~TBSTATE_PRESSED;
-
- infoPtr->nButtonDown = -1;
- infoPtr->nOldHit = -1;
-
- InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr,
- btnPtr));
- }
- return 0;
-}
-
-static LRESULT
TOOLBAR_MouseLeave (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
- TBUTTON_INFO *hotBtnPtr, *btnPtr;
+ TBUTTON_INFO *hotBtnPtr;
if (infoPtr->nOldHit < 0)
+ {
+ /*
+ * Can get here by LButtonDown, MouseLeave, then releasing the mouse
+ * outside of the btn rect. In this case, we must reset nButtonDown,
+ * so when the mouse is moved over the btn again (handled by MouseMove)
+ * the btn doesn't get put into the pressed state.
+ */
+ infoPtr->nButtonDown = -1;
return TRUE;
+ }
hotBtnPtr = &infoPtr->buttons[infoPtr->nOldHit];
@@ -3601,17 +3583,6 @@
hotBtnPtr));
}
- /* If the last button we were over is depressed then make it not */
- /* depressed and redraw it */
- if(infoPtr->nOldHit == infoPtr->nButtonDown)
- {
- btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];
-
- btnPtr->fsState &= ~TBSTATE_PRESSED;
-
- InvalidateRect (hwnd, &(btnPtr->rect), TRUE);
- }
-
infoPtr->nOldHit = -1; /* reset the old hit index as we've left the toolbar */
infoPtr->nHotItem = -2; /* It has to be initially different from nOldHit */
@@ -3658,7 +3629,7 @@
{
/* Remove the effect of an old hot button if the button was enabled and was
drawn with the hot button effect */
- if(infoPtr->nOldHit >= 0 && infoPtr->nOldHit == infoPtr->nHotItem &&
+ if(infoPtr->nOldHit >= 0 && (infoPtr->nOldHit == infoPtr->nHotItem) &&
(infoPtr->buttons[infoPtr->nOldHit].fsState & TBSTATE_ENABLED))
{
oldBtnPtr = &infoPtr->buttons[infoPtr->nOldHit];
@@ -4237,9 +4208,6 @@
case WM_MOUSELEAVE:
return TOOLBAR_MouseLeave (hwnd, wParam, lParam);
-
- case WM_CAPTURECHANGED:
- return TOOLBAR_CaptureChanged(hwnd);
case WM_NCACTIVATE:
return TOOLBAR_NCActivate (hwnd, wParam, lParam);