diff --git a/dlls/comctl32/toolbar.c b/dlls/comctl32/toolbar.c index 5765fbd2588..3977f1a66d4 100644 --- a/dlls/comctl32/toolbar.c +++ b/dlls/comctl32/toolbar.c @@ -176,6 +176,12 @@ typedef struct WCHAR text[64]; } CUSTOMBUTTON, *PCUSTOMBUTTON; +typedef enum +{ + IMAGE_LIST_DEFAULT, + IMAGE_LIST_HOT, + IMAGE_LIST_DISABLED +} IMAGE_LIST_TYPE; #define SEPARATOR_WIDTH 8 #define TOP_BORDER 2 @@ -364,12 +370,11 @@ TOOLBAR_IsValidBitmapIndex(TOOLBAR_INFO *infoPtr, INT index) * function. It returns TRUE if the image was drawn, FALSE otherwise. */ static BOOL -TOOLBAR_DrawImageList (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HIMAGELIST himl, +TOOLBAR_DrawImageList (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, IMAGE_LIST_TYPE imagelist, HDC hdc, UINT left, UINT top, UINT draw_flags) { INT index; - - if (!himl) return FALSE; + HIMAGELIST himl; if (!TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap)) { if (btnPtr->iBitmap == I_IMAGENONE) return FALSE; @@ -385,6 +390,29 @@ TOOLBAR_DrawImageList (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HIMAGELIST h index); return FALSE; } + + switch(imagelist) + { + case IMAGE_LIST_DEFAULT: + himl = GETDEFIMAGELIST(infoPtr, GETHIMLID(infoPtr, btnPtr->iBitmap)); + break; + case IMAGE_LIST_HOT: + himl = GETHOTIMAGELIST(infoPtr, GETHIMLID(infoPtr, btnPtr->iBitmap)); + break; + case IMAGE_LIST_DISABLED: + himl = GETDISIMAGELIST(infoPtr, GETHIMLID(infoPtr, btnPtr->iBitmap)); + break; + default: + himl = NULL; + FIXME("Shouldn't reach here\n"); + } + + if (!himl) + { + TRACE("no image list, returning FALSE\n"); + return FALSE; + } + TRACE("drawing index=%d, himl=%p, left=%d, top=%d, flags=%08x\n", index, himl, left, top, draw_flags); @@ -524,31 +552,32 @@ TOOLBAR_DrawArrow (HDC hdc, INT left, INT top, INT colorRef) */ static void TOOLBAR_DrawString (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, - HDC hdc, INT nState, DWORD dwStyle, + HDC hdc, DWORD dwStyle, RECT *rcText, LPWSTR lpText, NMTBCUSTOMDRAW *tbcd) { HFONT hOldFont = 0; COLORREF clrOld = 0; + UINT state = tbcd->nmcd.uItemState; /* draw text */ if (lpText) { - TRACE("string rect=(%ld,%ld)-(%ld,%ld)\n", + TRACE("string=%s rect=(%ld,%ld)-(%ld,%ld)\n", debugstr_w(lpText), rcText->left, rcText->top, rcText->right, rcText->bottom); hOldFont = SelectObject (hdc, infoPtr->hFont); - if (!(nState & TBSTATE_ENABLED)) { + if ((state & CDIS_HOT) && (infoPtr->dwItemCDFlag & TBCDRF_HILITEHOTTRACK )) { + clrOld = SetTextColor (hdc, tbcd->clrTextHighlight); + } + else if (state & CDIS_DISABLED) { clrOld = SetTextColor (hdc, tbcd->clrBtnHighlight); OffsetRect (rcText, 1, 1); DrawTextW (hdc, lpText, -1, rcText, infoPtr->dwDTFlags); SetTextColor (hdc, comctl32_color.clr3dShadow); OffsetRect (rcText, -1, -1); } - else if (nState & TBSTATE_INDETERMINATE) { + else if (state & CDIS_INDETERMINATE) { clrOld = SetTextColor (hdc, comctl32_color.clr3dShadow); } - else if (btnPtr->bHot && (infoPtr->dwItemCDFlag & TBCDRF_HILITEHOTTRACK )) { - clrOld = SetTextColor (hdc, tbcd->clrTextHighlight); - } else { clrOld = SetTextColor (hdc, tbcd->clrText); } @@ -636,7 +665,6 @@ TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc) NMTBCUSTOMDRAW tbcd; DWORD ntfret; INT offset; - HIMAGELIST himlDef; if (btnPtr->fsState & TBSTATE_HIDDEN) return; @@ -734,6 +762,10 @@ TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc) tbcd.rcText.top = 0; tbcd.rcText.right = rcText.right - rc.left; tbcd.rcText.bottom = rcText.bottom - rc.top; + /* we use this state later on to decide how to draw the buttons */ + /* NOTE: applications can and do alter this to customize their */ + /* toolbars */ + tbcd.nmcd.uItemState = TOOLBAR_TranslateState(btnPtr); /* FIXME: what should these be set to ????? */ tbcd.hbrMonoDither = 0; @@ -749,7 +781,6 @@ TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc) tbcd.nmcd.hdc = hdc; tbcd.nmcd.rc = rc; tbcd.nmcd.dwItemSpec = btnPtr->idCommand; - tbcd.nmcd.uItemState = TOOLBAR_TranslateState(btnPtr); tbcd.nmcd.lItemlParam = btnPtr->dwData; ntfret = TOOLBAR_SendNotify ((NMHDR *)&tbcd, infoPtr, NM_CUSTOMDRAW); infoPtr->dwItemCustDraw = ntfret & 0xffff; @@ -784,12 +815,31 @@ TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc) goto FINALNOTIFY; } - /* Determine index of image list */ - himlDef = GETDEFIMAGELIST(infoPtr, GETHIMLID(infoPtr, btnPtr->iBitmap)); + if ((dwStyle & TBSTYLE_FLAT) && (tbcd.nmcd.uItemState & CDIS_HOT)) + { + if ( infoPtr->dwItemCDFlag & TBCDRF_HILITEHOTTRACK ) + { + COLORREF oldclr; + + oldclr = SetBkColor(hdc, tbcd.clrHighlightHotTrack); + ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, 0); + if (hasDropDownArrow) + ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rcArrow, NULL, 0, 0); + SetBkColor(hdc, oldclr); + } + else + { + if (!(tbcd.nmcd.uItemState & CDIS_DISABLED) && !(infoPtr->dwItemCDFlag & TBCDRF_NOEDGES)) + { + DrawEdge (hdc, &rc, BDR_RAISEDINNER, BF_RECT); + if (hasDropDownArrow) + DrawEdge (hdc, &rcArrow, BDR_RAISEDINNER, BF_RECT); + } + } + } /* disabled */ - if (!(btnPtr->fsState & TBSTATE_ENABLED)) { - HIMAGELIST himlDis = GETDISIMAGELIST(infoPtr, GETHIMLID(infoPtr, btnPtr->iBitmap)); + if (tbcd.nmcd.uItemState & CDIS_DISABLED) { if (!(dwStyle & TBSTYLE_FLAT) && !(infoPtr->dwItemCDFlag & TBCDRF_NOEDGES)) { DrawEdge (hdc, &rc, EDGE_RAISED, @@ -805,17 +855,17 @@ TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc) TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top + (rcArrow.bottom - rcArrow.top - ARROW_HEIGHT) / 2, COLOR_3DSHADOW); } - if (!TOOLBAR_DrawImageList (infoPtr, btnPtr, himlDis, + if (!TOOLBAR_DrawImageList (infoPtr, btnPtr, IMAGE_LIST_DISABLED, hdc, rcBitmap.left, rcBitmap.top, ILD_NORMAL)) TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rcBitmap.left, rcBitmap.top); - TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle, &rcText, lpText, &tbcd); + TOOLBAR_DrawString (infoPtr, btnPtr, hdc, dwStyle, &rcText, lpText, &tbcd); goto FINALNOTIFY; } /* pressed TBSTYLE_BUTTON */ - if (btnPtr->fsState & TBSTATE_PRESSED) { + if (tbcd.nmcd.uItemState & CDIS_SELECTED) { offset = (infoPtr->dwItemCDFlag & TBCDRF_NOOFFSET) ? 0 : 1; if (!(infoPtr->dwItemCDFlag & TBCDRF_NOEDGES)) { @@ -836,17 +886,17 @@ TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc) if (hasDropDownArrow) TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top + (rcArrow.bottom - rcArrow.top - ARROW_HEIGHT) / 2, COLOR_WINDOWFRAME); - TOOLBAR_DrawImageList (infoPtr, btnPtr, himlDef, + TOOLBAR_DrawImageList (infoPtr, btnPtr, IMAGE_LIST_DEFAULT, hdc, rcBitmap.left+offset, rcBitmap.top+offset, ILD_NORMAL); - TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle, &rcText, lpText, &tbcd); + TOOLBAR_DrawString (infoPtr, btnPtr, hdc, dwStyle, &rcText, lpText, &tbcd); goto FINALNOTIFY; } /* checked TBSTYLE_CHECK */ - if ((btnPtr->fsStyle & TBSTYLE_CHECK) && - (btnPtr->fsState & TBSTATE_CHECKED)) { + if ((tbcd.nmcd.uItemState & CDIS_CHECKED) && + (btnPtr->fsStyle & TBSTYLE_CHECK)) { if (!(infoPtr->dwItemCDFlag & TBCDRF_NOEDGES)) { if (dwStyle & TBSTYLE_FLAT) @@ -859,80 +909,45 @@ TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc) TOOLBAR_DrawPattern (hdc, &rc); - TOOLBAR_DrawImageList (infoPtr, btnPtr, himlDef, + TOOLBAR_DrawImageList (infoPtr, btnPtr, IMAGE_LIST_DEFAULT, hdc, rcBitmap.left+1, rcBitmap.top+1, ILD_NORMAL); - TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle, &rcText, lpText, &tbcd); + TOOLBAR_DrawString (infoPtr, btnPtr, hdc, dwStyle, &rcText, lpText, &tbcd); goto FINALNOTIFY; } /* indeterminate */ - if (btnPtr->fsState & TBSTATE_INDETERMINATE) { + if (tbcd.nmcd.uItemState & CDIS_INDETERMINATE) { if (!(infoPtr->dwItemCDFlag & TBCDRF_NOEDGES)) DrawEdge (hdc, &rc, EDGE_RAISED, BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST); TOOLBAR_DrawPattern (hdc, &rc); TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rcBitmap.left, rcBitmap.top); - TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle, &rcText, lpText, &tbcd); + TOOLBAR_DrawString (infoPtr, btnPtr, hdc, dwStyle, &rcText, lpText, &tbcd); goto FINALNOTIFY; } /* normal state */ if (dwStyle & TBSTYLE_FLAT) { - if (btnPtr->bHot) - { - if ( infoPtr->dwItemCDFlag & TBCDRF_HILITEHOTTRACK ) - { - COLORREF oldclr; - - oldclr = SetBkColor(hdc, tbcd.clrHighlightHotTrack); - ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, 0); - if (hasDropDownArrow) - ExtTextOutA(hdc, 0, 0, ETO_OPAQUE, &rcArrow, NULL, 0, 0); - SetBkColor(hdc, oldclr); - } - else - { - if (!(infoPtr->dwItemCDFlag & TBCDRF_NOEDGES)) - { - DrawEdge (hdc, &rc, BDR_RAISEDINNER, BF_RECT); - if (hasDropDownArrow) - DrawEdge (hdc, &rcArrow, BDR_RAISEDINNER, BF_RECT); - } - } - } -#if 1 - else /* The following code needs to be removed after - * "hot item" support has been implemented for the - * case where it is being de-selected. - */ - { - FrameRect(hdc, &rc, GetSysColorBrush(COLOR_BTNFACE)); - if (hasDropDownArrow) - FrameRect(hdc, &rcArrow, GetSysColorBrush(COLOR_BTNFACE)); - } -#endif - if (hasDropDownArrow) TOOLBAR_DrawArrow(hdc, rcArrow.left+1, rcArrow.top + (rcArrow.bottom - rcArrow.top - ARROW_HEIGHT) / 2, COLOR_WINDOWFRAME); - if (btnPtr->bHot) { - HIMAGELIST himlHot = GETHOTIMAGELIST(infoPtr, - GETHIMLID(infoPtr, btnPtr->iBitmap)); - /* if hot, attempt to draw with himlHot, if fails, use himlDef */ + if (tbcd.nmcd.uItemState & CDIS_HOT) { + /* if hot, attempt to draw with hot image list, if fails, + use default image list */ if (!TOOLBAR_DrawImageList (infoPtr, btnPtr, - himlHot, + IMAGE_LIST_HOT, hdc, rcBitmap.left, rcBitmap.top, ILD_NORMAL)) - TOOLBAR_DrawImageList (infoPtr, btnPtr, himlDef, + TOOLBAR_DrawImageList (infoPtr, btnPtr, IMAGE_LIST_DEFAULT, hdc, rcBitmap.left, rcBitmap.top, ILD_NORMAL); } else - TOOLBAR_DrawImageList (infoPtr, btnPtr, himlDef, + TOOLBAR_DrawImageList (infoPtr, btnPtr, IMAGE_LIST_DEFAULT, hdc, rcBitmap.left, rcBitmap.top, ILD_NORMAL); } @@ -950,12 +965,13 @@ TOOLBAR_DrawButton (HWND hwnd, TBUTTON_INFO *btnPtr, HDC hdc) TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top + (rcArrow.bottom - rcArrow.top - ARROW_HEIGHT) / 2, COLOR_WINDOWFRAME); } - TOOLBAR_DrawImageList (infoPtr, btnPtr, himlDef, + TOOLBAR_DrawImageList (infoPtr, btnPtr, IMAGE_LIST_DEFAULT, hdc, rcBitmap.left, rcBitmap.top, - ILD_NORMAL);} + ILD_NORMAL); + } - TOOLBAR_DrawString (infoPtr, btnPtr, hdc, btnPtr->fsState, dwStyle, &rcText, lpText, &tbcd); + TOOLBAR_DrawString (infoPtr, btnPtr, hdc, dwStyle, &rcText, lpText, &tbcd); FINALNOTIFY: if (infoPtr->dwItemCustDraw & CDRF_NOTIFYPOSTPAINT) @@ -2780,6 +2796,8 @@ TOOLBAR_ChangeBitmap (HWND hwnd, WPARAM wParam, LPARAM lParam) TBUTTON_INFO *btnPtr; INT nIndex; + TRACE("button %d, iBitmap now %d\n", wParam, LOWORD(lParam)); + nIndex = TOOLBAR_GetButtonIndex (infoPtr, (INT)wParam, FALSE); if (nIndex == -1) return FALSE; @@ -4227,6 +4245,8 @@ TOOLBAR_SetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam) if (infoPtr->iVersion >= 5) id = wParam; + TRACE("hwnd = %p, himl = %p, id = %d\n", hwnd, himl, id); + himlTemp = TOOLBAR_InsertImageList(&infoPtr->himlHot, &infoPtr->cimlHot, himl, id); @@ -5170,10 +5190,9 @@ TOOLBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam) if (infoPtr->nOldHit != nHit) { - /* Remove the effect of an old hot button if the button was enabled and was + /* Remove the effect of an old hot button if the button was drawn with the hot button effect */ - if(infoPtr->nOldHit >= 0 && infoPtr->nOldHit == infoPtr->nHotItem && - (infoPtr->buttons[infoPtr->nOldHit].fsState & TBSTATE_ENABLED)) + if(infoPtr->nOldHit >= 0 && infoPtr->nOldHit == infoPtr->nHotItem) { oldBtnPtr = &infoPtr->buttons[infoPtr->nOldHit]; oldBtnPtr->bHot = FALSE; @@ -5186,11 +5205,7 @@ TOOLBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam) infoPtr->nHotItem = nHit; - /* only enabled buttons show hot effect */ - if(infoPtr->buttons[nHit].fsState & TBSTATE_ENABLED) - { - btnPtr->bHot = TRUE; - } + btnPtr->bHot = TRUE; } nmhotitem.dwFlags = HICF_MOUSE; @@ -5208,7 +5223,7 @@ TOOLBAR_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam) if (oldBtnPtr) InvalidateRect (hwnd, &oldBtnPtr->rect, TOOLBAR_HasText(infoPtr, oldBtnPtr)); - if (btnPtr && (btnPtr->fsState & TBSTATE_ENABLED)) + if (btnPtr) InvalidateRect(hwnd, &btnPtr->rect, TOOLBAR_HasText(infoPtr, btnPtr));