[COMCTL32_WINETEST] Sync with Wine Staging 2.9. CORE-13362

svn path=/trunk/; revision=74903
This commit is contained in:
Amine Khaldi 2017-06-04 12:53:30 +00:00
parent b44a9ed6f6
commit afc72d800f
21 changed files with 700 additions and 90 deletions

View file

@ -24,6 +24,7 @@ list(APPEND SOURCE
subclass.c
syslink.c
tab.c
taskdialog.c
toolbar.c
tooltips.c
trackbar.c

View file

@ -160,8 +160,9 @@ static void test_play(void)
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);

View file

@ -124,8 +124,8 @@ static BOOL ignore_message( UINT message )
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 LRESULT WINAPI test_parent_wndproc(HWND hwnd, UINT message, WPARAM wParam
{
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 @@ static LRESULT WINAPI test_parent_wndproc(HWND hwnd, UINT message, WPARAM wParam
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;

View file

@ -90,8 +90,8 @@ static LRESULT WINAPI editbox_subclass_proc(HWND hwnd, UINT message, WPARAM wPar
{
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;

View file

@ -142,15 +142,14 @@ static LRESULT WINAPI datetime_subclass_proc(HWND hwnd, UINT message, WPARAM wPa
{
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++;

View file

@ -394,7 +394,7 @@ static char pszOutOfRangeItem[] = "Out Of Range Item";
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 @@ static LRESULT WINAPI header_subclass_proc(HWND hwnd, UINT message, WPARAM wPara
{
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 @@ static void test_header_order (void)
{
hdi.lParam = i;
SendMessageA(hWndHeader, HDM_INSERTITEMA, rand1[i], (LPARAM)&hdi);
rand();
}
check_order(ids1, ord1, 5, "insert without iOrder");
@ -1582,7 +1580,6 @@ static void test_header_order (void)
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 @@ static void test_header_order (void)
{
hdi.iOrder = rand5[i];
SendMessageA(hWndHeader, HDM_SETITEMA, rand4[i], (LPARAM)&hdi);
rand(); rand();
}
check_order(ids2, ord3, 10, "setitems changing order");

View file

@ -922,36 +922,34 @@ static void check_iml_data(HIMAGELIST himl, INT cx, INT cy, INT cur, INT max, IN
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 @@ static void check_iml_data(HIMAGELIST himl, INT cx, INT cy, INT cur, INT max, IN
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 @@ static void test_color_table(UINT ilc)
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 @@ START_TEST(imagelist)
test_iconsize();
test_color_table(ILC_COLOR4);
test_color_table(ILC_COLOR8);
test_copy();
FreeLibrary(hComCtl32);

View file

@ -710,8 +710,8 @@ static LRESULT WINAPI header_subclass_proc(HWND hwnd, UINT message, WPARAM wPara
{
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 @@ static LRESULT WINAPI editbox_subclass_proc(HWND hwnd, UINT message, WPARAM wPar
{
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 @@ static void test_finditem(void)
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,12 +5129,22 @@ static void test_finditem(void)
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);
DestroyWindow(hwnd);
}
@ -5549,6 +5576,43 @@ static void test_LVM_SETITEMTEXT(void)
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)
{
HWND hwnd, header;
@ -5923,6 +5987,7 @@ START_TEST(listview)
test_createdragimage();
test_dispinfo();
test_LVM_SETITEMTEXT();
test_LVM_REDRAWITEMS();
test_imagelists();
test_deleteitem();
test_insertitem();

View file

@ -202,29 +202,6 @@ static void test_Alloc(void)
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 @@ START_TEST(misc)
return;
test_builtin_classes();
test_TaskDialogIndirect();
test_LoadIconWithScaleDown();
unload_v6_module(ctx_cookie, hCtx);

View file

@ -624,15 +624,14 @@ static LRESULT WINAPI monthcal_subclass_proc(HWND hwnd, UINT message, WPARAM wPa
{
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 */

View file

@ -371,7 +371,7 @@ static void ok_sequence_(struct msg_sequence **seq, int sequence_index,
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);

View file

@ -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 @@ static const struct message set_child_seq[] = {
{ 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 @@ static const struct message set_pos_seq[] = {
{ 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 HWND create_parent_window(void)
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 @@ static HWND create_pager_control( DWORD style )
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,16 +265,36 @@ static void test_pager(void)
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 );
ok_sequence(sequences, PAGER_SEQ_INDEX, set_pos_seq, "set pos", TRUE);

View file

@ -713,7 +713,7 @@ static const struct message property_sheet_seq[] = {
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 @@ if (0)
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 @@ START_TEST(propsheet)
test_messages();
test_PSM_ADDPAGE();
test_PSM_INSERTPAGE();
test_CreatePropertySheetPage();
}

View file

@ -146,15 +146,14 @@ static WNDPROC syslink_oldproc;
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++;

View file

@ -304,8 +304,8 @@ create_tabcontrol (DWORD style, DWORD mask)
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 @@ static LRESULT WINAPI parentWindowProcess(HWND hwnd, UINT message, WPARAM wParam
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 @@ static LRESULT WINAPI tabSubclassProcess(HWND hwnd, UINT message, WPARAM wParam,
{
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 @@ static LRESULT WINAPI tabSubclassProcess(HWND hwnd, UINT message, WPARAM wParam,
if (defwndproc_counter) msg.flags |= defwinproc;
msg.wParam = wParam;
msg.lParam = lParam;
msg.id = 0;
add_message(sequences, TAB_SEQ_INDEX, &msg);
}

View file

@ -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);
}

View file

@ -23,6 +23,7 @@ extern void func_status(void);
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 @@ const struct test winetest_testlist[] =
{ "subclass", func_subclass },
{ "syslink", func_syslink },
{ "tab", func_tab },
{ "taskdialog", func_taskdialog },
{ "toolbar", func_toolbar },
{ "tooltips", func_tooltips },
{ "trackbar", func_trackbar },

View file

@ -2276,7 +2276,8 @@ static void test_save(void)
{
HWND wnd = NULL;
TBSAVEPARAMSW params;
static const WCHAR subkey[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','T','e','s','t',0};
static const WCHAR 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;

View file

@ -442,15 +442,14 @@ static HWND create_parent_window(void){
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++;

View file

@ -54,6 +54,21 @@ static BOOL g_v6;
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 },
{ TVM_INSERTITEMA, sent },
@ -201,6 +216,13 @@ static const struct message test_get_set_unicodeformat_seq[] = {
{ 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 },
@ -342,6 +364,12 @@ static const struct message parent_vk_return_seq[] = {
{ 0 }
};
static const struct message parent_right_click_seq[] = {
{ WM_NOTIFY, sent|id, 0, 0, NM_RCLICK },
{ WM_CONTEXTMENU, sent },
{ 0 }
};
static HWND hMainWnd;
static HTREEITEM hRoot, hChild;
@ -383,15 +411,14 @@ static LRESULT WINAPI TreeviewWndProc(HWND hwnd, UINT message, WPARAM wParam, LP
{
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 void test_get_set_unicodeformat(void)
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 @@ static LRESULT CALLBACK parent_wnd_proc(HWND hWnd, UINT message, WPARAM wParam,
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 &&
@ -1299,6 +1324,13 @@ static LRESULT CALLBACK parent_wnd_proc(HWND hWnd, UINT message, WPARAM wParam,
}
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;
}
}
}
break;
@ -2397,6 +2429,238 @@ static void test_TVS_FULLROWSELECT(void)
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)
{
HMODULE hComctl32;
@ -2473,6 +2737,8 @@ START_TEST(treeview)
test_customdraw();
test_WM_KEYDOWN();
test_TVS_FULLROWSELECT();
test_TVM_SORTCHILDREN();
test_right_click();
if (!load_v6_module(&ctx_cookie, &hCtx))
{

View file

@ -169,8 +169,8 @@ static const struct message test_updown_pos_nochange_seq[] = {
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 @@ static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LP
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 @@ static LRESULT WINAPI edit_subclass_proc(HWND hwnd, UINT message, WPARAM wParam,
{
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 @@ static LRESULT WINAPI updown_subclass_proc(HWND hwnd, UINT message, WPARAM wPara
{
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;