On Thursday 11 December 2003 21:32, Andrew de Quincey wrote: > IDA (yes, that again :), doesn't redraw its toolbar buttons properly. When > you move the mouse over them, its meant to have a button rollover. Under > wine however, it highlights the button, but does not de-highlight. > > Some investigation shows that these toolbar windows have the TBSTYLE_FLAT > style. > > Some more investigation (with spyxx) showed that under windows, each > toolbar receives a WM_PAINT message, and, when the mouse leaves a button > (and it should be de-highlighted), it receives a single WM_ERASEBKGND > message. > > I have concluded that the WM_ERASEBKGND is sent from within WM_PAINT when > the toolbar detects that the mouse has moved off a button and wants to > de-highlight it. > > Lemme know what you think.. any suggestions greatly appreciated. However, Dimitrie O. Paun pointed out: > Calling InvalidateRect() is the right thing to do, we can't just send > WM_ERASEBKGND messages like so... This updated patch does as suggested.
Index: dlls/comctl32/toolbar.c =================================================================== RCS file: /home/wine/wine/dlls/comctl32/toolbar.c,v retrieving revision 1.147 diff -u -b -r1.147 toolbar.c --- dlls/comctl32/toolbar.c 26 Nov 2003 22:05:02 -0000 1.147 +++ dlls/comctl32/toolbar.c 12 Dec 2003 01:26:53 -0000 @@ -205,6 +205,7 @@ #define TOOLBAR_GetInfoPtr(hwnd) ((TOOLBAR_INFO *)GetWindowLongA(hwnd,0)) #define TOOLBAR_HasText(x, y) (TOOLBAR_GetText(x, y) ? TRUE : FALSE) +#define TOOLBAR_ShouldEraseBg(x, y, z) ((TOOLBAR_GetText(x, y) ? TRUE : FALSE) | (z & TBSTYLE_FLAT ? TRUE : FALSE)) #define TOOLBAR_HasDropDownArrows(exStyle) ((exStyle & TBSTYLE_EX_DRAWDDARROWS) ? TRUE : FALSE) /* Used to find undocumented extended styles */ @@ -2857,6 +2858,7 @@ static LRESULT TOOLBAR_CheckButton (HWND hwnd, WPARAM wParam, LPARAM lParam) { + DWORD dwStyle = GetWindowLongA(hwnd, GWL_STYLE); TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd); TBUTTON_INFO *btnPtr; INT nIndex; @@ -2893,7 +2895,7 @@ if (nOldIndex != -1) { InvalidateRect(hwnd, &infoPtr->buttons[nOldIndex].rect, - TOOLBAR_HasText(infoPtr, &infoPtr->buttons[nOldIndex])); + TOOLBAR_ShouldEraseBg(infoPtr, &infoPtr->buttons[nOldIndex], dwStyle)); } InvalidateRect(hwnd, &btnPtr->rect, TRUE); } @@ -3009,6 +3011,7 @@ static LRESULT TOOLBAR_EnableButton (HWND hwnd, WPARAM wParam, LPARAM lParam) { + DWORD dwStyle = GetWindowLongA(hwnd, GWL_STYLE); TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd); TBUTTON_INFO *btnPtr; INT nIndex; @@ -3033,7 +3036,7 @@ if(bState != (btnPtr->fsState & TBSTATE_ENABLED)) { InvalidateRect(hwnd, &btnPtr->rect, - TOOLBAR_HasText(infoPtr, btnPtr)); + TOOLBAR_ShouldEraseBg(infoPtr, btnPtr, dwStyle)); } return TRUE; @@ -3506,6 +3509,7 @@ static LRESULT TOOLBAR_Indeterminate (HWND hwnd, WPARAM wParam, LPARAM lParam) { + DWORD dwStyle = GetWindowLongA(hwnd, GWL_STYLE); TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd); TBUTTON_INFO *btnPtr; INT nIndex; @@ -3520,7 +3524,7 @@ else btnPtr->fsState |= TBSTATE_INDETERMINATE; - InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr, btnPtr)); + InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_ShouldEraseBg(infoPtr, btnPtr, dwStyle)); return TRUE; } @@ -3822,6 +3826,7 @@ static LRESULT TOOLBAR_PressButton (HWND hwnd, WPARAM wParam, LPARAM lParam) { + DWORD dwStyle = GetWindowLongA(hwnd, GWL_STYLE); TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd); TBUTTON_INFO *btnPtr; INT nIndex; @@ -3836,7 +3841,7 @@ else btnPtr->fsState |= TBSTATE_PRESSED; - InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr, btnPtr)); + InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_ShouldEraseBg(infoPtr, btnPtr, dwStyle)); return TRUE; } @@ -4307,6 +4312,7 @@ static LRESULT TOOLBAR_SetHotItem (HWND hwnd, WPARAM wParam) { + DWORD dwStyle = GetWindowLongA(hwnd, GWL_STYLE); TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd); INT nOldHotItem = infoPtr->nHotItem; TBUTTON_INFO *btnPtr; @@ -4323,14 +4329,14 @@ btnPtr = &infoPtr->buttons[(INT)wParam]; btnPtr->bHot = TRUE; InvalidateRect (hwnd, &btnPtr->rect, - TOOLBAR_HasText(infoPtr, btnPtr)); + TOOLBAR_ShouldEraseBg(infoPtr, btnPtr, dwStyle)); } if (nOldHotItem>=0) { btnPtr = &infoPtr->buttons[nOldHotItem]; btnPtr->bHot = FALSE; InvalidateRect (hwnd, &btnPtr->rect, - TOOLBAR_HasText(infoPtr, btnPtr)); + TOOLBAR_ShouldEraseBg(infoPtr, btnPtr, dwStyle)); } } @@ -4493,6 +4499,7 @@ static LRESULT TOOLBAR_SetState (HWND hwnd, WPARAM wParam, LPARAM lParam) { + DWORD dwStyle = GetWindowLongA(hwnd, GWL_STYLE); TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd); TBUTTON_INFO *btnPtr; INT nIndex; @@ -4507,7 +4514,7 @@ if ((btnPtr->fsState & TBSTATE_HIDDEN) != (LOWORD(lParam) & TBSTATE_HIDDEN)) { btnPtr->fsState = LOWORD(lParam); TOOLBAR_CalcToolbar (hwnd); - InvalidateRect(hwnd, 0, TOOLBAR_HasText(infoPtr, btnPtr)); + InvalidateRect(hwnd, 0, TOOLBAR_ShouldEraseBg(infoPtr, btnPtr, dwStyle)); return TRUE; } @@ -4515,8 +4522,8 @@ if(btnPtr->fsState != LOWORD(lParam)) { btnPtr->fsState = LOWORD(lParam); - InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr, - btnPtr)); + InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_ShouldEraseBg(infoPtr, + btnPtr, dwStyle)); } return TRUE; @@ -4615,6 +4622,7 @@ static LRESULT TOOLBAR_Unkwn45E (HWND hwnd, WPARAM wParam, LPARAM lParam) { + DWORD dwStyle = GetWindowLongA(hwnd, GWL_STYLE); TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd); INT nOldHotItem = infoPtr->nHotItem; TBUTTON_INFO *btnPtr; @@ -4639,13 +4647,13 @@ btnPtr = &infoPtr->buttons[(INT)wParam]; btnPtr->bHot = (no_hi) ? FALSE : TRUE; InvalidateRect (hwnd, &btnPtr->rect, - TOOLBAR_HasText(infoPtr, btnPtr)); + TOOLBAR_ShouldEraseBg(infoPtr, btnPtr, dwStyle)); } if (nOldHotItem>=0) { btnPtr = &infoPtr->buttons[nOldHotItem]; btnPtr->bHot = FALSE; InvalidateRect (hwnd, &btnPtr->rect, - TOOLBAR_HasText(infoPtr, btnPtr)); + TOOLBAR_ShouldEraseBg(infoPtr, btnPtr, dwStyle)); } GetFocus(); TRACE("old item=%d, new item=%d, flags=%08lx, notify=%d\n", @@ -4908,6 +4916,7 @@ static LRESULT TOOLBAR_LButtonDblClk (HWND hwnd, WPARAM wParam, LPARAM lParam) { + DWORD dwStyle = GetWindowLongA(hwnd, GWL_STYLE); TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd); TBUTTON_INFO *btnPtr; POINT pt; @@ -4927,8 +4936,8 @@ btnPtr->fsState |= TBSTATE_PRESSED; - InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr, - btnPtr)); + InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_ShouldEraseBg(infoPtr, + btnPtr, dwStyle)); } else if (GetWindowLongA (hwnd, GWL_STYLE) & CCS_ADJUSTABLE) TOOLBAR_Customize (hwnd); @@ -4940,6 +4949,7 @@ static LRESULT TOOLBAR_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam) { + DWORD dwStyle = GetWindowLongA(hwnd, GWL_STYLE); TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd); TBUTTON_INFO *btnPtr; POINT pt; @@ -4995,7 +5005,7 @@ btnPtr->bHot = FALSE; if (btnPtr->fsState & TBSTATE_ENABLED) - InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr, btnPtr)); + InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_ShouldEraseBg(infoPtr, btnPtr, dwStyle)); UpdateWindow(hwnd); SetCapture (hwnd); @@ -5019,6 +5029,7 @@ static LRESULT TOOLBAR_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam) { + DWORD dwStyle = GetWindowLongA(hwnd, GWL_STYLE); TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd); TBUTTON_INFO *btnPtr; POINT pt; @@ -5067,7 +5078,7 @@ if (nOldIndex != -1) { InvalidateRect(hwnd, &infoPtr->buttons[nOldIndex].rect, - TOOLBAR_HasText(infoPtr, &infoPtr->buttons[nOldIndex])); + TOOLBAR_ShouldEraseBg(infoPtr, &infoPtr->buttons[nOldIndex], dwStyle)); } /* @@ -5117,6 +5128,7 @@ static LRESULT TOOLBAR_CaptureChanged(HWND hwnd) { + DWORD dwStyle = GetWindowLongA(hwnd, GWL_STYLE); TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd); TBUTTON_INFO *btnPtr; @@ -5129,9 +5141,10 @@ infoPtr->nOldHit = -1; - if (btnPtr->fsState & TBSTATE_ENABLED) - InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr, - btnPtr)); + if (btnPtr->fsState & TBSTATE_ENABLED) { + InvalidateRect(hwnd, &btnPtr->rect, + TOOLBAR_ShouldEraseBg(infoPtr, btnPtr, dwStyle)); + } } return 0; } @@ -5139,6 +5152,7 @@ static LRESULT TOOLBAR_MouseLeave (HWND hwnd, WPARAM wParam, LPARAM lParam) { + DWORD dwStyle = GetWindowLongA(hwnd, GWL_STYLE); TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd); TBUTTON_INFO *hotBtnPtr, *btnPtr; RECT rc1; @@ -5148,6 +5162,8 @@ hotBtnPtr = &infoPtr->buttons[infoPtr->nOldHit]; + InvalidateRect(hwnd, NULL, TRUE); + /* Redraw the button if the last button we were over is the hot button and it is enabled */ if((infoPtr->nOldHit == infoPtr->nHotItem) && (hotBtnPtr->fsState & TBSTATE_ENABLED)) @@ -5155,8 +5171,8 @@ hotBtnPtr->bHot = FALSE; rc1 = hotBtnPtr->rect; InflateRect (&rc1, 1, 1); - InvalidateRect (hwnd, &rc1, TOOLBAR_HasText(infoPtr, - hotBtnPtr)); + InvalidateRect (hwnd, &rc1, TOOLBAR_ShouldEraseBg(infoPtr, + hotBtnPtr, dwStyle)); } /* If the last button we were over is depressed then make it not */ @@ -5181,6 +5197,7 @@ static LRESULT TOOLBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam) { + DWORD dwStyle = GetWindowLongA(hwnd, GWL_STYLE); TBUTTON_INFO *btnPtr = NULL, *oldBtnPtr = NULL; TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd); POINT pt; @@ -5249,10 +5266,10 @@ /* now invalidate the old and new buttons so they will be painted */ if (oldBtnPtr) InvalidateRect (hwnd, &oldBtnPtr->rect, - TOOLBAR_HasText(infoPtr, oldBtnPtr)); + TOOLBAR_ShouldEraseBg(infoPtr, oldBtnPtr, dwStyle)); if (btnPtr) InvalidateRect(hwnd, &btnPtr->rect, - TOOLBAR_HasText(infoPtr, btnPtr)); + TOOLBAR_ShouldEraseBg(infoPtr, btnPtr, dwStyle)); if (infoPtr->bCaptured) { btnPtr = &infoPtr->buttons[infoPtr->nButtonDown];