dll/win32/comctl32/toolbar.c | 1219 +++++++++++++++++------------------------- 1 file changed, 491 insertions(+), 728 deletions(-) diff --git a/dll/win32/comctl32/toolbar.c b/dll/win32/comctl32/toolbar.c index c43dc0c..0dad1a0 100644 --- a/dll/win32/comctl32/toolbar.c +++ b/dll/win32/comctl32/toolbar.c @@ -117,6 +117,7 @@ typedef struct typedef struct { DWORD dwStructSize; /* size of TBBUTTON struct */ + INT nWidth; /* width of the toolbar */ RECT client_rect; RECT rcBound; /* bounding rectangle */ INT nButtonHeight; @@ -137,11 +138,8 @@ typedef struct INT nOldHit; INT nHotItem; /* index of the "hot" item */ SIZE szPadding; /* padding values around button */ -#ifdef __REACTOS__ SIZE szBarPadding; /* padding values around the toolbar (NOT USED BUT STORED) */ SIZE szSpacing; /* spacing values between buttons */ - MARGINS themeMargins; -#endif INT iTopMargin; /* the top margin */ INT iListGap; /* default gap between text and image for toolbar with list style */ HFONT hDefaultFont; @@ -211,20 +209,14 @@ typedef enum #define DEFPAD_CX 7 #define DEFPAD_CY 6 -#ifdef __REACTOS__ /* default space between buttons and between rows */ #define DEFSPACE_CX 7 #define DEFSPACE_CY 6 -#endif #define DEFLISTGAP 4 /* vertical padding used in list mode when image is present */ -#ifdef __REACTOS__ #define LISTPAD_CY 2 -#else -#define LISTPAD_CY 9 -#endif /* how wide to treat the bitmap if it isn't present */ #define NONLIST_NOTEXT_OFFSET 2 @@ -262,17 +254,16 @@ static LRESULT TOOLBAR_AutoSize(TOOLBAR_INFO *infoPtr); static void TOOLBAR_CheckImageListIconSize(TOOLBAR_INFO *infoPtr); static void TOOLBAR_TooltipAddTool(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *button); static void TOOLBAR_TooltipSetRect(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *button); -static LRESULT TOOLBAR_SetButtonInfo(TOOLBAR_INFO *infoPtr, INT Id, - const TBBUTTONINFOW *lptbbi, BOOL isW); static inline int default_top_margin(const TOOLBAR_INFO *infoPtr) { -#ifdef __REACTOS__ - if (infoPtr->iVersion == 6) - return infoPtr->szBarPadding.cy; -#endif +#ifndef __REACTOS__ return (infoPtr->dwStyle & TBSTYLE_FLAT ? 0 : TOP_BORDER); +#else /* r65766 */ + /* This is the behaviour in comctl32 v6 */ + return 0; +#endif } static inline BOOL TOOLBAR_HasDropDownArrows(DWORD exStyle) @@ -280,12 +271,6 @@ static inline BOOL TOOLBAR_HasDropDownArrows(DWORD exStyle) return (exStyle & TBSTYLE_EX_DRAWDDARROWS) != 0; } -static inline BOOL button_has_ddarrow(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *btnPtr) -{ - return (TOOLBAR_HasDropDownArrows( infoPtr->dwExStyle ) && (btnPtr->fsStyle & BTNS_DROPDOWN)) || - (btnPtr->fsStyle & BTNS_WHOLEDROPDOWN); -} - static LPWSTR TOOLBAR_GetText(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *btnPtr) { @@ -303,9 +288,9 @@ TOOLBAR_GetText(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *btnPtr) static void TOOLBAR_DumpTBButton(const TBBUTTON *tbb, BOOL fUnicode) { - TRACE("TBBUTTON: id %d, bitmap=%d, state=%02x, style=%02x, data=%p, stringid=%p (%s)\n", tbb->idCommand, - tbb->iBitmap, tbb->fsState, tbb->fsStyle, (void *)tbb->dwData, (void *)tbb->iString, - tbb->iString != -1 ? (fUnicode ? debugstr_w((LPWSTR)tbb->iString) : debugstr_a((LPSTR)tbb->iString)) : ""); + TRACE("TBBUTTON: id %d, bitmap=%d, state=%02x, style=%02x, data=%08lx, stringid=0x%08lx (%s)\n", + tbb->idCommand,tbb->iBitmap, tbb->fsState, tbb->fsStyle, tbb->dwData, tbb->iString, + (fUnicode ? wine_dbgstr_w((LPWSTR)tbb->iString) : wine_dbgstr_a((LPSTR)tbb->iString))); } static void @@ -349,37 +334,6 @@ TOOLBAR_ButtonHasString(const TBUTTON_INFO *btnPtr) return HIWORD(btnPtr->iString) && btnPtr->iString != -1; } -static void set_string_index( TBUTTON_INFO *btn, INT_PTR str, BOOL unicode ) -{ - if (!IS_INTRESOURCE( str ) && str != -1) - { - if (!TOOLBAR_ButtonHasString( btn )) btn->iString = 0; - - if (unicode) - Str_SetPtrW( (WCHAR **)&btn->iString, (WCHAR *)str ); - else - Str_SetPtrAtoW( (WCHAR **)&btn->iString, (char *)str ); - } - else - { - if (TOOLBAR_ButtonHasString( btn )) Free( (WCHAR *)btn->iString ); - - btn->iString = str; - } -} - -static void set_stringT( TBUTTON_INFO *btn, const WCHAR *str, BOOL unicode ) -{ - if (IS_INTRESOURCE( (DWORD_PTR)str ) || (DWORD_PTR)str == -1) return; - set_string_index( btn, (DWORD_PTR)str, unicode ); -} - -static void free_string( TBUTTON_INFO *btn ) -{ - set_string_index( btn, 0, TRUE ); - -} - /*********************************************************************** * TOOLBAR_CheckStyle * @@ -631,9 +585,6 @@ TOOLBAR_DrawString (const TOOLBAR_INFO *infoPtr, RECT *rcText, LPCWSTR lpText, COLORREF clrOldBk = 0; int oldBkMode = 0; UINT state = tbcd->nmcd.uItemState; -#ifdef __REACTOS__ - HTHEME theme = GetWindowTheme (infoPtr->hwndSelf); -#endif /* draw text */ if (lpText && infoPtr->nMaxTextRows > 0) { @@ -641,31 +592,6 @@ TOOLBAR_DrawString (const TOOLBAR_INFO *infoPtr, RECT *rcText, LPCWSTR lpText, wine_dbgstr_rect(rcText)); hOldFont = SelectObject (hdc, infoPtr->hFont); -#ifdef __REACTOS__ - if (theme) - { - DWORD dwDTFlags2 = 0; - int partId = TP_BUTTON; - int stateId = TS_NORMAL; - - if (state & CDIS_DISABLED) - { - stateId = TS_DISABLED; - dwDTFlags2 = DTT_GRAYED; - } - else if (state & CDIS_SELECTED) - stateId = TS_PRESSED; - else if (state & CDIS_CHECKED) - stateId = (state & CDIS_HOT) ? TS_HOTCHECKED : TS_HOT; - else if (state & CDIS_HOT) - stateId = TS_HOT; - - DrawThemeText(theme, hdc, partId, stateId, lpText, -1, infoPtr->dwDTFlags, dwDTFlags2, rcText); - SelectObject (hdc, hOldFont); - return; - } -#endif - if ((state & CDIS_HOT) && (dwItemCDFlag & TBCDRF_HILITEHOTTRACK )) { clrOld = SetTextColor (hdc, tbcd->clrTextHighlight); } @@ -788,10 +714,8 @@ TOOLBAR_DrawImage(const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, INT left, I INT index; INT offset = 0; UINT draw_flags = ILD_TRANSPARENT; -#ifdef __REACTOS__ IMAGEINFO info = {0}; BITMAP bm = {0}; -#endif if (tbcd->nmcd.uItemState & (CDIS_DISABLED | CDIS_INDETERMINATE)) { @@ -800,7 +724,6 @@ TOOLBAR_DrawImage(const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, INT left, I { himl = TOOLBAR_GetImageListForDrawing(infoPtr, btnPtr, IMAGE_LIST_DEFAULT, &index); -#ifdef __REACTOS__ ImageList_GetImageInfo(himl, index, &info); GetObjectW(info.hbmImage, sizeof(bm), &bm); @@ -812,9 +735,6 @@ TOOLBAR_DrawImage(const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, INT left, I { draw_masked = TRUE; } -#else - draw_masked = TRUE; -#endif } } else if (tbcd->nmcd.uItemState & CDIS_CHECKED || @@ -953,7 +873,9 @@ static void TOOLBAR_DrawButton (const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HDC hdc, DWORD dwBaseCustDraw) { DWORD dwStyle = infoPtr->dwStyle; - BOOL hasDropDownArrow = button_has_ddarrow( infoPtr, btnPtr ); + BOOL hasDropDownArrow = (TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle) && + (btnPtr->fsStyle & BTNS_DROPDOWN)) || + (btnPtr->fsStyle & BTNS_WHOLEDROPDOWN); BOOL drawSepDropDownArrow = hasDropDownArrow && (~btnPtr->fsStyle & BTNS_WHOLEDROPDOWN); RECT rc, rcArrow, rcBitmap, rcText; @@ -967,7 +889,7 @@ TOOLBAR_DrawButton (const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HDC hdc, HTHEME theme = GetWindowTheme (infoPtr->hwndSelf); rc = btnPtr->rect; - rcArrow = rc; + CopyRect (&rcArrow, &rc); /* separator - doesn't send NM_CUSTOMDRAW */ if (btnPtr->fsStyle & BTNS_SEP) { @@ -1021,8 +943,8 @@ TOOLBAR_DrawButton (const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HDC hdc, /* copy text & bitmap rects after adjusting for drop-down arrow * so that text & bitmap is centered in the rectangle not containing * the arrow */ - rcText = rc; - rcBitmap = rc; + CopyRect(&rcText, &rc); + CopyRect(&rcBitmap, &rc); /* Center the bitmap horizontally and vertically */ if (dwStyle & TBSTYLE_LIST) @@ -1039,9 +961,6 @@ TOOLBAR_DrawButton (const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HDC hdc, rcBitmap.left += ((rc.right - rc.left) - infoPtr->nBitmapWidth) / 2; rcBitmap.top += infoPtr->szPadding.cy / 2; -#ifdef __REACTOS__ - rcBitmap.top += infoPtr->themeMargins.cyTopHeight; -#endif TRACE("iBitmap=%d, start=(%d,%d) w=%d, h=%d\n", btnPtr->iBitmap, rcBitmap.left, rcBitmap.top, @@ -1052,7 +971,8 @@ TOOLBAR_DrawButton (const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HDC hdc, /* calculate text position */ if (lpText) { - InflateRect(&rcText, -GetSystemMetrics(SM_CXEDGE), 0); + rcText.left += GetSystemMetrics(SM_CXEDGE); + rcText.right -= GetSystemMetrics(SM_CXEDGE); if (dwStyle & TBSTYLE_LIST) { rcText.left += infoPtr->nBitmapWidth + infoPtr->iListGap + 2; @@ -1150,11 +1070,7 @@ TOOLBAR_DrawButton (const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HDC hdc, else if (tbcd.nmcd.uItemState & CDIS_SELECTED) stateId = TS_PRESSED; else if (tbcd.nmcd.uItemState & CDIS_CHECKED) -#ifdef __REACTOS__ - stateId = (tbcd.nmcd.uItemState & CDIS_HOT) ? TS_HOTCHECKED : TS_CHECKED; -#else stateId = (tbcd.nmcd.uItemState & CDIS_HOT) ? TS_HOTCHECKED : TS_HOT; -#endif else if ((tbcd.nmcd.uItemState & CDIS_HOT) || (drawSepDropDownArrow && btnPtr->bDropDownPressed)) stateId = TS_HOT; @@ -1180,11 +1096,7 @@ TOOLBAR_DrawButton (const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HDC hdc, else if (btnPtr->bDropDownPressed || (tbcd.nmcd.uItemState & CDIS_SELECTED)) stateId = TS_PRESSED; else if (tbcd.nmcd.uItemState & CDIS_CHECKED) -#ifdef __REACTOS__ - stateId = (tbcd.nmcd.uItemState & CDIS_HOT) ? TS_HOTCHECKED : TS_CHECKED; -#else stateId = (tbcd.nmcd.uItemState & CDIS_HOT) ? TS_HOTCHECKED : TS_HOT; -#endif else if (tbcd.nmcd.uItemState & CDIS_HOT) stateId = TS_HOT; @@ -1209,7 +1121,6 @@ TOOLBAR_DrawButton (const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HDC hdc, TOOLBAR_DrawArrow(hdc, rcArrow.left+1, rcArrow.top+1 + (rcArrow.bottom - rcArrow.top - ARROW_HEIGHT) / 2, comctl32_color.clrBtnHighlight); TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top + (rcArrow.bottom - rcArrow.top - ARROW_HEIGHT) / 2, comctl32_color.clr3dShadow); } -#ifndef __REACTOS__ else if (tbcd.nmcd.uItemState & (CDIS_SELECTED | CDIS_CHECKED)) { offset = (dwItemCDFlag & TBCDRF_NOOFFSET) ? 0 : 1; @@ -1217,22 +1128,6 @@ TOOLBAR_DrawButton (const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HDC hdc, } else TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top + (rcArrow.bottom - rcArrow.top - ARROW_HEIGHT) / 2, comctl32_color.clrBtnText); -#else - else - { - COLORREF clr = comctl32_color.clrBtnText; - if (theme) - GetThemeColor(theme, TP_BUTTON, TS_NORMAL, TMT_TEXTCOLOR, &clr); - - if (tbcd.nmcd.uItemState & (CDIS_SELECTED | CDIS_CHECKED)) - { - offset = (dwItemCDFlag & TBCDRF_NOOFFSET) ? 0 : 1; - TOOLBAR_DrawArrow(hdc, rcArrow.left + offset, rcArrow.top + offset + (rcArrow.bottom - rcArrow.top - ARROW_HEIGHT) / 2, clr); - } - else - TOOLBAR_DrawArrow(hdc, rcArrow.left, rcArrow.top + (rcArrow.bottom - rcArrow.top - ARROW_HEIGHT) / 2, clr); - } -#endif } if (dwItemCustDraw & CDRF_NOTIFYPOSTPAINT) @@ -1359,7 +1254,9 @@ TOOLBAR_MeasureString(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *btnPtr, GetTextExtentPoint32W (hdc, lpText, strlenW (lpText), lpSize); /* feed above size into the rectangle for DrawText */ - SetRect(&myrect, 0, 0, lpSize->cx, lpSize->cy); + myrect.left = myrect.top = 0; + myrect.right = lpSize->cx; + myrect.bottom = lpSize->cy; /* Use DrawText to get true size as drawn (less pesky "&") */ DrawTextW (hdc, lpText, -1, &myrect, DT_VCENTER | DT_SINGLELINE | @@ -1422,7 +1319,7 @@ TOOLBAR_CalcStrings (const TOOLBAR_INFO *infoPtr, LPSIZE lpSize) SelectObject (hdc, hOldFont); ReleaseDC (infoPtr->hwndSelf, hdc); - TRACE("max string size %d x %d\n", lpSize->cx, lpSize->cy); + TRACE("max string size %d x %d!\n", lpSize->cx, lpSize->cy); } /*********************************************************************** @@ -1444,150 +1341,164 @@ static void TOOLBAR_WrapToolbar(TOOLBAR_INFO *infoPtr) { TBUTTON_INFO *btnPtr; - INT x, cx, i, j, width; + INT x, cx, i, j; + RECT rc; BOOL bButtonWrap; /* When the toolbar window style is not TBSTYLE_WRAPABLE, */ /* no layout is necessary. Applications may use this style */ /* to perform their own layout on the toolbar. */ - if( !(infoPtr->dwStyle & TBSTYLE_WRAPABLE) && - !(infoPtr->dwExStyle & TBSTYLE_EX_VERTICAL) ) return; + if (!(infoPtr->dwStyle & TBSTYLE_WRAPABLE) && + !(infoPtr->dwExStyle & TBSTYLE_EX_VERTICAL)) return; btnPtr = infoPtr->buttons; - x = infoPtr->nIndent; - width = infoPtr->client_rect.right - infoPtr->client_rect.left; + x = infoPtr->nIndent; + + if (GetParent(infoPtr->hwndSelf)) + { + /* this can get the parents width, to know how far we can extend + * this toolbar. We cannot use its height, as there may be multiple + * toolbars in a rebar control + */ + GetClientRect(GetParent(infoPtr->hwndSelf), &rc); + infoPtr->nWidth = rc.right - rc.left; + } + else + { + GetWindowRect(infoPtr->hwndSelf, &rc); + infoPtr->nWidth = rc.right - rc.left; + } bButtonWrap = FALSE; - TRACE("start ButtonWidth=%d, BitmapWidth=%d, width=%d, nIndent=%d\n", - infoPtr->nButtonWidth, infoPtr->nBitmapWidth, width, - infoPtr->nIndent); + TRACE("start ButtonWidth=%d, BitmapWidth=%d, nWidth=%d, nIndent=%d\n", + infoPtr->nButtonWidth, infoPtr->nBitmapWidth, infoPtr->nWidth, + infoPtr->nIndent); - for (i = 0; i < infoPtr->nNumButtons; i++ ) + for (i = 0; i < infoPtr->nNumButtons; i++) { - btnPtr[i].fsState &= ~TBSTATE_WRAP; + btnPtr[i].fsState &= ~TBSTATE_WRAP; - if (btnPtr[i].fsState & TBSTATE_HIDDEN) - continue; + if (btnPtr[i].fsState & TBSTATE_HIDDEN) + continue; if (btnPtr[i].cx > 0) cx = btnPtr[i].cx; /* horizontal separators are treated as buttons for width */ - else if ((btnPtr[i].fsStyle & BTNS_SEP) && - !(infoPtr->dwStyle & CCS_VERT)) + else if ((btnPtr[i].fsStyle & BTNS_SEP) && + !(infoPtr->dwStyle & CCS_VERT)) cx = (btnPtr[i].iBitmap > 0) ? btnPtr[i].iBitmap : SEPARATOR_WIDTH; - else - cx = infoPtr->nButtonWidth; - - if (!btnPtr[i].cx && button_has_ddarrow( infoPtr, btnPtr + i )) - cx += DDARROW_WIDTH; - - /* Two or more adjacent separators form a separator group. */ - /* The first separator in a group should be wrapped to the */ - /* next row if the previous wrapping is on a button. */ - if( bButtonWrap && - (btnPtr[i].fsStyle & BTNS_SEP) && - (i + 1 < infoPtr->nNumButtons ) && - (btnPtr[i + 1].fsStyle & BTNS_SEP) ) - { - TRACE("wrap point 1 btn %d style %02x\n", i, btnPtr[i].fsStyle); - btnPtr[i].fsState |= TBSTATE_WRAP; - x = infoPtr->nIndent; - i++; - bButtonWrap = FALSE; - continue; - } + else + cx = infoPtr->nButtonWidth; + + /* Two or more adjacent separators form a separator group. */ + /* The first separator in a group should be wrapped to the */ + /* next row if the previous wrapping is on a button. */ + if (bButtonWrap && + (btnPtr[i].fsStyle & BTNS_SEP) && + (i + 1 < infoPtr->nNumButtons) && + (btnPtr[i + 1].fsStyle & BTNS_SEP)) + { + TRACE("wrap point 1 btn %d style %02x\n", i, btnPtr[i].fsStyle); + btnPtr[i].fsState |= TBSTATE_WRAP; + x = infoPtr->nIndent; + i++; + bButtonWrap = FALSE; + continue; + } - /* The layout makes sure the bitmap is visible, but not the button. */ - /* Test added to also wrap after a button that starts a row but */ - /* is bigger than the area. - GA 8/01 */ - if ((x + cx - (infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2 > width) || - ((x == infoPtr->nIndent) && (cx > width))) - { - BOOL bFound = FALSE; - - /* If the current button is a separator and not hidden, */ - /* go to the next until it reaches a non separator. */ - /* Wrap the last separator if it is before a button. */ - while( ( ((btnPtr[i].fsStyle & BTNS_SEP) && - !(btnPtr[i].fsStyle & BTNS_DROPDOWN)) || - (btnPtr[i].fsState & TBSTATE_HIDDEN) ) && - i < infoPtr->nNumButtons ) - { - i++; - bFound = TRUE; - } + /* The layout makes sure the bitmap is visible, but not the button. */ + /* Test added to also wrap after a button that starts a row but */ + /* is bigger than the area. - GA 8/01 */ + if ((x + cx - (infoPtr->nButtonWidth - infoPtr->nBitmapWidth) / 2 + > infoPtr->nWidth) || + ((x == infoPtr->nIndent) && (cx > infoPtr->nWidth))) + { + BOOL bFound = FALSE; + + /* If the current button is a separator and not hidden, */ + /* go to the next until it reaches a non separator. */ + /* Wrap the last separator if it is before a button. */ + while ((((btnPtr[i].fsStyle & BTNS_SEP) && + !(btnPtr[i].fsStyle & BTNS_DROPDOWN)) || + (btnPtr[i].fsState & TBSTATE_HIDDEN)) && + i < infoPtr->nNumButtons) + { + i++; + bFound = TRUE; + } - if( bFound && i < infoPtr->nNumButtons ) - { - i--; - TRACE("wrap point 2 btn %d style %02x, x=%d, cx=%d\n", - i, btnPtr[i].fsStyle, x, cx); - btnPtr[i].fsState |= TBSTATE_WRAP; - x = infoPtr->nIndent; - bButtonWrap = FALSE; - continue; - } - else if ( i >= infoPtr->nNumButtons) - break; + if (bFound && i < infoPtr->nNumButtons) + { + i--; + TRACE("wrap point 2 btn %d style %02x, x=%d, cx=%d\n", + i, btnPtr[i].fsStyle, x, cx); + btnPtr[i].fsState |= TBSTATE_WRAP; + x = infoPtr->nIndent; + bButtonWrap = FALSE; + continue; + } + else if (i >= infoPtr->nNumButtons) + break; - /* If the current button is not a separator, find the last */ - /* separator and wrap it. */ - for ( j = i - 1; j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--) - { - if ((btnPtr[j].fsStyle & BTNS_SEP) && - !(btnPtr[j].fsState & TBSTATE_HIDDEN)) - { - bFound = TRUE; - i = j; - TRACE("wrap point 3 btn %d style %02x, x=%d, cx=%d\n", - i, btnPtr[i].fsStyle, x, cx); - x = infoPtr->nIndent; - btnPtr[j].fsState |= TBSTATE_WRAP; - bButtonWrap = FALSE; - break; - } - } + /* If the current button is not a separator, find the last */ + /* separator and wrap it. */ + for (j = i - 1; j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--) + { + if ((btnPtr[j].fsStyle & BTNS_SEP) && + !(btnPtr[j].fsState & TBSTATE_HIDDEN)) + { + bFound = TRUE; + i = j; + TRACE("wrap point 3 btn %d style %02x, x=%d, cx=%d\n", + i, btnPtr[i].fsStyle, x, cx); + x = infoPtr->nIndent; + btnPtr[j].fsState |= TBSTATE_WRAP; + bButtonWrap = FALSE; + break; + } + } - /* If no separator available for wrapping, wrap one of */ - /* non-hidden previous button. */ - if (!bFound) - { - for ( j = i - 1; - j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--) - { - if (btnPtr[j].fsState & TBSTATE_HIDDEN) - continue; - - bFound = TRUE; - i = j; - TRACE("wrap point 4 btn %d style %02x, x=%d, cx=%d\n", - i, btnPtr[i].fsStyle, x, cx); - x = infoPtr->nIndent; - btnPtr[j].fsState |= TBSTATE_WRAP; - bButtonWrap = TRUE; - break; - } - } + /* If no separator available for wrapping, wrap one of */ + /* non-hidden previous button. */ + if (!bFound) + { + for (j = i - 1; + j >= 0 && !(btnPtr[j].fsState & TBSTATE_WRAP); j--) + { + if (btnPtr[j].fsState & TBSTATE_HIDDEN) + continue; + + bFound = TRUE; + i = j; + TRACE("wrap point 4 btn %d style %02x, x=%d, cx=%d\n", + i, btnPtr[i].fsStyle, x, cx); + x = infoPtr->nIndent; + btnPtr[j].fsState |= TBSTATE_WRAP; + bButtonWrap = TRUE; + break; + } + } - /* If all above failed, wrap the current button. */ - if (!bFound) - { - TRACE("wrap point 5 btn %d style %02x, x=%d, cx=%d\n", - i, btnPtr[i].fsStyle, x, cx); - btnPtr[i].fsState |= TBSTATE_WRAP; - x = infoPtr->nIndent; - if (btnPtr[i].fsStyle & BTNS_SEP ) - bButtonWrap = FALSE; - else - bButtonWrap = TRUE; - } - } - else { - TRACE("wrap point 6 btn %d style %02x, x=%d, cx=%d\n", - i, btnPtr[i].fsStyle, x, cx); - x += cx; - } + /* If all above failed, wrap the current button. */ + if (!bFound) + { + TRACE("wrap point 5 btn %d style %02x, x=%d, cx=%d\n", + i, btnPtr[i].fsStyle, x, cx); + btnPtr[i].fsState |= TBSTATE_WRAP; + x = infoPtr->nIndent; + if (btnPtr[i].fsStyle & BTNS_SEP) + bButtonWrap = FALSE; + else + bButtonWrap = TRUE; + } + } + else + { + TRACE("wrap point 6 btn %d style %02x, x=%d, cx=%d\n", + i, btnPtr[i].fsStyle, x, cx); + x += cx; + } } } @@ -1713,14 +1624,8 @@ static inline SIZE TOOLBAR_MeasureButton(const TOOLBAR_INFO *infoPtr, SIZE sizeS /* ... add on the necessary padding */ if (bValidImageList) { -#ifdef __REACTOS__ sizeButton.cy += infoPtr->szPadding.cy; if (!bHasBitmap) -#else - if (bHasBitmap) - sizeButton.cy += DEFPAD_CY; - else -#endif sizeButton.cy += LISTPAD_CY; } else @@ -1737,11 +1642,7 @@ static inline SIZE TOOLBAR_MeasureButton(const TOOLBAR_INFO *infoPtr, SIZE sizeS { if (bHasBitmap) { -#ifdef __REACTOS__ sizeButton.cy = infoPtr->nBitmapHeight + infoPtr->szPadding.cy; -#else - sizeButton.cy = infoPtr->nBitmapHeight + DEFPAD_CY; -#endif if (sizeString.cy > 0) sizeButton.cy += 1 + sizeString.cy; sizeButton.cx = infoPtr->szPadding.cx + @@ -1755,12 +1656,6 @@ static inline SIZE TOOLBAR_MeasureButton(const TOOLBAR_INFO *infoPtr, SIZE sizeS max(2*GetSystemMetrics(SM_CXEDGE) + sizeString.cx, infoPtr->nBitmapWidth); } } - -#ifdef __REACTOS__ - sizeButton.cx += infoPtr->themeMargins.cxLeftWidth + infoPtr->themeMargins.cxRightWidth; - sizeButton.cy += infoPtr->themeMargins.cyTopHeight + infoPtr->themeMargins.cyBottomHeight; -#endif - return sizeButton; } @@ -1804,16 +1699,17 @@ static void TOOLBAR_LayoutToolbar(TOOLBAR_INFO *infoPtr) { TBUTTON_INFO *btnPtr; - SIZE sizeButton; - INT i, nRows, nSepRows; - INT x, y, cx, cy; - BOOL bWrap; - BOOL validImageList = TOOLBAR_IsValidImageList(infoPtr, 0); + SIZE sizeButton; + INT i, nRows, nSepRows; + INT x, y, cx, cy; + BOOL bWrap; + BOOL validImageList = TOOLBAR_IsValidImageList(infoPtr, 0); + BOOL hasDropDownArrows = TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle); TOOLBAR_WrapToolbar(infoPtr); - x = infoPtr->nIndent; - y = infoPtr->iTopMargin; + x = infoPtr->nIndent; + y = infoPtr->iTopMargin; cx = infoPtr->nButtonWidth; cy = infoPtr->nButtonHeight; @@ -1828,124 +1724,112 @@ TOOLBAR_LayoutToolbar(TOOLBAR_INFO *infoPtr) TRACE("cy=%d\n", cy); - for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++ ) + for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++) { - bWrap = FALSE; - if (btnPtr->fsState & TBSTATE_HIDDEN) - { - SetRectEmpty (&btnPtr->rect); - TOOLBAR_TooltipSetRect(infoPtr, btnPtr); - continue; - } + bWrap = FALSE; + if (btnPtr->fsState & TBSTATE_HIDDEN) + { + SetRectEmpty(&btnPtr->rect); + continue; + } - cy = infoPtr->nButtonHeight; + cy = infoPtr->nButtonHeight; - if (btnPtr->fsStyle & BTNS_SEP) { - if (infoPtr->dwStyle & CCS_VERT) { + if (btnPtr->fsStyle & BTNS_SEP) + { + if (infoPtr->dwStyle & CCS_VERT) + { cy = (btnPtr->iBitmap > 0) ? btnPtr->iBitmap : SEPARATOR_WIDTH; cx = (btnPtr->cx > 0) ? btnPtr->cx : infoPtr->nButtonWidth; - } - else + } + else + { cx = (btnPtr->cx > 0) ? btnPtr->cx : (btnPtr->iBitmap > 0) ? btnPtr->iBitmap : SEPARATOR_WIDTH; - } - else - { + } + } + else + { if (btnPtr->cx) - cx = btnPtr->cx; -#ifdef __REACTOS__ - /* Revert Wine Commit 5b7b911 as it breaks Explorer Toolbar Buttons - FIXME: Revisit this when the bug is fixed. CORE-9970 */ - else if ((infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) || - (btnPtr->fsStyle & BTNS_AUTOSIZE)) -#else - else if (btnPtr->fsStyle & BTNS_AUTOSIZE) -#endif { - SIZE sz; - HDC hdc; - HFONT hOldFont; + cx = btnPtr->cx; + } + else if ((infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) || + (btnPtr->fsStyle & BTNS_AUTOSIZE)) + { + SIZE sz; + HDC hdc; + HFONT hOldFont; - hdc = GetDC (infoPtr->hwndSelf); - hOldFont = SelectObject (hdc, infoPtr->hFont); + hdc = GetDC(infoPtr->hwndSelf); + hOldFont = SelectObject(hdc, infoPtr->hFont); - TOOLBAR_MeasureString(infoPtr, btnPtr, hdc, &sz); + TOOLBAR_MeasureString(infoPtr, btnPtr, hdc, &sz); - SelectObject (hdc, hOldFont); - ReleaseDC (infoPtr->hwndSelf, hdc); + SelectObject(hdc, hOldFont); + ReleaseDC(infoPtr->hwndSelf, hdc); - sizeButton = TOOLBAR_MeasureButton(infoPtr, sz, - TOOLBAR_IsValidBitmapIndex(infoPtr, infoPtr->buttons[i].iBitmap), - validImageList); - cx = sizeButton.cx; + sizeButton = TOOLBAR_MeasureButton(infoPtr, sz, + TOOLBAR_IsValidBitmapIndex(infoPtr, infoPtr->buttons[i].iBitmap), + validImageList); + cx = sizeButton.cx; } else - cx = infoPtr->nButtonWidth; + cx = infoPtr->nButtonWidth; /* if size has been set manually then don't add on extra space * for the drop down arrow */ - if (!btnPtr->cx && button_has_ddarrow( infoPtr, btnPtr )) - cx += DDARROW_WIDTH; - } - if (btnPtr->fsState & TBSTATE_WRAP) - bWrap = TRUE; + if (!btnPtr->cx && hasDropDownArrows && + ((btnPtr->fsStyle & BTNS_DROPDOWN) || (btnPtr->fsStyle & BTNS_WHOLEDROPDOWN))) + cx += DDARROW_WIDTH; + } + if (btnPtr->fsState & TBSTATE_WRAP) + bWrap = TRUE; - SetRect (&btnPtr->rect, x, y, x + cx, y + cy); + SetRect(&btnPtr->rect, x, y, x + cx, y + cy); - if (infoPtr->rcBound.left > x) - infoPtr->rcBound.left = x; - if (infoPtr->rcBound.right < x + cx) - infoPtr->rcBound.right = x + cx; - if (infoPtr->rcBound.bottom < y + cy) - infoPtr->rcBound.bottom = y + cy; + if (infoPtr->rcBound.left > x) + infoPtr->rcBound.left = x; + if (infoPtr->rcBound.right < x + cx) + infoPtr->rcBound.right = x + cx; + if (infoPtr->rcBound.bottom < y + cy) + infoPtr->rcBound.bottom = y + cy; TOOLBAR_TooltipSetRect(infoPtr, btnPtr); - /* btnPtr->nRow is zero based. The space between the rows is */ - /* also considered as a row. */ - btnPtr->nRow = nRows + nSepRows; + /* btnPtr->nRow is zero based. The space between the rows is */ + /* also considered as a row. */ + btnPtr->nRow = nRows + nSepRows; - TRACE("button %d style=%x, bWrap=%d, nRows=%d, nSepRows=%d, btnrow=%d, (%d,%d)-(%d,%d)\n", - i, btnPtr->fsStyle, bWrap, nRows, nSepRows, btnPtr->nRow, - x, y, x+cx, y+cy); + TRACE("button %d style=%x, bWrap=%d, nRows=%d, nSepRows=%d, btnrow=%d, (%d,%d)-(%d,%d)\n", + i, btnPtr->fsStyle, bWrap, nRows, nSepRows, btnPtr->nRow, + x, y, x + cx, y + cy); - if( bWrap ) - { - if ( !(btnPtr->fsStyle & BTNS_SEP) ) -#ifdef __REACTOS__ - y += cy + infoPtr->szSpacing.cy; -#else - y += cy; -#endif - else - { - if ( !(infoPtr->dwStyle & CCS_VERT)) - y += cy + ( (btnPtr->cx > 0 ) ? - btnPtr->cx : SEPARATOR_WIDTH) * 2 /3; - else -#ifdef __REACTOS__ - y += cy + infoPtr->szSpacing.cy; -#else - y += cy; -#endif + if (bWrap) + { + if (!(btnPtr->fsStyle & BTNS_SEP)) + y += cy; + else + { + if (!(infoPtr->dwStyle & CCS_VERT)) + y += cy + ((btnPtr->cx > 0) ? + btnPtr->cx : SEPARATOR_WIDTH) * 2 / 3; + else + y += cy; - /* nSepRows is used to calculate the extra height following */ - /* the last row. */ - nSepRows++; - } - x = infoPtr->nIndent; + /* nSepRows is used to calculate the extra height following */ + /* the last row. */ + nSepRows++; + } + x = infoPtr->nIndent; - /* Increment row number unless this is the last button */ - /* and it has Wrap set. */ - if (i != infoPtr->nNumButtons-1) - nRows++; - } - else -#ifdef __REACTOS__ - x += cx + infoPtr->szSpacing.cx; -#else - x += cx; -#endif + /* Increment row number unless this is the last button */ + /* and it has Wrap set. */ + if (i != infoPtr->nNumButtons - 1) + nRows++; + } + else + x += cx; } /* infoPtr->nRows is the number of rows on the toolbar */ @@ -1971,13 +1855,13 @@ TOOLBAR_InternalHitTest (const TOOLBAR_INFO *infoPtr, const POINT *lpPt, BOOL *b if (btnPtr->fsStyle & BTNS_SEP) { if (PtInRect (&btnPtr->rect, *lpPt)) { - TRACE(" ON SEPARATOR %d\n", i); + TRACE(" ON SEPARATOR %d!\n", i); return -i; } } else { if (PtInRect (&btnPtr->rect, *lpPt)) { - TRACE(" ON BUTTON %d\n", i); + TRACE(" ON BUTTON %d!\n", i); if (button) *button = TRUE; return i; @@ -1985,7 +1869,7 @@ TOOLBAR_InternalHitTest (const TOOLBAR_INFO *infoPtr, const POINT *lpPt, BOOL *b } } - TRACE(" NOWHERE\n"); + TRACE(" NOWHERE!\n"); return TOOLBAR_NOWHERE; } @@ -2011,7 +1895,6 @@ TOOLBAR_InternalInsertButtonsT(TOOLBAR_INFO *infoPtr, INT iIndex, UINT nAddButto /* insert new buttons data */ for (iButton = 0; iButton < nAddButtons; iButton++) { TBUTTON_INFO *btnPtr = &infoPtr->buttons[iIndex + iButton]; - INT_PTR str; TOOLBAR_DumpTBButton(lpTbb + iButton, fUnicode); @@ -2022,13 +1905,18 @@ TOOLBAR_InternalInsertButtonsT(TOOLBAR_INFO *infoPtr, INT iIndex, UINT nAddButto btnPtr->fsState = lpTbb[iButton].fsState; btnPtr->fsStyle = lpTbb[iButton].fsStyle; btnPtr->dwData = lpTbb[iButton].dwData; - if (btnPtr->fsStyle & BTNS_SEP) - str = -1; + btnPtr->iString = -1; + else if(!IS_INTRESOURCE(lpTbb[iButton].iString) && lpTbb[iButton].iString != -1) + { + if (fUnicode) + Str_SetPtrW((LPWSTR*)&btnPtr->iString, (LPWSTR)lpTbb[iButton].iString ); + else + Str_SetPtrAtoW((LPWSTR*)&btnPtr->iString, (LPSTR)lpTbb[iButton].iString); + fHasString = TRUE; + } else - str = lpTbb[iButton].iString; - set_string_index( btnPtr, str, fUnicode ); - fHasString |= TOOLBAR_ButtonHasString( btnPtr ); + btnPtr->iString = lpTbb[iButton].iString; TOOLBAR_TooltipAddTool(infoPtr, btnPtr); } @@ -2131,6 +2019,16 @@ TOOLBAR_RelayEvent (HWND hwndTip, HWND hwndMsg, UINT uMsg, SendMessageW (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg); } + +static LRESULT +TOOLBAR_ThemeChanged(HWND hwnd) +{ + HTHEME theme = GetWindowTheme(hwnd); + CloseThemeData(theme); + OpenThemeData(hwnd, themeClass); + return 0; +} + static void TOOLBAR_TooltipAddTool(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *button) { @@ -2791,7 +2689,7 @@ TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) btnInfo = (PCUSTOMBUTTON)SendDlgItemMessageW (hwnd, wParam, LB_GETITEMDATA, lpdis->itemID, 0); if (btnInfo == NULL) { - FIXME("btnInfo invalid\n"); + FIXME("btnInfo invalid!\n"); return TRUE; } @@ -2811,9 +2709,9 @@ TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) lpdis->rcItem.right, lpdis->rcItem.bottom); /* calculate button and text rectangles */ - rcButton = lpdis->rcItem; + CopyRect (&rcButton, &lpdis->rcItem); InflateRect (&rcButton, -1, -1); - rcText = rcButton; + CopyRect (&rcText, &rcButton); rcButton.right = rcButton.left + custInfo->tbInfo->nBitmapWidth + 6; rcText.left = rcButton.right + 2; @@ -2973,22 +2871,18 @@ TOOLBAR_AddBitmap (TOOLBAR_INFO *infoPtr, INT count, const TBADDBITMAP *lpAddBmp switch (lpAddBmp->nID) { case IDB_STD_SMALL_COLOR: - case 2: info.nButtons = 15; info.nID = IDB_STD_SMALL; break; case IDB_STD_LARGE_COLOR: - case 3: info.nButtons = 15; info.nID = IDB_STD_LARGE; break; case IDB_VIEW_SMALL_COLOR: - case 6: info.nButtons = 12; info.nID = IDB_VIEW_SMALL; break; case IDB_VIEW_LARGE_COLOR: - case 7: info.nButtons = 12; info.nID = IDB_VIEW_LARGE; break; @@ -3001,11 +2895,10 @@ TOOLBAR_AddBitmap (TOOLBAR_INFO *infoPtr, INT count, const TBADDBITMAP *lpAddBmp info.nID = IDB_HIST_LARGE; break; default: - WARN("unknown bitmap id, %ld\n", lpAddBmp->nID); return -1; } - TRACE ("adding %d internal bitmaps\n", info.nButtons); + TRACE ("adding %d internal bitmaps!\n", info.nButtons); /* Windows resize all the buttons to the size of a newly added standard image */ if (lpAddBmp->nID & 1) @@ -3026,7 +2919,7 @@ TOOLBAR_AddBitmap (TOOLBAR_INFO *infoPtr, INT count, const TBADDBITMAP *lpAddBmp info.nButtons = count; info.hInst = lpAddBmp->hInst; info.nID = lpAddBmp->nID; - TRACE("adding %d bitmaps\n", info.nButtons); + TRACE("adding %d bitmaps!\n", info.nButtons); } /* check if the bitmap is already loaded and compute iSumButtons */ @@ -3041,7 +2934,7 @@ TOOLBAR_AddBitmap (TOOLBAR_INFO *infoPtr, INT count, const TBADDBITMAP *lpAddBmp if (!infoPtr->cimlDef) { /* create new default image list */ - TRACE ("creating default image list\n"); + TRACE ("creating default image list!\n"); himlDef = ImageList_Create (infoPtr->nBitmapWidth, infoPtr->nBitmapHeight, ILC_COLOR32 | ILC_MASK, info.nButtons, 2); @@ -3074,7 +2967,7 @@ TOOLBAR_AddBitmap (TOOLBAR_INFO *infoPtr, INT count, const TBADDBITMAP *lpAddBmp static LRESULT TOOLBAR_AddButtonsT(TOOLBAR_INFO *infoPtr, INT nAddButtons, const TBBUTTON* lpTbb, BOOL fUnicode) { - TRACE("adding %d buttons (unicode=%d)\n", nAddButtons, fUnicode); + TRACE("adding %d buttons (unicode=%d)!\n", nAddButtons, fUnicode); return TOOLBAR_InternalInsertButtonsT(infoPtr, -1, nAddButtons, lpTbb, fUnicode); } @@ -3200,28 +3093,38 @@ TOOLBAR_AddStringA (TOOLBAR_INFO *infoPtr, HINSTANCE hInstance, LPARAM lParam) static LRESULT TOOLBAR_AutoSize (TOOLBAR_INFO *infoPtr) { - TRACE("auto sizing, style=%#x\n", infoPtr->dwStyle); - TRACE("nRows: %d, infoPtr->nButtonHeight: %d\n", infoPtr->nRows, infoPtr->nButtonHeight); + RECT parent_rect; + HWND parent; + INT x, y; + INT cx, cy; - if (!(infoPtr->dwStyle & CCS_NORESIZE)) - { - RECT window_rect, parent_rect; - UINT uPosFlags = SWP_NOZORDER | SWP_NOACTIVATE; - HWND parent; - INT x, y, cx, cy; + TRACE("auto sizing, style=%x!\n", infoPtr->dwStyle); - parent = GetParent (infoPtr->hwndSelf); + parent = GetParent (infoPtr->hwndSelf); - if (!parent || !infoPtr->bDoRedraw) - return 0; + if (!parent || !infoPtr->bDoRedraw) + return 0; + + GetClientRect(parent, &parent_rect); + + x = parent_rect.left; + y = parent_rect.top; - GetClientRect(parent, &parent_rect); + TRACE("nRows: %d, infoPtr->nButtonHeight: %d\n", infoPtr->nRows, infoPtr->nButtonHeight); + + cy = TOP_BORDER + infoPtr->nRows * infoPtr->nButtonHeight + BOTTOM_BORDER; + cx = parent_rect.right - parent_rect.left; - x = parent_rect.left; - y = parent_rect.top; + if ((infoPtr->dwStyle & TBSTYLE_WRAPABLE) || (infoPtr->dwExStyle & TBSTYLE_EX_VERTICAL)) + { + TOOLBAR_LayoutToolbar(infoPtr); + InvalidateRect( infoPtr->hwndSelf, NULL, TRUE ); + } - cy = TOP_BORDER + infoPtr->nRows * infoPtr->nButtonHeight + BOTTOM_BORDER; - cx = parent_rect.right - parent_rect.left; + if (!(infoPtr->dwStyle & CCS_NORESIZE)) + { + RECT window_rect; + UINT uPosFlags = SWP_NOZORDER | SWP_NOACTIVATE; if ((infoPtr->dwStyle & CCS_BOTTOM) == CCS_NOMOVEY) { @@ -3250,12 +3153,6 @@ TOOLBAR_AutoSize (TOOLBAR_INFO *infoPtr) SetWindowPos(infoPtr->hwndSelf, NULL, x, y, cx, cy, uPosFlags); } - if ((infoPtr->dwStyle & TBSTYLE_WRAPABLE) || (infoPtr->dwExStyle & TBSTYLE_EX_VERTICAL)) - { - TOOLBAR_LayoutToolbar(infoPtr); - InvalidateRect( infoPtr->hwndSelf, NULL, TRUE ); - } - return 0; } @@ -3318,7 +3215,7 @@ TOOLBAR_CheckButton (TOOLBAR_INFO *infoPtr, INT Id, LPARAM lParam) bChecked = (btnPtr->fsState & TBSTATE_CHECKED) != 0; - if (!LOWORD(lParam)) + if (LOWORD(lParam) == FALSE) btnPtr->fsState &= ~TBSTATE_CHECKED; else { if (btnPtr->fsStyle & BTNS_GROUP) { @@ -3396,17 +3293,17 @@ TOOLBAR_DeleteButton (TOOLBAR_INFO *infoPtr, INT nIndex) TOOLBAR_TooltipDelTool(infoPtr, &infoPtr->buttons[nIndex]); - infoPtr->nHotItem = -1; if (infoPtr->nNumButtons == 1) { - TRACE(" simple delete\n"); - free_string( infoPtr->buttons ); + TRACE(" simple delete!\n"); + if (TOOLBAR_ButtonHasString(infoPtr->buttons)) + Free((LPWSTR)infoPtr->buttons[0].iString); Free (infoPtr->buttons); infoPtr->buttons = NULL; infoPtr->nNumButtons = 0; } else { TBUTTON_INFO *oldButtons = infoPtr->buttons; - TRACE("complex delete [nIndex=%d]\n", nIndex); + TRACE("complex delete! [nIndex=%d]\n", nIndex); infoPtr->nNumButtons--; infoPtr->buttons = Alloc (sizeof (TBUTTON_INFO) * infoPtr->nNumButtons); @@ -3420,7 +3317,8 @@ TOOLBAR_DeleteButton (TOOLBAR_INFO *infoPtr, INT nIndex) (infoPtr->nNumButtons - nIndex) * sizeof(TBUTTON_INFO)); } - free_string( oldButtons + nIndex ); + if (TOOLBAR_ButtonHasString(&oldButtons[nIndex])) + Free((LPWSTR)oldButtons[nIndex].iString); Free (oldButtons); } @@ -3451,7 +3349,7 @@ TOOLBAR_EnableButton (TOOLBAR_INFO *infoPtr, INT Id, LPARAM lParam) bState = btnPtr->fsState & TBSTATE_ENABLED; /* update the toolbar button state */ - if(!LOWORD(lParam)) { + if(LOWORD(lParam) == FALSE) { btnPtr->fsState &= ~(TBSTATE_ENABLED | TBSTATE_PRESSED); } else { btnPtr->fsState |= TBSTATE_ENABLED; @@ -3541,7 +3439,8 @@ TOOLBAR_GetButtonInfoT(const TOOLBAR_INFO *infoPtr, INT Id, LPTBBUTTONINFOW lpTb if (nIndex == -1) return -1; - btnPtr = &infoPtr->buttons[nIndex]; + if (!(btnPtr = &infoPtr->buttons[nIndex])) return -1; + if (lpTbInfo->dwMask & TBIF_COMMAND) lpTbInfo->idCommand = btnPtr->idCommand; if (lpTbInfo->dwMask & TBIF_IMAGE) @@ -3567,7 +3466,7 @@ TOOLBAR_GetButtonInfoT(const TOOLBAR_INFO *infoPtr, INT Id, LPTBBUTTONINFOW lpTb Str_GetPtrW(lpText, lpTbInfo->pszText, lpTbInfo->cchText); else Str_GetPtrWtoA(lpText, (LPSTR)lpTbInfo->pszText, lpTbInfo->cchText); - } else if (!bUnicode || lpTbInfo->pszText) + } else lpTbInfo->pszText[0] = '\0'; } return nIndex; @@ -3718,12 +3617,14 @@ TOOLBAR_GetMaxSize (const TOOLBAR_INFO *infoPtr, LPSIZE lpSize) return TRUE; } -#ifdef __REACTOS__ + static LRESULT -TOOLBAR_GetMetrics(const TOOLBAR_INFO *infoPtr, TBMETRICS *pMetrics) +TOOLBAR_GetMetrics (const TOOLBAR_INFO *infoPtr, TBMETRICS *pMetrics) { - if (pMetrics == NULL || pMetrics->cbSize != sizeof(TBMETRICS)) - return 0; + if (pMetrics == NULL) + return FALSE; + + /* TODO: check if cbSize is a valid value */ if (pMetrics->dwMask & TBMF_PAD) { @@ -3743,9 +3644,9 @@ TOOLBAR_GetMetrics(const TOOLBAR_INFO *infoPtr, TBMETRICS *pMetrics) pMetrics->cyButtonSpacing = infoPtr->szSpacing.cy; } - return 0; + return TRUE; } -#endif + /* << TOOLBAR_GetObject >> */ @@ -4268,55 +4169,12 @@ TOOLBAR_ReplaceBitmap (TOOLBAR_INFO *infoPtr, const TBREPLACEBITMAP *lpReplace) /* helper for TOOLBAR_SaveRestoreW */ static BOOL -TOOLBAR_Save(TOOLBAR_INFO *infoPtr, const TBSAVEPARAMSW *params) +TOOLBAR_Save(const TBSAVEPARAMSW *lpSave) { - NMTBSAVE save; - INT ret, i; - BOOL alloced = FALSE; - HKEY key; - - TRACE( "save to %s %s\n", debugstr_w(params->pszSubKey), debugstr_w(params->pszValueName) ); - - memset( &save, 0, sizeof(save) ); - save.cbData = infoPtr->nNumButtons * sizeof(DWORD); - save.iItem = -1; - save.cButtons = infoPtr->nNumButtons; - save.tbButton.idCommand = -1; - TOOLBAR_SendNotify( &save.hdr, infoPtr, TBN_SAVE ); - - if (!save.pData) - { - save.pData = Alloc( save.cbData ); - if (!save.pData) return FALSE; - alloced = TRUE; - } - if (!save.pCurrent) save.pCurrent = save.pData; - - for (i = 0; i < infoPtr->nNumButtons; i++) - { - save.iItem = i; - save.tbButton.iBitmap = infoPtr->buttons[i].iBitmap; - save.tbButton.idCommand = infoPtr->buttons[i].idCommand; - save.tbButton.fsState = infoPtr->buttons[i].fsState; - save.tbButton.fsStyle = infoPtr->buttons[i].fsStyle; - memset( save.tbButton.bReserved, 0, sizeof(save.tbButton.bReserved) ); - save.tbButton.dwData = infoPtr->buttons[i].dwData; - save.tbButton.iString = infoPtr->buttons[i].iString; - - *save.pCurrent++ = save.tbButton.idCommand; - - TOOLBAR_SendNotify( &save.hdr, infoPtr, TBN_SAVE ); - } - - ret = RegCreateKeyW( params->hkr, params->pszSubKey, &key ); - if (ret == ERROR_SUCCESS) - { - ret = RegSetValueExW( key, params->pszValueName, 0, REG_BINARY, (BYTE *)save.pData, save.cbData ); - RegCloseKey( key ); - } + FIXME("save to %s %s\n", debugstr_w(lpSave->pszSubKey), + debugstr_w(lpSave->pszValueName)); - if (alloced) Free( save.pData ); - return !ret; + return FALSE; } @@ -4328,7 +4186,6 @@ TOOLBAR_DeleteAllButtons(TOOLBAR_INFO *infoPtr) for (i = 0; i < infoPtr->nNumButtons; i++) { - free_string( infoPtr->buttons + i ); TOOLBAR_TooltipDelTool(infoPtr, &infoPtr->buttons[i]); } @@ -4348,7 +4205,6 @@ TOOLBAR_Restore(TOOLBAR_INFO *infoPtr, const TBSAVEPARAMSW *lpSave) DWORD dwType; DWORD dwSize = 0; NMTBRESTORE nmtbr; - NMHDR hdr; /* restore toolbar information */ TRACE("restore from %s %s\n", debugstr_w(lpSave->pszSubKey), @@ -4381,30 +4237,30 @@ TOOLBAR_Restore(TOOLBAR_INFO *infoPtr, const TBSAVEPARAMSW *lpSave) if (!TOOLBAR_SendNotify(&nmtbr.hdr, infoPtr, TBN_RESTORE)) { - INT i, count = nmtbr.cButtons; + INT i; /* remove all existing buttons as this function is designed to * restore the toolbar to a previously saved state */ TOOLBAR_DeleteAllButtons(infoPtr); - for (i = 0; i < count; i++) + for (i = 0; i < nmtbr.cButtons; i++) { nmtbr.iItem = i; nmtbr.tbButton.iBitmap = -1; nmtbr.tbButton.fsState = 0; nmtbr.tbButton.fsStyle = 0; - nmtbr.tbButton.dwData = 0; - nmtbr.tbButton.iString = 0; - - if (*nmtbr.pCurrent & 0x80000000) + nmtbr.tbButton.idCommand = 0; + if (*nmtbr.pCurrent == (DWORD)-1) { /* separator */ - nmtbr.tbButton.iBitmap = SEPARATOR_WIDTH; - nmtbr.tbButton.idCommand = 0; - nmtbr.tbButton.fsStyle = BTNS_SEP; - if (*nmtbr.pCurrent != (DWORD)-1) - nmtbr.tbButton.fsState = TBSTATE_HIDDEN; + nmtbr.tbButton.fsStyle = TBSTYLE_SEP; + /* when inserting separators, iBitmap controls its size. + 0 sets default size (width) */ + nmtbr.tbButton.iBitmap = 0; } + else if (*nmtbr.pCurrent == (DWORD)-2) + /* hidden button */ + nmtbr.tbButton.fsState = TBSTATE_HIDDEN; else nmtbr.tbButton.idCommand = (int)*nmtbr.pCurrent; @@ -4412,51 +4268,21 @@ TOOLBAR_Restore(TOOLBAR_INFO *infoPtr, const TBSAVEPARAMSW *lpSave) TOOLBAR_SendNotify(&nmtbr.hdr, infoPtr, TBN_RESTORE); - /* All returned ptrs and -1 are ignored */ + /* can't contain real string as we don't know whether + * the client put an ANSI or Unicode string in there */ if (!IS_INTRESOURCE(nmtbr.tbButton.iString)) nmtbr.tbButton.iString = 0; TOOLBAR_InsertButtonT(infoPtr, -1, &nmtbr.tbButton, TRUE); } - TOOLBAR_SendNotify( &hdr, infoPtr, TBN_BEGINADJUST ); - for (i = 0; ; i++) + /* do legacy notifications */ + if (infoPtr->iVersion < 5) { - NMTOOLBARW tb; - TBBUTTONINFOW bi; - WCHAR buf[128]; - UINT code = infoPtr->bUnicode ? TBN_GETBUTTONINFOW : TBN_GETBUTTONINFOA; - INT idx; - - memset( &tb, 0, sizeof(tb) ); - tb.iItem = i; - tb.cchText = ARRAY_SIZE(buf); - tb.pszText = buf; - - /* Use the same struct for both A and W versions since the layout is the same. */ - if (!TOOLBAR_SendNotify( &tb.hdr, infoPtr, code )) - break; - - idx = TOOLBAR_GetButtonIndex( infoPtr, tb.tbButton.idCommand, FALSE ); - if (idx == -1) continue; - - /* tb.pszText is ignored - the string comes from tb.tbButton.iString, which may - be an index or a ptr. Either way it is simply copied. There is no api to change - the string index, so we set it manually. The other properties can be set with SetButtonInfo. */ - free_string( infoPtr->buttons + idx ); - infoPtr->buttons[idx].iString = tb.tbButton.iString; - - memset( &bi, 0, sizeof(bi) ); - bi.cbSize = sizeof(bi); - bi.dwMask = TBIF_IMAGE | TBIF_STATE | TBIF_STYLE | TBIF_LPARAM; - bi.iImage = tb.tbButton.iBitmap; - bi.fsState = tb.tbButton.fsState; - bi.fsStyle = tb.tbButton.fsStyle; - bi.lParam = tb.tbButton.dwData; - - TOOLBAR_SetButtonInfo( infoPtr, tb.tbButton.idCommand, &bi, TRUE ); + /* FIXME: send TBN_BEGINADJUST */ + FIXME("send TBN_GETBUTTONINFO for each button\n"); + /* FIXME: send TBN_ENDADJUST */ } - TOOLBAR_SendNotify( &hdr, infoPtr, TBN_ENDADJUST ); /* remove all uninitialised buttons * note: loop backwards to avoid having to fixup i on a @@ -4482,7 +4308,7 @@ TOOLBAR_SaveRestoreW (TOOLBAR_INFO *infoPtr, WPARAM wParam, const TBSAVEPARAMSW if (lpSave == NULL) return 0; if (wParam) - return TOOLBAR_Save(infoPtr, lpSave); + return TOOLBAR_Save(lpSave); else return TOOLBAR_Restore(infoPtr, lpSave); } @@ -4500,7 +4326,7 @@ TOOLBAR_SaveRestoreA (TOOLBAR_INFO *infoPtr, WPARAM wParam, const TBSAVEPARAMSA len = MultiByteToWideChar(CP_ACP, 0, lpSave->pszSubKey, -1, NULL, 0); pszSubKey = Alloc(len * sizeof(WCHAR)); - if (!pszSubKey) goto exit; + if (pszSubKey) goto exit; MultiByteToWideChar(CP_ACP, 0, lpSave->pszSubKey, -1, pszSubKey, len); len = MultiByteToWideChar(CP_ACP, 0, lpSave->pszValueName, -1, NULL, 0); @@ -4543,7 +4369,7 @@ TOOLBAR_SetBitmapSize (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam) short width = (short)LOWORD(lParam); short height = (short)HIWORD(lParam); - TRACE("hwnd=%p, wParam=%ld, size %d x %d\n", infoPtr->hwndSelf, wParam, width, height); + TRACE("hwnd=%p, wParam=%ld, lParam=%ld\n", infoPtr->hwndSelf, wParam, lParam); if (wParam != 0) FIXME("wParam is %ld. Perhaps image list index?\n", wParam); @@ -4617,8 +4443,15 @@ TOOLBAR_SetButtonInfo (TOOLBAR_INFO *infoPtr, INT Id, if (lptbbi->dwMask & TBIF_STYLE) btnPtr->fsStyle = lptbbi->fsStyle; - if (lptbbi->dwMask & TBIF_TEXT) - set_stringT( btnPtr, lptbbi->pszText, isW ); + if ((lptbbi->dwMask & TBIF_TEXT) && ((INT_PTR)lptbbi->pszText != -1)) { + /* iString is index, zero it to make Str_SetPtr succeed */ + if (!TOOLBAR_ButtonHasString(btnPtr)) btnPtr->iString = 0; + + if (isW) + Str_SetPtrW ((LPWSTR *)&btnPtr->iString, lptbbi->pszText); + else + Str_SetPtrAtoW ((LPWSTR *)&btnPtr->iString, (LPSTR)lptbbi->pszText); + } /* save the button rect to see if we need to redraw the whole toolbar */ oldBtnRect = btnPtr->rect; @@ -4637,7 +4470,6 @@ static LRESULT TOOLBAR_SetButtonSize (TOOLBAR_INFO *infoPtr, LPARAM lParam) { INT cx = (short)LOWORD(lParam), cy = (short)HIWORD(lParam); - int top = default_top_margin(infoPtr); if ((cx < 0) || (cy < 0)) { @@ -4660,25 +4492,15 @@ TOOLBAR_SetButtonSize (TOOLBAR_INFO *infoPtr, LPARAM lParam) */ if (cx == 0) cx = 24; if (cy == 0) cy = 22; - -#ifdef __REACTOS__ - cx = max(cx, infoPtr->szPadding.cx + infoPtr->nBitmapWidth + infoPtr->themeMargins.cxLeftWidth + infoPtr->themeMargins.cxRightWidth); - cy = max(cy, infoPtr->szPadding.cy + infoPtr->nBitmapHeight + infoPtr->themeMargins.cyTopHeight + infoPtr->themeMargins.cyBottomHeight); -#else + cx = max(cx, infoPtr->szPadding.cx + infoPtr->nBitmapWidth); cy = max(cy, infoPtr->szPadding.cy + infoPtr->nBitmapHeight); -#endif - - if (cx != infoPtr->nButtonWidth || cy != infoPtr->nButtonHeight || - top != infoPtr->iTopMargin) - { - infoPtr->nButtonWidth = cx; - infoPtr->nButtonHeight = cy; - infoPtr->iTopMargin = top; - TOOLBAR_LayoutToolbar( infoPtr ); - InvalidateRect( infoPtr->hwndSelf, NULL, TRUE ); - } + infoPtr->nButtonWidth = cx; + infoPtr->nButtonHeight = cy; + + infoPtr->iTopMargin = default_top_margin(infoPtr); + TOOLBAR_LayoutToolbar(infoPtr); return TRUE; } @@ -4722,7 +4544,7 @@ TOOLBAR_SetCmdId (TOOLBAR_INFO *infoPtr, INT nIndex, INT nId) if (infoPtr->hwndToolTip) { - FIXME("change tool tip\n"); + FIXME("change tool tip!\n"); } @@ -4749,16 +4571,17 @@ TOOLBAR_SetDisabledImageList (TOOLBAR_INFO *infoPtr, WPARAM wParam, HIMAGELIST h static LRESULT -TOOLBAR_SetDrawTextFlags (TOOLBAR_INFO *infoPtr, DWORD mask, DWORD flags) +TOOLBAR_SetDrawTextFlags (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam) { - DWORD old_flags; + DWORD dwTemp; - TRACE("hwnd = %p, mask = 0x%08x, flags = 0x%08x\n", infoPtr->hwndSelf, mask, flags); + TRACE("hwnd = %p, dwMask = 0x%08x, dwDTFlags = 0x%08x\n", infoPtr->hwndSelf, (DWORD)wParam, (DWORD)lParam); - old_flags = infoPtr->dwDTFlags; - infoPtr->dwDTFlags = (old_flags & ~mask) | (flags & mask); + dwTemp = infoPtr->dwDTFlags; + infoPtr->dwDTFlags = + (infoPtr->dwDTFlags & (DWORD)wParam) | (DWORD)lParam; - return (LRESULT)old_flags; + return (LRESULT)dwTemp; } /* This function differs a bit from what MSDN says it does: @@ -5005,9 +4828,9 @@ TOOLBAR_SetMaxTextRows (TOOLBAR_INFO *infoPtr, INT nMaxRows) return TRUE; } -#ifdef __REACTOS__ + static LRESULT -TOOLBAR_SetMetrics(TOOLBAR_INFO *infoPtr, TBMETRICS *pMetrics) +TOOLBAR_SetMetrics (TOOLBAR_INFO *infoPtr, TBMETRICS *pMetrics) { BOOL changed = FALSE; @@ -5042,7 +4865,6 @@ TOOLBAR_SetMetrics(TOOLBAR_INFO *infoPtr, TBMETRICS *pMetrics) return TRUE; } -#endif /* MSDN gives slightly wrong info on padding. * 1. It is not only used on buttons with the BTNS_AUTOSIZE style @@ -5233,45 +5055,11 @@ TOOLBAR_SetState (TOOLBAR_INFO *infoPtr, INT Id, LPARAM lParam) return TRUE; } -static inline void unwrap(TOOLBAR_INFO *info) -{ - int i; - - for (i = 0; i < info->nNumButtons; i++) - info->buttons[i].fsState &= ~TBSTATE_WRAP; -} static LRESULT TOOLBAR_SetStyle (TOOLBAR_INFO *infoPtr, DWORD style) { - DWORD dwOldStyle = infoPtr->dwStyle; - - TRACE("new style 0x%08x\n", style); - - if (style & TBSTYLE_LIST) - infoPtr->dwDTFlags = DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS; - else - infoPtr->dwDTFlags = DT_CENTER | DT_END_ELLIPSIS; - infoPtr->dwStyle = style; - TOOLBAR_CheckStyle(infoPtr); - - if ((dwOldStyle ^ style) & TBSTYLE_WRAPABLE) - { - if (dwOldStyle & TBSTYLE_WRAPABLE) - unwrap(infoPtr); - TOOLBAR_CalcToolbar(infoPtr); - } - else if ((dwOldStyle ^ style) & CCS_VERT) - TOOLBAR_LayoutToolbar(infoPtr); - - /* only resize if one of the CCS_* styles was changed */ - if ((dwOldStyle ^ style) & COMMON_STYLES) - { - TOOLBAR_AutoSize(infoPtr); - InvalidateRect(infoPtr->hwndSelf, NULL, TRUE); - } - return 0; } @@ -5332,16 +5120,6 @@ TOOLBAR_SetVersion (TOOLBAR_INFO *infoPtr, INT iVersion) { INT iOldVersion = infoPtr->iVersion; -#ifdef __REACTOS__ - /* The v6 control doesn't support changing its version */ - if (iOldVersion == 6) - return iOldVersion; - - /* And a control that is not v6 can't be set to be a v6 one */ - if (iVersion >= 6) - return -1; -#endif - infoPtr->iVersion = iVersion; if (infoPtr->iVersion >= 5) @@ -5402,13 +5180,16 @@ TOOLBAR_GetStringW (const TOOLBAR_INFO *infoPtr, WPARAM wParam, LPWSTR str) return ret; } -static LRESULT TOOLBAR_SetBoundingSize(HWND hwnd, WPARAM wParam, LPARAM lParam) +/* UNDOCUMENTED MESSAGE: This appears to set some kind of size. Perhaps it + * is the maximum size of the toolbar? */ +static LRESULT TOOLBAR_Unkwn45D(HWND hwnd, WPARAM wParam, LPARAM lParam) { SIZE * pSize = (SIZE*)lParam; - FIXME("hwnd=%p, wParam=0x%08lx, size.cx=%d, size.cy=%d stub\n", hwnd, wParam, pSize->cx, pSize->cy); + FIXME("hwnd=%p, wParam=0x%08lx, size.cx=%d, size.cy=%d stub!\n", hwnd, wParam, pSize->cx, pSize->cy); return 0; } + /* This is an extended version of the TB_SETHOTITEM message. It allows the * caller to specify a reason why the hot item changed (rather than just the * HICF_OTHER that TB_SETHOTITEM sends). */ @@ -5528,16 +5309,8 @@ TOOLBAR_Create (HWND hwnd, const CREATESTRUCTW *lpcs) SystemParametersInfoW (SPI_GETICONTITLELOGFONT, 0, &logFont, 0); infoPtr->hFont = infoPtr->hDefaultFont = CreateFontIndirectW (&logFont); - -#ifdef __REACTOS__ - { - HTHEME theme = OpenThemeData (hwnd, themeClass); - if (theme) - GetThemeMargins(theme, NULL, TP_BUTTON, TS_NORMAL, TMT_CONTENTMARGINS, NULL, &infoPtr->themeMargins); - } -#else + OpenThemeData (hwnd, themeClass); -#endif TOOLBAR_CheckStyle (infoPtr); @@ -5560,7 +5333,8 @@ TOOLBAR_Destroy (TOOLBAR_INFO *infoPtr) /* delete button data */ for (i = 0; i < infoPtr->nNumButtons; i++) - free_string( infoPtr->buttons + i ); + if (TOOLBAR_ButtonHasString(&infoPtr->buttons[i])) + Free ((LPWSTR)infoPtr->buttons[i].iString); Free (infoPtr->buttons); /* delete strings */ @@ -5788,92 +5562,95 @@ TOOLBAR_LButtonDown (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam) nHit = TOOLBAR_InternalHitTest (infoPtr, &pt, &button); if (button) - { btnPtr = &infoPtr->buttons[nHit]; - if (bDragKeyPressed && (infoPtr->dwStyle & CCS_ADJUSTABLE)) - { - infoPtr->nButtonDrag = nHit; - SetCapture (infoPtr->hwndSelf); - - /* If drag cursor has not been loaded, load it. - * Note: it doesn't need to be freed */ - if (!hCursorDrag) - hCursorDrag = LoadCursorW(COMCTL32_hModule, (LPCWSTR)IDC_MOVEBUTTON); - SetCursor(hCursorDrag); - } - else - { - RECT arrowRect; - infoPtr->nOldHit = nHit; - - arrowRect = btnPtr->rect; - arrowRect.left = max(btnPtr->rect.left, btnPtr->rect.right - DDARROW_WIDTH); + if (button && bDragKeyPressed && (infoPtr->dwStyle & CCS_ADJUSTABLE)) + { + infoPtr->nButtonDrag = nHit; + SetCapture (infoPtr->hwndSelf); + + /* If drag cursor has not been loaded, load it. + * Note: it doesn't need to be freed */ + if (!hCursorDrag) + hCursorDrag = LoadCursorW(COMCTL32_hModule, (LPCWSTR)IDC_MOVEBUTTON); + SetCursor(hCursorDrag); + } + else if (button) + { + RECT arrowRect; + infoPtr->nOldHit = nHit; + + CopyRect(&arrowRect, &btnPtr->rect); + arrowRect.left = max(btnPtr->rect.left, btnPtr->rect.right - DDARROW_WIDTH); + + /* for EX_DRAWDDARROWS style, click must be in the drop-down arrow rect */ + if ((btnPtr->fsState & TBSTATE_ENABLED) && + ((btnPtr->fsStyle & BTNS_WHOLEDROPDOWN) || + ((btnPtr->fsStyle & BTNS_DROPDOWN) && + ((TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle) && PtInRect(&arrowRect, pt)) || + (!TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle)))))) + { + LRESULT res; - /* for EX_DRAWDDARROWS style, click must be in the drop-down arrow rect */ - if ((btnPtr->fsState & TBSTATE_ENABLED) && - ((btnPtr->fsStyle & BTNS_WHOLEDROPDOWN) || - ((btnPtr->fsStyle & BTNS_DROPDOWN) && - ((TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle) && PtInRect(&arrowRect, pt)) || - (!TOOLBAR_HasDropDownArrows(infoPtr->dwExStyle)))))) + /* draw in pressed state */ + if (btnPtr->fsStyle & BTNS_WHOLEDROPDOWN) + btnPtr->fsState |= TBSTATE_PRESSED; + else + btnPtr->bDropDownPressed = TRUE; + RedrawWindow(infoPtr->hwndSelf,&btnPtr->rect,0, + RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW); + + memset(&nmtb, 0, sizeof(nmtb)); + nmtb.iItem = btnPtr->idCommand; + nmtb.rcButton = btnPtr->rect; + res = TOOLBAR_SendNotify ((NMHDR *) &nmtb, infoPtr, + TBN_DROPDOWN); + TRACE("TBN_DROPDOWN responded with %ld\n", res); + + if (res != TBDDRET_TREATPRESSED) { - LRESULT res; - - /* draw in pressed state */ - if (btnPtr->fsStyle & BTNS_WHOLEDROPDOWN) - btnPtr->fsState |= TBSTATE_PRESSED; - else - btnPtr->bDropDownPressed = TRUE; - RedrawWindow(infoPtr->hwndSelf, &btnPtr->rect, 0, RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW); + MSG msg; - memset(&nmtb, 0, sizeof(nmtb)); - nmtb.iItem = btnPtr->idCommand; - nmtb.rcButton = btnPtr->rect; - res = TOOLBAR_SendNotify ((NMHDR *) &nmtb, infoPtr, TBN_DROPDOWN); - TRACE("TBN_DROPDOWN responded with %ld\n", res); + /* redraw button in unpressed state */ + if (btnPtr->fsStyle & BTNS_WHOLEDROPDOWN) + btnPtr->fsState &= ~TBSTATE_PRESSED; + else + btnPtr->bDropDownPressed = FALSE; + InvalidateRect(infoPtr->hwndSelf, &btnPtr->rect, TRUE); - if (res != TBDDRET_TREATPRESSED) - { - MSG msg; + /* find and set hot item */ + GetCursorPos(&pt); + ScreenToClient(infoPtr->hwndSelf, &pt); + nHit = TOOLBAR_InternalHitTest(infoPtr, &pt, &button); + if (!infoPtr->bAnchor || button) + TOOLBAR_SetHotItemEx(infoPtr, button ? nHit : TOOLBAR_NOWHERE, HICF_MOUSE | HICF_LMOUSE); + + /* remove any left mouse button down or double-click messages + * so that we can get a toggle effect on the button */ + while (PeekMessageW(&msg, infoPtr->hwndSelf, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_REMOVE) || + PeekMessageW(&msg, infoPtr->hwndSelf, WM_LBUTTONDBLCLK, WM_LBUTTONDBLCLK, PM_REMOVE)) + ; - /* redraw button in unpressed state */ - if (btnPtr->fsStyle & BTNS_WHOLEDROPDOWN) - btnPtr->fsState &= ~TBSTATE_PRESSED; - else - btnPtr->bDropDownPressed = FALSE; - InvalidateRect(infoPtr->hwndSelf, &btnPtr->rect, TRUE); - - /* find and set hot item */ - GetCursorPos(&pt); - ScreenToClient(infoPtr->hwndSelf, &pt); - nHit = TOOLBAR_InternalHitTest(infoPtr, &pt, &button); - if (!infoPtr->bAnchor || button) - TOOLBAR_SetHotItemEx(infoPtr, nHit, HICF_MOUSE | HICF_LMOUSE); - - /* remove any left mouse button down or double-click messages - * so that we can get a toggle effect on the button */ - while (PeekMessageW(&msg, infoPtr->hwndSelf, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_REMOVE) || - PeekMessageW(&msg, infoPtr->hwndSelf, WM_LBUTTONDBLCLK, WM_LBUTTONDBLCLK, PM_REMOVE)) - ; - - return 0; - } - /* otherwise drop through and process as pushed */ + return 0; } - infoPtr->bCaptured = TRUE; - infoPtr->nButtonDown = nHit; - infoPtr->bDragOutSent = FALSE; + /* otherwise drop through and process as pushed */ + } + infoPtr->bCaptured = TRUE; + infoPtr->nButtonDown = nHit; + infoPtr->bDragOutSent = FALSE; - btnPtr->fsState |= TBSTATE_PRESSED; + btnPtr->fsState |= TBSTATE_PRESSED; - TOOLBAR_SetHotItemEx(infoPtr, nHit, HICF_MOUSE | HICF_LMOUSE); + TOOLBAR_SetHotItemEx(infoPtr, button ? nHit : TOOLBAR_NOWHERE, HICF_MOUSE | HICF_LMOUSE); - if (btnPtr->fsState & TBSTATE_ENABLED) - InvalidateRect(infoPtr->hwndSelf, &btnPtr->rect, TRUE); - UpdateWindow(infoPtr->hwndSelf); - SetCapture (infoPtr->hwndSelf); - } + if (btnPtr->fsState & TBSTATE_ENABLED) + InvalidateRect(infoPtr->hwndSelf, &btnPtr->rect, TRUE); + UpdateWindow(infoPtr->hwndSelf); + SetCapture (infoPtr->hwndSelf); + } + if (button) + { memset(&nmtb, 0, sizeof(nmtb)); nmtb.iItem = btnPtr->idCommand; TOOLBAR_SendNotify((NMHDR *)&nmtb, infoPtr, TBN_BEGINDRAG); @@ -6276,6 +6053,7 @@ TOOLBAR_NCCreate (HWND hwnd, WPARAM wParam, const CREATESTRUCTW *lpcs) /* paranoid!! */ infoPtr->dwStructSize = sizeof(TBBUTTON); infoPtr->nRows = 1; + infoPtr->nWidth = 0; /* initialize info structure */ infoPtr->nButtonWidth = 23; @@ -6309,11 +6087,8 @@ TOOLBAR_NCCreate (HWND hwnd, WPARAM wParam, const CREATESTRUCTW *lpcs) infoPtr->clrBtnShadow = CLR_DEFAULT; infoPtr->szPadding.cx = DEFPAD_CX; infoPtr->szPadding.cy = DEFPAD_CY; -#ifdef __REACTOS__ - infoPtr->szSpacing.cx = 0; - infoPtr->szSpacing.cy = 0; - memset(&infoPtr->themeMargins, 0 , sizeof(infoPtr->themeMargins)); -#endif + infoPtr->szSpacing.cx = DEFSPACE_CX; + infoPtr->szSpacing.cy = DEFSPACE_CY; infoPtr->iListGap = DEFLISTGAP; infoPtr->iTopMargin = default_top_margin(infoPtr); infoPtr->dwStyle = lpcs->style; @@ -6411,7 +6186,7 @@ static LRESULT TOOLBAR_TTGetDispInfo (TOOLBAR_INFO *infoPtr, NMTTDISPINFOW *lpnm TRACE("TBN_GETINFOTIPW - got string %s\n", debugstr_w(tbgit.pszText)); len = strlenW(tbgit.pszText); - if (len > ARRAY_SIZE(lpnmtdi->szText) - 1) + if (len > sizeof(lpnmtdi->szText)/sizeof(lpnmtdi->szText[0])-1) { /* need to allocate temporary buffer in infoPtr as there * isn't enough space in buffer passed to us by the @@ -6449,7 +6224,7 @@ static LRESULT TOOLBAR_TTGetDispInfo (TOOLBAR_INFO *infoPtr, NMTTDISPINFOW *lpnm TRACE("TBN_GETINFOTIPA - got string %s\n", debugstr_a(tbgit.pszText)); len = MultiByteToWideChar(CP_ACP, 0, tbgit.pszText, -1, NULL, 0); - if (len > ARRAY_SIZE(lpnmtdi->szText)) + if (len > sizeof(lpnmtdi->szText)/sizeof(lpnmtdi->szText[0])) { /* need to allocate temporary buffer in infoPtr as there * isn't enough space in buffer passed to us by the @@ -6464,7 +6239,8 @@ static LRESULT TOOLBAR_TTGetDispInfo (TOOLBAR_INFO *infoPtr, NMTTDISPINFOW *lpnm } else if (tbgit.pszText && tbgit.pszText[0]) { - MultiByteToWideChar(CP_ACP, 0, tbgit.pszText, -1, lpnmtdi->lpszText, ARRAY_SIZE(lpnmtdi->szText)); + MultiByteToWideChar(CP_ACP, 0, tbgit.pszText, -1, + lpnmtdi->lpszText, sizeof(lpnmtdi->szText)/sizeof(lpnmtdi->szText[0])); return 0; } } @@ -6479,7 +6255,7 @@ static LRESULT TOOLBAR_TTGetDispInfo (TOOLBAR_INFO *infoPtr, NMTTDISPINFOW *lpnm TRACE("using button hidden text %s\n", debugstr_w(pszText)); - if (len > ARRAY_SIZE(lpnmtdi->szText) - 1) + if (len > sizeof(lpnmtdi->szText)/sizeof(lpnmtdi->szText[0])-1) { /* need to allocate temporary buffer in infoPtr as there * isn't enough space in buffer passed to us by the @@ -6657,7 +6433,7 @@ TOOLBAR_SetRedraw (TOOLBAR_INFO *infoPtr, WPARAM wParam) static LRESULT TOOLBAR_Size (TOOLBAR_INFO *infoPtr) { - TRACE("sizing toolbar\n"); + TRACE("sizing toolbar!\n"); if (infoPtr->dwExStyle & TBSTYLE_EX_HIDECLIPPEDBUTTONS) { @@ -6708,7 +6484,30 @@ static LRESULT TOOLBAR_StyleChanged (TOOLBAR_INFO *infoPtr, INT nType, const STYLESTRUCT *lpStyle) { if (nType == GWL_STYLE) - return TOOLBAR_SetStyle(infoPtr, lpStyle->styleNew); + { + DWORD dwOldStyle = infoPtr->dwStyle; + + if (lpStyle->styleNew & TBSTYLE_LIST) + infoPtr->dwDTFlags = DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS; + else + infoPtr->dwDTFlags = DT_CENTER | DT_END_ELLIPSIS; + + TRACE("new style 0x%08x\n", lpStyle->styleNew); + + infoPtr->dwStyle = lpStyle->styleNew; + TOOLBAR_CheckStyle (infoPtr); + + if ((dwOldStyle ^ lpStyle->styleNew) & (TBSTYLE_WRAPABLE | CCS_VERT)) + TOOLBAR_LayoutToolbar(infoPtr); + + /* only resize if one of the CCS_* styles was changed */ + if ((dwOldStyle ^ lpStyle->styleNew) & COMMON_STYLES) + { + TOOLBAR_AutoSize (infoPtr); + + InvalidateRect(infoPtr->hwndSelf, NULL, TRUE); + } + } return 0; } @@ -6722,30 +6521,6 @@ TOOLBAR_SysColorChange (void) return 0; } -#ifdef __REACTOS__ -/* update theme after a WM_THEMECHANGED message */ -static LRESULT theme_changed (TOOLBAR_INFO *infoPtr) -{ - HTHEME theme = GetWindowTheme (infoPtr->hwndSelf); - CloseThemeData (theme); - OpenThemeData (infoPtr->hwndSelf, themeClass); - theme = GetWindowTheme (infoPtr->hwndSelf); - if (theme) - GetThemeMargins(theme, NULL, TP_BUTTON, TS_NORMAL, TMT_CONTENTMARGINS, NULL, &infoPtr->themeMargins); - else - memset(&infoPtr->themeMargins, 0 ,sizeof(infoPtr->themeMargins)); - - return 0; -} -#else -static LRESULT theme_changed (HWND hwnd) -{ - HTHEME theme = GetWindowTheme (hwnd); - CloseThemeData (theme); - OpenThemeData (hwnd, themeClass); - return 0; -} -#endif static LRESULT WINAPI ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) @@ -6850,10 +6625,9 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case TB_GETMAXSIZE: return TOOLBAR_GetMaxSize (infoPtr, (LPSIZE)lParam); -#ifdef __REACTOS__ + case TB_GETMETRICS: return TOOLBAR_GetMetrics (infoPtr, (TBMETRICS*)lParam); -#endif /* case TB_GETOBJECT: */ /* 4.71 */ @@ -6870,7 +6644,7 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return TOOLBAR_GetState (infoPtr, wParam); case TB_GETSTRINGA: - return TOOLBAR_GetStringA (infoPtr, wParam, (LPSTR)lParam); + return TOOLBAR_GetStringA (infoPtr, wParam, (LPSTR)lParam); case TB_GETSTRINGW: return TOOLBAR_GetStringW (infoPtr, wParam, (LPWSTR)lParam); @@ -6995,10 +6769,8 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case TB_SETMAXTEXTROWS: return TOOLBAR_SetMaxTextRows (infoPtr, wParam); -#ifdef __REACTOS__ case TB_SETMETRICS: return TOOLBAR_SetMetrics (infoPtr, (TBMETRICS*)lParam); -#endif case TB_SETPADDING: return TOOLBAR_SetPadding (infoPtr, lParam); @@ -7021,8 +6793,8 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case TB_SETUNICODEFORMAT: return TOOLBAR_SetUnicodeFormat (infoPtr, wParam); - case TB_SETBOUNDINGSIZE: - return TOOLBAR_SetBoundingSize(hwnd, wParam, lParam); + case TB_UNKWN45D: + return TOOLBAR_Unkwn45D(hwnd, wParam, lParam); case TB_SETHOTITEM2: return TOOLBAR_SetHotItem2 (infoPtr, wParam, lParam); @@ -7097,7 +6869,6 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return TOOLBAR_MouseLeave (infoPtr); case WM_CAPTURECHANGED: - if (hwnd == (HWND)lParam) return 0; return TOOLBAR_CaptureChanged(infoPtr); case WM_NCACTIVATE: @@ -7144,11 +6915,7 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_SYSCOLORCHANGE: return TOOLBAR_SysColorChange (); case WM_THEMECHANGED: -#ifdef __REACTOS__ - return theme_changed (infoPtr); -#else - return theme_changed (hwnd); -#endif + return TOOLBAR_ThemeChanged(hwnd); /* case WM_WININICHANGE: */ @@ -7238,10 +7005,6 @@ static HIMAGELIST TOOLBAR_InsertImageList(PIMLENTRY **pies, INT *cies, HIMAGELIS /* Check if the entry already exists */ c = TOOLBAR_GetImageListEntry(*pies, *cies, id); - /* Don't add new entry for NULL imagelist */ - if (!c && !himl) - return NULL; - /* If this is a new entry we must create it and insert into the array */ if (!c) {