Module: wine Branch: master Commit: ca9f7d314046aafc22aeccda9e3135e434c06af4 URL: http://source.winehq.org/git/wine.git/?a=commit;h=ca9f7d314046aafc22aeccda9e...
Author: Mikołaj Zalewski mikolaj@zalewski.pl Date: Sun Feb 1 12:52:58 2009 +0100
comctl32: toolbar: Move common TB_ADDBUTTONS and TB_INSERTBUTTONS code into a helper function, makes TB_INSERTBUTTON with a text perform a recalc (with testcase).
---
dlls/comctl32/tests/toolbar.c | 44 ++++++++++++++ dlls/comctl32/toolbar.c | 133 +++++++++++++++++----------------------- 2 files changed, 101 insertions(+), 76 deletions(-)
diff --git a/dlls/comctl32/tests/toolbar.c b/dlls/comctl32/tests/toolbar.c index ee86c1c..6aefd41 100644 --- a/dlls/comctl32/tests/toolbar.c +++ b/dlls/comctl32/tests/toolbar.c @@ -999,6 +999,49 @@ static void test_sizes(void) DestroyWindow(hToolbar); }
+/* Toolbar control has two ways of reacting to a change. We call them a + * relayout and recalc. A recalc forces a recompute of values like button size + * and top margin (the latter in comctl32 <v6), while a relayout uses the cached + * values. This functions creates a flat toolbar with a top margin of a non-flat + * toolbar. We will notice a recalc, as it will recompte the top margin and + * change it to zero*/ +static void prepare_recalc_test(HWND *phToolbar) +{ + RECT rect; + rebuild_toolbar_with_buttons(phToolbar); + SetWindowLong(*phToolbar, GWL_STYLE, + GetWindowLong(*phToolbar, GWL_STYLE) | TBSTYLE_FLAT); + SendMessage(*phToolbar, TB_GETITEMRECT, 1, (LPARAM)&rect); + ok(rect.top == 2, "Test will make no sense because initial top is %d instead of 2\n", + rect.top); +} + +static BOOL did_recalc(HWND hToolbar) +{ + RECT rect; + SendMessage(hToolbar, TB_GETITEMRECT, 1, (LPARAM)&rect); + ok(rect.top == 2 || rect.top == 0, "Unexpected top margin %d in recalc test\n", + rect.top); + return (rect.top == 0); +} + +static void test_recalc(void) +{ + HWND hToolbar; + + /* Like TB_ADDBUTTONS tested in test_sized, inserting a button without text + * results in a relayout, while adding one with text forces a recalc */ + prepare_recalc_test(&hToolbar); + SendMessage(hToolbar, TB_INSERTBUTTON, 1, (LPARAM)&buttons3[0]); + ok(!did_recalc(hToolbar), "Unexpected recalc - adding button without text\n"); + + prepare_recalc_test(&hToolbar); + SendMessage(hToolbar, TB_INSERTBUTTON, 1, (LPARAM)&buttons3[3]); + ok(did_recalc(hToolbar), "Expected a recalc - adding button with text\n"); + + DestroyWindow(hToolbar); +} + static void test_getbuttoninfo(void) { HWND hToolbar = NULL; @@ -1224,6 +1267,7 @@ START_TEST(toolbar) test_add_string(); test_hotitem(); test_sizes(); + test_recalc(); test_getbuttoninfo(); test_createtoolbarex(); test_dispinfo(); diff --git a/dlls/comctl32/toolbar.c b/dlls/comctl32/toolbar.c index df5b19d..b2dcfb1 100644 --- a/dlls/comctl32/toolbar.c +++ b/dlls/comctl32/toolbar.c @@ -251,6 +251,7 @@ static void TOOLBAR_SetHotItemEx (TOOLBAR_INFO *infoPtr, INT nHit, DWORD dwReaso static void TOOLBAR_LayoutToolbar(HWND hwnd); static LRESULT TOOLBAR_AutoSize(HWND hwnd); 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 @@ -1814,6 +1815,59 @@ TOOLBAR_InternalHitTest (HWND hwnd, const POINT *lpPt) }
+/* worker for TB_ADDBUTTONS and TB_INSERTBUTTON */ +static BOOL +TOOLBAR_InternalInsertButtonsT(TOOLBAR_INFO *infoPtr, INT iIndex, UINT nAddButtons, TBBUTTON *lpTbb, BOOL fUnicode) +{ + INT nOldButtons, nNewButtons, iButton; + BOOL fHasString = FALSE; + + if (iIndex < 0) /* iIndex can be negative, what means adding at the end */ + iIndex = infoPtr->nNumButtons; + + nOldButtons = infoPtr->nNumButtons; + nNewButtons = nOldButtons + nAddButtons; + + infoPtr->buttons = ReAlloc(infoPtr->buttons, sizeof(TBUTTON_INFO)*nNewButtons); + memmove(&infoPtr->buttons[iIndex + nAddButtons], &infoPtr->buttons[iIndex], + (nOldButtons - iIndex) * sizeof(TBUTTON_INFO)); + infoPtr->nNumButtons += nAddButtons; + + /* insert new buttons data */ + for (iButton = 0; iButton < nAddButtons; iButton++) { + TBUTTON_INFO *btnPtr = &infoPtr->buttons[iIndex + iButton]; + ZeroMemory(btnPtr, sizeof(*btnPtr)); + btnPtr->iBitmap = lpTbb[iButton].iBitmap; + btnPtr->idCommand = lpTbb[iButton].idCommand; + btnPtr->fsState = lpTbb[iButton].fsState; + btnPtr->fsStyle = lpTbb[iButton].fsStyle; + btnPtr->dwData = lpTbb[iButton].dwData; + if(HIWORD(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 + btnPtr->iString = lpTbb[iButton].iString; + + TOOLBAR_TooltipAddTool(infoPtr, btnPtr); + } + + if (infoPtr->nNumStrings > 0 || fHasString) + TOOLBAR_CalcToolbar(infoPtr->hwndSelf); + else + TOOLBAR_LayoutToolbar(infoPtr->hwndSelf); + TOOLBAR_AutoSize(infoPtr->hwndSelf); + + TOOLBAR_DumpToolbar(infoPtr, __LINE__); + InvalidateRect(infoPtr->hwndSelf, NULL, TRUE); + return TRUE; +} + + static INT TOOLBAR_GetButtonIndex (const TOOLBAR_INFO *infoPtr, INT idCommand, BOOL CommandIsIndex) { @@ -2839,52 +2893,11 @@ TOOLBAR_AddButtonsT(HWND hwnd, WPARAM wParam, LPARAM lParam, BOOL fUnicode) { TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd); LPTBBUTTON lpTbb = (LPTBBUTTON)lParam; - INT nOldButtons, nNewButtons, nAddButtons, nCount; - BOOL fHasString = FALSE; + INT nAddButtons = (UINT)wParam;
TRACE("adding %ld buttons (unicode=%d)!\n", wParam, fUnicode);
- nAddButtons = (UINT)wParam; - nOldButtons = infoPtr->nNumButtons; - nNewButtons = nOldButtons + nAddButtons; - - infoPtr->buttons = ReAlloc(infoPtr->buttons, sizeof(TBUTTON_INFO)*nNewButtons); - infoPtr->nNumButtons = nNewButtons; - - /* insert new button data */ - for (nCount = 0; nCount < nAddButtons; nCount++) { - TBUTTON_INFO *btnPtr = &infoPtr->buttons[nOldButtons+nCount]; - btnPtr->iBitmap = lpTbb[nCount].iBitmap; - btnPtr->idCommand = lpTbb[nCount].idCommand; - btnPtr->fsState = lpTbb[nCount].fsState; - btnPtr->fsStyle = lpTbb[nCount].fsStyle; - btnPtr->dwData = lpTbb[nCount].dwData; - btnPtr->bHot = FALSE; - if(HIWORD(lpTbb[nCount].iString) && lpTbb[nCount].iString != -1) - { - if (fUnicode) - Str_SetPtrW ((LPWSTR*)&btnPtr->iString, (LPWSTR)lpTbb[nCount].iString ); - else - Str_SetPtrAtoW((LPWSTR*)&btnPtr->iString, (LPSTR)lpTbb[nCount].iString); - fHasString = TRUE; - } - else - btnPtr->iString = lpTbb[nCount].iString; - - TOOLBAR_TooltipAddTool(infoPtr, btnPtr); - } - - if (infoPtr->nNumStrings > 0 || fHasString) - TOOLBAR_CalcToolbar(hwnd); - else - TOOLBAR_LayoutToolbar(hwnd); - TOOLBAR_AutoSize (hwnd); - - TOOLBAR_DumpToolbar (infoPtr, __LINE__); - - InvalidateRect(hwnd, NULL, TRUE); - - return TRUE; + return TOOLBAR_InternalInsertButtonsT(infoPtr, -1, nAddButtons, lpTbb, fUnicode); }
@@ -3783,39 +3796,7 @@ TOOLBAR_InsertButtonT(HWND hwnd, WPARAM wParam, LPARAM lParam, BOOL fUnicode) TRACE("adjust index=%d\n", nIndex); }
- infoPtr->nNumButtons++; - infoPtr->buttons = ReAlloc(infoPtr->buttons, sizeof(TBUTTON_INFO) * infoPtr->nNumButtons); - memmove(&infoPtr->buttons[nIndex+1], &infoPtr->buttons[nIndex], - (infoPtr->nNumButtons - nIndex - 1) * sizeof(TBUTTON_INFO)); - - /* insert new button */ - ZeroMemory(&infoPtr->buttons[nIndex], sizeof(infoPtr->buttons[nIndex])); - infoPtr->buttons[nIndex].iBitmap = lpTbb->iBitmap; - infoPtr->buttons[nIndex].idCommand = lpTbb->idCommand; - infoPtr->buttons[nIndex].fsState = lpTbb->fsState; - infoPtr->buttons[nIndex].fsStyle = lpTbb->fsStyle; - infoPtr->buttons[nIndex].dwData = lpTbb->dwData; - /* if passed string and not index, then add string */ - if(HIWORD(lpTbb->iString) && lpTbb->iString!=-1) { - if (fUnicode) - Str_SetPtrW((LPWSTR *)&infoPtr->buttons[nIndex].iString, (LPWSTR)lpTbb->iString); - else - Str_SetPtrAtoW((LPWSTR *)&infoPtr->buttons[nIndex].iString, (LPCSTR )lpTbb->iString); - } - else - infoPtr->buttons[nIndex].iString = lpTbb->iString; - - TOOLBAR_TooltipAddTool(infoPtr, &infoPtr->buttons[nIndex]); - - if (infoPtr->nNumStrings > 0) - TOOLBAR_CalcToolbar(hwnd); - else - TOOLBAR_LayoutToolbar(hwnd); - TOOLBAR_AutoSize (hwnd); - - InvalidateRect (hwnd, NULL, TRUE); - - return TRUE; + return TOOLBAR_InternalInsertButtonsT(infoPtr, nIndex, 1, lpTbb, fUnicode); }
/* << TOOLBAR_InsertMarkHitTest >> */