Mikołaj Zalewski : 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).

Alexandre Julliard julliard at winehq.org
Mon Feb 2 09:01:27 CST 2009


Module: wine
Branch: master
Commit: ca9f7d314046aafc22aeccda9e3135e434c06af4
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=ca9f7d314046aafc22aeccda9e3135e434c06af4

Author: Mikołaj Zalewski <mikolaj at 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 >> */




More information about the wine-cvs mailing list