[PATCH 2/2] comctl32: Implement the legacy notifications during restore.

Huw Davies huw at codeweavers.com
Wed Jul 1 15:17:19 CDT 2015


---
try 2: Use an allocated, rather than a static, string in the test.
 dlls/comctl32/tests/toolbar.c | 84 ++++++++++++++++++++++++++++++++++++++++---
 dlls/comctl32/toolbar.c       | 44 ++++++++++++++++++++---
 2 files changed, 119 insertions(+), 9 deletions(-)

diff --git a/dlls/comctl32/tests/toolbar.c b/dlls/comctl32/tests/toolbar.c
index 96ec3b4..23eb250 100644
--- a/dlls/comctl32/tests/toolbar.c
+++ b/dlls/comctl32/tests/toolbar.c
@@ -66,6 +66,28 @@ static const struct message save_parent_seq[] = {
     { 0 }
 };
 
+static const struct message restore_parent_seq[] = {
+    { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_RESTORE, -1 },
+    { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_RESTORE, 0 },
+    { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_RESTORE, 1 },
+    { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_RESTORE, 2 },
+    { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_RESTORE, 3 },
+    { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_RESTORE, 4 },
+    { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_RESTORE, 5 },
+    { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_RESTORE, 6 },
+    { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_RESTORE, 7 },
+    { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_RESTORE, 8 },
+    { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_RESTORE, 9 },
+    { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_RESTORE, 0xa },
+    { WM_NOTIFY, sent|id, 0, 0, TBN_BEGINADJUST },
+    { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_GETBUTTONINFOA, 0 },
+    { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_GETBUTTONINFOA, 1 },
+    { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_GETBUTTONINFOA, 2 },
+    { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_GETBUTTONINFOA, 3 },
+    { WM_NOTIFY, sent|id, 0, 0, TBN_ENDADJUST },
+    { 0 }
+};
+
 #define DEFINE_EXPECT(func) \
     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
 
@@ -105,6 +127,8 @@ static void MakeButton(TBBUTTON *p, int idCommand, int fsStyle, int nString) {
   p->iString = nString;
 }
 
+static void *alloced_str;
+
 static LRESULT parent_wnd_notify(LPARAM lParam)
 {
     NMHDR *hdr = (NMHDR *)lParam;
@@ -245,6 +269,35 @@ static LRESULT parent_wnd_notify(LPARAM lParam)
             if (restore->iItem == -1) return 0;
             return 1;
         }
+        case TBN_GETBUTTONINFOA:
+        {
+            NMTOOLBARA *tb = (NMTOOLBARA *)lParam;
+            tb->tbButton.iBitmap = 0;
+            tb->tbButton.fsState = 0;
+            tb->tbButton.fsStyle = 0;
+            tb->tbButton.dwData = 0;
+            ok( tb->cchText == 128, "got %d\n", tb->cchText );
+            switch (tb->iItem)
+            {
+            case 0:
+                tb->tbButton.idCommand = 7;
+                alloced_str = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 8 );
+                strcpy( alloced_str, "foo" );
+                tb->tbButton.iString = (INT_PTR)alloced_str;
+                return 1;
+            case 1:
+                tb->tbButton.idCommand = 9;
+                tb->tbButton.iString = 0;
+                /* tb->pszText is ignored */
+                strcpy( tb->pszText, "foo" );
+                return 1;
+           case 2:
+                tb->tbButton.idCommand = 11;
+                tb->tbButton.iString = 3;
+                return 1;
+            }
+            return 0;
+        }
     }
     return 0;
 }
@@ -271,6 +324,18 @@ static LRESULT CALLBACK parent_wnd_proc(HWND hWnd, UINT message, WPARAM wParam,
             msg.stage = save->iItem;
         }
         break;
+        case TBN_RESTORE:
+        {
+            NMTBRESTORE *restore = (NMTBRESTORE *)lParam;
+            msg.stage = restore->iItem;
+        }
+        break;
+        case TBN_GETBUTTONINFOA:
+        {
+            NMTOOLBARA *tb = (NMTOOLBARA *)lParam;
+            msg.stage = tb->iItem;
+        }
+        break;
         }
     }
 
@@ -2228,9 +2293,9 @@ static void test_save(void)
         {0, 1, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0},
         {0, 3, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 1, 2},
         {0, 5, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 2, 0},
-        {0, 7, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 3, 0},
-        {0, 9, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 4, 0},
-        {0, 11, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 5, 0},
+        {0, 7, 0, BTNS_BUTTON, {0}, 0, (INT_PTR)"foo"},
+        {0, 9, 0, BTNS_BUTTON, {0}, 0, 0},
+        {0, 11, 0, BTNS_BUTTON, {0}, 0, 3},
         {0, 13, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 6, 0},
         {0, 0, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 7, 0},
         {0, 0, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 8, 0},
@@ -2263,8 +2328,11 @@ static void test_save(void)
 
     wnd = NULL;
     rebuild_toolbar( &wnd );
+
+    flush_sequences(sequences, NUM_MSG_SEQUENCES);
     res = SendMessageW( wnd, TB_SAVERESTOREW, FALSE, (LPARAM)&params );
     ok( res, "restoring failed\n" );
+    ok_sequence(sequences, PARENT_SEQ_INDEX, restore_parent_seq, "restore", FALSE);
     count = SendMessageW( wnd, TB_BUTTONCOUNT, 0, 0 );
     ok( count == sizeof(expect_btns) / sizeof(expect_btns[0]), "got %d\n", count );
 
@@ -2278,7 +2346,15 @@ static void test_save(void)
         ok( tb.fsState == expect_btns[i].fsState, "%d: got %02x\n", i, tb.fsState );
         ok( tb.fsStyle == expect_btns[i].fsStyle, "%d: got %02x\n", i, tb.fsStyle );
         ok( tb.dwData == expect_btns[i].dwData, "%d: got %lx\n", i, tb.dwData );
-        ok( tb.iString == expect_btns[i].iString, "%d: got %lx\n", i, tb.iString );
+        if (IS_INTRESOURCE(expect_btns[i].iString))
+            ok( tb.iString == expect_btns[i].iString, "%d: got %lx\n", i, tb.iString );
+        else
+            ok( !strcmp( (char *)tb.iString, (char *)expect_btns[i].iString ),
+                "%d: got %s\n", i, (char *)tb.iString );
+
+        /* In fact the ptr value set in TBN_GETBUTTONINFOA is simply copied */
+        if (tb.idCommand == 7)
+            ok( tb.iString == (INT_PTR)alloced_str, "string not set\n");
     }
 
     DestroyWindow( wnd );
diff --git a/dlls/comctl32/toolbar.c b/dlls/comctl32/toolbar.c
index 11e9678..c777f5b 100644
--- a/dlls/comctl32/toolbar.c
+++ b/dlls/comctl32/toolbar.c
@@ -247,6 +247,8 @@ 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)
@@ -4151,6 +4153,7 @@ 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),
@@ -4221,13 +4224,44 @@ TOOLBAR_Restore(TOOLBAR_INFO *infoPtr, const TBSAVEPARAMSW *lpSave)
                 TOOLBAR_InsertButtonT(infoPtr, -1, &nmtbr.tbButton, TRUE);
             }
 
-            /* do legacy notifications */
-            if (infoPtr->iVersion < 5)
+            TOOLBAR_SendNotify( &hdr, infoPtr, TBN_BEGINADJUST );
+            for (i = 0; ; i++)
             {
-                /* FIXME: send TBN_BEGINADJUST */
-                FIXME("send TBN_GETBUTTONINFO for each button\n");
-                /* FIXME: send TBN_ENDADJUST */
+                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 = sizeof(buf) / sizeof(buf[0]);
+                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 );
             }
+            TOOLBAR_SendNotify( &hdr, infoPtr, TBN_ENDADJUST );
 
             /* remove all uninitialised buttons
              * note: loop backwards to avoid having to fixup i on a
-- 
1.8.0




More information about the wine-patches mailing list