Huw Davies : comctl32: Implement toolbar saving.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Jul 1 09:06:25 CDT 2015


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

Author: Huw Davies <huw at codeweavers.com>
Date:   Wed Jul  1 09:14:54 2015 +0100

comctl32: Implement toolbar saving.

---

 dlls/comctl32/tests/toolbar.c | 89 ++++++++++++++++++++++++++++++++++++++++++-
 dlls/comctl32/toolbar.c       | 53 +++++++++++++++++++++++---
 2 files changed, 136 insertions(+), 6 deletions(-)

diff --git a/dlls/comctl32/tests/toolbar.c b/dlls/comctl32/tests/toolbar.c
index 2041216..18dc534 100644
--- a/dlls/comctl32/tests/toolbar.c
+++ b/dlls/comctl32/tests/toolbar.c
@@ -54,6 +54,18 @@ static const struct message ttgetdispinfo_parent_seq[] = {
     { 0 }
 };
 
+static const struct message save_parent_seq[] = {
+    { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_SAVE, -1 },
+    { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_SAVE, 0 },
+    { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_SAVE, 1 },
+    { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_SAVE, 2 },
+    { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_SAVE, 3 },
+    { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_SAVE, 4 },
+    { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_SAVE, 5 },
+    { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_SAVE, 6 },
+    { 0 }
+};
+
 #define DEFINE_EXPECT(func) \
     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
 
@@ -133,6 +145,25 @@ static LRESULT parent_wnd_notify(LPARAM lParam)
             compare(nmdisp->dwMask, g_dwExpectedDispInfoMask, "%x");
             ok(nmdisp->pszText == NULL, "pszText is not NULL\n");
         break;
+        case TBN_SAVE:
+        {
+            NMTBSAVE *save = (NMTBSAVE *)lParam;
+            if (save->iItem == -1)
+            {
+                save->cbData = save->cbData * 2 + sizeof(DWORD);
+                save->pData = HeapAlloc( GetProcessHeap(), 0, save->cbData );
+                save->pData[0] = 0xcafe;
+                save->pCurrent = save->pData + 1;
+            }
+            else
+            {
+                save->pCurrent[0] = 0xcafe0000 + save->iItem;
+                save->pCurrent++;
+            }
+            /* Return value is ignored */
+            return 1;
+        }
+
     }
     return 0;
 }
@@ -148,7 +179,19 @@ static LRESULT CALLBACK parent_wnd_proc(HWND hWnd, UINT message, WPARAM wParam,
     if (defwndproc_counter) msg.flags |= defwinproc;
     msg.wParam = wParam;
     msg.lParam = lParam;
-    if (message == WM_NOTIFY && lParam) msg.id = ((NMHDR*)lParam)->code;
+    if (message == WM_NOTIFY && lParam)
+    {
+        msg.id = ((NMHDR*)lParam)->code;
+        switch (msg.id)
+        {
+        case TBN_SAVE:
+        {
+            NMTBSAVE *save = (NMTBSAVE *)lParam;
+            msg.stage = save->iItem;
+        }
+        break;
+        }
+    }
 
     /* log system messages, except for painting */
     if (message < WM_USER &&
@@ -2079,6 +2122,49 @@ static void test_noresize(void)
 
 }
 
+static void test_save(void)
+{
+    HWND wnd = NULL;
+    TBSAVEPARAMSW params;
+    static const WCHAR subkey[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','T','e','s','t',0};
+    static const WCHAR value[] = {'t','o','o','l','b','a','r','t','e','s','t',0};
+    LONG res;
+    HKEY key;
+    BYTE data[100];
+    DWORD size = sizeof(data), type;
+    static const TBBUTTON more_btns[2] =
+        {
+            {0, 11, TBSTATE_HIDDEN, BTNS_BUTTON, {0}, 0, -1},
+            {0, 13, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, -1}
+        };
+    static const DWORD expect[] = {0xcafe, 1, 0xcafe0000, 3, 0xcafe0001, 5, 0xcafe0002, 7, 0xcafe0003,
+                                   9, 0xcafe0004, 11, 0xcafe0005, 13, 0xcafe0006 };
+
+    params.hkr = HKEY_CURRENT_USER;
+    params.pszSubKey = subkey;
+    params.pszValueName = value;
+
+    rebuild_toolbar_with_buttons( &wnd );
+    SendMessageW( wnd, TB_ADDBUTTONSW, sizeof(more_btns) / sizeof(more_btns[0]), (LPARAM)more_btns );
+
+    flush_sequences(sequences, NUM_MSG_SEQUENCES);
+    res = SendMessageW( wnd, TB_SAVERESTOREW, TRUE, (LPARAM)&params );
+    ok( res, "saving failed\n" );
+    ok_sequence(sequences, PARENT_SEQ_INDEX, save_parent_seq, "save", FALSE);
+    DestroyWindow( wnd );
+
+    res = RegOpenKeyW( HKEY_CURRENT_USER, subkey, &key );
+    ok( !res, "got %08x\n", res );
+    res = RegQueryValueExW( key, value, NULL, &type, data, &size );
+    ok( !res, "got %08x\n", res );
+    ok( type == REG_BINARY, "got %08x\n", type );
+    ok( size == sizeof(expect), "got %08x\n", size );
+    ok( !memcmp( data, expect, size ), "mismatch\n" );
+
+    RegDeleteValueW( key, value );
+    RegCloseKey( key );
+}
+
 START_TEST(toolbar)
 {
     WNDCLASSA wc;
@@ -2122,6 +2208,7 @@ START_TEST(toolbar)
     test_create();
     test_TB_GET_SET_EXTENDEDSTYLE();
     test_noresize();
+    test_save();
 
     PostQuitMessage(0);
     while(GetMessageA(&msg,0,0,0)) {
diff --git a/dlls/comctl32/toolbar.c b/dlls/comctl32/toolbar.c
index aa9ffcd..e230d885 100644
--- a/dlls/comctl32/toolbar.c
+++ b/dlls/comctl32/toolbar.c
@@ -4071,12 +4071,55 @@ TOOLBAR_ReplaceBitmap (TOOLBAR_INFO *infoPtr, const TBREPLACEBITMAP *lpReplace)
 
 /* helper for TOOLBAR_SaveRestoreW */
 static BOOL
-TOOLBAR_Save(const TBSAVEPARAMSW *lpSave)
+TOOLBAR_Save(TOOLBAR_INFO *infoPtr, const TBSAVEPARAMSW *params)
 {
-    FIXME("save to %s %s\n", debugstr_w(lpSave->pszSubKey),
-        debugstr_w(lpSave->pszValueName));
+    NMTBSAVE save;
+    INT ret, i;
+    BOOL alloced = FALSE;
+    HKEY key;
 
-    return FALSE;
+    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 );
+    }
+
+    if (alloced) Free( save.pData );
+    return !ret;
 }
 
 
@@ -4211,7 +4254,7 @@ TOOLBAR_SaveRestoreW (TOOLBAR_INFO *infoPtr, WPARAM wParam, const TBSAVEPARAMSW
     if (lpSave == NULL) return 0;
 
     if (wParam)
-        return TOOLBAR_Save(lpSave);
+        return TOOLBAR_Save(infoPtr, lpSave);
     else
         return TOOLBAR_Restore(infoPtr, lpSave);
 }




More information about the wine-cvs mailing list