From 34400f4d6f84e732cb65e9bcacef2840439c1a41 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Tue, 1 Mar 2016 19:02:49 +0000 Subject: [PATCH] [COMCTL32_WINETEST] Sync with Wine Staging 1.9.4. CORE-10912 svn path=/trunk/; revision=70847 --- rostests/winetests/comctl32/button.c | 5 + rostests/winetests/comctl32/header.c | 6 +- rostests/winetests/comctl32/imagelist.c | 99 ++++++--- rostests/winetests/comctl32/listview.c | 63 +++--- rostests/winetests/comctl32/misc.c | 31 +++ rostests/winetests/comctl32/monthcal.c | 7 +- rostests/winetests/comctl32/propsheet.c | 2 +- rostests/winetests/comctl32/tooltips.c | 27 +++ rostests/winetests/comctl32/trackbar.c | 258 ++++++++++++++++++------ rostests/winetests/comctl32/treeview.c | 55 ++++- 10 files changed, 411 insertions(+), 142 deletions(-) diff --git a/rostests/winetests/comctl32/button.c b/rostests/winetests/comctl32/button.c index b56b1af7875..751a81f098d 100644 --- a/rostests/winetests/comctl32/button.c +++ b/rostests/winetests/comctl32/button.c @@ -210,6 +210,7 @@ static const struct message setfocus_seq[] = { { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 2 }, + { BM_GETSTATE, sent|optional }, /* when touchscreen is present */ { WM_SETFOCUS, sent|wparam }, { WM_COMMAND, sent|wparam|parent, MAKEWPARAM(ID_BUTTON, BN_SETFOCUS) }, { WM_APP, sent|wparam|lparam }, @@ -232,6 +233,7 @@ static const struct message setfocus_static_seq[] = { { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 2 }, + { BM_GETSTATE, sent|optional }, /* when touchscreen is present */ { WM_SETFOCUS, sent|wparam, 0 }, { WM_COMMAND, sent|wparam|parent, MAKEWPARAM(ID_BUTTON, BN_SETFOCUS) }, { WM_COMMAND, sent|wparam|parent|optional, MAKEWPARAM(ID_BUTTON, BN_CLICKED) }, /* radio button */ @@ -244,6 +246,7 @@ static const struct message setfocus_groupbox_seq[] = { { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 2 }, + { BM_GETSTATE, sent|optional }, /* when touchscreen is present */ { WM_SETFOCUS, sent|wparam, 0 }, { WM_COMMAND, sent|wparam|parent, MAKEWPARAM(ID_BUTTON, BN_SETFOCUS) }, { WM_COMMAND, sent|wparam|parent|optional, MAKEWPARAM(ID_BUTTON, BN_CLICKED) }, /* radio button */ @@ -267,6 +270,7 @@ static const struct message setfocus_ownerdraw_seq[] = { { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 2 }, + { BM_GETSTATE, sent|optional }, /* when touchscreen is present */ { WM_SETFOCUS, sent|wparam, 0 }, { WM_DRAWITEM, sent|wparam|parent, ID_BUTTON }, { WM_COMMAND, sent|wparam|parent, MAKEWPARAM(ID_BUTTON, BN_SETFOCUS) }, @@ -292,6 +296,7 @@ static const struct message lbuttondown_seq[] = { WM_LBUTTONDOWN, sent|wparam|lparam, 0, 0 }, { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 }, { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 2 }, + { BM_GETSTATE, sent|defwinproc|optional }, /* when touchscreen is present */ { WM_SETFOCUS, sent|wparam|defwinproc, 0 }, { BM_SETSTATE, sent|wparam|defwinproc, TRUE }, { 0 } diff --git a/rostests/winetests/comctl32/header.c b/rostests/winetests/comctl32/header.c index 90d4ea15547..976d49368f9 100644 --- a/rostests/winetests/comctl32/header.c +++ b/rostests/winetests/comctl32/header.c @@ -1732,11 +1732,7 @@ static void check_orderarray(HWND hwnd, DWORD start, DWORD set, DWORD expected, for(i = 1; i<=count; i++) array |= order[i-1]<<(4*(count-i)); - if (todo) { - todo_wine - ok_(__FILE__, line)(array == expected, "Expected %x, got %x\n", expected, array); - } - else + todo_wine_if(todo) ok_(__FILE__, line)(array == expected, "Expected %x, got %x\n", expected, array); } diff --git a/rostests/winetests/comctl32/imagelist.c b/rostests/winetests/comctl32/imagelist.c index c0342761499..06b36a9bc9a 100644 --- a/rostests/winetests/comctl32/imagelist.c +++ b/rostests/winetests/comctl32/imagelist.c @@ -44,16 +44,6 @@ #include #include "v6util.h" -#undef VISIBLE - -#ifdef VISIBLE -#define WAIT Sleep (1000) -#define REDRAW(hwnd) RedrawWindow (hwnd, NULL, 0, RDW_UPDATENOW) -#else -#define WAIT -#define REDRAW(hwnd) -#endif - #define IMAGELIST_MAGIC (('L' << 8) | 'I') #include "pshpack2.h" @@ -83,6 +73,16 @@ static HRESULT (WINAPI *pHIMAGELIST_QueryInterface)(HIMAGELIST,REFIID,void **); static HINSTANCE hinst; +/* only used in interactive mode */ +static void force_redraw(HWND hwnd) +{ + if (!winetest_interactive) + return; + + RedrawWindow(hwnd, NULL, 0, RDW_UPDATENOW); + Sleep(1000); +} + /* These macros build cursor/bitmap data in 4x4 pixel blocks */ #define B(x,y) ((x?0xf0:0)|(y?0xf:0)) #define ROW1(a,b,c,d,e,f,g,h) B(a,b),B(c,d),B(e,f),B(g,h) @@ -165,11 +165,11 @@ static HWND create_a_window(void) CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, 0, 0, hinst, 0); -#ifdef VISIBLE - ShowWindow (hWnd, SW_SHOW); -#endif - REDRAW(hWnd); - WAIT; + if (winetest_interactive) + { + ShowWindow (hWnd, SW_SHOW); + force_redraw (hWnd); + } return hWnd; } @@ -177,16 +177,15 @@ static HWND create_a_window(void) static HDC show_image(HWND hwnd, HIMAGELIST himl, int idx, int size, LPCSTR loc, BOOL clear) { - HDC hdc = NULL; -#ifdef VISIBLE - if (!himl) return NULL; + HDC hdc; + + if (!winetest_interactive || !himl) return NULL; - SetWindowText(hwnd, loc); + SetWindowTextA(hwnd, loc); hdc = GetDC(hwnd); ImageList_Draw(himl, idx, hdc, 0, 0, ILD_TRANSPARENT); - REDRAW(hwnd); - WAIT; + force_redraw(hwnd); if (clear) { @@ -194,12 +193,11 @@ static HDC show_image(HWND hwnd, HIMAGELIST himl, int idx, int size, ReleaseDC(hwnd, hdc); hdc = NULL; } -#endif /* VISIBLE */ + return hdc; } /* Useful for checking differences */ -#if 0 static void dump_bits(const BYTE *p, const BYTE *q, int size) { int i, j; @@ -220,18 +218,16 @@ static void dump_bits(const BYTE *p, const BYTE *q, int size) } printf("\n"); } -#endif static void check_bits(HWND hwnd, HIMAGELIST himl, int idx, int size, const BYTE *checkbits, LPCSTR loc) { -#ifdef VISIBLE BYTE bits[100*100/8]; COLORREF c; HDC hdc; int x, y, i = -1; - if (!himl) return; + if (!winetest_interactive || !himl) return; memset(bits, 0, sizeof(bits)); hdc = show_image(hwnd, himl, idx, size, loc, FALSE); @@ -254,7 +250,6 @@ static void check_bits(HWND hwnd, HIMAGELIST himl, int idx, int size, "%s: bits different\n", loc); if (memcmp(bits, checkbits, (size * size)/8)) dump_bits(bits, checkbits, size); -#endif /* VISIBLE */ } static void test_begindrag(void) @@ -507,8 +502,7 @@ static void test_DrawIndirect(void) ok(!pImageList_DrawIndirect(&imldp),"bad himl succeeded!\n"); imldp.himl = himl; - REDRAW(hwndfortest); - WAIT; + force_redraw(hwndfortest); imldp.fStyle = SRCCOPY; imldp.rgbBk = CLR_DEFAULT; @@ -1825,8 +1819,7 @@ if (0) imldp.hdcDst = hdc; imldp.himl = himl; - REDRAW(hwndfortest); - WAIT; + force_redraw(hwndfortest); imldp.fStyle = SRCCOPY; imldp.rgbBk = CLR_DEFAULT; @@ -1975,7 +1968,11 @@ static void test_iconsize(void) static void test_create_destroy(void) { HIMAGELIST himl; + IImageList *imgl; + INT cx, cy; BOOL rc; + HRESULT hr; + INT ret; /* list with zero or negative image dimensions */ himl = ImageList_Create(0, 0, ILC_COLOR16, 0, 3); @@ -1995,6 +1992,46 @@ static void test_create_destroy(void) rc = ImageList_Destroy((HIMAGELIST)0xdeadbeef); ok(rc == FALSE, "ImageList_Destroy(0xdeadbeef) should fail and not crash\n"); + + /* DDB image lists */ + himl = ImageList_Create(0, 14, ILC_COLORDDB, 4, 4); + ok(himl != NULL, "got %p\n", himl); + imgl = (IImageList*)himl; + IImageList_GetIconSize(imgl, &cx, &cy); + ok (cx == 0, "Wrong cx (%i)\n", cx); + ok (cy == 14, "Wrong cy (%i)\n", cy); + ImageList_Destroy(himl); + + himl = ImageList_Create(0, 0, ILC_COLORDDB, 4, 4); + ok(himl != NULL, "got %p\n", himl); + imgl = (IImageList*)himl; + IImageList_GetIconSize(imgl, &cx, &cy); + ok (cx == 0, "Wrong cx (%i)\n", cx); + ok (cy == 0, "Wrong cy (%i)\n", cy); + ImageList_Destroy(himl); + + himl = ImageList_Create(0, 0, ILC_COLORDDB, 0, 4); + ok(himl != NULL, "got %p\n", himl); + imgl = (IImageList*)himl; + IImageList_GetIconSize(imgl, &cx, &cy); + ok (cx == 0, "Wrong cx (%i)\n", cx); + ok (cy == 0, "Wrong cy (%i)\n", cy); + + hr = IImageList_SetImageCount(imgl, 3); + ok(hr == S_OK, "got 0x%08x\n", hr); + hr = IImageList_GetImageCount(imgl, &ret); + ok(hr == S_OK && ret == 3, "invalid image count after increase\n"); + + /* Trying to actually add an image causes a crash on Windows */ + ImageList_Destroy(himl); + + /* Negative values fail */ + himl = ImageList_Create(-1, -1, ILC_COLORDDB, 4, 4); + ok(himl == NULL, "got %p\n", himl); + himl = ImageList_Create(-1, 1, ILC_COLORDDB, 4, 4); + ok(himl == NULL, "got %p\n", himl); + himl = ImageList_Create(1, -1, ILC_COLORDDB, 4, 4); + ok(himl == NULL, "got %p\n", himl); } static void test_IImageList_Clone(void) diff --git a/rostests/winetests/comctl32/listview.c b/rostests/winetests/comctl32/listview.c index 66468bd32e1..67c40c78336 100644 --- a/rostests/winetests/comctl32/listview.c +++ b/rostests/winetests/comctl32/listview.c @@ -201,7 +201,7 @@ static const struct message forward_erasebkgnd_parent_seq[] = { { 0 } }; -static const struct message ownderdata_select_focus_parent_seq[] = { +static const struct message ownerdata_select_focus_parent_seq[] = { { WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED }, { WM_NOTIFY, sent|id, 0, 0, LVN_GETDISPINFOA }, { WM_NOTIFY, sent|id|optional, 0, 0, LVN_GETDISPINFOA }, /* version 4.7x */ @@ -793,16 +793,7 @@ static void test_lvm_hittest_(HWND hwnd, INT x, INT y, INT item, UINT flags, UIN ret = SendMessageA(hwnd, LVM_HITTEST, 0, (LPARAM)&lpht); - if (todo_item) - { - todo_wine - { - ok_(__FILE__, line)(ret == item, "Expected %d retval, got %d\n", item, ret); - ok_(__FILE__, line)(lpht.iItem == item, "Expected %d item, got %d\n", item, lpht.iItem); - ok_(__FILE__, line)(lpht.iSubItem == 10, "Expected subitem not overwrited\n"); - } - } - else + todo_wine_if(todo_item) { ok_(__FILE__, line)(ret == item, "Expected %d retval, got %d\n", item, ret); ok_(__FILE__, line)(lpht.iItem == item, "Expected %d item, got %d\n", item, lpht.iItem); @@ -835,34 +826,16 @@ static void test_lvm_subitemhittest_(HWND hwnd, INT x, INT y, INT item, INT subi ret = SendMessageA(hwnd, LVM_SUBITEMHITTEST, 0, (LPARAM)&lpht); - if (todo_item) - { - todo_wine - { - ok_(__FILE__, line)(ret == item, "Expected %d retval, got %d\n", item, ret); - ok_(__FILE__, line)(lpht.iItem == item, "Expected %d item, got %d\n", item, lpht.iItem); - } - } - else + todo_wine_if(todo_item) { ok_(__FILE__, line)(ret == item, "Expected %d retval, got %d\n", item, ret); ok_(__FILE__, line)(lpht.iItem == item, "Expected %d item, got %d\n", item, lpht.iItem); } - if (todo_subitem) - { - todo_wine - ok_(__FILE__, line)(lpht.iSubItem == subitem, "Expected subitem %d, got %d\n", subitem, lpht.iSubItem); - } - else + todo_wine_if(todo_subitem) ok_(__FILE__, line)(lpht.iSubItem == subitem, "Expected subitem %d, got %d\n", subitem, lpht.iSubItem); - if (todo_flags) - { - todo_wine - ok_(__FILE__, line)(lpht.flags == flags, "Expected flags 0x%x, got 0x%x\n", flags, lpht.flags); - } - else + todo_wine_if(todo_flags) ok_(__FILE__, line)(lpht.flags == flags, "Expected flags 0x%x, got 0x%x\n", flags, lpht.flags); } @@ -3149,7 +3122,7 @@ static void test_ownerdata(void) res = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item); expect(TRUE, res); - ok_sequence(sequences, PARENT_SEQ_INDEX, ownderdata_select_focus_parent_seq, + ok_sequence(sequences, PARENT_SEQ_INDEX, ownerdata_select_focus_parent_seq, "ownerdata select notification", TRUE); flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -3160,7 +3133,7 @@ static void test_ownerdata(void) res = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item); expect(TRUE, res); - ok_sequence(sequences, PARENT_SEQ_INDEX, ownderdata_select_focus_parent_seq, + ok_sequence(sequences, PARENT_SEQ_INDEX, ownerdata_select_focus_parent_seq, "ownerdata focus notification", TRUE); /* select all, check notifications */ @@ -3421,6 +3394,28 @@ static void test_ownerdata(void) style = GetWindowLongPtrA(hwnd, GWL_STYLE); ok(style & LVS_SORTDESCENDING, "Expected LVS_SORTDESCENDING to be set\n"); DestroyWindow(hwnd); + + /* The focused item is updated after the invalidation */ + hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT); + ok(hwnd != NULL, "failed to create a listview window\n"); + res = SendMessageA(hwnd, LVM_SETITEMCOUNT, 3, 0); + expect(TRUE, res); + + memset(&item, 0, sizeof(item)); + item.stateMask = LVIS_FOCUSED; + item.state = LVIS_FOCUSED; + res = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item); + expect(TRUE, res); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + res = SendMessageA(hwnd, LVM_SETITEMCOUNT, 0, 0); + expect(TRUE, res); + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, + "ownerdata setitemcount", FALSE); + + res = SendMessageA(hwnd, LVM_GETNEXTITEM, -1, LVNI_FOCUSED); + expect(-1, res); + DestroyWindow(hwnd); } static void test_norecompute(void) diff --git a/rostests/winetests/comctl32/misc.c b/rostests/winetests/comctl32/misc.c index 95ba1888cd2..8b0781d1fcc 100644 --- a/rostests/winetests/comctl32/misc.c +++ b/rostests/winetests/comctl32/misc.c @@ -368,6 +368,36 @@ static void test_LoadIconWithScaleDown(void) FreeLibrary(hinst); } +static void check_class( const char *name, int must_exist, UINT style, UINT ignore ) +{ + WNDCLASSA wc; + + if (GetClassInfoA( 0, name, &wc )) + { +todo_wine + ok( !(~wc.style & style & ~ignore), "System class %s is missing bits %x (%08x/%08x)\n", + name, ~wc.style & style, wc.style, style ); + ok( !(wc.style & ~style), "System class %s has extra bits %x (%08x/%08x)\n", + name, wc.style & ~style, wc.style, style ); + ok( !wc.hInstance, "System class %s has hInstance %p\n", name, wc.hInstance ); + } + else + ok( !must_exist, "System class %s does not exist\n", name ); +} + +/* test styles of system classes */ +static void test_builtin_classes(void) +{ + /* check style bits */ + check_class( "Button", 1, CS_PARENTDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS, 0 ); + check_class( "ComboBox", 1, CS_PARENTDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS, 0 ); + check_class( "Edit", 1, CS_PARENTDC | CS_DBLCLKS | CS_GLOBALCLASS, 0 ); + check_class( "ListBox", 1, CS_PARENTDC | CS_DBLCLKS | CS_GLOBALCLASS, 0 ); + check_class( "ScrollBar", 1, CS_PARENTDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS, 0 ); + check_class( "Static", 1, CS_PARENTDC | CS_DBLCLKS | CS_GLOBALCLASS, 0 ); + check_class( "ComboLBox", 1, CS_SAVEBITS | CS_DBLCLKS | CS_DROPSHADOW | CS_GLOBALCLASS, CS_DROPSHADOW ); +} + START_TEST(misc) { ULONG_PTR ctx_cookie; @@ -382,6 +412,7 @@ START_TEST(misc) if (!load_v6_module(&ctx_cookie, &hCtx)) return; + test_builtin_classes(); test_TaskDialogIndirect(); test_LoadIconWithScaleDown(); diff --git a/rostests/winetests/comctl32/monthcal.c b/rostests/winetests/comctl32/monthcal.c index 4653f52ca10..5367af177eb 100644 --- a/rostests/winetests/comctl32/monthcal.c +++ b/rostests/winetests/comctl32/monthcal.c @@ -1185,14 +1185,9 @@ if (0) if (sizeof(title_hits) / sizeof(title_hits[0]) <= title_index) break; - if (title_hits[title_index].todo) { - todo_wine + todo_wine_if(title_hits[title_index].todo) ok(title_hits[title_index].ht == res, "Expected %x, got %x, pos %d\n", title_hits[title_index].ht, res, x); - } else { - ok(title_hits[title_index].ht == res, "Expected %x, got %x, pos %d\n", - title_hits[title_index].ht, res, x); - } } old_res = res; } diff --git a/rostests/winetests/comctl32/propsheet.c b/rostests/winetests/comctl32/propsheet.c index 6383890715f..e942a23d927 100644 --- a/rostests/winetests/comctl32/propsheet.c +++ b/rostests/winetests/comctl32/propsheet.c @@ -935,7 +935,7 @@ if (0) ret = SendMessageA(hdlg, PSM_INSERTPAGE, 0, (LPARAM)INVALID_HANDLE_VALUE); } - ret = SendMessageA(hdlg, PSM_INSERTPAGE, (LPARAM)INVALID_HANDLE_VALUE, (LPARAM)hpsp[2]); + ret = SendMessageA(hdlg, PSM_INSERTPAGE, (WPARAM)INVALID_HANDLE_VALUE, (LPARAM)hpsp[2]); ok(ret == FALSE, "got %d\n", ret); /* check item count */ diff --git a/rostests/winetests/comctl32/tooltips.c b/rostests/winetests/comctl32/tooltips.c index 4c0c7dfb1b8..886f501b6b3 100644 --- a/rostests/winetests/comctl32/tooltips.c +++ b/rostests/winetests/comctl32/tooltips.c @@ -450,6 +450,33 @@ static void test_gettext(void) r = SendMessageW(hwnd, TTM_ADDTOOLW, 0, (LPARAM)&toolinfoW); ok(!r, "Adding the tool to the tooltip succeeded!\n"); + /* lpszText with an invalid address */ + toolinfoW.cbSize = sizeof(TTTOOLINFOW); + toolinfoW.hwnd = notify; + toolinfoW.hinst = GetModuleHandleA(NULL); + toolinfoW.uFlags = 0; + toolinfoW.uId = 0; + toolinfoW.lpszText = (LPWSTR)0xdeadbeef; + toolinfoW.lParam = 0; + GetClientRect(hwnd, &toolinfoW.rect); + r = SendMessageA(hwnd, TTM_ADDTOOLW, 0, (LPARAM)&toolinfoW); + ok(!r, "Adding the tool to the tooltip succeeded!\n"); + + /* lpszText with an invalid address. Crashes using TTTOOLINFOA message */ + if(0) + { + toolinfoA.cbSize = sizeof(TTTOOLINFOA); + toolinfoA.hwnd = notify; + toolinfoA.hinst = GetModuleHandleA(NULL); + toolinfoA.uFlags = 0; + toolinfoA.uId = 0; + toolinfoA.lpszText = (LPSTR)0xdeadbeef; + toolinfoA.lParam = 0; + GetClientRect(hwnd, &toolinfoA.rect); + r = SendMessageA(hwnd, TTM_ADDTOOLA, 0, (LPARAM)&toolinfoA); + ok(!r, "Adding the tool to the tooltip succeeded!\n"); + } + if (0) /* crashes on NT4 */ { toolinfoW.hwnd = NULL; diff --git a/rostests/winetests/comctl32/trackbar.c b/rostests/winetests/comctl32/trackbar.c index f49c27d1737..07407274878 100644 --- a/rostests/winetests/comctl32/trackbar.c +++ b/rostests/winetests/comctl32/trackbar.c @@ -32,8 +32,19 @@ #define PARENT_SEQ_INDEX 0 #define TRACKBAR_SEQ_INDEX 1 +static const DWORD defaultstyle = WS_VISIBLE | TBS_TOOLTIPS | TBS_ENABLESELRANGE | TBS_FIXEDLENGTH | TBS_AUTOTICKS; static HWND hWndParent; +static LRESULT WINAPI trackbar_no_wmpaint_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); + + if (message == WM_PAINT) + return 0; + + return CallWindowProcA(oldproc, hwnd, message, wParam, lParam); +} + static struct msg_sequence *sequences[NUM_MSG_SEQUENCE]; static const struct message empty_seq[] = { @@ -467,14 +478,27 @@ static HWND create_trackbar(DWORD style, HWND parent){ return hWndTrack; } +static HWND create_trackbar2(DWORD style, HWND parent) +{ + RECT rect; + GetClientRect(parent, &rect); + return CreateWindowA(TRACKBAR_CLASSA, "Trackbar Control", style, + rect.right, rect.bottom, 100, 50, + parent, NULL, GetModuleHandleA(NULL), NULL); +} + /* test functions for setters, getters, and sequences */ -static void test_trackbar_buddy(HWND hWndTrackbar){ - HWND hWndLeftBuddy; +static void test_trackbar_buddy(void) +{ + HWND hWndLeftBuddy, hWndTrackbar; HWND hWndRightBuddy; HWND hWndCurrentBuddy; HWND rTest; + hWndTrackbar = create_trackbar(defaultstyle, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + flush_sequences(sequences, NUM_MSG_SEQUENCE); hWndLeftBuddy = CreateWindowA(STATUSCLASSNAMEA, NULL, 0, 0, 0, 300, 20, NULL, NULL, NULL, NULL); @@ -518,11 +542,17 @@ static void test_trackbar_buddy(HWND hWndTrackbar){ ok_sequence(sequences, TRACKBAR_SEQ_INDEX, buddy_window_test_seq, "buddy test sequence", TRUE); ok_sequence(sequences, PARENT_SEQ_INDEX, parent_buddy_window_test_seq, "parent buddy test seq", TRUE); + DestroyWindow(hWndTrackbar); } -static void test_line_size(HWND hWndTrackbar){ +static void test_line_size(void) +{ + HWND hWndTrackbar; int r; + hWndTrackbar = create_trackbar(defaultstyle, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + flush_sequences(sequences, NUM_MSG_SEQUENCE); /* test TBM_SETLINESIZE */ @@ -537,12 +567,19 @@ static void test_line_size(HWND hWndTrackbar){ ok_sequence(sequences, TRACKBAR_SEQ_INDEX, line_size_test_seq, "linesize test sequence", FALSE); ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "parent line test sequence", FALSE); + + DestroyWindow(hWndTrackbar); } -static void test_page_size(HWND hWndTrackbar){ +static void test_page_size(void) +{ + HWND hWndTrackbar; int r; + hWndTrackbar = create_trackbar(defaultstyle, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + flush_sequences(sequences, NUM_MSG_SEQUENCE); /* test TBM_SETPAGESIZE */ @@ -573,12 +610,22 @@ static void test_page_size(HWND hWndTrackbar){ expect(20, r); r = SendMessageA(hWndTrackbar, TBM_GETPAGESIZE, 0, 0); expect(-2, r); + + DestroyWindow(hWndTrackbar); } -static void test_position(HWND hWndTrackbar){ +static void test_position(void) +{ + HWND hWndTrackbar; + RECT rect, rect2; + WNDPROC oldproc; int r; + hWndTrackbar = create_trackbar(defaultstyle, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + flush_sequences(sequences, NUM_MSG_SEQUENCE); + /* test TBM_SETPOS */ SendMessageA(hWndTrackbar, TBM_SETPOS, TRUE, -1); r = SendMessageA(hWndTrackbar, TBM_GETPOS, 0, 0); @@ -601,12 +648,55 @@ static void test_position(HWND hWndTrackbar){ ok_sequence(sequences, TRACKBAR_SEQ_INDEX, position_test_seq, "position test sequence", TRUE); ok_sequence(sequences, PARENT_SEQ_INDEX, parent_position_test_seq, "parent position test sequence", TRUE); + + DestroyWindow(hWndTrackbar); + + hWndTrackbar = create_trackbar2(defaultstyle, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + + /* subclassing procedure blocks WM_PAINT */ + oldproc = (WNDPROC)SetWindowLongPtrA(hWndTrackbar, GWLP_WNDPROC, (LONG_PTR)trackbar_no_wmpaint_proc); + SetWindowLongPtrA(hWndTrackbar, GWLP_USERDATA, (LONG_PTR)oldproc); + + memset(&rect, 0, sizeof(rect)); + memset(&rect2, 0, sizeof(rect2)); + + SendMessageA(hWndTrackbar, TBM_GETTHUMBRECT, 0, (LPARAM)&rect); + + /* without repaint */ + SendMessageA(hWndTrackbar, TBM_SETPOS, FALSE, 25); + r = SendMessageA(hWndTrackbar, TBM_GETPOS, 0, 0); + ok(r == 25, "got %d\n", r); + SendMessageA(hWndTrackbar, TBM_GETTHUMBRECT, 0, (LPARAM)&rect2); + ok(rect.left == rect2.left, "got %d\n", rect.left); + + /* with repaint */ + SendMessageA(hWndTrackbar, TBM_SETPOS, TRUE, 30); + r = SendMessageA(hWndTrackbar, TBM_GETPOS, 0, 0); + ok(r == 30, "got %d\n", r); + SendMessageA(hWndTrackbar, TBM_GETTHUMBRECT, 0, (LPARAM)&rect2); + ok(rect.left != rect2.left, "got %d, expected %d\n", rect2.left, rect.left); + + /* now move it with keys */ + SendMessageA(hWndTrackbar, WM_KEYDOWN, VK_END, 0); + r = SendMessageA(hWndTrackbar, TBM_GETPOS, 0, 0); + ok(r == 100, "got %d\n", r); + SendMessageA(hWndTrackbar, TBM_GETTHUMBRECT, 0, (LPARAM)&rect); + ok(rect.left != rect2.left, "got %d, expected %d\n", rect.left, rect2.left); + + DestroyWindow(hWndTrackbar); } -static void test_range(HWND hWndTrackbar){ +static void test_range(void) +{ + HWND hWndTrackbar; int r; + hWndTrackbar = create_trackbar(defaultstyle, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + flush_sequences(sequences, NUM_MSG_SEQUENCE); + /* test TBM_SETRANGE */ SendMessageA(hWndTrackbar, TBM_SETRANGE, TRUE, MAKELONG(0, 10)); r = SendMessageA(hWndTrackbar, TBM_GETRANGEMAX, 0,0); @@ -664,12 +754,23 @@ static void test_range(HWND hWndTrackbar){ ok_sequence(sequences, TRACKBAR_SEQ_INDEX, range_test_seq, "range test sequence", TRUE); ok_sequence(sequences, PARENT_SEQ_INDEX, parent_range_test_seq, "parent range test sequence", TRUE); + + DestroyWindow(hWndTrackbar); } -static void test_selection(HWND hWndTrackbar){ +static void test_selection(void) +{ + HWND hWndTrackbar; int r; + hWndTrackbar = create_trackbar(defaultstyle, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + + SendMessageA(hWndTrackbar, TBM_SETRANGEMIN, FALSE, 5); + SendMessageA(hWndTrackbar, TBM_SETRANGEMAX, FALSE, 10); + flush_sequences(sequences, NUM_MSG_SEQUENCE); + /* test TBM_SETSEL */ SendMessageA(hWndTrackbar, TBM_SETSEL, TRUE, MAKELONG(0,10)); r = SendMessageA(hWndTrackbar, TBM_GETSELEND, 0,0); @@ -725,12 +826,20 @@ static void test_selection(HWND hWndTrackbar){ ok_sequence(sequences, TRACKBAR_SEQ_INDEX, selection_test_seq, "selection test sequence", TRUE); ok_sequence(sequences, PARENT_SEQ_INDEX, parent_selection_test_seq, "parent selection test sequence", TRUE); + + DestroyWindow(hWndTrackbar); } -static void test_thumb_length(HWND hWndTrackbar){ +static void test_thumb_length(void) +{ + HWND hWndTrackbar; int r; + hWndTrackbar = create_trackbar(defaultstyle, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + flush_sequences(sequences, NUM_MSG_SEQUENCE); + /* testing TBM_SETTHUMBLENGTH */ SendMessageA(hWndTrackbar, TBM_SETTHUMBLENGTH, 15, 0); r = SendMessageA(hWndTrackbar, TBM_GETTHUMBLENGTH, 0,0); @@ -754,11 +863,21 @@ static void test_thumb_length(HWND hWndTrackbar){ ok_sequence(sequences, TRACKBAR_SEQ_INDEX, thumb_length_test_seq, "thumb length test sequence", TRUE); ok_sequence(sequences, PARENT_SEQ_INDEX, parent_thumb_length_test_seq, "parent thumb length test sequence", TRUE); + + DestroyWindow(hWndTrackbar); } -static void test_tic_settings(HWND hWndTrackbar){ +static void test_tic_settings(void) +{ + HWND hWndTrackbar; int r; + hWndTrackbar = create_trackbar(defaultstyle, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + + SendMessageA(hWndTrackbar, TBM_SETRANGEMIN, FALSE, 5); + SendMessageA(hWndTrackbar, TBM_SETRANGEMAX, FALSE, 10); + /* testing TBM_SETTIC */ /* Set tics at 5 and 10 */ /* 0 and 20 are out of range and should not be set */ @@ -818,11 +937,16 @@ static void test_tic_settings(HWND hWndTrackbar){ expect(3, r); } -static void test_tic_placement(HWND hWndTrackbar){ +static void test_tic_placement(void) +{ + HWND hWndTrackbar; int r; DWORD *rPTics; DWORD numtics; + hWndTrackbar = create_trackbar(defaultstyle, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + SendMessageA(hWndTrackbar, TBM_SETRANGE, TRUE, MAKELONG(1, 6)); SendMessageA(hWndTrackbar, TBM_SETTICFREQ, 1, 0); @@ -853,15 +977,21 @@ static void test_tic_placement(HWND hWndTrackbar){ ok_sequence(sequences, TRACKBAR_SEQ_INDEX, tic_placement_test_seq, "get tic placement test sequence", FALSE); ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "parent get tic placement test sequence", FALSE); -} + DestroyWindow(hWndTrackbar); +} -static void test_tool_tips(HWND hWndTrackbar){ - int r; - HWND hWndTooltip; +static void test_tool_tips(void) +{ + HWND hWndTooltip, hWndTrackbar; HWND rTest; + int r; + + hWndTrackbar = create_trackbar(defaultstyle, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); flush_sequences(sequences, NUM_MSG_SEQUENCE); + /* testing TBM_SETTIPSIDE */ r = SendMessageA(hWndTrackbar, TBM_SETTIPSIDE, TBTS_TOP, 0); expect(TBTS_TOP, r); @@ -897,13 +1027,21 @@ static void test_tool_tips(HWND hWndTrackbar){ ok_sequence(sequences, TRACKBAR_SEQ_INDEX, tool_tips_test_seq, "tool tips test sequence", FALSE); ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "parent tool tips test sequence", FALSE); + + DestroyWindow(hWndTrackbar); } -static void test_unicode(HWND hWndTrackbar){ +static void test_unicode(void) +{ + HWND hWndTrackbar; int r; + hWndTrackbar = create_trackbar(defaultstyle, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + flush_sequences(sequences, NUM_MSG_SEQUENCE); + /* testing TBM_SETUNICODEFORMAT */ r = SendMessageA(hWndTrackbar, TBM_SETUNICODEFORMAT, TRUE, 0); ok(r == FALSE, "Expected FALSE, got %d\n",r); @@ -916,11 +1054,18 @@ static void test_unicode(HWND hWndTrackbar){ ok_sequence(sequences, TRACKBAR_SEQ_INDEX, unicode_test_seq, "unicode test sequence", FALSE); ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "parent unicode test sequence", FALSE); + + DestroyWindow(hWndTrackbar); } -static void test_ignore_selection(HWND hWndTrackbar){ +static void test_ignore_selection(void) +{ + HWND hWndTrackbar; int r; + hWndTrackbar = create_trackbar(0, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + flush_sequences(sequences, NUM_MSG_SEQUENCE); /* test TBM_SETSEL ensure that it is ignored */ SendMessageA(hWndTrackbar, TBM_SETSEL, TRUE, MAKELONG(0,10)); @@ -958,6 +1103,8 @@ static void test_ignore_selection(HWND hWndTrackbar){ ok_sequence(sequences, TRACKBAR_SEQ_INDEX, ignore_selection_test_seq, "ignore selection setting test sequence", FALSE); ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "parent ignore selection setting test sequence", FALSE); + + DestroyWindow(hWndTrackbar); } static void test_initial_state(void) @@ -1037,72 +1184,55 @@ static void test_TBS_AUTOTICKS(void) DestroyWindow(hWnd); } -START_TEST(trackbar) +static void test_create(void) { - DWORD style = WS_VISIBLE | TBS_TOOLTIPS | TBS_ENABLESELRANGE | TBS_FIXEDLENGTH | TBS_AUTOTICKS; HWND hWndTrackbar; - init_msg_sequences(sequences, NUM_MSG_SEQUENCE); - InitCommonControls(); - - /* create parent window */ - hWndParent = create_parent_window(); - ok(hWndParent != NULL, "Failed to create parent Window!\n"); - - if(!hWndParent){ - skip("parent window not present\n"); - return; - } - flush_sequences(sequences, NUM_MSG_SEQUENCE); - /* create trackbar with set styles */ - hWndTrackbar = create_trackbar(style, hWndParent); - + hWndTrackbar = create_trackbar(defaultstyle, hWndParent); ok(hWndTrackbar != NULL, "Expected non NULL value\n"); - - if (!hWndTrackbar){ - skip("trackbar control not present?\n"); - return; - } - ok_sequence(sequences, TRACKBAR_SEQ_INDEX, empty_seq, "create Trackbar Window", FALSE); ok_sequence(sequences, PARENT_SEQ_INDEX, parent_create_trackbar_wnd_seq, "parent trackbar window", TRUE); - flush_sequences(sequences, NUM_MSG_SEQUENCE); - /* TEST OF ALL SETTER and GETTER MESSAGES with required styles turned on*/ - test_trackbar_buddy(hWndTrackbar); - test_line_size(hWndTrackbar); - test_page_size(hWndTrackbar); - test_position(hWndTrackbar); - test_range(hWndTrackbar); - test_selection(hWndTrackbar); - test_thumb_length(hWndTrackbar); - test_tic_settings(hWndTrackbar); - test_tic_placement(hWndTrackbar); - test_tool_tips(hWndTrackbar); - test_unicode(hWndTrackbar); - test_TBS_AUTOTICKS(); + DestroyWindow(hWndTrackbar); + /* no style bits */ flush_sequences(sequences, NUM_MSG_SEQUENCE); + hWndTrackbar = create_trackbar(0, hWndParent); + ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + ok_sequence(sequences, PARENT_SEQ_INDEX, parent_new_window_test_seq, "new trackbar window test sequence", TRUE); DestroyWindow(hWndTrackbar); +} - /* test getters and setters without styles set */ - hWndTrackbar = create_trackbar(0, hWndParent); +START_TEST(trackbar) +{ + init_msg_sequences(sequences, NUM_MSG_SEQUENCE); + InitCommonControls(); - ok(hWndTrackbar != NULL, "Expected non NULL value\n"); + /* create parent window */ + hWndParent = create_parent_window(); + ok(hWndParent != NULL, "Failed to create parent Window!\n"); - if (!hWndTrackbar){ - skip("trackbar control not present?\n"); + if(!hWndParent){ + skip("parent window not present\n"); return; } - ok_sequence(sequences, PARENT_SEQ_INDEX, parent_new_window_test_seq, "new trackbar window test sequence", TRUE); - - test_ignore_selection(hWndTrackbar); - - DestroyWindow(hWndTrackbar); - + test_create(); + test_trackbar_buddy(); + test_line_size(); + test_page_size(); + test_position(); + test_range(); + test_selection(); + test_thumb_length(); + test_tic_settings(); + test_tic_placement(); + test_tool_tips(); + test_unicode(); + test_TBS_AUTOTICKS(); + test_ignore_selection(); test_initial_state(); DestroyWindow(hWndParent); diff --git a/rostests/winetests/comctl32/treeview.c b/rostests/winetests/comctl32/treeview.c index 3d46aa83596..f1c227e869a 100644 --- a/rostests/winetests/comctl32/treeview.c +++ b/rostests/winetests/comctl32/treeview.c @@ -1193,7 +1193,9 @@ static LRESULT CALLBACK parent_wnd_proc(HWND hWnd, UINT message, WPARAM wParam, case TVN_ENDLABELEDITA: return TRUE; case TVN_ITEMEXPANDINGA: - ok(pTreeView->itemNew.mask == + { + UINT newmask = pTreeView->itemNew.mask & ~TVIF_CHILDREN; + ok(newmask == (TVIF_HANDLE | TVIF_SELECTEDIMAGE | TVIF_IMAGE | TVIF_PARAM | TVIF_STATE), "got wrong mask %x\n", pTreeView->itemNew.mask); ok(pTreeView->itemOld.mask == 0, @@ -1207,6 +1209,7 @@ static LRESULT CALLBACK parent_wnd_proc(HWND hWnd, UINT message, WPARAM wParam, ok(ret == TRUE, "got %lu\n", ret); } break; + } case TVN_ITEMEXPANDEDA: ok(pTreeView->itemNew.mask & TVIF_STATE, "got wrong mask %x\n", pTreeView->itemNew.mask); ok(pTreeView->itemNew.state & (TVIS_EXPANDED|TVIS_EXPANDEDONCE), @@ -1529,6 +1532,7 @@ static void test_get_insertmarkcolor(void) static void test_expandnotify(void) { + HTREEITEM hitem; HWND hTree; BOOL ret; TVITEMA item; @@ -1679,6 +1683,22 @@ static void test_expandnotify(void) expect(FALSE, ret); ok_sequence(sequences, PARENT_SEQ_INDEX, parent_expand_empty_kb_seq, "expand node with no children", FALSE); + /* stay on current selection and set non-zero children count */ + hitem = (HTREEITEM)SendMessageA(hTree, TVM_GETNEXTITEM, TVGN_CARET, 0); + ok(hitem != NULL, "got %p\n", hitem); + + item.hItem = hitem; + item.mask = TVIF_CHILDREN; + item.cChildren = 0x80000000; + + ret = SendMessageA(hTree, TVM_SETITEMA, 0, (LPARAM)&item); + expect(TRUE, ret); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + ret = SendMessageA(hTree, WM_KEYDOWN, VK_ADD, 0); + expect(FALSE, ret); + ok_sequence(sequences, PARENT_SEQ_INDEX, parent_collapse_2nd_kb_seq, "expand node with children", FALSE); + DestroyWindow(hTree); } @@ -1858,8 +1878,13 @@ static void test_delete_items(void) { const struct message *msg; HWND hTree; + HTREEITEM hItem1, hItem2; + TVINSERTSTRUCTA ins; INT ret; + static CHAR item1[] = "Item 1"; + static CHAR item2[] = "Item 2"; + hTree = create_treeview_control(0); fill_tree(hTree); @@ -1881,6 +1906,34 @@ static void test_delete_items(void) ok(ret == 0, "got %d\n", ret); DestroyWindow(hTree); + + /* Regression test for a crash when deleting the first visible item while bRedraw == false. */ + hTree = create_treeview_control(0); + + ret = SendMessageA(hTree, WM_SETREDRAW, FALSE, 0); + ok(ret == 0, "got %d\n", ret); + + ins.hParent = TVI_ROOT; + ins.hInsertAfter = TVI_ROOT; + U(ins).item.mask = TVIF_TEXT; + U(ins).item.pszText = item1; + hItem1 = TreeView_InsertItemA(hTree, &ins); + ok(hItem1 != NULL, "InsertItem failed\n"); + + ins.hParent = TVI_ROOT; + ins.hInsertAfter = hItem1; + U(ins).item.mask = TVIF_TEXT; + U(ins).item.pszText = item2; + hItem2 = TreeView_InsertItemA(hTree, &ins); + ok(hItem2 != NULL, "InsertItem failed\n"); + + ret = SendMessageA(hTree, TVM_DELETEITEM, 0, (LPARAM)hItem1); + ok(ret == TRUE, "got %d\n", ret); + + ret = SendMessageA(hTree, WM_SETREDRAW, TRUE, 0); + ok(ret == 0, "got %d\n", ret); + + DestroyWindow(hTree); } static void test_cchildren(void) -- 2.17.1