Author: akhaldi Date: Sun Jun 4 12:53:30 2017 New Revision: 74903 URL: http://svn.reactos.org/svn/reactos?rev=74903&view=rev Log: [COMCTL32_WINETEST] Sync with Wine Staging 2.9. CORE-13362
Added: trunk/rostests/winetests/comctl32/taskdialog.c (with props) Modified: trunk/rostests/winetests/comctl32/CMakeLists.txt trunk/rostests/winetests/comctl32/animate.c trunk/rostests/winetests/comctl32/button.c trunk/rostests/winetests/comctl32/comboex.c trunk/rostests/winetests/comctl32/datetime.c trunk/rostests/winetests/comctl32/header.c trunk/rostests/winetests/comctl32/imagelist.c trunk/rostests/winetests/comctl32/listview.c trunk/rostests/winetests/comctl32/misc.c trunk/rostests/winetests/comctl32/monthcal.c trunk/rostests/winetests/comctl32/msg.h trunk/rostests/winetests/comctl32/pager.c trunk/rostests/winetests/comctl32/propsheet.c trunk/rostests/winetests/comctl32/syslink.c trunk/rostests/winetests/comctl32/tab.c trunk/rostests/winetests/comctl32/testlist.c trunk/rostests/winetests/comctl32/toolbar.c trunk/rostests/winetests/comctl32/trackbar.c trunk/rostests/winetests/comctl32/treeview.c trunk/rostests/winetests/comctl32/updown.c Modified: trunk/rostests/winetests/comctl32/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/comctl32/CMakeLists.txt?rev=74903&r1=74902&r2=74903&view=diff ============================================================================== --- trunk/rostests/winetests/comctl32/CMakeLists.txt [iso-8859-1] (original) +++ trunk/rostests/winetests/comctl32/CMakeLists.txt [iso-8859-1] Sun Jun 4 12:53:30 2017 @@ -24,6 +24,7 @@ subclass.c syslink.c tab.c + taskdialog.c toolbar.c tooltips.c trackbar.c Modified: trunk/rostests/winetests/comctl32/animate.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/comctl32/animate.c?rev=74903&r1=74902&r2=74903&view=diff ============================================================================== --- trunk/rostests/winetests/comctl32/animate.c [iso-8859-1] (original) +++ trunk/rostests/winetests/comctl32/animate.c [iso-8859-1] Sun Jun 4 12:53:30 2017 @@ -160,8 +160,9 @@ SetLastError(0xdeadbeef); res = SendMessageA(hAnimateWnd, ACM_PLAY, (WPARAM) -1, MAKELONG(0, -1)); + err = GetLastError(); ok(res == 0, "Play should have failed\n"); - ok(err == ERROR_RESOURCE_NAME_NOT_FOUND, "Expected 1814, got %u\n", err); + ok(err == 0xdeadbeef, "Expected 0xdeadbeef, got %u\n", err); destroy_animate(); create_animate(0, 0); Modified: trunk/rostests/winetests/comctl32/button.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/comctl32/button.c?rev=74903&r1=74902&r2=74903&view=diff ============================================================================== --- trunk/rostests/winetests/comctl32/button.c [iso-8859-1] (original) +++ trunk/rostests/winetests/comctl32/button.c [iso-8859-1] Sun Jun 4 12:53:30 2017 @@ -124,8 +124,8 @@ static LRESULT CALLBACK button_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, UINT_PTR id, DWORD_PTR ref_data) { static LONG defwndproc_counter = 0; + struct message msg = { 0 }; LRESULT ret; - struct message msg; if (ignore_message( message )) return pDefSubclassProc(hwnd, message, wParam, lParam); @@ -160,8 +160,8 @@ { static LONG defwndproc_counter = 0; static LONG beginpaint_counter = 0; + struct message msg = { 0 }; LRESULT ret; - struct message msg; if (ignore_message( message )) return 0; @@ -171,17 +171,6 @@ message == WM_DRAWITEM || message == WM_COMMAND || message == WM_IME_SETCONTEXT) { - switch (message) - { - /* ignore */ - case WM_NCHITTEST: - return HTCLIENT; - case WM_SETCURSOR: - case WM_MOUSEMOVE: - case WM_NCMOUSEMOVE: - return 0; - } - msg.message = message; msg.flags = sent|parent|wparam|lparam; if (defwndproc_counter) msg.flags |= defwinproc; Modified: trunk/rostests/winetests/comctl32/comboex.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/comctl32/comboex.c?rev=74903&r1=74902&r2=74903&view=diff ============================================================================== --- trunk/rostests/winetests/comctl32/comboex.c [iso-8859-1] (original) +++ trunk/rostests/winetests/comctl32/comboex.c [iso-8859-1] Sun Jun 4 12:53:30 2017 @@ -90,8 +90,8 @@ { WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); static LONG defwndproc_counter = 0; + struct message msg = { 0 }; LRESULT ret; - struct message msg; msg.message = message; msg.flags = sent|wparam|lparam; Modified: trunk/rostests/winetests/comctl32/datetime.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/comctl32/datetime.c?rev=74903&r1=74902&r2=74903&view=diff ============================================================================== --- trunk/rostests/winetests/comctl32/datetime.c [iso-8859-1] (original) +++ trunk/rostests/winetests/comctl32/datetime.c [iso-8859-1] Sun Jun 4 12:53:30 2017 @@ -142,15 +142,14 @@ { WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); static LONG defwndproc_counter = 0; + struct message msg = { 0 }; LRESULT ret; - struct message msg; msg.message = message; msg.flags = sent|wparam|lparam; if (defwndproc_counter) msg.flags |= defwinproc; msg.wParam = wParam; msg.lParam = lParam; - msg.id = 0; add_message(sequences, DATETIME_SEQ_INDEX, &msg); defwndproc_counter++; Modified: trunk/rostests/winetests/comctl32/header.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/comctl32/header.c?rev=74903&r1=74902&r2=74903&view=diff ============================================================================== --- trunk/rostests/winetests/comctl32/header.c [iso-8859-1] (original) +++ trunk/rostests/winetests/comctl32/header.c [iso-8859-1] Sun Jun 4 12:53:30 2017 @@ -394,7 +394,7 @@ static char *str_items[] = {pszFirstItem, pszSecondItem, pszThirdItem, pszFourthItem, pszReplaceItem, pszOutOfRangeItem}; - + static char pszUniTestA[] = "TST"; static WCHAR pszUniTestW[] = {'T','S','T',0}; @@ -414,15 +414,14 @@ { WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); static LONG defwndproc_counter = 0; + struct message msg = { 0 }; LRESULT ret; - struct message msg; msg.message = message; msg.flags = sent|wparam|lparam; if (defwndproc_counter) msg.flags |= defwinproc; msg.wParam = wParam; msg.lParam = lParam; - msg.id = 0; add_message(sequences, HEADER_SEQ_INDEX, &msg); defwndproc_counter++; @@ -1572,7 +1571,6 @@ { hdi.lParam = i; SendMessageA(hWndHeader, HDM_INSERTITEMA, rand1[i], (LPARAM)&hdi); - rand(); } check_order(ids1, ord1, 5, "insert without iOrder"); @@ -1582,7 +1580,6 @@ hdi.lParam = i + 5; hdi.iOrder = rand2[i]; SendMessageA(hWndHeader, HDM_INSERTITEMA, rand3[i], (LPARAM)&hdi); - rand(); rand(); } check_order(ids2, ord2, 10, "insert with order"); @@ -1591,7 +1588,6 @@ { hdi.iOrder = rand5[i]; SendMessageA(hWndHeader, HDM_SETITEMA, rand4[i], (LPARAM)&hdi); - rand(); rand(); } check_order(ids2, ord3, 10, "setitems changing order"); Modified: trunk/rostests/winetests/comctl32/imagelist.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/comctl32/imagelist.c?rev=74903&r1=74902&r2=74903&view=diff ============================================================================== --- trunk/rostests/winetests/comctl32/imagelist.c [iso-8859-1] (original) +++ trunk/rostests/winetests/comctl32/imagelist.c [iso-8859-1] Sun Jun 4 12:53:30 2017 @@ -922,36 +922,34 @@ char *data; HRESULT hr; - trace("%s\n", comment); - ret = ImageList_GetImageCount(himl); - ok(ret == cur, "expected image count %d got %d\n", cur, ret); + ok(ret == cur, "%s: expected image count %d got %d\n", comment, cur, ret); ret = ImageList_GetIconSize(himl, &cxx, &cyy); ok(ret, "ImageList_GetIconSize failed\n"); - ok(cxx == cx, "wrong cx %d (expected %d)\n", cxx, cx); - ok(cyy == cy, "wrong cy %d (expected %d)\n", cyy, cy); + ok(cxx == cx, "%s: wrong cx %d (expected %d)\n", comment, cxx, cx); + ok(cyy == cy, "%s: wrong cy %d (expected %d)\n", comment, cyy, cy); init_memstream(&stream); ret = ImageList_Write(himl, &stream.IStream_iface); - ok(ret, "ImageList_Write failed\n"); + ok(ret, "%s: ImageList_Write failed\n", comment); hr = GetHGlobalFromStream(stream.stream, &hglobal); - ok(hr == S_OK, "Failed to get hglobal, %#x\n", hr); + ok(hr == S_OK, "%s: Failed to get hglobal, %#x\n", comment, hr); IStream_Stat(stream.stream, &stat, STATFLAG_NONAME); data = GlobalLock(hglobal); - ok(data != 0, "ImageList_Write didn't write any data\n"); - ok(stat.cbSize.LowPart > sizeof(ILHEAD), "ImageList_Write wrote not enough data\n"); + ok(data != 0, "%s: ImageList_Write didn't write any data\n", comment); + ok(stat.cbSize.LowPart > sizeof(ILHEAD), "%s: ImageList_Write wrote not enough data\n", comment); check_ilhead_data(data, cx, cy, cur, max, grow, flags); size = check_bitmap_data(data + sizeof(ILHEAD), stat.cbSize.LowPart - sizeof(ILHEAD), width, height, flags & 0xfe, comment); if (size < stat.cbSize.LowPart - sizeof(ILHEAD)) /* mask is present */ { - ok( flags & ILC_MASK, "extra data %u/%u but mask not expected\n", stat.cbSize.LowPart, size ); + ok( flags & ILC_MASK, "%s: extra data %u/%u but mask not expected\n", comment, stat.cbSize.LowPart, size ); check_bitmap_data(data + sizeof(ILHEAD) + size, stat.cbSize.LowPart - sizeof(ILHEAD) - size, width, height, 1, comment); } @@ -960,7 +958,7 @@ mv.QuadPart = 0; IStream_Seek(stream.stream, mv, STREAM_SEEK_SET, NULL); himl2 = ImageList_Read(&stream.IStream_iface); - ok(himl2 != NULL, "Failed to deserialize imagelist\n"); + ok(himl2 != NULL, "%s: Failed to deserialize imagelist\n", comment); ImageList_Destroy(himl2); GlobalUnlock(hglobal); @@ -2220,6 +2218,29 @@ ImageList_Destroy(himl); } +static void test_copy(void) +{ + HIMAGELIST dst, src; + BOOL ret; + int count; + + dst = ImageList_Create(5, 11, ILC_COLOR, 1, 1); + count = ImageList_GetImageCount(dst); + ok(!count, "ImageList not empty.\n"); + src = createImageList(7, 13); + count = ImageList_GetImageCount(src); + ok(count > 2, "Tests need an ImageList with more than 2 images\n"); + + /* ImageList_Copy() cannot copy between two ImageLists */ + ret = ImageList_Copy(dst, 0, src, 2, ILCF_MOVE); + ok(!ret, "ImageList_Copy() should have returned FALSE\n"); + count = ImageList_GetImageCount(dst); + ok(count == 0, "Expected no image in dst ImageList, got %d\n", count); + + ImageList_Destroy(dst); + ImageList_Destroy(src); +} + static void test_IImageList_Clone(void) { IImageList *imgl, *imgl2; @@ -2370,6 +2391,7 @@ test_iconsize(); test_color_table(ILC_COLOR4); test_color_table(ILC_COLOR8); + test_copy(); FreeLibrary(hComCtl32); Modified: trunk/rostests/winetests/comctl32/listview.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/comctl32/listview.c?rev=74903&r1=74902&r2=74903&view=diff ============================================================================== --- trunk/rostests/winetests/comctl32/listview.c [iso-8859-1] (original) +++ trunk/rostests/winetests/comctl32/listview.c [iso-8859-1] Sun Jun 4 12:53:30 2017 @@ -710,8 +710,8 @@ { WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); static LONG defwndproc_counter = 0; + struct message msg = { 0 }; LRESULT ret; - struct message msg; msg.message = message; msg.flags = sent|wparam|lparam; @@ -744,15 +744,14 @@ { WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); static LONG defwndproc_counter = 0; + struct message msg = { 0 }; LRESULT ret; - struct message msg; msg.message = message; msg.flags = sent|wparam|lparam; if (defwndproc_counter) msg.flags |= defwinproc; msg.wParam = wParam; msg.lParam = lParam; - msg.id = 0; /* all we need is sizing */ if (message == WM_WINDOWPOSCHANGING || @@ -5076,12 +5075,30 @@ fi.psz = f; r = SendMessageA(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi); expect(0, r); + + fi.flags = LVFI_STRING | LVFI_PARTIAL; + r = SendMessageA(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi); + expect(0, r); + + fi.flags = LVFI_PARTIAL; + r = SendMessageA(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi); + expect(0, r); + /* partial string search, inserted text was "foo" */ strcpy(f, "fo"); fi.flags = LVFI_STRING | LVFI_PARTIAL; fi.psz = f; r = SendMessageA(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi); expect(0, r); + + fi.flags = LVFI_STRING; + r = SendMessageA(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi); + expect(-1, r); + + fi.flags = LVFI_PARTIAL; + r = SendMessageA(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi); + expect(0, r); + /* partial string search, part after start char */ strcpy(f, "oo"); fi.flags = LVFI_STRING | LVFI_PARTIAL; @@ -5112,9 +5129,19 @@ r = SendMessageA(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi); expect(-1, r); + strcpy(f, "o"); + fi.flags = LVFI_SUBSTRING | LVFI_PARTIAL; + fi.psz = f; + r = SendMessageA(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi); + expect(-1, r); + strcpy(f, "f"); fi.flags = LVFI_SUBSTRING | LVFI_STRING; fi.psz = f; + r = SendMessageA(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi); + expect(0, r); + + fi.flags = LVFI_SUBSTRING | LVFI_PARTIAL; r = SendMessageA(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi); expect(0, r); @@ -5547,6 +5574,43 @@ expect(TRUE, ret); DestroyWindow(hwnd); +} + +static void test_LVM_REDRAWITEMS(void) +{ + HWND list; + DWORD ret; + + list = create_listview_control(LVS_ICON); + ok(list != NULL, "failed to create listview window\n"); + + ret = SendMessageA(list, LVM_REDRAWITEMS, 0, 0); + expect(TRUE, ret); + + insert_item(list, 0); + + ret = SendMessageA(list, LVM_REDRAWITEMS, -1, 0); + expect(TRUE, ret); + + ret = SendMessageA(list, LVM_REDRAWITEMS, 0, -1); + expect(TRUE, ret); + + ret = SendMessageA(list, LVM_REDRAWITEMS, 0, 0); + expect(TRUE, ret); + + ret = SendMessageA(list, LVM_REDRAWITEMS, 0, 1); + expect(TRUE, ret); + + ret = SendMessageA(list, LVM_REDRAWITEMS, 0, 2); + expect(TRUE, ret); + + ret = SendMessageA(list, LVM_REDRAWITEMS, 1, 0); + expect(TRUE, ret); + + ret = SendMessageA(list, LVM_REDRAWITEMS, 2, 3); + expect(TRUE, ret); + + DestroyWindow(list); } static void test_imagelists(void) @@ -5923,6 +5987,7 @@ test_createdragimage(); test_dispinfo(); test_LVM_SETITEMTEXT(); + test_LVM_REDRAWITEMS(); test_imagelists(); test_deleteitem(); test_insertitem(); Modified: trunk/rostests/winetests/comctl32/misc.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/comctl32/misc.c?rev=74903&r1=74902&r2=74903&view=diff ============================================================================== --- trunk/rostests/winetests/comctl32/misc.c [iso-8859-1] (original) +++ trunk/rostests/winetests/comctl32/misc.c [iso-8859-1] Sun Jun 4 12:53:30 2017 @@ -202,29 +202,6 @@ ok(res == TRUE, "Expected TRUE, got %d\n", res); } -static void test_TaskDialogIndirect(void) -{ - HINSTANCE hinst; - void *ptr, *ptr2; - - hinst = LoadLibraryA("comctl32.dll"); - - ptr = GetProcAddress(hinst, "TaskDialogIndirect"); - if (!ptr) - { -#ifdef __REACTOS__ - /* Skipped on 2k3 */ - skip("TaskDialogIndirect not exported by name\n"); -#else - win_skip("TaskDialogIndirect not exported by name\n"); -#endif - return; - } - - ptr2 = GetProcAddress(hinst, (const CHAR*)345); - ok(ptr == ptr2, "got wrong pointer for ordinal 345, %p expected %p\n", ptr2, ptr); -} - static void test_LoadIconWithScaleDown(void) { static const WCHAR nonexisting_fileW[] = {'n','o','n','e','x','i','s','t','i','n','g','.','i','c','o',0}; @@ -413,7 +390,6 @@ return; test_builtin_classes(); - test_TaskDialogIndirect(); test_LoadIconWithScaleDown(); unload_v6_module(ctx_cookie, hCtx); Modified: trunk/rostests/winetests/comctl32/monthcal.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/comctl32/monthcal.c?rev=74903&r1=74902&r2=74903&view=diff ============================================================================== --- trunk/rostests/winetests/comctl32/monthcal.c [iso-8859-1] (original) +++ trunk/rostests/winetests/comctl32/monthcal.c [iso-8859-1] Sun Jun 4 12:53:30 2017 @@ -624,15 +624,14 @@ { WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); static LONG defwndproc_counter = 0; + struct message msg = { 0 }; LRESULT ret; - struct message msg; msg.message = message; msg.flags = sent|wparam|lparam; if (defwndproc_counter) msg.flags |= defwinproc; msg.wParam = wParam; msg.lParam = lParam; - msg.id = 0; add_message(sequences, MONTHCAL_SEQ_INDEX, &msg); /* some debug output for style changing */ Modified: trunk/rostests/winetests/comctl32/msg.h URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/comctl32/msg.h?rev=74903&r1=74902&r2=74903&view=diff ============================================================================== --- trunk/rostests/winetests/comctl32/msg.h [iso-8859-1] (original) +++ trunk/rostests/winetests/comctl32/msg.h [iso-8859-1] Sun Jun 4 12:53:30 2017 @@ -371,7 +371,7 @@ if(todo && !failcount) /* succeeded yet marked todo */ { - dump++; + if (!strcmp(winetest_platform, "wine")) dump++; todo_wine { ok_(file, line)(TRUE, "%s: marked \"todo_wine\" but succeeds\n", context); Modified: trunk/rostests/winetests/comctl32/pager.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/comctl32/pager.c?rev=74903&r1=74902&r2=74903&view=diff ============================================================================== --- trunk/rostests/winetests/comctl32/pager.c [iso-8859-1] (original) +++ trunk/rostests/winetests/comctl32/pager.c [iso-8859-1] Sun Jun 4 12:53:30 2017 @@ -30,7 +30,10 @@ #define NUM_MSG_SEQUENCES 1 #define PAGER_SEQ_INDEX 0 -static HWND parent_wnd; +static HWND parent_wnd, child1_wnd, child2_wnd; + +#define CHILD1_ID 1 +#define CHILD2_ID 2 static BOOL (WINAPI *pSetWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR, DWORD_PTR); @@ -42,6 +45,29 @@ { WM_NCCALCSIZE, sent|wparam, TRUE }, { WM_NOTIFY, sent|id|parent, 0, 0, PGN_CALCSIZE }, { WM_WINDOWPOSCHANGED, sent }, + { WM_WINDOWPOSCHANGING, sent|id, 0, 0, CHILD1_ID }, + { WM_NCCALCSIZE, sent|wparam|id|optional, TRUE, 0, CHILD1_ID }, + { WM_CHILDACTIVATE, sent|id, 0, 0, CHILD1_ID }, + { WM_WINDOWPOSCHANGED, sent|id, 0, 0, CHILD1_ID }, + { WM_SIZE, sent|id|defwinproc|optional, 0, 0, CHILD1_ID }, + { 0 } +}; + +/* This differs from the above message list only in the child window that is + * expected to receive the child messages. No message is sent to the old child. + * Also child 2 is hidden while child 1 is visible. The pager does not make the + * hidden child visible. */ +static const struct message switch_child_seq[] = { + { PGM_SETCHILD, sent }, + { WM_WINDOWPOSCHANGING, sent }, + { WM_NCCALCSIZE, sent|wparam, TRUE }, + { WM_NOTIFY, sent|id|parent, 0, 0, PGN_CALCSIZE }, + { WM_WINDOWPOSCHANGED, sent }, + { WM_WINDOWPOSCHANGING, sent|id, 0, 0, CHILD2_ID }, + { WM_NCCALCSIZE, sent|wparam|id, TRUE, 0, CHILD2_ID }, + { WM_CHILDACTIVATE, sent|id, 0, 0, CHILD2_ID }, + { WM_WINDOWPOSCHANGED, sent|id, 0, 0, CHILD2_ID }, + { WM_SIZE, sent|id|defwinproc, 0, 0, CHILD2_ID }, { 0 } }; @@ -52,7 +78,20 @@ { WM_NOTIFY, sent|id|parent, 0, 0, PGN_CALCSIZE }, { WM_WINDOWPOSCHANGED, sent }, { WM_MOVE, sent|optional }, + /* The WM_SIZE handler sends WM_WINDOWPOSCHANGING, WM_CHILDACTIVATE + * and WM_WINDOWPOSCHANGED (which sends WM_MOVE) to the child. + * Another WM_WINDOWPOSCHANGING is sent afterwards. + * + * The 2nd WM_WINDOWPOSCHANGING is unconditional, but the comparison + * function is too simple to roll back an accepted message, so we have + * to mark the 2nd message optional. */ { WM_SIZE, sent|optional }, + { WM_WINDOWPOSCHANGING, sent|id, 0, 0, CHILD1_ID }, /* Actually optional. */ + { WM_CHILDACTIVATE, sent|id, 0, 0, CHILD1_ID }, /* Actually optional. */ + { WM_WINDOWPOSCHANGED, sent|id|optional, TRUE, 0, CHILD1_ID}, + { WM_MOVE, sent|id|optional|defwinproc, 0, 0, CHILD1_ID }, + { WM_WINDOWPOSCHANGING, sent|id|optional, 0, 0, CHILD1_ID }, /* Actually not optional. */ + { WM_CHILDACTIVATE, sent|id|optional, 0, 0, CHILD1_ID }, /* Actually not optional. */ { 0 } }; @@ -145,13 +184,12 @@ static LRESULT WINAPI pager_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); - struct message msg; + struct message msg = { 0 }; msg.message = message; msg.flags = sent|wparam|lparam; msg.wParam = wParam; msg.lParam = lParam; - msg.id = 0; add_message(sequences, PAGER_SEQ_INDEX, &msg); return CallWindowProcA(oldproc, hwnd, message, wParam, lParam); } @@ -170,9 +208,55 @@ return hwnd; } +static LRESULT WINAPI child_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + static LONG defwndproc_counter; + struct message msg = { 0 }; + LRESULT ret; + + msg.message = message; + msg.flags = sent | wparam | lparam; + if (defwndproc_counter) + msg.flags |= defwinproc; + msg.wParam = wParam; + msg.lParam = lParam; + + if (hwnd == child1_wnd) + msg.id = CHILD1_ID; + else if (hwnd == child2_wnd) + msg.id = CHILD2_ID; + else + msg.id = 0; + + add_message(sequences, PAGER_SEQ_INDEX, &msg); + + defwndproc_counter++; + ret = DefWindowProcA(hwnd, message, wParam, lParam); + defwndproc_counter--; + + return ret; +} + +static BOOL register_child_wnd_class(void) +{ + WNDCLASSA cls; + + cls.style = 0; + cls.lpfnWndProc = child_proc; + cls.cbClsExtra = 0; + cls.cbWndExtra = 0; + cls.hInstance = GetModuleHandleA(NULL); + cls.hIcon = 0; + cls.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW); + cls.hbrBackground = GetStockObject(WHITE_BRUSH); + cls.lpszMenuName = NULL; + cls.lpszClassName = "Pager test child class"; + return RegisterClassA(&cls); +} + static void test_pager(void) { - HWND pager, child; + HWND pager; RECT rect, rect2; pager = create_pager_control( PGS_HORZ ); @@ -181,15 +265,35 @@ win_skip( "Pager control not supported\n" ); return; } - child = CreateWindowA( "BUTTON", "button", WS_CHILD | WS_BORDER | WS_VISIBLE, 0, 0, 300, 300, + + register_child_wnd_class(); + + child1_wnd = CreateWindowA( "Pager test child class", "button", WS_CHILD | WS_BORDER | WS_VISIBLE, 0, 0, 300, 300, pager, 0, GetModuleHandleA(0), 0 ); + child2_wnd = CreateWindowA("Pager test child class", "button", WS_CHILD | WS_BORDER, 0, 0, 300, 300, + pager, 0, GetModuleHandleA(0), 0); flush_sequences( sequences, NUM_MSG_SEQUENCES ); - SendMessageA( pager, PGM_SETCHILD, 0, (LPARAM)child ); - ok_sequence(sequences, PAGER_SEQ_INDEX, set_child_seq, "set child", TRUE); + SendMessageA( pager, PGM_SETCHILD, 0, (LPARAM)child1_wnd ); + ok_sequence(sequences, PAGER_SEQ_INDEX, set_child_seq, "set child", FALSE); GetWindowRect( pager, &rect ); ok( rect.right - rect.left == 100 && rect.bottom - rect.top == 100, "pager resized %dx%d\n", rect.right - rect.left, rect.bottom - rect.top ); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + SendMessageA(pager, PGM_SETCHILD, 0, (LPARAM)child2_wnd); + ok_sequence(sequences, PAGER_SEQ_INDEX, switch_child_seq, "switch to invisible child", FALSE); + GetWindowRect(pager, &rect); + ok(rect.right - rect.left == 100 && rect.bottom - rect.top == 100, + "pager resized %dx%d\n", rect.right - rect.left, rect.bottom - rect.top); + ok(!IsWindowVisible(child2_wnd), "Child window 2 is visible\n"); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + SendMessageA(pager, PGM_SETCHILD, 0, (LPARAM)child1_wnd); + ok_sequence(sequences, PAGER_SEQ_INDEX, set_child_seq, "switch to visible child", FALSE); + GetWindowRect(pager, &rect); + ok(rect.right - rect.left == 100 && rect.bottom - rect.top == 100, + "pager resized %dx%d\n", rect.right - rect.left, rect.bottom - rect.top); flush_sequences( sequences, NUM_MSG_SEQUENCES ); SendMessageA( pager, PGM_SETPOS, 0, 10 ); Modified: trunk/rostests/winetests/comctl32/propsheet.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/comctl32/propsheet.c?rev=74903&r1=74902&r2=74903&view=diff ============================================================================== --- trunk/rostests/winetests/comctl32/propsheet.c [iso-8859-1] (original) +++ trunk/rostests/winetests/comctl32/propsheet.c [iso-8859-1] Sun Jun 4 12:53:30 2017 @@ -713,7 +713,7 @@ static void save_message(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, INT receiver) { - struct message msg; + struct message msg = { 0 }; if (message < WM_USER && message != WM_GETICON && @@ -990,6 +990,141 @@ DestroyWindow(hdlg); } +struct custom_proppage +{ + union + { + PROPSHEETPAGEA pageA; + PROPSHEETPAGEW pageW; + } u; + unsigned int addref_called; + unsigned int release_called; +}; + +static UINT CALLBACK proppage_callback_a(HWND hwnd, UINT msg, PROPSHEETPAGEA *psp) +{ + struct custom_proppage *cpage = (struct custom_proppage *)psp->lParam; + PROPSHEETPAGEA *psp_orig = &cpage->u.pageA; + + ok(hwnd == NULL, "Expected NULL hwnd, got %p\n", hwnd); + + ok(psp->lParam && psp->lParam != (LPARAM)psp, "Expected newly allocated page description, got %lx, %p\n", + psp->lParam, psp); + ok(psp_orig->pszTitle == psp->pszTitle, "Expected same page title pointer\n"); + ok(!lstrcmpA(psp_orig->pszTitle, psp->pszTitle), "Expected same page title string\n"); + + switch (msg) + { + case PSPCB_ADDREF: + ok(psp->dwSize > PROPSHEETPAGEA_V1_SIZE, "Expected ADDREF for V2+ only, got size %u\n", psp->dwSize); + cpage->addref_called++; + break; + case PSPCB_RELEASE: + ok(psp->dwSize >= PROPSHEETPAGEA_V1_SIZE, "Unexpected RELEASE, got size %u\n", psp->dwSize); + cpage->release_called++; + break; + default: + ok(0, "Unexpected message %u\n", msg); + } + + return 1; +} + +static UINT CALLBACK proppage_callback_w(HWND hwnd, UINT msg, PROPSHEETPAGEW *psp) +{ + struct custom_proppage *cpage = (struct custom_proppage *)psp->lParam; + PROPSHEETPAGEW *psp_orig = &cpage->u.pageW; + + ok(hwnd == NULL, "Expected NULL hwnd, got %p\n", hwnd); + ok(psp->lParam && psp->lParam != (LPARAM)psp, "Expected newly allocated page description, got %lx, %p\n", + psp->lParam, psp); + ok(psp_orig->pszTitle == psp->pszTitle, "Expected same page title pointer\n"); + ok(!lstrcmpW(psp_orig->pszTitle, psp->pszTitle), "Expected same page title string\n"); + + switch (msg) + { + case PSPCB_ADDREF: + ok(psp->dwSize > PROPSHEETPAGEW_V1_SIZE, "Expected ADDREF for V2+ only, got size %u\n", psp->dwSize); + cpage->addref_called++; + break; + case PSPCB_RELEASE: + ok(psp->dwSize >= PROPSHEETPAGEW_V1_SIZE, "Unexpected RELEASE, got size %u\n", psp->dwSize); + cpage->release_called++; + break; + default: + ok(0, "Unexpected message %u\n", msg); + } + + return 1; +} + +static void test_CreatePropertySheetPage(void) +{ + static const WCHAR titleW[] = {'T','i','t','l','e',0}; + struct custom_proppage page; + HPROPSHEETPAGE hpsp; + BOOL ret; + + memset(&page.u.pageA, 0, sizeof(page.u.pageA)); + page.u.pageA.dwFlags = PSP_USECALLBACK; + page.u.pageA.pfnDlgProc = page_dlg_proc_messages; + page.u.pageA.pfnCallback = proppage_callback_a; + page.u.pageA.lParam = (LPARAM)&page; + page.u.pageA.pszTitle = "Title"; + + /* Only minimal size validation is performed */ + for (page.u.pageA.dwSize = PROPSHEETPAGEA_V1_SIZE - 1; page.u.pageA.dwSize <= PROPSHEETPAGEA_V4_SIZE + 1; page.u.pageA.dwSize++) + { + page.addref_called = 0; + hpsp = CreatePropertySheetPageA(&page.u.pageA); + + if (page.u.pageA.dwSize < PROPSHEETPAGEA_V1_SIZE) + ok(hpsp == NULL, "Expected failure, size %u\n", page.u.pageA.dwSize); + else + { + ok(hpsp != NULL, "Failed to create a page, size %u\n", page.u.pageA.dwSize); + ok(page.addref_called == (page.u.pageA.dwSize > PROPSHEETPAGEA_V1_SIZE) ? 1 : 0, "Expected ADDREF callback message\n"); + } + + if (hpsp) + { + page.release_called = 0; + ret = DestroyPropertySheetPage(hpsp); + ok(ret, "Failed to destroy a page\n"); + ok(page.release_called == 1, "Expected RELEASE callback message\n"); + } + } + + memset(&page.u.pageW, 0, sizeof(page.u.pageW)); + page.u.pageW.dwFlags = PSP_USECALLBACK; + page.u.pageW.pfnDlgProc = page_dlg_proc_messages; + page.u.pageW.pfnCallback = proppage_callback_w; + page.u.pageW.lParam = (LPARAM)&page; + page.u.pageW.pszTitle = titleW; + + for (page.u.pageW.dwSize = PROPSHEETPAGEW_V1_SIZE - 1; page.u.pageW.dwSize <= PROPSHEETPAGEW_V4_SIZE + 1; page.u.pageW.dwSize++) + { + page.addref_called = 0; + hpsp = CreatePropertySheetPageW(&page.u.pageW); + + if (page.u.pageW.dwSize < PROPSHEETPAGEW_V1_SIZE) + ok(hpsp == NULL, "Expected failure, size %u\n", page.u.pageW.dwSize); + else + { + ok(hpsp != NULL, "Failed to create a page, size %u\n", page.u.pageW.dwSize); + ok(page.addref_called == (page.u.pageW.dwSize > PROPSHEETPAGEW_V1_SIZE) ? 1 : 0, "Expected ADDREF callback message\n"); + } + + if (hpsp) + { + page.release_called = 0; + ret = DestroyPropertySheetPage(hpsp); + ok(ret, "Failed to destroy a page\n"); + ok(page.release_called == 1, "Expected RELEASE callback message\n"); + } + } +} + START_TEST(propsheet) { test_title(); @@ -1001,4 +1136,5 @@ test_messages(); test_PSM_ADDPAGE(); test_PSM_INSERTPAGE(); -} + test_CreatePropertySheetPage(); +} Modified: trunk/rostests/winetests/comctl32/syslink.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/comctl32/syslink.c?rev=74903&r1=74902&r2=74903&view=diff ============================================================================== --- trunk/rostests/winetests/comctl32/syslink.c [iso-8859-1] (original) +++ trunk/rostests/winetests/comctl32/syslink.c [iso-8859-1] Sun Jun 4 12:53:30 2017 @@ -146,15 +146,14 @@ static LRESULT WINAPI syslink_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static LONG defwndproc_counter = 0; + struct message msg = { 0 }; LRESULT ret; - struct message msg; msg.message = message; msg.flags = sent|wparam|lparam; if (defwndproc_counter) msg.flags |= defwinproc; msg.wParam = wParam; msg.lParam = lParam; - msg.id = 0; add_message(sequences, SYSLINK_SEQ_INDEX, &msg); defwndproc_counter++; Modified: trunk/rostests/winetests/comctl32/tab.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/comctl32/tab.c?rev=74903&r1=74902&r2=74903&view=diff ============================================================================== --- trunk/rostests/winetests/comctl32/tab.c [iso-8859-1] (original) +++ trunk/rostests/winetests/comctl32/tab.c [iso-8859-1] Sun Jun 4 12:53:30 2017 @@ -304,8 +304,8 @@ static LRESULT WINAPI parentWindowProcess(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static LONG defwndproc_counter = 0; + struct message msg = { 0 }; LRESULT ret; - struct message msg; /* do not log painting messages */ if (message != WM_PAINT && @@ -321,7 +321,6 @@ if (defwndproc_counter) msg.flags |= defwinproc; msg.wParam = wParam; msg.lParam = lParam; - msg.id = 0; add_message(sequences, PARENT_SEQ_INDEX, &msg); } @@ -367,8 +366,8 @@ { WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); static LONG defwndproc_counter = 0; + struct message msg = { 0 }; LRESULT ret; - struct message msg; /* do not log painting messages */ if (message != WM_PAINT && @@ -384,7 +383,6 @@ if (defwndproc_counter) msg.flags |= defwinproc; msg.wParam = wParam; msg.lParam = lParam; - msg.id = 0; add_message(sequences, TAB_SEQ_INDEX, &msg); } Added: trunk/rostests/winetests/comctl32/taskdialog.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/comctl32/taskdialog.c?rev=74903 ============================================================================== --- trunk/rostests/winetests/comctl32/taskdialog.c (added) +++ trunk/rostests/winetests/comctl32/taskdialog.c [iso-8859-1] Sun Jun 4 12:53:30 2017 @@ -0,0 +1,58 @@ +/* Unit tests for the task dialog control. + * + * Copyright 2017 Fabian Maurer for the Wine project + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "commctrl.h" + +#include "wine/test.h" +#include "v6util.h" + +static HRESULT (WINAPI *pTaskDialogIndirect)(const TASKDIALOGCONFIG *, int *, int *, BOOL *); + +START_TEST(taskdialog) +{ + ULONG_PTR ctx_cookie; + void *ptr_ordinal; + HINSTANCE hinst; + HANDLE hCtx; + + if (!load_v6_module(&ctx_cookie, &hCtx)) + return; + + /* Check if task dialogs are available */ + hinst = LoadLibraryA("comctl32.dll"); + + pTaskDialogIndirect = (void *)GetProcAddress(hinst, "TaskDialogIndirect"); + if (!pTaskDialogIndirect) + { + win_skip("TaskDialogIndirect not exported by name\n"); + unload_v6_module(ctx_cookie, hCtx); + return; + } + + ptr_ordinal = GetProcAddress(hinst, (const char *)345); + ok(pTaskDialogIndirect == ptr_ordinal, "got wrong pointer for ordinal 345, %p expected %p\n", + ptr_ordinal, pTaskDialogIndirect); + + unload_v6_module(ctx_cookie, hCtx); +} Propchange: trunk/rostests/winetests/comctl32/taskdialog.c ------------------------------------------------------------------------------ svn:eol-style = native Modified: trunk/rostests/winetests/comctl32/testlist.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/comctl32/testlist.c?rev=74903&r1=74902&r2=74903&view=diff ============================================================================== --- trunk/rostests/winetests/comctl32/testlist.c [iso-8859-1] (original) +++ trunk/rostests/winetests/comctl32/testlist.c [iso-8859-1] Sun Jun 4 12:53:30 2017 @@ -23,6 +23,7 @@ extern void func_subclass(void); extern void func_syslink(void); extern void func_tab(void); +extern void func_taskdialog(void); extern void func_toolbar(void); extern void func_tooltips(void); extern void func_trackbar(void); @@ -51,6 +52,7 @@ { "subclass", func_subclass }, { "syslink", func_syslink }, { "tab", func_tab }, + { "taskdialog", func_taskdialog }, { "toolbar", func_toolbar }, { "tooltips", func_tooltips }, { "trackbar", func_trackbar }, Modified: trunk/rostests/winetests/comctl32/toolbar.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/comctl32/toolbar.c?rev=74903&r1=74902&r2=74903&view=diff ============================================================================== --- trunk/rostests/winetests/comctl32/toolbar.c [iso-8859-1] (original) +++ trunk/rostests/winetests/comctl32/toolbar.c [iso-8859-1] Sun Jun 4 12:53:30 2017 @@ -2276,7 +2276,8 @@ { 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 subkey[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','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; Modified: trunk/rostests/winetests/comctl32/trackbar.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/comctl32/trackbar.c?rev=74903&r1=74902&r2=74903&view=diff ============================================================================== --- trunk/rostests/winetests/comctl32/trackbar.c [iso-8859-1] (original) +++ trunk/rostests/winetests/comctl32/trackbar.c [iso-8859-1] Sun Jun 4 12:53:30 2017 @@ -442,15 +442,14 @@ static LRESULT WINAPI trackbar_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); static LONG defwndproc_counter = 0; + struct message msg = { 0 }; LRESULT ret; - struct message msg; msg.message = message; msg.flags = sent|wparam|lparam; if (defwndproc_counter) msg.flags |= defwinproc; msg.wParam = wParam; msg.lParam = lParam; - msg.id = 0; add_message(sequences, TRACKBAR_SEQ_INDEX, &msg); defwndproc_counter++; Modified: trunk/rostests/winetests/comctl32/treeview.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/comctl32/treeview.c?rev=74903&r1=74902&r2=74903&view=diff ============================================================================== --- trunk/rostests/winetests/comctl32/treeview.c [iso-8859-1] (original) +++ trunk/rostests/winetests/comctl32/treeview.c [iso-8859-1] Sun Jun 4 12:53:30 2017 @@ -53,6 +53,21 @@ static struct msg_sequence *sequences[NUM_MSG_SEQUENCES]; static struct msg_sequence *item_sequence[1]; + +static void flush_events(void) +{ + MSG msg; + int diff = 200; + int min_timeout = 100; + DWORD time = GetTickCount() + diff; + + while (diff > 0) + { + if (MsgWaitForMultipleObjects(0, NULL, FALSE, min_timeout, QS_ALLINPUT) == WAIT_TIMEOUT) break; + while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg); + diff = time - GetTickCount(); + } +} static const struct message FillRootSeq[] = { { TVM_INSERTITEMA, sent }, @@ -201,6 +216,13 @@ { 0 } }; +static const struct message test_right_click_seq[] = { + { WM_RBUTTONDOWN, sent|wparam, MK_RBUTTON }, + { WM_CAPTURECHANGED, sent|defwinproc }, + { TVM_GETNEXTITEM, sent|wparam|lparam|defwinproc, TVGN_CARET, 0 }, + { 0 } +}; + static const struct message parent_expand_seq[] = { { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDINGA }, { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDEDA }, @@ -339,6 +361,12 @@ { WM_NOTIFY, sent|id, 0, 0, TVN_KEYDOWN }, { WM_NOTIFY, sent|id, 0, 0, NM_RETURN }, { WM_CHANGEUISTATE, sent|optional }, + { 0 } +}; + +static const struct message parent_right_click_seq[] = { + { WM_NOTIFY, sent|id, 0, 0, NM_RCLICK }, + { WM_CONTEXTMENU, sent }, { 0 } }; @@ -383,15 +411,14 @@ { static LONG defwndproc_counter = 0; LRESULT ret; - struct message msg; WNDPROC lpOldProc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); + struct message msg = { 0 }; msg.message = message; msg.flags = sent|wparam|lparam; if (defwndproc_counter) msg.flags |= defwinproc; msg.wParam = wParam; msg.lParam = lParam; - msg.id = 0; add_message(sequences, TREEVIEW_SEQ_INDEX, &msg); defwndproc_counter++; @@ -1099,7 +1126,7 @@ static LRESULT CALLBACK parent_wnd_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static LONG defwndproc_counter = 0; - struct message msg; + struct message msg = { 0 }; LRESULT ret; RECT rect; HTREEITEM visibleItem; @@ -1111,8 +1138,6 @@ msg.lParam = lParam; if (message == WM_NOTIFY && lParam) msg.id = ((NMHDR*)lParam)->code; - else - msg.id = 0; /* log system messages, except for painting */ if (message < WM_USER && @@ -1297,6 +1322,13 @@ default: ; } + break; + } + case NM_RCLICK: + { + HTREEITEM selected = (HTREEITEM)SendMessageA(((NMHDR *)lParam)->hwndFrom, + TVM_GETNEXTITEM, TVGN_CARET, 0); + ok(selected == hChild, "child item should still be selected\n"); break; } } @@ -2395,6 +2427,238 @@ ok(style & TVS_FULLROWSELECT, "got style 0x%08x\n", style); DestroyWindow(hwnd); +} + +static void get_item_names_string(HWND hwnd, HTREEITEM item, char *str) +{ + TVITEMA tvitem = { 0 }; + HTREEITEM child; + char name[16]; + + if (!item) + { + item = (HTREEITEM)SendMessageA(hwnd, TVM_GETNEXTITEM, TVGN_ROOT, 0); + str[0] = 0; + } + + child = (HTREEITEM)SendMessageA(hwnd, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)item); + + tvitem.mask = TVIF_TEXT; + tvitem.hItem = item; + tvitem.pszText = name; + tvitem.cchTextMax = sizeof(name); + SendMessageA(hwnd, TVM_GETITEMA, 0, (LPARAM)&tvitem); + strcat(str, tvitem.pszText); + + while (child != NULL) + { + get_item_names_string(hwnd, child, str); + child = (HTREEITEM)SendMessageA(hwnd, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)child); + } +} + +static void fill_treeview_sort_test(HWND hwnd) +{ + static const char *itemnames[] = + { + "root", "Wasp", "Caribou", "Vacuum", + "Ocelot", "Newspaper", "Litter bin" + }; + + HTREEITEM root, children[2]; + TVINSERTSTRUCTA ins; + unsigned i = 0; + + SendMessageA(hwnd, TVM_DELETEITEM, 0, 0); + + /* root, two children, with two children each */ + ins.hParent = TVI_ROOT; + ins.hInsertAfter = TVI_ROOT; + U(ins).item.mask = TVIF_TEXT; + U(ins).item.pszText = (char *)itemnames[i++]; + root = (HTREEITEM)SendMessageA(hwnd, TVM_INSERTITEMA, 0, (LPARAM)&ins); + + ins.hParent = root; + ins.hInsertAfter = TVI_LAST; + U(ins).item.mask = TVIF_TEXT; + U(ins).item.pszText = (char *)itemnames[i++]; + children[0] = (HTREEITEM)SendMessageA(hwnd, TVM_INSERTITEMA, 0, (LPARAM)&ins); + + U(ins).item.pszText = (char *)itemnames[i++]; + children[1] = (HTREEITEM)SendMessageA(hwnd, TVM_INSERTITEMA, 0, (LPARAM)&ins); + + ins.hParent = children[0]; + U(ins).item.pszText = (char *)itemnames[i++]; + SendMessageA(hwnd, TVM_INSERTITEMA, 0, (LPARAM)&ins); + + U(ins).item.pszText = (char *)itemnames[i++]; + SendMessageA(hwnd, TVM_INSERTITEMA, 0, (LPARAM)&ins); + + ins.hParent = children[1]; + U(ins).item.pszText = (char *)itemnames[i++]; + SendMessageA(hwnd, TVM_INSERTITEMA, 0, (LPARAM)&ins); + + U(ins).item.pszText = (char *)itemnames[i++]; + SendMessageA(hwnd, TVM_INSERTITEMA, 0, (LPARAM)&ins); +} + +static void test_TVM_SORTCHILDREN(void) +{ + static const char *initial_order = "rootWaspVacuumOcelotCaribouNewspaperLitter bin"; + static const char *sorted_order = "rootCaribouNewspaperLitter binWaspVacuumOcelot"; + TVINSERTSTRUCTA ins; + char buff[256]; + HTREEITEM root; + HWND hwnd; + BOOL ret; + + hwnd = create_treeview_control(0); + + /* call on empty tree */ + ret = SendMessageA(hwnd, TVM_SORTCHILDREN, 0, 0); + ok(!ret, "Unexpected ret value %d\n", ret); + + ret = SendMessageA(hwnd, TVM_SORTCHILDREN, 0, (LPARAM)TVI_ROOT); + ok(!ret, "Unexpected ret value %d\n", ret); + + /* add only root, sort from it */ + ins.hParent = TVI_ROOT; + ins.hInsertAfter = TVI_ROOT; + U(ins).item.mask = TVIF_TEXT; + U(ins).item.pszText = (char *)"root"; + root = (HTREEITEM)SendMessageA(hwnd, TVM_INSERTITEMA, 0, (LPARAM)&ins); + ok(root != NULL, "Expected root node\n"); + + ret = SendMessageA(hwnd, TVM_SORTCHILDREN, 0, (LPARAM)root); + ok(!ret, "Unexpected ret value %d\n", ret); + + ret = SendMessageA(hwnd, TVM_SORTCHILDREN, TRUE, (LPARAM)root); + ok(!ret, "Unexpected ret value %d\n", ret); + + /* root, two children, with two children each */ + fill_treeview_sort_test(hwnd); + get_item_names_string(hwnd, NULL, buff); + ok(!strcmp(buff, initial_order), "Wrong initial order %s, expected %s\n", buff, initial_order); + + /* with NULL item nothing is sorted */ + fill_treeview_sort_test(hwnd); + ret = SendMessageA(hwnd, TVM_SORTCHILDREN, 0, 0); +todo_wine + ok(ret, "Unexpected ret value %d\n", ret); + get_item_names_string(hwnd, NULL, buff); + ok(!strcmp(buff, initial_order), "Wrong sorted order %s, expected %s\n", buff, initial_order); + + /* TVI_ROOT as item */ + fill_treeview_sort_test(hwnd); + ret = SendMessageA(hwnd, TVM_SORTCHILDREN, 0, (LPARAM)TVI_ROOT); +todo_wine + ok(ret, "Unexpected ret value %d\n", ret); + get_item_names_string(hwnd, NULL, buff); + ok(!strcmp(buff, initial_order), "Wrong sorted order %s, expected %s\n", buff, initial_order); + + /* zero WPARAM, item is specified */ + fill_treeview_sort_test(hwnd); + root = (HTREEITEM)SendMessageA(hwnd, TVM_GETNEXTITEM, TVGN_ROOT, 0); + ok(root != NULL, "Failed to get root item\n"); + ret = SendMessageA(hwnd, TVM_SORTCHILDREN, 0, (LPARAM)root); + ok(ret, "Unexpected ret value %d\n", ret); + get_item_names_string(hwnd, NULL, buff); + ok(!strcmp(buff, sorted_order), "Wrong sorted order %s, expected %s\n", buff, sorted_order); + + /* non-zero WPARAM, NULL item */ + fill_treeview_sort_test(hwnd); + ret = SendMessageA(hwnd, TVM_SORTCHILDREN, TRUE, 0); +todo_wine + ok(ret, "Unexpected ret value %d\n", ret); + get_item_names_string(hwnd, NULL, buff); + ok(!strcmp(buff, initial_order), "Wrong sorted order %s, expected %s\n", buff, sorted_order); + + /* TVI_ROOT as item */ + fill_treeview_sort_test(hwnd); + ret = SendMessageA(hwnd, TVM_SORTCHILDREN, TRUE, (LPARAM)TVI_ROOT); +todo_wine + ok(ret, "Unexpected ret value %d\n", ret); + get_item_names_string(hwnd, NULL, buff); + ok(!strcmp(buff, initial_order), "Wrong sorted order %s, expected %s\n", buff, sorted_order); + + /* non-zero WPARAM, item is specified */ + fill_treeview_sort_test(hwnd); + root = (HTREEITEM)SendMessageA(hwnd, TVM_GETNEXTITEM, TVGN_ROOT, 0); + ok(root != NULL, "Failed to get root item\n"); + ret = SendMessageA(hwnd, TVM_SORTCHILDREN, TRUE, (LPARAM)root); + ok(ret, "Unexpected ret value %d\n", ret); + get_item_names_string(hwnd, NULL, buff); + ok(!strcmp(buff, sorted_order), "Wrong sorted order %s, expected %s\n", buff, sorted_order); + + /* case insensitive comparison */ + SendMessageA(hwnd, TVM_DELETEITEM, 0, 0); + + ins.hParent = TVI_ROOT; + ins.hInsertAfter = TVI_ROOT; + U(ins).item.mask = TVIF_TEXT; + U(ins).item.pszText = (char *)"root"; + root = (HTREEITEM)SendMessageA(hwnd, TVM_INSERTITEMA, 0, (LPARAM)&ins); + ok(root != NULL, "Expected root node\n"); + + ins.hParent = root; + ins.hInsertAfter = TVI_LAST; + U(ins).item.pszText = (char *)"I1"; + SendMessageA(hwnd, TVM_INSERTITEMA, 0, (LPARAM)&ins); + + ins.hParent = root; + ins.hInsertAfter = TVI_LAST; + U(ins).item.pszText = (char *)"i1"; + SendMessageA(hwnd, TVM_INSERTITEMA, 0, (LPARAM)&ins); + + ret = SendMessageA(hwnd, TVM_SORTCHILDREN, TRUE, (LPARAM)root); + ok(ret, "Unexpected ret value %d\n", ret); + get_item_names_string(hwnd, NULL, buff); + ok(!strcmp(buff, "rootI1i1"), "Wrong sorted order %s\n", buff); + + DestroyWindow(hwnd); +} + +static void test_right_click(void) +{ + HWND hTree; + HTREEITEM selected; + RECT rc; + LRESULT result; + POINT pt; + + hTree = create_treeview_control(0); + fill_tree(hTree); + + SendMessageA(hTree, TVM_ENSUREVISIBLE, 0, (LPARAM)hChild); + SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hChild); + selected = (HTREEITEM)SendMessageA(hTree, TVM_GETNEXTITEM, TVGN_CARET, 0); + ok(selected == hChild, "child item not selected\n"); + + *(HTREEITEM *)&rc = hRoot; + result = SendMessageA(hTree, TVM_GETITEMRECT, TRUE, (LPARAM)&rc); + ok(result, "TVM_GETITEMRECT failed\n"); + + flush_events(); + + pt.x = (rc.left + rc.right) / 2; + pt.y = (rc.top + rc.bottom) / 2; + ClientToScreen(hMainWnd, &pt); + + flush_events(); + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + PostMessageA(hTree, WM_RBUTTONDOWN, MK_RBUTTON, MAKELPARAM(pt.x, pt.y)); + PostMessageA(hTree, WM_RBUTTONUP, 0, MAKELPARAM(pt.x, pt.y)); + + flush_events(); + + ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_right_click_seq, "right click sequence", FALSE); + ok_sequence(sequences, PARENT_SEQ_INDEX, parent_right_click_seq, "parent right click sequence", FALSE); + + selected = (HTREEITEM)SendMessageA(hTree, TVM_GETNEXTITEM, TVGN_CARET, 0); + ok(selected == hChild, "child item should still be selected\n"); + + DestroyWindow(hTree); } START_TEST(treeview) @@ -2473,6 +2737,8 @@ test_customdraw(); test_WM_KEYDOWN(); test_TVS_FULLROWSELECT(); + test_TVM_SORTCHILDREN(); + test_right_click(); if (!load_v6_module(&ctx_cookie, &hCtx)) { Modified: trunk/rostests/winetests/comctl32/updown.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/comctl32/updown.c?rev=74903&r1=74902&r2=74903&view=diff ============================================================================== --- trunk/rostests/winetests/comctl32/updown.c [iso-8859-1] (original) +++ trunk/rostests/winetests/comctl32/updown.c [iso-8859-1] Sun Jun 4 12:53:30 2017 @@ -169,8 +169,8 @@ static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static LONG defwndproc_counter = 0; + struct message msg = { 0 }; LRESULT ret; - struct message msg; /* log system messages, except for painting */ if (message < WM_USER && @@ -187,7 +187,6 @@ if (defwndproc_counter) msg.flags |= defwinproc; msg.wParam = wParam; msg.lParam = lParam; - msg.id = 0; add_message(sequences, PARENT_SEQ_INDEX, &msg); } @@ -232,8 +231,8 @@ { WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); static LONG defwndproc_counter = 0; + struct message msg = { 0 }; LRESULT ret; - struct message msg; msg.message = message; msg.flags = sent|wparam|lparam; @@ -272,8 +271,8 @@ { WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); static LONG defwndproc_counter = 0; + struct message msg = { 0 }; LRESULT ret; - struct message msg; msg.message = message; msg.flags = sent|wparam|lparam;