diff --git a/dlls/comctl32/tests/resources.h b/dlls/comctl32/tests/resources.h index 6c52e8cc21f..826f9c53919 100644 --- a/dlls/comctl32/tests/resources.h +++ b/dlls/comctl32/tests/resources.h @@ -24,4 +24,14 @@ #define IDB_BITMAP_128x15 10 #define IDB_BITMAP_80x15 11 +#define IDS_TBADD1 16 +#define IDS_TBADD2 17 +#define IDS_TBADD3 18 +#define IDS_TBADD4 19 +#define IDS_TBADD5 20 +#define IDS_TBADD6 21 +#define IDS_TBADD7 22 +#define IDS_TBADD8 23 +#define IDS_TBADD9 24 + #endif /* __WINE_COMCTL32_TEST_RESOURCES_H */ diff --git a/dlls/comctl32/tests/rsrc.rc b/dlls/comctl32/tests/rsrc.rc index 23d9ffbcfbf..b68ab1bdc32 100644 --- a/dlls/comctl32/tests/rsrc.rc +++ b/dlls/comctl32/tests/rsrc.rc @@ -30,6 +30,17 @@ FONT 8, "MS Shell Dlg" LTEXT "Test", -1, 10, 6, 100, 8 } +STRINGTABLE +{ + IDS_TBADD1 "abc" + IDS_TBADD2 "|p|q|r" + IDS_TBADD3 "*p*q*" + IDS_TBADD4 "#p#q##" + IDS_TBADD5 "|p||q|r|" + IDS_TBADD6 "\000a\000\000" + IDS_TBADD7 "abracadabra" +} + /* BINRES bmp128x15.bmp */ IDB_BITMAP_128x15 BITMAP bmp128x15.bmp /* { diff --git a/dlls/comctl32/tests/toolbar.c b/dlls/comctl32/tests/toolbar.c index 7cdc5b9c2d7..c9ff6e34769 100644 --- a/dlls/comctl32/tests/toolbar.c +++ b/dlls/comctl32/tests/toolbar.c @@ -312,6 +312,64 @@ static void test_add_bitmap(void) DestroyWindow(hToolbar); } +#define CHECK_STRING_TABLE(count, tab) { \ + INT _i; \ + CHAR _buf[260]; \ + for (_i = 0; _i < (count); _i++) {\ + ret = SendMessageA(hToolbar, TB_GETSTRING, MAKEWPARAM(260, _i), (LPARAM)_buf); \ + ok(ret >= 0, "TB_GETSTRING - unexpected return %d while checking string %d\n", ret, _i); \ + if (ret >= 0) \ + ok(strcmp(_buf, (tab)[_i]) == 0, "Invalid string #%d - '%s' vs '%s'\n", _i, (tab)[_i], _buf); \ + } \ + ok(SendMessageA(hToolbar, TB_GETSTRING, MAKEWPARAM(260, (count)), (LPARAM)_buf) == -1, \ + "Too many string in table\n"); \ + } + +void test_add_string() +{ + LPCSTR test1 = "a\0b\0"; + LPCSTR test2 = "|a|b||\0"; + LPCSTR ret1[] = {"a", "b"}; + LPCSTR ret2[] = {"a", "b", "|a|b||"}; + LPCSTR ret3[] = {"a", "b", "|a|b||", "p", "q"}; + LPCSTR ret4[] = {"a", "b", "|a|b||", "p", "q", "p"}; + LPCSTR ret5[] = {"a", "b", "|a|b||", "p", "q", "p", "p", "q"}; + LPCSTR ret6[] = {"a", "b", "|a|b||", "p", "q", "p", "p", "q", "p", "", "q"}; + LPCSTR ret7[] = {"a", "b", "|a|b||", "p", "q", "p", "p", "q", "p", "", "q", "br", "c", "d"}; + HWND hToolbar = NULL; + int ret; + + rebuild_toolbar(&hToolbar); + ret = SendMessageA(hToolbar, TB_ADDSTRINGA, 0, (LPARAM)test1); + ok(ret == 0, "TB_ADDSTRINGA - unexpected return %d\n", ret); + CHECK_STRING_TABLE(2, ret1); + ret = SendMessageA(hToolbar, TB_ADDSTRINGA, 0, (LPARAM)test2); + ok(ret == 2, "TB_ADDSTRINGA - unexpected return %d\n", ret); + CHECK_STRING_TABLE(3, ret2); + + ret = SendMessageA(hToolbar, TB_ADDSTRINGA, (WPARAM)GetModuleHandle(NULL), IDS_TBADD1); + ok(ret == 3, "TB_ADDSTRINGA - unexpected return %d\n", ret); + CHECK_STRING_TABLE(3, ret2); + ret = SendMessageA(hToolbar, TB_ADDSTRINGA, (WPARAM)GetModuleHandle(NULL), IDS_TBADD2); + ok(ret == 3, "TB_ADDSTRINGA - unexpected return %d\n", ret); + CHECK_STRING_TABLE(5, ret3); + ret = SendMessageA(hToolbar, TB_ADDSTRINGA, (WPARAM)GetModuleHandle(NULL), IDS_TBADD3); + ok(ret == 5, "TB_ADDSTRINGA - unexpected return %d\n", ret); + CHECK_STRING_TABLE(6, ret4); + ret = SendMessageA(hToolbar, TB_ADDSTRINGA, (WPARAM)GetModuleHandle(NULL), IDS_TBADD4); + ok(ret == 6, "TB_ADDSTRINGA - unexpected return %d\n", ret); + CHECK_STRING_TABLE(8, ret5); + ret = SendMessageA(hToolbar, TB_ADDSTRINGA, (WPARAM)GetModuleHandle(NULL), IDS_TBADD5); + ok(ret == 8, "TB_ADDSTRINGA - unexpected return %d\n", ret); + CHECK_STRING_TABLE(11, ret6); + ret = SendMessageA(hToolbar, TB_ADDSTRINGA, (WPARAM)GetModuleHandle(NULL), IDS_TBADD6); + ok(ret == 11, "TB_ADDSTRINGA - unexpected return %d\n", ret); + CHECK_STRING_TABLE(11, ret6); + ret = SendMessageA(hToolbar, TB_ADDSTRINGA, (WPARAM)GetModuleHandle(NULL), IDS_TBADD7); + ok(ret == 11, "TB_ADDSTRINGA - unexpected return %d\n", ret); + CHECK_STRING_TABLE(14, ret7); +} + START_TEST(toolbar) { WNDCLASSA wc; @@ -339,6 +397,7 @@ START_TEST(toolbar) basic_test(); test_add_bitmap(); + test_add_string(); PostQuitMessage(0); while(GetMessageA(&msg,0,0,0)) { diff --git a/dlls/comctl32/toolbar.c b/dlls/comctl32/toolbar.c index fe26ac1b378..9de8e768798 100644 --- a/dlls/comctl32/toolbar.c +++ b/dlls/comctl32/toolbar.c @@ -2931,64 +2931,57 @@ TOOLBAR_AddButtonsW (HWND hwnd, WPARAM wParam, LPARAM lParam) static LRESULT -TOOLBAR_AddStringA (HWND hwnd, WPARAM wParam, LPARAM lParam) +TOOLBAR_AddStringW (HWND hwnd, WPARAM wParam, LPARAM lParam) { +#define MAX_RESOURCE_STRING_LENGTH 512 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd); - INT nIndex; + INT nIndex = infoPtr->nNumStrings; if ((wParam) && (HIWORD(lParam) == 0)) { - char szString[256]; + WCHAR szString[MAX_RESOURCE_STRING_LENGTH]; + WCHAR delimiter; + WCHAR *next_delim; + WCHAR *p; INT len; TRACE("adding string from resource!\n"); - len = LoadStringA ((HINSTANCE)wParam, (UINT)lParam, szString, sizeof(szString)); + LoadStringW ((HINSTANCE)wParam, (UINT)lParam, + szString, MAX_RESOURCE_STRING_LENGTH); + len = lstrlenW(szString); - TRACE("len=%d \"%s\"\n", len, szString); - nIndex = infoPtr->nNumStrings; - if (infoPtr->nNumStrings == 0) { - infoPtr->strings = - Alloc (sizeof(LPWSTR)); - } - else { - LPWSTR *oldStrings = infoPtr->strings; - infoPtr->strings = - Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1)); - memcpy (&infoPtr->strings[0], &oldStrings[0], - sizeof(LPWSTR) * infoPtr->nNumStrings); - Free (oldStrings); - } + TRACE("len=%d %s\n", len, debugstr_w(szString)); + if (len == 0 || len == 1) + return nIndex; - /*Alloc zeros out the allocated memory*/ - Str_SetPtrAtoW (&infoPtr->strings[infoPtr->nNumStrings], szString ); - infoPtr->nNumStrings++; + TRACE("Delimiter: 0x%x\n", *szString); + delimiter = *szString; + p = szString + 1; + if (szString[len-1] == delimiter) + szString[len-1] = 0; + + while ((next_delim = strchrW(p, delimiter)) != NULL) { + *next_delim = 0; + + infoPtr->strings = ReAlloc(infoPtr->strings, sizeof(LPWSTR)*(infoPtr->nNumStrings+1)); + Str_SetPtrW(&infoPtr->strings[infoPtr->nNumStrings], p); + infoPtr->nNumStrings++; + + p = next_delim + 1; + } } else { - LPSTR p = (LPSTR)lParam; + LPWSTR p = (LPWSTR)lParam; INT len; if (p == NULL) return -1; TRACE("adding string(s) from array!\n"); - - nIndex = infoPtr->nNumStrings; while (*p) { - len = strlen (p); - TRACE("len=%d \"%s\"\n", len, p); + len = strlenW (p); - if (infoPtr->nNumStrings == 0) { - infoPtr->strings = - Alloc (sizeof(LPWSTR)); - } - else { - LPWSTR *oldStrings = infoPtr->strings; - infoPtr->strings = - Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1)); - memcpy (&infoPtr->strings[0], &oldStrings[0], - sizeof(LPWSTR) * infoPtr->nNumStrings); - Free (oldStrings); - } - - Str_SetPtrAtoW (&infoPtr->strings[infoPtr->nNumStrings], p ); + TRACE("len=%d %s\n", len, debugstr_w(p)); + infoPtr->strings = ReAlloc(infoPtr->strings, sizeof(LPWSTR)*(infoPtr->nNumStrings+1)); + Str_SetPtrW (&infoPtr->strings[infoPtr->nNumStrings], p); infoPtr->nNumStrings++; p += (len+1); @@ -3000,109 +2993,31 @@ TOOLBAR_AddStringA (HWND hwnd, WPARAM wParam, LPARAM lParam) static LRESULT -TOOLBAR_AddStringW (HWND hwnd, WPARAM wParam, LPARAM lParam) +TOOLBAR_AddStringA (HWND hwnd, WPARAM wParam, LPARAM lParam) { -#define MAX_RESOURCE_STRING_LENGTH 512 TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd); + LPSTR p; INT nIndex; + INT len; - if ((wParam) && (HIWORD(lParam) == 0)) { - WCHAR szString[MAX_RESOURCE_STRING_LENGTH]; - INT len; - TRACE("adding string from resource!\n"); + if ((wParam) && (HIWORD(lParam) == 0)) /* load from resources */ + return TOOLBAR_AddStringW(hwnd, wParam, lParam); - len = LoadStringW ((HINSTANCE)wParam, (UINT)lParam, - szString, MAX_RESOURCE_STRING_LENGTH); + p = (LPSTR)lParam; + if (p == NULL) + return -1; - TRACE("len=%d %s\n", len, debugstr_w(szString)); - TRACE("First char: 0x%x\n", *szString); - if (szString[0] == L'|') - { - PWSTR p = szString + 1; + TRACE("adding string(s) from array!\n"); + nIndex = infoPtr->nNumStrings; + while (*p) { + len = strlen (p); + TRACE("len=%d \"%s\"\n", len, p); - nIndex = infoPtr->nNumStrings; - while (*p != L'|' && *p != L'\0') { - PWSTR np; + infoPtr->strings = ReAlloc(infoPtr->strings, sizeof(LPWSTR)*(infoPtr->nNumStrings+1)); + Str_SetPtrAtoW(&infoPtr->strings[infoPtr->nNumStrings], p); + infoPtr->nNumStrings++; - if (infoPtr->nNumStrings == 0) { - infoPtr->strings = Alloc (sizeof(LPWSTR)); - } - else - { - LPWSTR *oldStrings = infoPtr->strings; - infoPtr->strings = Alloc(sizeof(LPWSTR) * (infoPtr->nNumStrings + 1)); - memcpy(&infoPtr->strings[0], &oldStrings[0], - sizeof(LPWSTR) * infoPtr->nNumStrings); - Free(oldStrings); - } - - np=strchrW (p, '|'); - if (np!=NULL) { - len = np - p; - np++; - } else { - len = strlenW(p); - np = p + len; - } - TRACE("len=%d %s\n", len, debugstr_w(p)); - infoPtr->strings[infoPtr->nNumStrings] = - Alloc (sizeof(WCHAR)*(len+1)); - lstrcpynW (infoPtr->strings[infoPtr->nNumStrings], p, len+1); - infoPtr->nNumStrings++; - - p = np; - } - } - else - { - nIndex = infoPtr->nNumStrings; - if (infoPtr->nNumStrings == 0) { - infoPtr->strings = - Alloc (sizeof(LPWSTR)); - } - else { - LPWSTR *oldStrings = infoPtr->strings; - infoPtr->strings = - Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1)); - memcpy (&infoPtr->strings[0], &oldStrings[0], - sizeof(LPWSTR) * infoPtr->nNumStrings); - Free (oldStrings); - } - - Str_SetPtrW (&infoPtr->strings[infoPtr->nNumStrings], szString); - infoPtr->nNumStrings++; - } - } - else { - LPWSTR p = (LPWSTR)lParam; - INT len; - - if (p == NULL) - return -1; - TRACE("adding string(s) from array!\n"); - nIndex = infoPtr->nNumStrings; - while (*p) { - len = strlenW (p); - - TRACE("len=%d %s\n", len, debugstr_w(p)); - if (infoPtr->nNumStrings == 0) { - infoPtr->strings = - Alloc (sizeof(LPWSTR)); - } - else { - LPWSTR *oldStrings = infoPtr->strings; - infoPtr->strings = - Alloc (sizeof(LPWSTR) * (infoPtr->nNumStrings + 1)); - memcpy (&infoPtr->strings[0], &oldStrings[0], - sizeof(LPWSTR) * infoPtr->nNumStrings); - Free (oldStrings); - } - - Str_SetPtrW (&infoPtr->strings[infoPtr->nNumStrings], p); - infoPtr->nNumStrings++; - - p += (len+1); - } + p += (len+1); } return nIndex;