mirror of
https://github.com/reactos/reactos.git
synced 2024-06-30 09:50:07 +00:00
[COMCTL32_WINETEST] Sync with Wine Staging 4.0. CORE-15682
This commit is contained in:
parent
07f4be3faf
commit
5f7243b577
|
@ -20,7 +20,9 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifdef __REACTOS__
|
||||
#undef USE_WINE_TODOS
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
|
@ -29,11 +31,18 @@
|
|||
#include "v6util.h"
|
||||
#include "msg.h"
|
||||
|
||||
#ifdef __REACTOS__
|
||||
#define BS_PUSHBOX 0x0000000AL
|
||||
#endif
|
||||
|
||||
#define IS_WNDPROC_HANDLE(x) (((ULONG_PTR)(x) >> 16) == (~0u >> 16))
|
||||
|
||||
static BOOL (WINAPI *pSetWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR, DWORD_PTR);
|
||||
static BOOL (WINAPI *pRemoveWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR);
|
||||
static LRESULT (WINAPI *pDefSubclassProc)(HWND, UINT, WPARAM, LPARAM);
|
||||
static HIMAGELIST (WINAPI *pImageList_Create)(int, int, UINT, int, int);
|
||||
static int (WINAPI *pImageList_Add)(HIMAGELIST, HBITMAP, HBITMAP);
|
||||
static BOOL (WINAPI *pImageList_Destroy)(HIMAGELIST);
|
||||
|
||||
/****************** button message test *************************/
|
||||
#define ID_BUTTON 0x000e
|
||||
|
@ -78,6 +87,12 @@ static void init_functions(void)
|
|||
MAKEFUNC_ORD(RemoveWindowSubclass, 412);
|
||||
MAKEFUNC_ORD(DefSubclassProc, 413);
|
||||
#undef MAKEFUNC_ORD
|
||||
|
||||
#define X(f) p##f = (void *)GetProcAddress(hmod, #f);
|
||||
X(ImageList_Create);
|
||||
X(ImageList_Add);
|
||||
X(ImageList_Destroy);
|
||||
#undef X
|
||||
}
|
||||
|
||||
/* try to make sure pending X events have been processed before continuing */
|
||||
|
@ -550,15 +565,15 @@ static void test_button_messages(void)
|
|||
hfont2 = CreateFontIndirectA(&logfont);
|
||||
ok(hfont2 != NULL, "Failed to create Tahoma font\n");
|
||||
|
||||
for (i = 0; i < sizeof(button)/sizeof(button[0]); i++)
|
||||
for (i = 0; i < ARRAY_SIZE(button); i++)
|
||||
{
|
||||
HFONT prevfont, hfont;
|
||||
MSG msg;
|
||||
DWORD style, state;
|
||||
HDC hdc;
|
||||
|
||||
trace("%d: button test sequence\n", i);
|
||||
hwnd = create_button(button[i].style, parent);
|
||||
ok(hwnd != NULL, "Failed to create a button.\n");
|
||||
|
||||
style = GetWindowLongA(hwnd, GWL_STYLE);
|
||||
style &= ~(WS_CHILD | BS_NOTIFY);
|
||||
|
@ -807,6 +822,395 @@ static void test_button_class(void)
|
|||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
static void test_note(void)
|
||||
{
|
||||
HWND hwnd;
|
||||
BOOL ret;
|
||||
WCHAR test_w[] = {'t', 'e', 's', 't', 0};
|
||||
WCHAR tes_w[] = {'t', 'e', 's', 0};
|
||||
WCHAR deadbeef_w[] = {'d', 'e', 'a', 'd', 'b', 'e', 'e', 'f', 0};
|
||||
WCHAR buffer_w[10];
|
||||
DWORD size;
|
||||
DWORD error;
|
||||
INT type;
|
||||
|
||||
hwnd = create_button(BS_COMMANDLINK, NULL);
|
||||
ok(hwnd != NULL, "Expect hwnd not null\n");
|
||||
SetLastError(0xdeadbeef);
|
||||
size = ARRAY_SIZE(buffer_w);
|
||||
ret = SendMessageA(hwnd, BCM_GETNOTE, (WPARAM)&size, (LPARAM)buffer_w);
|
||||
error = GetLastError();
|
||||
if (!ret && error == 0xdeadbeef)
|
||||
{
|
||||
win_skip("BCM_GETNOTE message is unavailable. Skipping note tests\n"); /* xp or 2003 */
|
||||
DestroyWindow(hwnd);
|
||||
return;
|
||||
}
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
for (type = BS_PUSHBUTTON; type <= BS_DEFCOMMANDLINK; type++)
|
||||
{
|
||||
if (type == BS_DEFCOMMANDLINK || type == BS_COMMANDLINK)
|
||||
{
|
||||
hwnd = create_button(type, NULL);
|
||||
ok(hwnd != NULL, "Expect hwnd not null\n");
|
||||
|
||||
/* Get note when note hasn't been not set yet */
|
||||
SetLastError(0xdeadbeef);
|
||||
lstrcpyW(buffer_w, deadbeef_w);
|
||||
size = ARRAY_SIZE(buffer_w);
|
||||
ret = SendMessageA(hwnd, BCM_GETNOTE, (WPARAM)&size, (LPARAM)buffer_w);
|
||||
error = GetLastError();
|
||||
ok(!ret, "Expect BCM_GETNOTE return false\n");
|
||||
ok(!lstrcmpW(buffer_w, deadbeef_w), "Expect note: %s, got: %s\n",
|
||||
wine_dbgstr_w(deadbeef_w), wine_dbgstr_w(buffer_w));
|
||||
ok(size == ARRAY_SIZE(buffer_w), "Got: %d\n", size);
|
||||
ok(error == ERROR_INVALID_PARAMETER, "Expect last error: 0x%08x, got: 0x%08x\n",
|
||||
ERROR_INVALID_PARAMETER, error);
|
||||
|
||||
/* Get note length when note is not set */
|
||||
ret = SendMessageA(hwnd, BCM_GETNOTELENGTH, 0, 0);
|
||||
ok(ret == 0, "Expect note length: %d, got: %d\n", 0, ret);
|
||||
|
||||
/* Successful set note, get note and get note length */
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = SendMessageA(hwnd, BCM_SETNOTE, 0, (LPARAM)test_w);
|
||||
ok(ret, "Expect BCM_SETNOTE return true\n");
|
||||
error = GetLastError();
|
||||
ok(error == NO_ERROR, "Expect last error: 0x%08x, got: 0x%08x\n", NO_ERROR, error);
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
lstrcpyW(buffer_w, deadbeef_w);
|
||||
size = ARRAY_SIZE(buffer_w);
|
||||
ret = SendMessageA(hwnd, BCM_GETNOTE, (WPARAM)&size, (LPARAM)buffer_w);
|
||||
ok(ret, "Expect BCM_GETNOTE return true\n");
|
||||
ok(!lstrcmpW(buffer_w, test_w), "Expect note: %s, got: %s\n", wine_dbgstr_w(test_w),
|
||||
wine_dbgstr_w(buffer_w));
|
||||
ok(size == ARRAY_SIZE(buffer_w), "Got: %d\n", size);
|
||||
error = GetLastError();
|
||||
ok(error == NO_ERROR, "Expect last error: 0x%08x, got: 0x%08x\n", NO_ERROR, error);
|
||||
|
||||
ret = SendMessageA(hwnd, BCM_GETNOTELENGTH, 0, 0);
|
||||
ok(ret == ARRAY_SIZE(test_w) - 1, "Got: %d\n", ret);
|
||||
|
||||
/* Insufficient buffer, return partial string */
|
||||
SetLastError(0xdeadbeef);
|
||||
lstrcpyW(buffer_w, deadbeef_w);
|
||||
size = ARRAY_SIZE(test_w) - 1;
|
||||
ret = SendMessageA(hwnd, BCM_GETNOTE, (WPARAM)&size, (LPARAM)buffer_w);
|
||||
ok(!ret, "Expect BCM_GETNOTE return false\n");
|
||||
ok(!lstrcmpW(buffer_w, tes_w), "Expect note: %s, got: %s\n", wine_dbgstr_w(tes_w),
|
||||
wine_dbgstr_w(buffer_w));
|
||||
ok(size == ARRAY_SIZE(test_w), "Got: %d\n", size);
|
||||
error = GetLastError();
|
||||
ok(error == ERROR_INSUFFICIENT_BUFFER, "Expect last error: 0x%08x, got: 0x%08x\n",
|
||||
ERROR_INSUFFICIENT_BUFFER, error);
|
||||
|
||||
/* Set note with NULL buffer */
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = SendMessageA(hwnd, BCM_SETNOTE, 0, 0);
|
||||
ok(ret, "Expect BCM_SETNOTE return false\n");
|
||||
error = GetLastError();
|
||||
ok(error == NO_ERROR, "Expect last error: 0x%08x, got: 0x%08x\n", NO_ERROR, error);
|
||||
|
||||
/* Check that set note with NULL buffer make note empty */
|
||||
SetLastError(0xdeadbeef);
|
||||
lstrcpyW(buffer_w, deadbeef_w);
|
||||
size = ARRAY_SIZE(buffer_w);
|
||||
ret = SendMessageA(hwnd, BCM_GETNOTE, (WPARAM)&size, (LPARAM)buffer_w);
|
||||
ok(ret, "Expect BCM_GETNOTE return true\n");
|
||||
ok(lstrlenW(buffer_w) == 0, "Expect note length 0\n");
|
||||
ok(size == ARRAY_SIZE(buffer_w), "Got: %d\n", size);
|
||||
error = GetLastError();
|
||||
ok(error == NO_ERROR, "Expect last error: 0x%08x, got: 0x%08x\n", NO_ERROR, error);
|
||||
ret = SendMessageA(hwnd, BCM_GETNOTELENGTH, 0, 0);
|
||||
ok(ret == 0, "Expect note length: %d, got: %d\n", 0, ret);
|
||||
|
||||
/* Get note with NULL buffer */
|
||||
SetLastError(0xdeadbeef);
|
||||
size = ARRAY_SIZE(buffer_w);
|
||||
ret = SendMessageA(hwnd, BCM_GETNOTE, (WPARAM)&size, 0);
|
||||
ok(!ret, "Expect BCM_SETNOTE return false\n");
|
||||
ok(size == ARRAY_SIZE(buffer_w), "Got: %d\n", size);
|
||||
error = GetLastError();
|
||||
ok(error == ERROR_INVALID_PARAMETER, "Expect last error: 0x%08x, got: 0x%08x\n",
|
||||
ERROR_INVALID_PARAMETER, error);
|
||||
|
||||
/* Get note with NULL size */
|
||||
SetLastError(0xdeadbeef);
|
||||
lstrcpyW(buffer_w, deadbeef_w);
|
||||
ret = SendMessageA(hwnd, BCM_GETNOTE, 0, (LPARAM)buffer_w);
|
||||
ok(!ret, "Expect BCM_SETNOTE return false\n");
|
||||
ok(!lstrcmpW(buffer_w, deadbeef_w), "Expect note: %s, got: %s\n",
|
||||
wine_dbgstr_w(deadbeef_w), wine_dbgstr_w(buffer_w));
|
||||
error = GetLastError();
|
||||
ok(error == ERROR_INVALID_PARAMETER, "Expect last error: 0x%08x, got: 0x%08x\n",
|
||||
ERROR_INVALID_PARAMETER, error);
|
||||
|
||||
/* Get note with zero size */
|
||||
SetLastError(0xdeadbeef);
|
||||
size = 0;
|
||||
lstrcpyW(buffer_w, deadbeef_w);
|
||||
ret = SendMessageA(hwnd, BCM_GETNOTE, (WPARAM)&size, (LPARAM)buffer_w);
|
||||
ok(!ret, "Expect BCM_GETNOTE return false\n");
|
||||
ok(!lstrcmpW(buffer_w, deadbeef_w), "Expect note: %s, got: %s\n",
|
||||
wine_dbgstr_w(deadbeef_w), wine_dbgstr_w(buffer_w));
|
||||
ok(size == 1, "Got: %d\n", size);
|
||||
error = GetLastError();
|
||||
ok(error == ERROR_INSUFFICIENT_BUFFER, "Expect last error: 0x%08x, got: 0x%08x\n",
|
||||
ERROR_INSUFFICIENT_BUFFER, error);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
hwnd = create_button(type, NULL);
|
||||
ok(hwnd != NULL, "Expect hwnd not null\n");
|
||||
SetLastError(0xdeadbeef);
|
||||
size = ARRAY_SIZE(buffer_w);
|
||||
ret = SendMessageA(hwnd, BCM_GETNOTE, (WPARAM)&size, (LPARAM)buffer_w);
|
||||
ok(!ret, "Expect BCM_GETNOTE return false\n");
|
||||
error = GetLastError();
|
||||
ok(error == ERROR_NOT_SUPPORTED, "Expect last error: 0x%08x, got: 0x%08x\n",
|
||||
ERROR_NOT_SUPPORTED, error);
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void test_bm_get_set_image(void)
|
||||
{
|
||||
HWND hwnd;
|
||||
HDC hdc;
|
||||
HBITMAP hbmp1x1;
|
||||
HBITMAP hbmp2x2;
|
||||
HBITMAP hmask2x2;
|
||||
ICONINFO icon_info2x2;
|
||||
HICON hicon2x2;
|
||||
HBITMAP hbmp;
|
||||
HICON hicon;
|
||||
ICONINFO icon_info;
|
||||
BITMAP bm;
|
||||
static const DWORD default_style = BS_PUSHBUTTON | WS_TABSTOP | WS_POPUP | WS_VISIBLE;
|
||||
|
||||
hdc = GetDC(0);
|
||||
hbmp1x1 = CreateCompatibleBitmap(hdc, 1, 1);
|
||||
hbmp2x2 = CreateCompatibleBitmap(hdc, 2, 2);
|
||||
ZeroMemory(&bm, sizeof(bm));
|
||||
ok(GetObjectW(hbmp1x1, sizeof(bm), &bm), "Expect GetObjectW() success\n");
|
||||
ok(bm.bmWidth == 1 && bm.bmHeight == 1, "Expect bitmap size: %d,%d, got: %d,%d\n", 1, 1,
|
||||
bm.bmWidth, bm.bmHeight);
|
||||
ZeroMemory(&bm, sizeof(bm));
|
||||
ok(GetObjectW(hbmp2x2, sizeof(bm), &bm), "Expect GetObjectW() success\n");
|
||||
ok(bm.bmWidth == 2 && bm.bmHeight == 2, "Expect bitmap size: %d,%d, got: %d,%d\n", 2, 2,
|
||||
bm.bmWidth, bm.bmHeight);
|
||||
|
||||
hmask2x2 = CreateCompatibleBitmap(hdc, 2, 2);
|
||||
ZeroMemory(&icon_info2x2, sizeof(icon_info2x2));
|
||||
icon_info2x2.fIcon = TRUE;
|
||||
icon_info2x2.hbmMask = hmask2x2;
|
||||
icon_info2x2.hbmColor = hbmp2x2;
|
||||
hicon2x2 = CreateIconIndirect(&icon_info2x2);
|
||||
ok(hicon2x2 !=NULL, "Expect CreateIconIndirect() success\n");
|
||||
|
||||
ZeroMemory(&icon_info, sizeof(icon_info));
|
||||
ok(GetIconInfo(hicon2x2, &icon_info), "Expect GetIconInfo() success\n");
|
||||
ZeroMemory(&bm, sizeof(bm));
|
||||
ok(GetObjectW(icon_info.hbmColor, sizeof(bm), &bm), "Expect GetObjectW() success\n");
|
||||
ok(bm.bmWidth == 2 && bm.bmHeight == 2, "Expect bitmap size: %d,%d, got: %d,%d\n", 2, 2,
|
||||
bm.bmWidth, bm.bmHeight);
|
||||
DeleteObject(icon_info.hbmColor);
|
||||
DeleteObject(icon_info.hbmMask);
|
||||
|
||||
hwnd = CreateWindowA(WC_BUTTONA, "test", default_style | BS_BITMAP, 0, 0, 100, 100, 0, 0,
|
||||
0, 0);
|
||||
ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
|
||||
/* Get image when image is not set */
|
||||
hbmp = (HBITMAP)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_BITMAP, 0);
|
||||
ok(hbmp == 0, "Expect hbmp == 0\n");
|
||||
/* Set image */
|
||||
hbmp = (HBITMAP)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hbmp1x1);
|
||||
ok(hbmp == 0, "Expect hbmp == 0\n");
|
||||
hbmp = (HBITMAP)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_BITMAP, 0);
|
||||
ok(hbmp != 0, "Expect hbmp != 0\n");
|
||||
/* Set null resets image */
|
||||
hbmp = (HBITMAP)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_BITMAP, 0);
|
||||
ok(hbmp != 0, "Expect hbmp != 0\n");
|
||||
hbmp = (HBITMAP)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_BITMAP, 0);
|
||||
ok(hbmp == 0, "Expect hbmp == 0\n");
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
/* Set bitmap with BS_BITMAP */
|
||||
hwnd = CreateWindowA(WC_BUTTONA, "test", default_style | BS_BITMAP, 0, 0, 100, 100, 0, 0,
|
||||
0, 0);
|
||||
ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
|
||||
hbmp = (HBITMAP)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hbmp1x1);
|
||||
ok(hbmp == 0, "Expect hbmp == 0\n");
|
||||
hbmp = (HBITMAP)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_BITMAP, 0);
|
||||
ok(hbmp != 0, "Expect hbmp != 0\n");
|
||||
ZeroMemory(&bm, sizeof(bm));
|
||||
ok(GetObjectW(hbmp, sizeof(bm), &bm), "Expect GetObjectW() success\n");
|
||||
ok(bm.bmWidth == 1 && bm.bmHeight == 1, "Expect bitmap size: %d,%d, got: %d,%d\n", 1, 1,
|
||||
bm.bmWidth, bm.bmHeight);
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
/* Set bitmap without BS_BITMAP */
|
||||
hwnd = CreateWindowA(WC_BUTTONA, "test", default_style, 0, 0, 100, 100, 0, 0, 0, 0);
|
||||
ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
|
||||
hbmp = (HBITMAP)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hbmp1x1);
|
||||
ok(hbmp == 0, "Expect hbmp == 0\n");
|
||||
hbmp = (HBITMAP)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_BITMAP, 0);
|
||||
if (hbmp == 0)
|
||||
{
|
||||
/* on xp or 2003*/
|
||||
win_skip("Show both image and text is not supported. Skip following tests.\n");
|
||||
DestroyWindow(hwnd);
|
||||
goto done;
|
||||
}
|
||||
ok(hbmp != 0, "Expect hbmp != 0\n");
|
||||
ZeroMemory(&bm, sizeof(bm));
|
||||
ok(GetObjectW(hbmp, sizeof(bm), &bm), "Expect GetObjectW() success\n");
|
||||
ok(bm.bmWidth == 1 && bm.bmHeight == 1, "Expect bitmap size: %d,%d, got: %d,%d\n", 1, 1,
|
||||
bm.bmWidth, bm.bmHeight);
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
/* Set icon with BS_ICON */
|
||||
hwnd = CreateWindowA(WC_BUTTONA, "test", default_style | BS_ICON, 0, 0, 100, 100, 0, 0, 0,
|
||||
0);
|
||||
ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
|
||||
hicon = (HICON)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hicon2x2);
|
||||
ok(hicon == 0, "Expect hicon == 0\n");
|
||||
hicon = (HICON)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_ICON, 0);
|
||||
ok(hicon != 0, "Expect hicon != 0\n");
|
||||
ZeroMemory(&icon_info, sizeof(icon_info));
|
||||
ok(GetIconInfo(hicon, &icon_info), "Expect GetIconInfo() success\n");
|
||||
ZeroMemory(&bm, sizeof(bm));
|
||||
ok(GetObjectW(icon_info.hbmColor, sizeof(bm), &bm), "Expect GetObjectW() success\n");
|
||||
ok(bm.bmWidth == 2 && bm.bmHeight == 2, "Expect bitmap size: %d,%d, got: %d,%d\n", 2, 2,
|
||||
bm.bmWidth, bm.bmHeight);
|
||||
DeleteObject(icon_info.hbmColor);
|
||||
DeleteObject(icon_info.hbmMask);
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
/* Set icon without BS_ICON */
|
||||
hwnd = CreateWindowA(WC_BUTTONA, "test", default_style, 0, 0, 100, 100, 0, 0, 0, 0);
|
||||
ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
|
||||
hicon = (HICON)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hicon2x2);
|
||||
ok(hicon == 0, "Expect hicon == 0\n");
|
||||
hicon = (HICON)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_ICON, 0);
|
||||
ok(hicon != 0, "Expect hicon != 0\n");
|
||||
ZeroMemory(&icon_info, sizeof(icon_info));
|
||||
ok(GetIconInfo(hicon, &icon_info), "Expect GetIconInfo() success\n");
|
||||
ZeroMemory(&bm, sizeof(bm));
|
||||
ok(GetObjectW(icon_info.hbmColor, sizeof(bm), &bm), "Expect GetObjectW() success\n");
|
||||
ok(bm.bmWidth == 2 && bm.bmHeight == 2, "Expect bitmap size: %d,%d, got: %d,%d\n", 2, 2,
|
||||
bm.bmWidth, bm.bmHeight);
|
||||
DeleteObject(icon_info.hbmColor);
|
||||
DeleteObject(icon_info.hbmMask);
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
/* Set icon with BS_BITMAP */
|
||||
hwnd = CreateWindowA(WC_BUTTONA, "test", default_style | BS_BITMAP, 0, 0, 100, 100, 0, 0,
|
||||
0, 0);
|
||||
ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
|
||||
hicon = (HICON)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hicon2x2);
|
||||
ok(hicon == 0, "Expect hicon == 0\n");
|
||||
hicon = (HICON)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_ICON, 0);
|
||||
ok(hicon != 0, "Expect hicon != 0\n");
|
||||
ZeroMemory(&icon_info, sizeof(icon_info));
|
||||
ok(GetIconInfo(hicon, &icon_info), "Expect GetIconInfo() success\n");
|
||||
ZeroMemory(&bm, sizeof(bm));
|
||||
ok(GetObjectW(icon_info.hbmColor, sizeof(bm), &bm), "Expect GetObjectW() success\n");
|
||||
ok(bm.bmWidth == 2 && bm.bmHeight == 2, "Expect bitmap size: %d,%d, got: %d,%d\n", 2, 2,
|
||||
bm.bmWidth, bm.bmHeight);
|
||||
DeleteObject(icon_info.hbmColor);
|
||||
DeleteObject(icon_info.hbmMask);
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
/* Set bitmap with BS_ICON */
|
||||
hwnd = CreateWindowA(WC_BUTTONA, "test", default_style | BS_ICON, 0, 0, 100, 100, 0, 0, 0,
|
||||
0);
|
||||
ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
|
||||
hbmp = (HBITMAP)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hbmp1x1);
|
||||
ok(hbmp == 0, "Expect hbmp == 0\n");
|
||||
hbmp = (HBITMAP)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_BITMAP, 0);
|
||||
ok(hbmp != 0, "Expect hbmp != 0\n");
|
||||
ZeroMemory(&bm, sizeof(bm));
|
||||
ok(GetObjectW(hbmp, sizeof(bm), &bm), "Expect GetObjectW() success\n");
|
||||
ok(bm.bmWidth == 1 && bm.bmHeight == 1, "Expect bitmap size: %d,%d, got: %d,%d\n", 1, 1,
|
||||
bm.bmWidth, bm.bmHeight);
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
/* Set bitmap with BS_BITMAP and IMAGE_ICON*/
|
||||
hwnd = CreateWindowA(WC_BUTTONA, "test", default_style | BS_BITMAP, 0, 0, 100, 100, 0, 0,
|
||||
0, 0);
|
||||
ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
|
||||
hbmp = (HBITMAP)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hbmp1x1);
|
||||
ok(hbmp == 0, "Expect hbmp == 0\n");
|
||||
hbmp = (HBITMAP)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_ICON, 0);
|
||||
ok(hbmp != 0, "Expect hbmp != 0\n");
|
||||
ZeroMemory(&bm, sizeof(bm));
|
||||
ok(GetObjectW(hbmp, sizeof(bm), &bm), "Expect GetObjectW() success\n");
|
||||
ok(bm.bmWidth == 1 && bm.bmHeight == 1, "Expect bitmap size: %d,%d, got: %d,%d\n", 1, 1,
|
||||
bm.bmWidth, bm.bmHeight);
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
/* Set icon with BS_ICON and IMAGE_BITMAP */
|
||||
hwnd = CreateWindowA(WC_BUTTONA, "test", default_style | BS_ICON, 0, 0, 100, 100, 0, 0, 0,
|
||||
0);
|
||||
ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
|
||||
hicon = (HICON)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hicon2x2);
|
||||
ok(hicon == 0, "Expect hicon == 0\n");
|
||||
hicon = (HICON)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_BITMAP, 0);
|
||||
ok(hicon != 0, "Expect hicon != 0\n");
|
||||
ZeroMemory(&icon_info, sizeof(icon_info));
|
||||
ok(GetIconInfo(hicon, &icon_info), "Expect GetIconInfo() success\n");
|
||||
ZeroMemory(&bm, sizeof(bm));
|
||||
ok(GetObjectW(icon_info.hbmColor, sizeof(BITMAP), &bm), "Expect GetObjectW() success\n");
|
||||
ok(bm.bmWidth == 2 && bm.bmHeight == 2, "Expect bitmap size: %d,%d, got: %d,%d\n", 2, 2,
|
||||
bm.bmWidth, bm.bmHeight);
|
||||
DeleteObject(icon_info.hbmColor);
|
||||
DeleteObject(icon_info.hbmMask);
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
/* Set bitmap with BS_ICON and IMAGE_ICON */
|
||||
hwnd = CreateWindowA(WC_BUTTONA, "test", default_style | BS_ICON, 0, 0, 100, 100, 0, 0, 0, 0);
|
||||
ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
|
||||
hbmp = (HBITMAP)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hbmp1x1);
|
||||
ok(hbmp == 0, "Expect hbmp == 0\n");
|
||||
hbmp = (HBITMAP)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_ICON, 0);
|
||||
ok(hbmp != 0, "Expect hbmp != 0\n");
|
||||
ZeroMemory(&bm, sizeof(bm));
|
||||
ok(GetObjectW(hbmp, sizeof(bm), &bm), "Expect GetObjectW() success\n");
|
||||
ok(bm.bmWidth == 1 && bm.bmHeight == 1, "Expect bitmap size: %d,%d, got: %d,%d\n", 1, 1,
|
||||
bm.bmWidth, bm.bmHeight);
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
/* Set icon with BS_BITMAP and IMAGE_BITMAP */
|
||||
hwnd = CreateWindowA(WC_BUTTONA, "test", default_style | BS_BITMAP, 0, 0, 100, 100, 0, 0, 0, 0);
|
||||
ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
|
||||
hicon = (HICON)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hicon2x2);
|
||||
ok(hicon == 0, "Expect hicon == 0\n");
|
||||
hicon = (HICON)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_BITMAP, 0);
|
||||
ok(hicon != 0, "Expect hicon != 0\n");
|
||||
ZeroMemory(&icon_info, sizeof(icon_info));
|
||||
ok(GetIconInfo(hicon, &icon_info), "Expect GetIconInfo() success\n");
|
||||
ZeroMemory(&bm, sizeof(bm));
|
||||
ok(GetObjectW(icon_info.hbmColor, sizeof(BITMAP), &bm), "Expect GetObjectW() success\n");
|
||||
ok(bm.bmWidth == 2 && bm.bmHeight == 2, "Expect bitmap size: %d,%d, got: %d,%d\n", 2, 2,
|
||||
bm.bmWidth, bm.bmHeight);
|
||||
DeleteObject(icon_info.hbmColor);
|
||||
DeleteObject(icon_info.hbmMask);
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
done:
|
||||
DestroyIcon(hicon2x2);
|
||||
DeleteObject(hmask2x2);
|
||||
DeleteObject(hbmp2x2);
|
||||
DeleteObject(hbmp1x1);
|
||||
ReleaseDC(0, hdc);
|
||||
}
|
||||
|
||||
static void register_parent_class(void)
|
||||
{
|
||||
WNDCLASSA cls;
|
||||
|
@ -824,6 +1228,504 @@ static void register_parent_class(void)
|
|||
RegisterClassA(&cls);
|
||||
}
|
||||
|
||||
static void test_button_data(void)
|
||||
{
|
||||
static const DWORD styles[] =
|
||||
{
|
||||
BS_PUSHBUTTON,
|
||||
BS_DEFPUSHBUTTON,
|
||||
BS_CHECKBOX,
|
||||
BS_AUTOCHECKBOX,
|
||||
BS_RADIOBUTTON,
|
||||
BS_3STATE,
|
||||
BS_AUTO3STATE,
|
||||
BS_GROUPBOX,
|
||||
BS_USERBUTTON,
|
||||
BS_AUTORADIOBUTTON,
|
||||
BS_OWNERDRAW,
|
||||
BS_SPLITBUTTON,
|
||||
BS_DEFSPLITBUTTON,
|
||||
BS_COMMANDLINK,
|
||||
BS_DEFCOMMANDLINK,
|
||||
};
|
||||
|
||||
struct button_desc
|
||||
{
|
||||
HWND self;
|
||||
HWND parent;
|
||||
LONG style;
|
||||
};
|
||||
unsigned int i;
|
||||
HWND parent;
|
||||
|
||||
parent = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
|
||||
100, 100, 200, 200, 0, 0, 0, NULL);
|
||||
ok(parent != 0, "Failed to create parent window\n");
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(styles); i++)
|
||||
{
|
||||
struct button_desc *desc;
|
||||
HWND hwnd;
|
||||
|
||||
hwnd = create_button(styles[i], parent);
|
||||
ok(hwnd != NULL, "Failed to create a button.\n");
|
||||
|
||||
desc = (void *)GetWindowLongPtrA(hwnd, 0);
|
||||
ok(desc != NULL, "Expected window data.\n");
|
||||
|
||||
if (desc)
|
||||
{
|
||||
ok(desc->self == hwnd, "Unexpected 'self' field.\n");
|
||||
ok(desc->parent == parent, "Unexpected 'parent' field.\n");
|
||||
ok(desc->style == (WS_CHILD | BS_NOTIFY | styles[i]), "Unexpected 'style' field.\n");
|
||||
}
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
DestroyWindow(parent);
|
||||
}
|
||||
|
||||
static void test_get_set_imagelist(void)
|
||||
{
|
||||
HWND hwnd;
|
||||
HIMAGELIST himl;
|
||||
BUTTON_IMAGELIST biml = {0};
|
||||
HDC hdc;
|
||||
HBITMAP hbmp;
|
||||
INT width = 16;
|
||||
INT height = 16;
|
||||
INT index;
|
||||
DWORD type;
|
||||
BOOL ret;
|
||||
|
||||
hdc = GetDC(0);
|
||||
hbmp = CreateCompatibleBitmap(hdc, width, height);
|
||||
ok(hbmp != NULL, "Expect hbmp not null\n");
|
||||
|
||||
himl = pImageList_Create(width, height, ILC_COLOR, 1, 0);
|
||||
ok(himl != NULL, "Expect himl not null\n");
|
||||
index = pImageList_Add(himl, hbmp, NULL);
|
||||
ok(index == 0, "Expect index == 0\n");
|
||||
DeleteObject(hbmp);
|
||||
ReleaseDC(0, hdc);
|
||||
|
||||
for (type = BS_PUSHBUTTON; type <= BS_DEFCOMMANDLINK; type++)
|
||||
{
|
||||
hwnd = create_button(type, NULL);
|
||||
ok(hwnd != NULL, "Expect hwnd not null\n");
|
||||
|
||||
/* Get imagelist when imagelist is unset yet */
|
||||
ret = SendMessageA(hwnd, BCM_GETIMAGELIST, 0, (LPARAM)&biml);
|
||||
ok(ret, "Expect BCM_GETIMAGELIST return true\n");
|
||||
ok(biml.himl == 0 && IsRectEmpty(&biml.margin) && biml.uAlign == 0,
|
||||
"Expect BUTTON_IMAGELIST is empty\n");
|
||||
|
||||
/* Set imagelist with himl null */
|
||||
biml.himl = 0;
|
||||
biml.uAlign = BUTTON_IMAGELIST_ALIGN_CENTER;
|
||||
ret = SendMessageA(hwnd, BCM_SETIMAGELIST, 0, (LPARAM)&biml);
|
||||
ok(ret || broken(!ret), /* xp or 2003 */
|
||||
"Expect BCM_SETIMAGELIST return true\n");
|
||||
|
||||
/* Set imagelist with uAlign invalid */
|
||||
biml.himl = himl;
|
||||
biml.uAlign = -1;
|
||||
ret = SendMessageA(hwnd, BCM_SETIMAGELIST, 0, (LPARAM)&biml);
|
||||
ok(ret, "Expect BCM_SETIMAGELIST return true\n");
|
||||
|
||||
/* Successful get and set imagelist */
|
||||
biml.himl = himl;
|
||||
biml.uAlign = BUTTON_IMAGELIST_ALIGN_CENTER;
|
||||
ret = SendMessageA(hwnd, BCM_SETIMAGELIST, 0, (LPARAM)&biml);
|
||||
ok(ret, "Expect BCM_SETIMAGELIST return true\n");
|
||||
ret = SendMessageA(hwnd, BCM_GETIMAGELIST, 0, (LPARAM)&biml);
|
||||
ok(ret, "Expect BCM_GETIMAGELIST return true\n");
|
||||
ok(biml.himl == himl, "Expect himl to be same\n");
|
||||
ok(biml.uAlign == BUTTON_IMAGELIST_ALIGN_CENTER, "Expect uAlign to be %x\n",
|
||||
BUTTON_IMAGELIST_ALIGN_CENTER);
|
||||
|
||||
/* BCM_SETIMAGELIST null pointer handling */
|
||||
ret = SendMessageA(hwnd, BCM_SETIMAGELIST, 0, 0);
|
||||
ok(!ret, "Expect BCM_SETIMAGELIST return false\n");
|
||||
ret = SendMessageA(hwnd, BCM_GETIMAGELIST, 0, (LPARAM)&biml);
|
||||
ok(ret, "Expect BCM_GETIMAGELIST return true\n");
|
||||
ok(biml.himl == himl, "Expect himl to be same\n");
|
||||
|
||||
/* BCM_GETIMAGELIST null pointer handling */
|
||||
biml.himl = himl;
|
||||
biml.uAlign = BUTTON_IMAGELIST_ALIGN_CENTER;
|
||||
ret = SendMessageA(hwnd, BCM_SETIMAGELIST, 0, (LPARAM)&biml);
|
||||
ok(ret, "Expect BCM_SETIMAGELIST return true\n");
|
||||
ret = SendMessageA(hwnd, BCM_GETIMAGELIST, 0, 0);
|
||||
ok(!ret, "Expect BCM_GETIMAGELIST return false\n");
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
pImageList_Destroy(himl);
|
||||
}
|
||||
|
||||
static void test_get_set_textmargin(void)
|
||||
{
|
||||
HWND hwnd;
|
||||
RECT margin_in;
|
||||
RECT margin_out;
|
||||
BOOL ret;
|
||||
DWORD type;
|
||||
|
||||
SetRect(&margin_in, 2, 1, 3, 4);
|
||||
for (type = BS_PUSHBUTTON; type <= BS_DEFCOMMANDLINK; type++)
|
||||
{
|
||||
hwnd = create_button(type, NULL);
|
||||
ok(hwnd != NULL, "Expect hwnd not null\n");
|
||||
|
||||
/* Get text margin when it is unset */
|
||||
ret = SendMessageA(hwnd, BCM_GETTEXTMARGIN, 0, (LPARAM)&margin_out);
|
||||
ok(ret, "Expect ret to be true\n");
|
||||
ok(IsRectEmpty(&margin_out), "Expect margin empty\n");
|
||||
|
||||
/* Successful get and set text margin */
|
||||
ret = SendMessageA(hwnd, BCM_SETTEXTMARGIN, 0, (LPARAM)&margin_in);
|
||||
ok(ret, "Expect ret to be true\n");
|
||||
SetRectEmpty(&margin_out);
|
||||
ret = SendMessageA(hwnd, BCM_GETTEXTMARGIN, 0, (LPARAM)&margin_out);
|
||||
ok(ret, "Expect ret to be true\n");
|
||||
ok(EqualRect(&margin_in, &margin_out), "Expect margins to be equal\n");
|
||||
|
||||
/* BCM_SETTEXTMARGIN null pointer handling */
|
||||
ret = SendMessageA(hwnd, BCM_SETTEXTMARGIN, 0, 0);
|
||||
ok(!ret, "Expect ret to be false\n");
|
||||
SetRectEmpty(&margin_out);
|
||||
ret = SendMessageA(hwnd, BCM_GETTEXTMARGIN, 0, (LPARAM)&margin_out);
|
||||
ok(ret, "Expect ret to be true\n");
|
||||
ok(EqualRect(&margin_in, &margin_out), "Expect margins to be equal\n");
|
||||
|
||||
/* BCM_GETTEXTMARGIN null pointer handling */
|
||||
ret = SendMessageA(hwnd, BCM_SETTEXTMARGIN, 0, (LPARAM)&margin_in);
|
||||
ok(ret, "Expect ret to be true\n");
|
||||
ret = SendMessageA(hwnd, BCM_GETTEXTMARGIN, 0, 0);
|
||||
ok(!ret, "Expect ret to be true\n");
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_state(void)
|
||||
{
|
||||
HWND hwnd;
|
||||
DWORD type;
|
||||
LONG state;
|
||||
|
||||
/* Initial button state */
|
||||
for (type = BS_PUSHBUTTON; type <= BS_DEFCOMMANDLINK; type++)
|
||||
{
|
||||
hwnd = create_button(type, NULL);
|
||||
state = SendMessageA(hwnd, BM_GETSTATE, 0, 0);
|
||||
ok(state == BST_UNCHECKED, "Expect state 0x%08x, got 0x%08x\n", BST_UNCHECKED, state);
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_bcm_get_ideal_size(void)
|
||||
{
|
||||
static const char *button_text2 = "WWWW\nWWWW";
|
||||
static const char *button_text = "WWWW";
|
||||
static const DWORD imagelist_aligns[] = {BUTTON_IMAGELIST_ALIGN_LEFT, BUTTON_IMAGELIST_ALIGN_RIGHT,
|
||||
BUTTON_IMAGELIST_ALIGN_TOP, BUTTON_IMAGELIST_ALIGN_BOTTOM,
|
||||
BUTTON_IMAGELIST_ALIGN_CENTER};
|
||||
static const DWORD aligns[] = {0, BS_TOP, BS_LEFT, BS_RIGHT, BS_BOTTOM,
|
||||
BS_CENTER, BS_VCENTER, BS_RIGHTBUTTON, WS_EX_RIGHT};
|
||||
DWORD default_style = WS_TABSTOP | WS_POPUP | WS_VISIBLE;
|
||||
const LONG client_width = 400, client_height = 200;
|
||||
LONG image_width, height, line_count, text_width;
|
||||
HFONT hfont, prev_font;
|
||||
DWORD style, type;
|
||||
BOOL ret;
|
||||
HWND hwnd;
|
||||
HDC hdc;
|
||||
LOGFONTA lf;
|
||||
TEXTMETRICA tm;
|
||||
SIZE size;
|
||||
HBITMAP hmask, hbmp;
|
||||
ICONINFO icon_info;
|
||||
HICON hicon;
|
||||
HIMAGELIST himl;
|
||||
BUTTON_IMAGELIST biml = {0};
|
||||
RECT rect;
|
||||
INT i, j;
|
||||
|
||||
/* Check for NULL pointer handling */
|
||||
hwnd = CreateWindowA(WC_BUTTONA, button_text, BS_PUSHBUTTON | default_style, 0, 0, client_width, client_height,
|
||||
NULL, NULL, 0, NULL);
|
||||
ret = SendMessageA(hwnd, BCM_GETIDEALSIZE, 0, 0);
|
||||
ok(!ret, "Expect BCM_GETIDEALSIZE message to return false.\n");
|
||||
|
||||
/* Set font so that the test is consistent on Wine and Windows */
|
||||
ZeroMemory(&lf, sizeof(lf));
|
||||
lf.lfWeight = FW_NORMAL;
|
||||
lf.lfHeight = 20;
|
||||
lstrcpyA(lf.lfFaceName, "Tahoma");
|
||||
hfont = CreateFontIndirectA(&lf);
|
||||
ok(hfont != NULL, "Failed to create test font.\n");
|
||||
|
||||
/* Get tmHeight */
|
||||
hdc = GetDC(hwnd);
|
||||
prev_font = SelectObject(hdc, hfont);
|
||||
GetTextMetricsA(hdc, &tm);
|
||||
SelectObject(hdc, prev_font);
|
||||
DrawTextA(hdc, button_text, -1, &rect, DT_CALCRECT);
|
||||
text_width = rect.right - rect.left;
|
||||
ReleaseDC(hwnd, hdc);
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
/* XP and 2003 doesn't support command links, getting ideal size with button having only text returns client size on these platforms. */
|
||||
hwnd = CreateWindowA(WC_BUTTONA, button_text, BS_DEFCOMMANDLINK | default_style, 0, 0, client_width, client_height, NULL,
|
||||
NULL, 0, NULL);
|
||||
ok(hwnd != NULL, "Expect hwnd not NULL\n");
|
||||
SendMessageA(hwnd, WM_SETFONT, (WPARAM)hfont, (LPARAM)TRUE);
|
||||
ZeroMemory(&size, sizeof(size));
|
||||
ret = SendMessageA(hwnd, BCM_GETIDEALSIZE, 0, (LPARAM)&size);
|
||||
ok(ret, "Expect BCM_GETIDEALSIZE message to return true\n");
|
||||
if (size.cx == client_width && size.cy == client_height)
|
||||
{
|
||||
/* on XP and 2003, buttons with image are not supported */
|
||||
win_skip("Skipping further tests on XP and 2003\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Tests for image placements */
|
||||
/* Prepare bitmap */
|
||||
image_width = 48;
|
||||
height = 48;
|
||||
hdc = GetDC(0);
|
||||
hmask = CreateCompatibleBitmap(hdc, image_width, height);
|
||||
hbmp = CreateCompatibleBitmap(hdc, image_width, height);
|
||||
|
||||
/* Only bitmap for push button, ideal size should be enough for image and text */
|
||||
hwnd = CreateWindowA(WC_BUTTONA, button_text, BS_DEFPUSHBUTTON | BS_BITMAP | default_style, 0, 0, client_width,
|
||||
client_height, NULL, NULL, 0, NULL);
|
||||
ok(hwnd != NULL, "Expect hwnd not NULL\n");
|
||||
SendMessageA(hwnd, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hbmp);
|
||||
SendMessageA(hwnd, WM_SETFONT, (WPARAM)hfont, (LPARAM)TRUE);
|
||||
ZeroMemory(&size, sizeof(size));
|
||||
ret = SendMessageA(hwnd, BCM_GETIDEALSIZE, 0, (LPARAM)&size);
|
||||
ok(ret, "Expect BCM_GETIDEALSIZE message to return true\n");
|
||||
/* Ideal size contains text rect even show bitmap only */
|
||||
ok((size.cx >= image_width + text_width && size.cy >= max(height, tm.tmHeight)),
|
||||
"Expect ideal cx %d >= %d and ideal cy %d >= %d\n", size.cx, image_width + text_width,
|
||||
size.cy, max(height, tm.tmHeight));
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
/* Image alignments when button has bitmap and text*/
|
||||
for (i = 0; i < ARRAY_SIZE(aligns); i++)
|
||||
for (j = 0; j < ARRAY_SIZE(aligns); j++)
|
||||
{
|
||||
style = BS_DEFPUSHBUTTON | default_style | aligns[i] | aligns[j];
|
||||
hwnd = CreateWindowA(WC_BUTTONA, button_text, style, 0, 0, client_width, client_height, NULL, NULL, 0, NULL);
|
||||
ok(hwnd != NULL, "Expect hwnd not NULL\n");
|
||||
SendMessageA(hwnd, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hbmp);
|
||||
SendMessageA(hwnd, WM_SETFONT, (WPARAM)hfont, (LPARAM)TRUE);
|
||||
ZeroMemory(&size, sizeof(size));
|
||||
ret = SendMessageA(hwnd, BCM_GETIDEALSIZE, 0, (LPARAM)&size);
|
||||
ok(ret, "Expect BCM_GETIDEALSIZE message to return true\n");
|
||||
if (!(style & (BS_CENTER | BS_VCENTER)) || ((style & BS_CENTER) && (style & BS_CENTER) != BS_CENTER)
|
||||
|| !(style & BS_VCENTER) || (style & BS_VCENTER) == BS_VCENTER)
|
||||
ok((size.cx >= image_width + text_width && size.cy >= max(height, tm.tmHeight)),
|
||||
"Style: 0x%08x expect ideal cx %d >= %d and ideal cy %d >= %d\n", style, size.cx,
|
||||
image_width + text_width, size.cy, max(height, tm.tmHeight));
|
||||
else
|
||||
ok((size.cx >= max(text_width, height) && size.cy >= height + tm.tmHeight),
|
||||
"Style: 0x%08x expect ideal cx %d >= %d and ideal cy %d >= %d\n", style, size.cx,
|
||||
max(text_width, height), size.cy, height + tm.tmHeight);
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
/* Image list alignments */
|
||||
himl = pImageList_Create(image_width, height, ILC_COLOR, 1, 1);
|
||||
pImageList_Add(himl, hbmp, 0);
|
||||
biml.himl = himl;
|
||||
for (i = 0; i < ARRAY_SIZE(imagelist_aligns); i++)
|
||||
{
|
||||
biml.uAlign = imagelist_aligns[i];
|
||||
hwnd = CreateWindowA(WC_BUTTONA, button_text, BS_DEFPUSHBUTTON | default_style, 0, 0, client_width,
|
||||
client_height, NULL, NULL, 0, NULL);
|
||||
ok(hwnd != NULL, "Expect hwnd not NULL\n");
|
||||
SendMessageA(hwnd, WM_SETFONT, (WPARAM)hfont, (LPARAM)TRUE);
|
||||
SendMessageA(hwnd, BCM_SETIMAGELIST, 0, (LPARAM)&biml);
|
||||
ZeroMemory(&size, sizeof(size));
|
||||
ret = SendMessageA(hwnd, BCM_GETIDEALSIZE, 0, (LPARAM)&size);
|
||||
ok(ret, "Expect BCM_GETIDEALSIZE message to return true\n");
|
||||
if (biml.uAlign == BUTTON_IMAGELIST_ALIGN_TOP || biml.uAlign == BUTTON_IMAGELIST_ALIGN_BOTTOM)
|
||||
ok((size.cx >= max(text_width, height) && size.cy >= height + tm.tmHeight),
|
||||
"Align:%d expect ideal cx %d >= %d and ideal cy %d >= %d\n", biml.uAlign, size.cx,
|
||||
max(text_width, height), size.cy, height + tm.tmHeight);
|
||||
else if (biml.uAlign == BUTTON_IMAGELIST_ALIGN_LEFT || biml.uAlign == BUTTON_IMAGELIST_ALIGN_RIGHT)
|
||||
ok((size.cx >= image_width + text_width && size.cy >= max(height, tm.tmHeight)),
|
||||
"Align:%d expect ideal cx %d >= %d and ideal cy %d >= %d\n", biml.uAlign, size.cx,
|
||||
image_width + text_width, size.cy, max(height, tm.tmHeight));
|
||||
else
|
||||
ok(size.cx >= image_width && size.cy >= height, "Align:%d expect ideal cx %d >= %d and ideal cy %d >= %d\n",
|
||||
biml.uAlign, size.cx, image_width, size.cy, height);
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
/* Icon as image */
|
||||
/* Create icon from bitmap */
|
||||
ZeroMemory(&icon_info, sizeof(icon_info));
|
||||
icon_info.fIcon = TRUE;
|
||||
icon_info.hbmMask = hmask;
|
||||
icon_info.hbmColor = hbmp;
|
||||
hicon = CreateIconIndirect(&icon_info);
|
||||
|
||||
/* Only icon, ideal size should be enough for image and text */
|
||||
hwnd = CreateWindowA(WC_BUTTONA, button_text, BS_DEFPUSHBUTTON | BS_ICON | default_style, 0, 0, client_width,
|
||||
client_height, NULL, NULL, 0, NULL);
|
||||
ok(hwnd != NULL, "Expect hwnd not NULL\n");
|
||||
SendMessageA(hwnd, BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)hicon);
|
||||
SendMessageA(hwnd, WM_SETFONT, (WPARAM)hfont, (LPARAM)TRUE);
|
||||
ZeroMemory(&size, sizeof(size));
|
||||
ret = SendMessageA(hwnd, BCM_GETIDEALSIZE, 0, (LPARAM)&size);
|
||||
ok(ret, "Expect BCM_GETIDEALSIZE message to return true\n");
|
||||
/* Ideal size contains text rect even show icons only */
|
||||
ok((size.cx >= image_width + text_width && size.cy >= max(height, tm.tmHeight)),
|
||||
"Expect ideal cx %d >= %d and ideal cy %d >= %d\n", size.cx, image_width + text_width, size.cy,
|
||||
max(height, tm.tmHeight));
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
/* Show icon and text */
|
||||
hwnd = CreateWindowA(WC_BUTTONA, button_text, BS_DEFPUSHBUTTON | default_style, 0, 0, client_width,
|
||||
client_height, NULL, NULL, 0, NULL);
|
||||
ok(hwnd != NULL, "Expect hwnd not NULL\n");
|
||||
SendMessageA(hwnd, BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)hicon);
|
||||
SendMessageA(hwnd, WM_SETFONT, (WPARAM)hfont, (LPARAM)TRUE);
|
||||
ZeroMemory(&size, sizeof(size));
|
||||
ret = SendMessageA(hwnd, BCM_GETIDEALSIZE, 0, (LPARAM)&size);
|
||||
ok(ret, "Expect BCM_GETIDEALSIZE message to return true\n");
|
||||
ok((size.cx >= image_width + text_width && size.cy >= max(height, tm.tmHeight)),
|
||||
"Expect ideal cx %d >= %d and ideal cy %d >= %d\n", size.cx, image_width + text_width, size.cy,
|
||||
max(height, tm.tmHeight));
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
/* Checkbox */
|
||||
/* Both bitmap and text for checkbox, ideal size is only enough for text because it doesn't support image(but not image list)*/
|
||||
hwnd = CreateWindowA(WC_BUTTONA, button_text, BS_AUTOCHECKBOX | default_style, 0, 0, client_width, client_height,
|
||||
NULL, NULL, 0, NULL);
|
||||
ok(hwnd != NULL, "Expect hwnd not NULL\n");
|
||||
SendMessageA(hwnd, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hbmp);
|
||||
SendMessageA(hwnd, WM_SETFONT, (WPARAM)hfont, (LPARAM)TRUE);
|
||||
ZeroMemory(&size, sizeof(size));
|
||||
ret = SendMessageA(hwnd, BCM_GETIDEALSIZE, 0, (LPARAM)&size);
|
||||
ok(ret, "Expect BCM_GETIDEALSIZE message to return true\n");
|
||||
ok((size.cx <= image_width + text_width && size.cx >= text_width && size.cy <= max(height, tm.tmHeight)
|
||||
&& size.cy >= tm.tmHeight),
|
||||
"Expect ideal cx %d within range (%d, %d ) and ideal cy %d within range (%d, %d )\n", size.cx,
|
||||
text_width, image_width + text_width, size.cy, tm.tmHeight, max(height, tm.tmHeight));
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
/* Both image list and text for checkbox, ideal size should have enough for image list and text */
|
||||
biml.uAlign = BUTTON_IMAGELIST_ALIGN_LEFT;
|
||||
hwnd = CreateWindowA(WC_BUTTONA, button_text, BS_AUTOCHECKBOX | BS_BITMAP | default_style, 0, 0, client_width,
|
||||
client_height, NULL, NULL, 0, NULL);
|
||||
ok(hwnd != NULL, "Expect hwnd not NULL\n");
|
||||
SendMessageA(hwnd, BCM_SETIMAGELIST, 0, (LPARAM)&biml);
|
||||
SendMessageA(hwnd, WM_SETFONT, (WPARAM)hfont, (LPARAM)TRUE);
|
||||
ZeroMemory(&size, sizeof(size));
|
||||
ret = SendMessageA(hwnd, BCM_GETIDEALSIZE, 0, (LPARAM)&size);
|
||||
ok(ret, "Expect BCM_GETIDEALSIZE message to return true\n");
|
||||
ok((size.cx >= image_width + text_width && size.cy >= max(height, tm.tmHeight)),
|
||||
"Expect ideal cx %d >= %d and ideal cy %d >= %d\n", size.cx, image_width + text_width, size.cy,
|
||||
max(height, tm.tmHeight));
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
/* Only bitmap for checkbox, ideal size should have enough for image and text */
|
||||
hwnd = CreateWindowA(WC_BUTTONA, button_text, BS_AUTOCHECKBOX | BS_BITMAP | default_style, 0, 0, client_width,
|
||||
client_height, NULL, NULL, 0, NULL);
|
||||
ok(hwnd != NULL, "Expect hwnd not NULL\n");
|
||||
SendMessageA(hwnd, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hbmp);
|
||||
SendMessageA(hwnd, WM_SETFONT, (WPARAM)hfont, (LPARAM)TRUE);
|
||||
ZeroMemory(&size, sizeof(size));
|
||||
ret = SendMessageA(hwnd, BCM_GETIDEALSIZE, 0, (LPARAM)&size);
|
||||
ok(ret, "Expect BCM_GETIDEALSIZE message to return true\n");
|
||||
ok((size.cx >= image_width + text_width && size.cy >= max(height, tm.tmHeight)),
|
||||
"Expect ideal cx %d >= %d and ideal cy %d >= %d\n", size.cx, image_width + text_width, size.cy,
|
||||
max(height, tm.tmHeight));
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
/* Test button with only text */
|
||||
/* No text */
|
||||
for (type = BS_PUSHBUTTON; type <= BS_DEFCOMMANDLINK; type++)
|
||||
{
|
||||
style = type | default_style;
|
||||
hwnd = CreateWindowA(WC_BUTTONA, "", style, 0, 0, client_width, client_height, NULL, NULL, 0, NULL);
|
||||
ok(hwnd != NULL, "Expect hwnd not NULL\n");
|
||||
SendMessageA(hwnd, WM_SETFONT, (WPARAM)hfont, (LPARAM)TRUE);
|
||||
|
||||
ZeroMemory(&size, sizeof(size));
|
||||
ret = SendMessageA(hwnd, BCM_GETIDEALSIZE, 0, (LPARAM)&size);
|
||||
ok(ret, "Expect BCM_GETIDEALSIZE message to return true\n");
|
||||
|
||||
if (type == BS_COMMANDLINK || type == BS_DEFCOMMANDLINK)
|
||||
{
|
||||
todo_wine ok((size.cx == 0 && size.cy > 0), "Style 0x%08x expect ideal cx %d >= %d and ideal cy %d >= %d\n",
|
||||
style, size.cx, 0, size.cy, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ok(size.cx == client_width && size.cy == client_height,
|
||||
"Style 0x%08x expect size.cx == %d and size.cy == %d, got size.cx: %d size.cy: %d\n", style,
|
||||
client_width, client_height, size.cx, size.cy);
|
||||
}
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
/* Single line and multiple lines text */
|
||||
for (line_count = 1; line_count <= 2; line_count++)
|
||||
{
|
||||
for (type = BS_PUSHBUTTON; type <= BS_DEFCOMMANDLINK; type++)
|
||||
{
|
||||
style = line_count > 1 ? type | BS_MULTILINE : type;
|
||||
style |= default_style;
|
||||
|
||||
hwnd = CreateWindowA(WC_BUTTONA, (line_count == 2 ? button_text2 : button_text), style, 0, 0, client_width,
|
||||
client_height, NULL, NULL, 0, NULL);
|
||||
ok(hwnd != NULL, "Expect hwnd not NULL\n");
|
||||
SendMessageA(hwnd, WM_SETFONT, (WPARAM)hfont, (LPARAM)TRUE);
|
||||
ZeroMemory(&size, sizeof(size));
|
||||
ret = SendMessageA(hwnd, BCM_GETIDEALSIZE, 0, (LPARAM)&size);
|
||||
ok(ret, "Expect BCM_GETIDEALSIZE message to return true\n");
|
||||
|
||||
if (type == BS_3STATE || type == BS_AUTO3STATE || type == BS_GROUPBOX || type == BS_PUSHBOX
|
||||
|| type == BS_OWNERDRAW)
|
||||
{
|
||||
ok(size.cx == client_width && size.cy == client_height,
|
||||
"Style 0x%08x expect ideal size (%d,%d), got (%d,%d)\n", style, client_width, client_height, size.cx,
|
||||
size.cy);
|
||||
}
|
||||
else if (type == BS_COMMANDLINK || type == BS_DEFCOMMANDLINK)
|
||||
{
|
||||
todo_wine ok((size.cx == 0 && size.cy > 0),
|
||||
"Style 0x%08x expect ideal cx %d >= %d and ideal cy %d >= %d\n", style, size.cx, 0,
|
||||
size.cy, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
height = line_count == 2 ? 2 * tm.tmHeight : tm.tmHeight;
|
||||
ok(size.cx >= 0 && size.cy >= height, "Style 0x%08x expect ideal cx %d >= 0 and ideal cy %d >= %d\n",
|
||||
style, size.cx, size.cy, height);
|
||||
}
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
}
|
||||
|
||||
pImageList_Destroy(himl);
|
||||
DestroyIcon(hicon);
|
||||
DeleteObject(hbmp);
|
||||
DeleteObject(hmask);
|
||||
ReleaseDC(0, hdc);
|
||||
DeleteObject(hfont);
|
||||
}
|
||||
|
||||
START_TEST(button)
|
||||
{
|
||||
ULONG_PTR ctx_cookie;
|
||||
|
@ -839,6 +1741,13 @@ START_TEST(button)
|
|||
|
||||
test_button_class();
|
||||
test_button_messages();
|
||||
test_note();
|
||||
test_button_data();
|
||||
test_bm_get_set_image();
|
||||
test_get_set_imagelist();
|
||||
test_get_set_textmargin();
|
||||
test_state();
|
||||
test_bcm_get_ideal_size();
|
||||
|
||||
unload_v6_module(ctx_cookie, hCtx);
|
||||
}
|
||||
|
|
|
@ -264,7 +264,7 @@ static void test_comboex_WM_LBUTTONDOWN(void)
|
|||
WS_VISIBLE|WS_CHILD|CBS_DROPDOWN, 0, 0, 200, 150,
|
||||
hComboExParentWnd, NULL, hMainHinst, NULL);
|
||||
|
||||
for (i = 0; i < sizeof(choices)/sizeof(UINT); i++){
|
||||
for (i = 0; i < ARRAY_SIZE(choices); i++){
|
||||
COMBOBOXEXITEMW cbexItem;
|
||||
wsprintfW(buffer, stringFormat, choices[i]);
|
||||
|
||||
|
@ -1165,11 +1165,11 @@ static void test_combo_dropdown_size(DWORD style)
|
|||
int limit;
|
||||
} info_height[] = {
|
||||
{33, 50, -1},
|
||||
{35, 50, 40},
|
||||
{35, 100, 40},
|
||||
{15, 50, 3},
|
||||
};
|
||||
|
||||
for (test = 0; test < sizeof(info_height) / sizeof(info_height[0]); test++)
|
||||
for (test = 0; test < ARRAY_SIZE(info_height); test++)
|
||||
{
|
||||
const struct list_size_info *info_test = &info_height[test];
|
||||
int height_item; /* Height of a list item */
|
||||
|
@ -1182,7 +1182,6 @@ static void test_combo_dropdown_size(DWORD style)
|
|||
info_test->height_combo, hMainWnd, (HMENU)COMBO_ID, NULL, 0);
|
||||
|
||||
min_visible_expected = SendMessageA(hCombo, CB_GETMINVISIBLE, 0, 0);
|
||||
todo_wine
|
||||
ok(min_visible_expected == 30, "Unexpected number of items %d.\n", min_visible_expected);
|
||||
|
||||
cbInfo.cbSize = sizeof(COMBOBOXINFO);
|
||||
|
@ -1202,10 +1201,8 @@ static void test_combo_dropdown_size(DWORD style)
|
|||
min_visible_expected = info_test->limit;
|
||||
|
||||
ret = SendMessageA(hCombo, CB_SETMINVISIBLE, min_visible_expected, 0);
|
||||
todo_wine
|
||||
ok(ret, "Failed to set visible limit.\n");
|
||||
min_visible_actual = SendMessageA(hCombo, CB_GETMINVISIBLE, 0, 0);
|
||||
todo_wine
|
||||
ok(min_visible_expected == min_visible_actual, "test %d: unexpected number of items %d.\n",
|
||||
test, min_visible_actual);
|
||||
}
|
||||
|
@ -1242,7 +1239,6 @@ static void test_combo_dropdown_size(DWORD style)
|
|||
if (expected_height_list < 0)
|
||||
expected_height_list = 0;
|
||||
|
||||
todo_wine
|
||||
ok(expected_height_list == height_list, "Test %d, expected list height to be %d, got %d\n",
|
||||
test, expected_height_list, height_list);
|
||||
}
|
||||
|
@ -1250,7 +1246,6 @@ static void test_combo_dropdown_size(DWORD style)
|
|||
{
|
||||
expected_height_list = min(info_test->num_items, min_visible_expected) * height_item;
|
||||
|
||||
todo_wine
|
||||
ok(expected_height_list == height_list, "Test %d, expected list height to be %d, got %d\n",
|
||||
test, expected_height_list, height_list);
|
||||
}
|
||||
|
|
|
@ -721,6 +721,46 @@ static void test_dtm_set_and_get_systemtime_with_limits(void)
|
|||
DestroyWindow(hWnd);
|
||||
}
|
||||
|
||||
static void test_dtm_get_ideal_size(void)
|
||||
{
|
||||
HWND hwnd;
|
||||
HDC hdc;
|
||||
HFONT hfont;
|
||||
LOGFONTA lf;
|
||||
TEXTMETRICA tm;
|
||||
SIZE size;
|
||||
BOOL r;
|
||||
|
||||
hwnd = create_datetime_control(0);
|
||||
r = SendMessageA(hwnd, DTM_GETIDEALSIZE, 0, (LPARAM)&size);
|
||||
if (!r)
|
||||
{
|
||||
win_skip("DTM_GETIDEALSIZE is not available\n");
|
||||
DestroyWindow(hwnd);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set font so that the test is consistent on Wine and Windows */
|
||||
ZeroMemory(&lf, sizeof(lf));
|
||||
lf.lfWeight = FW_NORMAL;
|
||||
lf.lfHeight = 20;
|
||||
lstrcpyA(lf.lfFaceName, "Tahoma");
|
||||
hfont = CreateFontIndirectA(&lf);
|
||||
SendMessageA(hwnd, WM_SETFONT, (WPARAM)hfont, (LPARAM)TRUE);
|
||||
|
||||
hdc = GetDC(hwnd);
|
||||
GetTextMetricsA(hdc, &tm);
|
||||
ReleaseDC(hwnd, hdc);
|
||||
|
||||
r = SendMessageA(hwnd, DTM_GETIDEALSIZE, 0, (LPARAM)&size);
|
||||
ok(r, "Expect DTM_GETIDEALSIZE message to return true\n");
|
||||
ok(size.cx > 0 && size.cy >= tm.tmHeight,
|
||||
"Expect size.cx > 0 and size.cy >= %d, got cx:%d cy:%d\n", tm.tmHeight, size.cx, size.cy);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
DeleteObject(hfont);
|
||||
}
|
||||
|
||||
static void test_wm_set_get_text(void)
|
||||
{
|
||||
static const CHAR a_str[] = "a";
|
||||
|
@ -821,6 +861,7 @@ START_TEST(datetime)
|
|||
test_dtm_set_and_get_mccolor();
|
||||
test_dtm_set_and_get_mcfont();
|
||||
test_dtm_get_monthcal();
|
||||
test_dtm_get_ideal_size();
|
||||
test_wm_set_get_text();
|
||||
test_dts_shownone();
|
||||
|
||||
|
|
|
@ -2969,7 +2969,7 @@ static void test_EM_GETLINE(void)
|
|||
hwnd[0] = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
|
||||
hwnd[1] = create_editcontrolW(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
|
||||
|
||||
for (i = 0; i < sizeof(hwnd)/sizeof(hwnd[0]); i++)
|
||||
for (i = 0; i < ARRAY_SIZE(hwnd); i++)
|
||||
{
|
||||
static const WCHAR strW[] = {'t','e','x','t',0};
|
||||
static const char *str = "text";
|
||||
|
@ -2994,13 +2994,13 @@ static void test_EM_GETLINE(void)
|
|||
ok(!strcmp(buff, str), "Unexpected line data %s.\n", buff);
|
||||
|
||||
memset(buffW, 0, sizeof(buffW));
|
||||
*(WORD *)buffW = sizeof(buffW)/sizeof(buffW[0]);
|
||||
*(WORD *)buffW = ARRAY_SIZE(buffW);
|
||||
r = SendMessageW(hwnd[i], EM_GETLINE, 0, (LPARAM)buffW);
|
||||
ok(r == lstrlenW(strW), "Failed to get a line %d.\n", r);
|
||||
ok(!lstrcmpW(buffW, strW), "Unexpected line data %s.\n", wine_dbgstr_w(buffW));
|
||||
|
||||
memset(buffW, 0, sizeof(buffW));
|
||||
*(WORD *)buffW = sizeof(buffW)/sizeof(buffW[0]);
|
||||
*(WORD *)buffW = ARRAY_SIZE(buffW);
|
||||
r = SendMessageW(hwnd[i], EM_GETLINE, 1, (LPARAM)buffW);
|
||||
ok(r == lstrlenW(strW), "Failed to get a line %d.\n", r);
|
||||
ok(!lstrcmpW(buffW, strW), "Unexpected line data %s.\n", wine_dbgstr_w(buffW));
|
||||
|
@ -3061,6 +3061,83 @@ static const struct message killfocus_combined_seq[] =
|
|||
{ 0 }
|
||||
};
|
||||
|
||||
static void test_cue_banner(void)
|
||||
{
|
||||
HWND hwnd_edit;
|
||||
BOOL ret;
|
||||
static WCHAR getcuetestW[5] = {'T',0};
|
||||
static const WCHAR testcmp1W[] = {'T','e','s','t',0};
|
||||
static const WCHAR testcmp2W[] = {'T','e','s',0};
|
||||
static const WCHAR emptyW[] = {0};
|
||||
|
||||
hwnd_edit = create_editcontrolW(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
|
||||
|
||||
ret = SendMessageW(hwnd_edit, EM_GETCUEBANNER, (WPARAM)getcuetestW, 5);
|
||||
if (lstrcmpW(getcuetestW, emptyW) != 0)
|
||||
{
|
||||
win_skip("skipping for Win XP and 2003 Server.\n");
|
||||
DestroyWindow(hwnd_edit);
|
||||
return;
|
||||
}
|
||||
ok(lstrcmpW(getcuetestW, emptyW) == 0, "First char is %c\n", getcuetestW[0]);
|
||||
ok(ret == FALSE, "EM_GETCUEBANNER should have returned FALSE.\n");
|
||||
|
||||
lstrcpyW(getcuetestW, testcmp1W);
|
||||
ret = SendMessageW(hwnd_edit, EM_GETCUEBANNER, (WPARAM)getcuetestW, 0);
|
||||
ok(lstrcmpW(getcuetestW, testcmp1W) == 0, "String was %s.\n", wine_dbgstr_w(getcuetestW));
|
||||
ok(ret == FALSE, "EM_GETCUEBANNER should have returned FALSE.\n");
|
||||
|
||||
ret = SendMessageW(hwnd_edit, EM_GETCUEBANNER, 0, 0);
|
||||
ok(ret == FALSE, "EM_GETCUEBANNER should have returned FALSE.\n");
|
||||
|
||||
ret = SendMessageW(hwnd_edit, EM_SETCUEBANNER, 0, 0);
|
||||
ok(ret == FALSE, "EM_SETCUEBANNER should have returned FALSE.\n");
|
||||
|
||||
ret = SendMessageW(hwnd_edit, EM_GETCUEBANNER, 0, 0);
|
||||
ok(ret == FALSE, "EM_GETCUEBANNER should have returned FALSE.\n");
|
||||
|
||||
lstrcpyW(getcuetestW, testcmp1W);
|
||||
ret = SendMessageW(hwnd_edit, EM_SETCUEBANNER, 0, (LPARAM)getcuetestW);
|
||||
ok(ret == TRUE, "EM_SETCUEBANNER should have returned TRUE.\n");
|
||||
|
||||
ret = SendMessageW(hwnd_edit, EM_GETCUEBANNER, 0, 5);
|
||||
ok(ret == TRUE, "EM_GETCUEBANNER should have returned TRUE.\n");
|
||||
|
||||
ret = SendMessageW(hwnd_edit, EM_GETCUEBANNER, (WPARAM)getcuetestW, 5);
|
||||
ok(ret == TRUE, "EM_GETCUEBANNER should have returned TRUE.\n");
|
||||
ok(lstrcmpW(getcuetestW, testcmp1W) == 0, "EM_GETCUEBANNER returned string %s.\n", wine_dbgstr_w(getcuetestW));
|
||||
|
||||
ret = SendMessageW(hwnd_edit, EM_SETCUEBANNER, 0, (LPARAM)emptyW);
|
||||
ok(ret == TRUE, "EM_SETCUEBANNER should have returned TRUE.\n");
|
||||
|
||||
ret = SendMessageW(hwnd_edit, EM_GETCUEBANNER, (WPARAM)getcuetestW, 5);
|
||||
ok(ret == TRUE, "EM_GETCUEBANNER should have returned TRUE.\n");
|
||||
ok(lstrcmpW(getcuetestW, emptyW) == 0, "EM_GETCUEBANNER returned string %s.\n", wine_dbgstr_w(getcuetestW));
|
||||
|
||||
/* EM_GETCUEBANNER's buffer size includes null char */
|
||||
ret = SendMessageW(hwnd_edit, EM_SETCUEBANNER, 0, (LPARAM)testcmp1W);
|
||||
ok(ret == TRUE, "EM_SETCUEBANNER should have returned TRUE.\n");
|
||||
memset(getcuetestW, 0, lstrlenW(testcmp1W)*sizeof(WCHAR));
|
||||
ret = SendMessageW(hwnd_edit, EM_GETCUEBANNER, (WPARAM)getcuetestW, (LPARAM)lstrlenW(testcmp1W)+1);
|
||||
ok(ret == TRUE, "EM_GETCUEBANNER should have returned TRUE.\n");
|
||||
ok(lstrcmpW(getcuetestW, testcmp1W) == 0, "EM_GETCUEBANNER returned string %s.\n", wine_dbgstr_w(getcuetestW));
|
||||
memset(getcuetestW, 0, lstrlenW(testcmp1W)*sizeof(WCHAR));
|
||||
ret = SendMessageW(hwnd_edit, EM_GETCUEBANNER, (WPARAM)getcuetestW, (LPARAM)lstrlenW(testcmp1W));
|
||||
ok(lstrcmpW(getcuetestW, testcmp2W) == 0, "EM_GETCUEBANNER returned string %s.\n", wine_dbgstr_w(getcuetestW));
|
||||
DestroyWindow(hwnd_edit);
|
||||
|
||||
/* setting cue banner fails for multi-line edit controls */
|
||||
hwnd_edit = create_editcontrolW(ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE, 0);
|
||||
lstrcpyW(getcuetestW, testcmp1W);
|
||||
ret = SendMessageW(hwnd_edit, EM_GETCUEBANNER, (WPARAM)getcuetestW, 5);
|
||||
ok(ret == FALSE, "EM_SETCUEBANNER.\n");
|
||||
ok(lstrcmpW(getcuetestW, testcmp1W) == 0, "String was %s.\n", wine_dbgstr_w(getcuetestW));
|
||||
ret = SendMessageW(hwnd_edit, EM_SETCUEBANNER, 0, (LPARAM)getcuetestW);
|
||||
ok(ret == FALSE, "EM_SETCUEBANNER.\n");
|
||||
|
||||
DestroyWindow(hwnd_edit);
|
||||
}
|
||||
|
||||
static void test_change_focus(void)
|
||||
{
|
||||
HWND hwnd, parent_wnd;
|
||||
|
@ -3138,6 +3215,7 @@ START_TEST(edit)
|
|||
test_EM_GETLINE();
|
||||
test_wordbreak_proc();
|
||||
test_change_focus();
|
||||
test_cue_banner();
|
||||
|
||||
UnregisterWindowClasses();
|
||||
|
||||
|
|
|
@ -1130,7 +1130,7 @@ static void test_hdm_index_messages(HWND hParent)
|
|||
ok_sequence(sequences, PARENT_SEQ_INDEX, add_header_to_parent_seq,
|
||||
"adder header control to parent", FALSE);
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
for (i = 0; i < sizeof(item_texts)/sizeof(item_texts[0]); i++)
|
||||
for (i = 0; i < ARRAY_SIZE(item_texts); i++)
|
||||
{
|
||||
hdItem.mask = HDI_TEXT | HDI_WIDTH | HDI_FORMAT;
|
||||
hdItem.pszText = (char*)item_texts[i];
|
||||
|
@ -1170,7 +1170,7 @@ static void test_hdm_index_messages(HWND hParent)
|
|||
|
||||
hdItem.mask = HDI_TEXT | HDI_WIDTH;
|
||||
hdItem.pszText = buffA;
|
||||
hdItem.cchTextMax = sizeof(buffA)/sizeof(buffA[0]);
|
||||
hdItem.cchTextMax = ARRAY_SIZE(buffA);
|
||||
retVal = SendMessageA(hChild, HDM_GETITEMA, 0, (LPARAM) &hdItem);
|
||||
ok(retVal == TRUE, "Getting the 1st header item should return TRUE, got %d\n", retVal);
|
||||
|
||||
|
|
|
@ -922,7 +922,6 @@ static void check_ilhead_data(const ILHEAD *ilh, INT cx, INT cy, INT cur, INT ma
|
|||
}
|
||||
else
|
||||
{
|
||||
grow = (WORD)(grow + 3) & ~3;
|
||||
ok(ilh->cMaxImage == max, "wrong cMaxImage %d (expected %d)\n", ilh->cMaxImage, max);
|
||||
ok(ilh->cGrow == grow_aligned, "Unexpected cGrow %d, expected %d\n", ilh->cGrow, grow_aligned);
|
||||
}
|
||||
|
@ -1100,7 +1099,7 @@ static void image_list_init(HIMAGELIST himl, INT grow)
|
|||
|
||||
check_iml_data(himl, BMP_CX, BMP_CX, 0, 2, grow, ILC_COLOR24, "total 0");
|
||||
|
||||
for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
|
||||
for (i = 0; i < ARRAY_SIZE(td); i++)
|
||||
{
|
||||
image_list_add_bitmap(himl, td[i].grey, i + 1);
|
||||
check_iml_data(himl, td[i].cx, td[i].cy, td[i].cur, td[i].max, grow, td[i].bpp, td[i].comment);
|
||||
|
@ -2029,7 +2028,11 @@ static void check_color_table(const char *name, HDC hdc, HIMAGELIST himl, UINT i
|
|||
{
|
||||
IMAGEINFO info;
|
||||
INT ret;
|
||||
#ifdef __REACTOS__
|
||||
char bmi_buffer[FIELD_OFFSET(BITMAPINFO, bmiColors) + 256 * sizeof(RGBQUAD)];
|
||||
#else
|
||||
char bmi_buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
|
||||
#endif
|
||||
BITMAPINFO *bmi = (BITMAPINFO *)bmi_buffer;
|
||||
int i, depth = ilc & 0xfe;
|
||||
|
||||
|
@ -2061,7 +2064,11 @@ static void check_color_table(const char *name, HDC hdc, HIMAGELIST himl, UINT i
|
|||
|
||||
static void get_default_color_table(HDC hdc, int bpp, RGBQUAD *table)
|
||||
{
|
||||
#ifdef __REACTOS__
|
||||
char bmi_buffer[FIELD_OFFSET(BITMAPINFO, bmiColors) + 256 * sizeof(RGBQUAD)];
|
||||
#else
|
||||
char bmi_buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
|
||||
#endif
|
||||
BITMAPINFO *bmi = (BITMAPINFO *)bmi_buffer;
|
||||
HBITMAP tmp;
|
||||
int i;
|
||||
|
@ -2109,7 +2116,11 @@ static void test_color_table(UINT ilc)
|
|||
{
|
||||
HIMAGELIST himl;
|
||||
INT ret;
|
||||
#ifdef __REACTOS__
|
||||
char bmi_buffer[FIELD_OFFSET(BITMAPINFO, bmiColors) + 256 * sizeof(RGBQUAD)];
|
||||
#else
|
||||
char bmi_buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
|
||||
#endif
|
||||
BITMAPINFO *bmi = (BITMAPINFO *)bmi_buffer;
|
||||
HDC hdc = CreateCompatibleDC(0);
|
||||
HBITMAP dib4, dib8, dib32;
|
||||
|
|
|
@ -50,12 +50,12 @@ static void test_get_set_text(void)
|
|||
}
|
||||
|
||||
/* check text just after creation */
|
||||
r = GetWindowTextA(hwnd, ip, sizeof(ip)/sizeof(CHAR));
|
||||
r = GetWindowTextA(hwnd, ip, ARRAY_SIZE(ip));
|
||||
expect(7, r);
|
||||
ok(strcmp(ip, "0.0.0.0") == 0, "Expected null IP address, got %s\n", ip);
|
||||
|
||||
SendMessageA(hwnd, IPM_SETADDRESS, 0, MAKEIPADDRESS(127, 0, 0, 1));
|
||||
r = GetWindowTextA(hwnd, ip, sizeof(ip)/sizeof(CHAR));
|
||||
r = GetWindowTextA(hwnd, ip, ARRAY_SIZE(ip));
|
||||
expect(9, r);
|
||||
ok(strcmp(ip, "127.0.0.1") == 0, "Expected 127.0.0.1, got %s\n", ip);
|
||||
|
||||
|
|
|
@ -30,6 +30,52 @@
|
|||
#include "wine/heap.h"
|
||||
#include "wine/test.h"
|
||||
#include "v6util.h"
|
||||
#include "msg.h"
|
||||
|
||||
enum seq_index
|
||||
{
|
||||
LB_SEQ_INDEX,
|
||||
PARENT_SEQ_INDEX,
|
||||
NUM_MSG_SEQUENCES
|
||||
};
|
||||
|
||||
static struct msg_sequence *sequences[NUM_MSG_SEQUENCES];
|
||||
|
||||
/* encoded MEASUREITEMSTRUCT into a WPARAM */
|
||||
typedef struct
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
UINT CtlType : 4;
|
||||
UINT CtlID : 4;
|
||||
UINT itemID : 4;
|
||||
UINT wParam : 20;
|
||||
} item;
|
||||
WPARAM wp;
|
||||
} u;
|
||||
} MEASURE_ITEM_STRUCT;
|
||||
|
||||
static unsigned hash_Ly_W(const WCHAR *str)
|
||||
{
|
||||
unsigned hash = 0;
|
||||
|
||||
for (; *str; str++)
|
||||
hash = hash * 1664525u + (unsigned char)(*str) + 1013904223u;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
static unsigned hash_Ly(const char *str)
|
||||
{
|
||||
unsigned hash = 0;
|
||||
|
||||
for (; *str; str++)
|
||||
hash = hash * 1664525u + (unsigned char)(*str) + 1013904223u;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
static const char * const strings[4] = {
|
||||
"First added",
|
||||
|
@ -43,22 +89,53 @@ static const char * const strings[4] = {
|
|||
|
||||
static const char BAD_EXTENSION[] = "*.badtxt";
|
||||
|
||||
static int strcmp_aw(LPCWSTR strw, const char *stra)
|
||||
{
|
||||
WCHAR buf[1024];
|
||||
#define ID_LISTBOX 1
|
||||
|
||||
if (!stra) return 1;
|
||||
MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, sizeof(buf)/sizeof(WCHAR));
|
||||
return lstrcmpW(strw, buf);
|
||||
static LRESULT WINAPI listbox_wnd_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;
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_SIZE:
|
||||
case WM_GETTEXT:
|
||||
case WM_PAINT:
|
||||
case WM_ERASEBKGND:
|
||||
case WM_WINDOWPOSCHANGING:
|
||||
case WM_WINDOWPOSCHANGED:
|
||||
case WM_NCCALCSIZE:
|
||||
case WM_NCPAINT:
|
||||
case WM_NCHITTEST:
|
||||
case WM_DEVICECHANGE:
|
||||
break;
|
||||
|
||||
default:
|
||||
msg.message = message;
|
||||
msg.flags = sent|wparam|lparam;
|
||||
if (defwndproc_counter) msg.flags |= defwinproc;
|
||||
msg.wParam = wParam;
|
||||
msg.lParam = lParam;
|
||||
add_message(sequences, LB_SEQ_INDEX, &msg);
|
||||
}
|
||||
|
||||
defwndproc_counter++;
|
||||
ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
|
||||
defwndproc_counter--;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HWND create_listbox(DWORD add_style, HWND parent)
|
||||
{
|
||||
INT_PTR ctl_id = 0;
|
||||
WNDPROC oldproc;
|
||||
HWND handle;
|
||||
|
||||
if (parent)
|
||||
ctl_id=1;
|
||||
ctl_id = ID_LISTBOX;
|
||||
|
||||
handle = CreateWindowA(WC_LISTBOXA, "TestList", (LBS_STANDARD & ~LBS_SORT) | add_style, 0, 0, 100, 100,
|
||||
parent, (HMENU)ctl_id, NULL, 0);
|
||||
|
@ -69,6 +146,9 @@ static HWND create_listbox(DWORD add_style, HWND parent)
|
|||
SendMessageA(handle, LB_ADDSTRING, 0, (LPARAM) strings[2]);
|
||||
SendMessageA(handle, LB_ADDSTRING, 0, (LPARAM) strings[3]);
|
||||
|
||||
oldproc = (WNDPROC)SetWindowLongPtrA(handle, GWLP_WNDPROC, (LONG_PTR)listbox_wnd_proc);
|
||||
SetWindowLongPtrA(handle, GWLP_USERDATA, (LONG_PTR)oldproc);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
@ -84,7 +164,6 @@ struct listbox_stat
|
|||
|
||||
struct listbox_test
|
||||
{
|
||||
struct listbox_prop prop;
|
||||
struct listbox_stat init, init_todo;
|
||||
struct listbox_stat click, click_todo;
|
||||
struct listbox_stat step, step_todo;
|
||||
|
@ -117,8 +196,7 @@ static void keypress(HWND handle, WPARAM keycode, BYTE scancode, BOOL extended)
|
|||
|
||||
#define listbox_field_ok(t, s, f, got) \
|
||||
ok (t.s.f==got.f, "style %#x, step " #s ", field " #f \
|
||||
": expected %d, got %d\n", (unsigned int)t.prop.add_style, \
|
||||
t.s.f, got.f)
|
||||
": expected %d, got %d\n", style, t.s.f, got.f)
|
||||
|
||||
#define listbox_todo_field_ok(t, s, f, got) \
|
||||
todo_wine_if (t.s##_todo.f) { listbox_field_ok(t, s, f, got); }
|
||||
|
@ -129,12 +207,23 @@ static void keypress(HWND handle, WPARAM keycode, BYTE scancode, BOOL extended)
|
|||
listbox_todo_field_ok(t, s, caret, got); \
|
||||
listbox_todo_field_ok(t, s, selcount, got)
|
||||
|
||||
static void run_test(const struct listbox_test test)
|
||||
static void run_test(DWORD style, const struct listbox_test test)
|
||||
{
|
||||
static const struct message delete_seq[] =
|
||||
{
|
||||
{ LB_DELETESTRING, sent|wparam|lparam, 0, 0 },
|
||||
{ LB_DELETESTRING, sent|wparam|lparam, 0, 0 },
|
||||
{ LB_DELETESTRING, sent|wparam|lparam, 0, 0 },
|
||||
{ LB_DELETESTRING, sent|wparam|lparam, 0, 0 },
|
||||
{ LB_RESETCONTENT, sent|wparam|lparam|defwinproc, 0, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
struct listbox_stat answer;
|
||||
HWND hLB=create_listbox (test.prop.add_style, 0);
|
||||
int i, res, count;
|
||||
RECT second_item;
|
||||
int i, res;
|
||||
HWND hLB;
|
||||
|
||||
hLB = create_listbox (style, 0);
|
||||
|
||||
listbox_query (hLB, &answer);
|
||||
listbox_ok (test, init, answer);
|
||||
|
@ -152,13 +241,13 @@ static void run_test(const struct listbox_test test)
|
|||
|
||||
DestroyWindow(hLB);
|
||||
|
||||
hLB = create_listbox(test.prop.add_style, 0);
|
||||
hLB = create_listbox(style, 0);
|
||||
|
||||
SendMessageA(hLB, LB_SELITEMRANGE, TRUE, MAKELPARAM(1, 2));
|
||||
listbox_query(hLB, &answer);
|
||||
listbox_ok(test, sel, answer);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
for (i = 0; i < 4 && !(style & LBS_NODATA); i++)
|
||||
{
|
||||
DWORD size = SendMessageA(hLB, LB_GETTEXTLEN, i, 0);
|
||||
int resA, resW;
|
||||
|
@ -171,13 +260,9 @@ static void run_test(const struct listbox_test test)
|
|||
|
||||
txtw = heap_alloc_zero((size + 1) * sizeof(*txtw));
|
||||
resW = SendMessageW(hLB, LB_GETTEXT, i, (LPARAM)txtw);
|
||||
if (resA != resW)
|
||||
trace("SendMessageW(LB_GETTEXT) not supported on this platform (resA=%d resW=%d), skipping...\n", resA, resW);
|
||||
else
|
||||
{
|
||||
WideCharToMultiByte(CP_ACP, 0, txtw, -1, txt, size, NULL, NULL);
|
||||
ok(!strcmp (txt, strings[i]), "returned string for item %d does not match %s vs %s\n", i, txt, strings[i]);
|
||||
}
|
||||
ok(resA == resW, "Unexpected text length.\n");
|
||||
WideCharToMultiByte(CP_ACP, 0, txtw, -1, txt, size, NULL, NULL);
|
||||
ok(!strcmp (txt, strings[i]), "Unexpected string for item %d, %s vs %s.\n", i, txt, strings[i]);
|
||||
|
||||
heap_free(txtw);
|
||||
heap_free(txt);
|
||||
|
@ -190,8 +275,17 @@ static void run_test(const struct listbox_test test)
|
|||
ok(res == LB_ERR, "Expected LB_ERR items, got %d\n", res);
|
||||
res = SendMessageA(hLB, LB_DELETESTRING, 4, 0);
|
||||
ok(res == LB_ERR, "Expected LB_ERR items, got %d\n", res);
|
||||
res = SendMessageA(hLB, LB_GETCOUNT, 0, 0);
|
||||
ok(res == 4, "Expected 4 items, got %d\n", res);
|
||||
count = SendMessageA(hLB, LB_GETCOUNT, 0, 0);
|
||||
ok(count == 4, "Unexpected item count %d.\n", count);
|
||||
|
||||
/* Emptying listbox sends a LB_RESETCONTENT to itself. */
|
||||
flush_sequence(sequences, LB_SEQ_INDEX);
|
||||
for (i = count; i--;)
|
||||
{
|
||||
res = SendMessageA(hLB, LB_DELETESTRING, 0, 0);
|
||||
ok(res == i, "Unexpected return value %d.\n", res);
|
||||
}
|
||||
ok_sequence(sequences, LB_SEQ_INDEX, delete_seq, "Emptying listbox", FALSE);
|
||||
|
||||
DestroyWindow(hLB);
|
||||
}
|
||||
|
@ -234,41 +328,85 @@ static void test_item_height(void)
|
|||
|
||||
static int got_selchange;
|
||||
|
||||
static LRESULT WINAPI main_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
static LRESULT WINAPI main_window_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static LONG defwndproc_counter = 0;
|
||||
struct message m = { 0 };
|
||||
LRESULT ret;
|
||||
|
||||
m.message = msg;
|
||||
m.flags = sent|wparam|lparam;
|
||||
if (defwndproc_counter) m.flags |= defwinproc;
|
||||
m.wParam = wParam;
|
||||
m.lParam = lParam;
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_MEASUREITEM:
|
||||
{
|
||||
DWORD style = GetWindowLongA(GetWindow(hwnd, GW_CHILD), GWL_STYLE);
|
||||
MEASUREITEMSTRUCT *mi = (void*)lparam;
|
||||
MEASUREITEMSTRUCT *mis = (void *)lParam;
|
||||
BOOL is_unicode_data = FALSE;
|
||||
MEASURE_ITEM_STRUCT mi;
|
||||
|
||||
ok(wparam == mi->CtlID, "got wParam=%08lx, expected %08x\n", wparam, mi->CtlID);
|
||||
ok(mi->CtlType == ODT_LISTBOX, "mi->CtlType = %u\n", mi->CtlType);
|
||||
ok(mi->CtlID == 1, "mi->CtlID = %u\n", mi->CtlID);
|
||||
ok(mi->itemHeight, "mi->itemHeight = 0\n");
|
||||
|
||||
if (mi->itemID > 4 || style & LBS_OWNERDRAWFIXED)
|
||||
break;
|
||||
|
||||
if (style & LBS_HASSTRINGS)
|
||||
if (mis->CtlType == ODT_LISTBOX)
|
||||
{
|
||||
ok(!strcmp_aw((WCHAR*)mi->itemData, strings[mi->itemID]),
|
||||
"mi->itemData = %s (%d)\n", wine_dbgstr_w((WCHAR*)mi->itemData), mi->itemID);
|
||||
HWND ctrl = GetDlgItem(hwnd, mis->CtlID);
|
||||
is_unicode_data = GetWindowLongA(ctrl, GWL_STYLE) & LBS_HASSTRINGS;
|
||||
}
|
||||
|
||||
mi.u.wp = 0;
|
||||
mi.u.item.CtlType = mis->CtlType;
|
||||
mi.u.item.CtlID = mis->CtlID;
|
||||
mi.u.item.itemID = mis->itemID;
|
||||
mi.u.item.wParam = wParam;
|
||||
|
||||
m.wParam = mi.u.wp;
|
||||
if (is_unicode_data)
|
||||
m.lParam = mis->itemData ? hash_Ly_W((const WCHAR *)mis->itemData) : 0;
|
||||
else
|
||||
m.lParam = mis->itemData ? hash_Ly((const char *)mis->itemData) : 0;
|
||||
add_message(sequences, PARENT_SEQ_INDEX, &m);
|
||||
|
||||
ok(wParam == mis->CtlID, "got wParam=%08lx, expected %08x\n", wParam, mis->CtlID);
|
||||
ok(mis->CtlType == ODT_LISTBOX, "mi->CtlType = %u\n", mis->CtlType);
|
||||
ok(mis->CtlID == 1, "mi->CtlID = %u\n", mis->CtlID);
|
||||
ok(mis->itemHeight, "mi->itemHeight = 0\n");
|
||||
|
||||
break;
|
||||
}
|
||||
case WM_COMPAREITEM:
|
||||
{
|
||||
COMPAREITEMSTRUCT *cis = (COMPAREITEMSTRUCT *)lParam;
|
||||
HWND ctrl = GetDlgItem(hwnd, cis->CtlID);
|
||||
BOOL is_unicode_data = TRUE;
|
||||
|
||||
ok(wParam == cis->CtlID, "expected %#x, got %#lx\n", cis->CtlID, wParam);
|
||||
ok(cis->hwndItem == ctrl, "expected %p, got %p\n", ctrl, cis->hwndItem);
|
||||
ok((int)cis->itemID1 >= 0, "expected >= 0, got %d\n", cis->itemID1);
|
||||
ok((int)cis->itemID2 == -1, "expected -1, got %d\n", cis->itemID2);
|
||||
|
||||
if (cis->CtlType == ODT_LISTBOX)
|
||||
is_unicode_data = GetWindowLongA(ctrl, GWL_STYLE) & LBS_HASSTRINGS;
|
||||
|
||||
if (is_unicode_data)
|
||||
{
|
||||
m.wParam = cis->itemData1 ? hash_Ly_W((const WCHAR *)cis->itemData1) : 0;
|
||||
m.lParam = cis->itemData2 ? hash_Ly_W((const WCHAR *)cis->itemData2) : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ok((void*)mi->itemData == strings[mi->itemID],
|
||||
"mi->itemData = %08lx, expected %p\n", mi->itemData, strings[mi->itemID]);
|
||||
m.wParam = cis->itemData1 ? hash_Ly((const char *)cis->itemData1) : 0;
|
||||
m.lParam = cis->itemData2 ? hash_Ly((const char *)cis->itemData2) : 0;
|
||||
}
|
||||
add_message(sequences, PARENT_SEQ_INDEX, &m);
|
||||
break;
|
||||
}
|
||||
case WM_DRAWITEM:
|
||||
{
|
||||
RECT rc_item, rc_client, rc_clip;
|
||||
DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lparam;
|
||||
DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lParam;
|
||||
|
||||
ok(wparam == dis->CtlID, "got wParam=%08lx instead of %08x\n", wparam, dis->CtlID);
|
||||
ok(wParam == dis->CtlID, "got wParam=%08lx instead of %08x\n", wParam, dis->CtlID);
|
||||
ok(dis->CtlType == ODT_LISTBOX, "wrong CtlType %04x\n", dis->CtlType);
|
||||
|
||||
GetClientRect(dis->hwndItem, &rc_client);
|
||||
|
@ -284,14 +422,18 @@ static LRESULT WINAPI main_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARA
|
|||
}
|
||||
|
||||
case WM_COMMAND:
|
||||
if (HIWORD( wparam ) == LBN_SELCHANGE) got_selchange++;
|
||||
if (HIWORD( wParam ) == LBN_SELCHANGE) got_selchange++;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return DefWindowProcA(hwnd, msg, wparam, lparam);
|
||||
defwndproc_counter++;
|
||||
ret = DefWindowProcA(hwnd, msg, wParam, lParam);
|
||||
defwndproc_counter--;
|
||||
|
||||
return msg == WM_COMPAREITEM ? -1 : ret;
|
||||
}
|
||||
|
||||
static HWND create_parent( void )
|
||||
|
@ -320,33 +462,72 @@ static HWND create_parent( void )
|
|||
|
||||
static void test_ownerdraw(void)
|
||||
{
|
||||
static const DWORD styles[] =
|
||||
{
|
||||
0,
|
||||
LBS_NODATA
|
||||
};
|
||||
HWND parent, hLB;
|
||||
INT ret;
|
||||
RECT rc;
|
||||
UINT i;
|
||||
|
||||
parent = create_parent();
|
||||
ok(parent != NULL, "Failed to create parent window.\n");
|
||||
|
||||
hLB = create_listbox(LBS_OWNERDRAWFIXED | WS_CHILD | WS_VISIBLE, parent);
|
||||
ok(hLB != NULL, "Failed to create listbox window.\n");
|
||||
for (i = 0; i < ARRAY_SIZE(styles); i++)
|
||||
{
|
||||
hLB = create_listbox(LBS_OWNERDRAWFIXED | WS_CHILD | WS_VISIBLE | styles[i], parent);
|
||||
ok(hLB != NULL, "Failed to create listbox window.\n");
|
||||
|
||||
SetForegroundWindow(hLB);
|
||||
UpdateWindow(hLB);
|
||||
SetForegroundWindow(hLB);
|
||||
UpdateWindow(hLB);
|
||||
|
||||
/* make height short enough */
|
||||
SendMessageA(hLB, LB_GETITEMRECT, 0, (LPARAM)&rc);
|
||||
SetWindowPos(hLB, 0, 0, 0, 100, rc.bottom - rc.top + 1, SWP_NOZORDER | SWP_NOMOVE);
|
||||
/* make height short enough */
|
||||
SendMessageA(hLB, LB_GETITEMRECT, 0, (LPARAM)&rc);
|
||||
SetWindowPos(hLB, 0, 0, 0, 100, rc.bottom - rc.top + 1, SWP_NOZORDER | SWP_NOMOVE);
|
||||
|
||||
/* make 0 item invisible */
|
||||
SendMessageA(hLB, LB_SETTOPINDEX, 1, 0);
|
||||
ret = SendMessageA(hLB, LB_GETTOPINDEX, 0, 0);
|
||||
ok(ret == 1, "wrong top index %d\n", ret);
|
||||
/* make 0 item invisible */
|
||||
SendMessageA(hLB, LB_SETTOPINDEX, 1, 0);
|
||||
ret = SendMessageA(hLB, LB_GETTOPINDEX, 0, 0);
|
||||
ok(ret == 1, "wrong top index %d\n", ret);
|
||||
|
||||
SendMessageA(hLB, LB_GETITEMRECT, 0, (LPARAM)&rc);
|
||||
ok(!IsRectEmpty(&rc), "empty item rect\n");
|
||||
ok(rc.top < 0, "rc.top is not negative (%d)\n", rc.top);
|
||||
SendMessageA(hLB, LB_GETITEMRECT, 0, (LPARAM)&rc);
|
||||
ok(!IsRectEmpty(&rc), "empty item rect\n");
|
||||
ok(rc.top < 0, "rc.top is not negative (%d)\n", rc.top);
|
||||
|
||||
DestroyWindow(hLB);
|
||||
|
||||
/* Both FIXED and VARIABLE, FIXED should override VARIABLE. */
|
||||
hLB = CreateWindowA(WC_LISTBOXA, "TestList", LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE | styles[i],
|
||||
0, 0, 100, 100, NULL, NULL, NULL, 0);
|
||||
ok(hLB != NULL, "last error 0x%08x\n", GetLastError());
|
||||
|
||||
ok(GetWindowLongA(hLB, GWL_STYLE) & LBS_OWNERDRAWVARIABLE, "Unexpected window style.\n");
|
||||
|
||||
ret = SendMessageA(hLB, LB_INSERTSTRING, -1, 0);
|
||||
ok(ret == 0, "Unexpected return value %d.\n", ret);
|
||||
ret = SendMessageA(hLB, LB_INSERTSTRING, -1, 0);
|
||||
ok(ret == 1, "Unexpected return value %d.\n", ret);
|
||||
|
||||
ret = SendMessageA(hLB, LB_SETITEMHEIGHT, 0, 13);
|
||||
ok(ret == LB_OKAY, "Failed to set item height, %d.\n", ret);
|
||||
|
||||
ret = SendMessageA(hLB, LB_GETITEMHEIGHT, 0, 0);
|
||||
ok(ret == 13, "Unexpected item height %d.\n", ret);
|
||||
|
||||
ret = SendMessageA(hLB, LB_SETITEMHEIGHT, 1, 42);
|
||||
ok(ret == LB_OKAY, "Failed to set item height, %d.\n", ret);
|
||||
|
||||
ret = SendMessageA(hLB, LB_GETITEMHEIGHT, 0, 0);
|
||||
ok(ret == 42, "Unexpected item height %d.\n", ret);
|
||||
|
||||
ret = SendMessageA(hLB, LB_GETITEMHEIGHT, 1, 0);
|
||||
ok(ret == 42, "Unexpected item height %d.\n", ret);
|
||||
|
||||
DestroyWindow (hLB);
|
||||
}
|
||||
|
||||
DestroyWindow(hLB);
|
||||
DestroyWindow(parent);
|
||||
}
|
||||
|
||||
|
@ -447,17 +628,121 @@ static void test_LB_SETCURSEL(void)
|
|||
|
||||
SendMessageA(hLB, LB_SETITEMHEIGHT, 0, 32);
|
||||
|
||||
ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
|
||||
ok(ret == -1, "Unexpected anchor index %d.\n", ret);
|
||||
|
||||
ret = SendMessageA(hLB, LB_SETCURSEL, 2, 0);
|
||||
ok(ret == 2, "LB_SETCURSEL returned %d instead of 2\n", ret);
|
||||
ret = GetScrollPos(hLB, SB_VERT);
|
||||
ok(ret == 0, "expected vscroll 0, got %d\n", ret);
|
||||
|
||||
ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
|
||||
ok(ret == -1, "Unexpected anchor index %d.\n", ret);
|
||||
|
||||
ret = SendMessageA(hLB, LB_SETCURSEL, 3, 0);
|
||||
ok(ret == 3, "LB_SETCURSEL returned %d instead of 3\n", ret);
|
||||
ret = GetScrollPos(hLB, SB_VERT);
|
||||
ok(ret == 1, "expected vscroll 1, got %d\n", ret);
|
||||
|
||||
ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
|
||||
ok(ret == -1, "Unexpected anchor index %d.\n", ret);
|
||||
|
||||
DestroyWindow(hLB);
|
||||
|
||||
hLB = create_listbox(0, 0);
|
||||
ok(hLB != NULL, "Failed to create ListBox window.\n");
|
||||
|
||||
ret = SendMessageA(hLB, LB_SETCURSEL, 1, 0);
|
||||
ok(ret == 1, "Unexpected return value %d.\n", ret);
|
||||
|
||||
ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
|
||||
ok(ret == -1, "Unexpected anchor index %d.\n", ret);
|
||||
|
||||
DestroyWindow(hLB);
|
||||
|
||||
/* LBS_EXTENDEDSEL */
|
||||
hLB = create_listbox(LBS_EXTENDEDSEL, 0);
|
||||
ok(hLB != NULL, "Failed to create listbox.\n");
|
||||
|
||||
ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
|
||||
ok(ret == -1, "Unexpected anchor index %d.\n", ret);
|
||||
|
||||
ret = SendMessageA(hLB, LB_SETCURSEL, 2, 0);
|
||||
ok(ret == -1, "LB_SETCURSEL returned %d instead of 2\n", ret);
|
||||
|
||||
ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
|
||||
ok(ret == -1, "Unexpected anchor index %d.\n", ret);
|
||||
|
||||
DestroyWindow(hLB);
|
||||
|
||||
/* LBS_MULTIPLESEL */
|
||||
hLB = create_listbox(LBS_MULTIPLESEL, 0);
|
||||
ok(hLB != NULL, "Failed to create listbox.\n");
|
||||
|
||||
ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
|
||||
ok(ret == -1, "Unexpected anchor index %d.\n", ret);
|
||||
|
||||
ret = SendMessageA(hLB, LB_SETCURSEL, 2, 0);
|
||||
ok(ret == -1, "LB_SETCURSEL returned %d instead of 2\n", ret);
|
||||
|
||||
ret = SendMessageA(hLB, LB_GETANCHORINDEX, 0, 0);
|
||||
ok(ret == -1, "Unexpected anchor index %d.\n", ret);
|
||||
|
||||
DestroyWindow(hLB);
|
||||
}
|
||||
|
||||
static void test_LB_SETSEL(void)
|
||||
{
|
||||
HWND list;
|
||||
int ret;
|
||||
|
||||
/* LBS_EXTENDEDSEL */
|
||||
list = create_listbox(LBS_EXTENDEDSEL, 0);
|
||||
ok(list != NULL, "Failed to create ListBox window.\n");
|
||||
|
||||
ret = SendMessageA(list, LB_GETANCHORINDEX, 0, 0);
|
||||
ok(ret == -1, "Unexpected anchor index %d.\n", ret);
|
||||
|
||||
ret = SendMessageA(list, LB_SETSEL, TRUE, 0);
|
||||
ok(ret == 0, "Unexpected return value %d.\n", ret);
|
||||
ret = SendMessageA(list, LB_GETANCHORINDEX, 0, 0);
|
||||
ok(ret == 0, "Unexpected anchor index %d.\n", ret);
|
||||
|
||||
ret = SendMessageA(list, LB_SETSEL, TRUE, 1);
|
||||
ok(ret == 0, "Unexpected return value %d.\n", ret);
|
||||
ret = SendMessageA(list, LB_GETANCHORINDEX, 0, 0);
|
||||
ok(ret == 1, "Unexpected anchor index %d.\n", ret);
|
||||
|
||||
ret = SendMessageA(list, LB_SETSEL, FALSE, 1);
|
||||
ok(ret == 0, "Unexpected return value %d.\n", ret);
|
||||
ret = SendMessageA(list, LB_GETANCHORINDEX, 0, 0);
|
||||
ok(ret == 1, "Unexpected anchor index %d.\n", ret);
|
||||
|
||||
DestroyWindow(list);
|
||||
|
||||
/* LBS_MULTIPLESEL */
|
||||
list = create_listbox(LBS_MULTIPLESEL, 0);
|
||||
ok(list != NULL, "Failed to create ListBox window.\n");
|
||||
|
||||
ret = SendMessageA(list, LB_GETANCHORINDEX, 0, 0);
|
||||
ok(ret == -1, "Unexpected anchor index %d.\n", ret);
|
||||
|
||||
ret = SendMessageA(list, LB_SETSEL, TRUE, 0);
|
||||
ok(ret == 0, "Unexpected return value %d.\n", ret);
|
||||
ret = SendMessageA(list, LB_GETANCHORINDEX, 0, 0);
|
||||
ok(ret == 0, "Unexpected anchor index %d.\n", ret);
|
||||
|
||||
ret = SendMessageA(list, LB_SETSEL, TRUE, 1);
|
||||
ok(ret == 0, "Unexpected return value %d.\n", ret);
|
||||
ret = SendMessageA(list, LB_GETANCHORINDEX, 0, 0);
|
||||
ok(ret == 1, "Unexpected anchor index %d.\n", ret);
|
||||
|
||||
ret = SendMessageA(list, LB_SETSEL, FALSE, 1);
|
||||
ok(ret == 0, "Unexpected return value %d.\n", ret);
|
||||
ret = SendMessageA(list, LB_GETANCHORINDEX, 0, 0);
|
||||
ok(ret == 1, "Unexpected anchor index %d.\n", ret);
|
||||
|
||||
DestroyWindow(list);
|
||||
}
|
||||
|
||||
static void test_listbox_height(void)
|
||||
|
@ -603,6 +888,7 @@ static void test_listbox_item_data(void)
|
|||
|
||||
static void test_listbox_LB_DIR(void)
|
||||
{
|
||||
char path[MAX_PATH], curdir[MAX_PATH];
|
||||
HWND hList;
|
||||
int res, itemCount;
|
||||
int itemCount_justFiles;
|
||||
|
@ -615,6 +901,16 @@ static void test_listbox_LB_DIR(void)
|
|||
char driveletter;
|
||||
const char *wildcard = "*";
|
||||
HANDLE file;
|
||||
BOOL ret;
|
||||
|
||||
GetCurrentDirectoryA(ARRAY_SIZE(curdir), curdir);
|
||||
|
||||
GetTempPathA(ARRAY_SIZE(path), path);
|
||||
ret = SetCurrentDirectoryA(path);
|
||||
ok(ret, "Failed to set current directory.\n");
|
||||
|
||||
ret = CreateDirectoryA("lb_dir_test", NULL);
|
||||
ok(ret, "Failed to create test directory.\n");
|
||||
|
||||
file = CreateFileA( "wtest1.tmp.c", GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL );
|
||||
ok(file != INVALID_HANDLE_VALUE, "Error creating the test file: %d\n", GetLastError());
|
||||
|
@ -945,11 +1241,11 @@ static void test_listbox_LB_DIR(void)
|
|||
itemCount, itemCount_allDirs);
|
||||
ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, *) returned incorrect index!\n");
|
||||
|
||||
if (itemCount && GetCurrentDirectoryA( MAX_PATH, pathBuffer ) > 3) /* there's no [..] in drive root */
|
||||
if (itemCount)
|
||||
{
|
||||
memset(pathBuffer, 0, MAX_PATH);
|
||||
SendMessageA(hList, LB_GETTEXT, 0, (LPARAM)pathBuffer);
|
||||
ok( !strcmp(pathBuffer, "[..]"), "First element is not [..]\n");
|
||||
ok( !strcmp(pathBuffer, "[..]"), "First element is %s, not [..]\n", pathBuffer);
|
||||
}
|
||||
|
||||
/* This tests behavior when no files match the wildcard */
|
||||
|
@ -1034,6 +1330,9 @@ static void test_listbox_LB_DIR(void)
|
|||
DestroyWindow(hList);
|
||||
|
||||
DeleteFileA( "wtest1.tmp.c" );
|
||||
RemoveDirectoryA("lb_dir_test");
|
||||
|
||||
SetCurrentDirectoryA(curdir);
|
||||
}
|
||||
|
||||
static HWND g_listBox;
|
||||
|
@ -1533,7 +1832,13 @@ static void test_listbox_dlgdir(void)
|
|||
|
||||
static void test_set_count( void )
|
||||
{
|
||||
static const DWORD styles[] =
|
||||
{
|
||||
LBS_OWNERDRAWFIXED,
|
||||
LBS_HASSTRINGS,
|
||||
};
|
||||
HWND parent, listbox;
|
||||
unsigned int i;
|
||||
LONG ret;
|
||||
RECT r;
|
||||
|
||||
|
@ -1563,37 +1868,39 @@ static void test_set_count( void )
|
|||
ok( !IsRectEmpty( &r ), "got empty rect\n");
|
||||
|
||||
DestroyWindow( listbox );
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(styles); ++i)
|
||||
{
|
||||
listbox = create_listbox( styles[i] | WS_CHILD | WS_VISIBLE, parent );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = SendMessageA( listbox, LB_SETCOUNT, 100, 0 );
|
||||
ok( ret == LB_ERR, "expected %d, got %d\n", LB_ERR, ret );
|
||||
ok( GetLastError() == 0xdeadbeef, "Unexpected error %d.\n", GetLastError() );
|
||||
|
||||
DestroyWindow( listbox );
|
||||
}
|
||||
|
||||
DestroyWindow( parent );
|
||||
}
|
||||
|
||||
static int lb_getlistboxinfo;
|
||||
|
||||
static LRESULT WINAPI listbox_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
|
||||
|
||||
if (message == LB_GETLISTBOXINFO)
|
||||
lb_getlistboxinfo++;
|
||||
|
||||
return CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
static void test_GetListBoxInfo(void)
|
||||
{
|
||||
static const struct message getlistboxinfo_seq[] =
|
||||
{
|
||||
{ LB_GETLISTBOXINFO, sent },
|
||||
{ 0 }
|
||||
};
|
||||
HWND listbox, parent;
|
||||
WNDPROC oldproc;
|
||||
DWORD ret;
|
||||
|
||||
parent = create_parent();
|
||||
listbox = create_listbox(WS_CHILD | WS_VISIBLE, parent);
|
||||
|
||||
oldproc = (WNDPROC)SetWindowLongPtrA(listbox, GWLP_WNDPROC, (LONG_PTR)listbox_subclass_proc);
|
||||
SetWindowLongPtrA(listbox, GWLP_USERDATA, (LONG_PTR)oldproc);
|
||||
|
||||
lb_getlistboxinfo = 0;
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
ret = GetListBoxInfo(listbox);
|
||||
ok(ret > 0, "got %d\n", ret);
|
||||
ok(lb_getlistboxinfo == 1, "got %d\n", lb_getlistboxinfo);
|
||||
ok_sequence(sequences, LB_SEQ_INDEX, getlistboxinfo_seq, "GetListBoxInfo()", FALSE);
|
||||
|
||||
DestroyWindow(listbox);
|
||||
DestroyWindow(parent);
|
||||
|
@ -1805,76 +2112,101 @@ static void test_listbox(void)
|
|||
{
|
||||
static const struct listbox_test SS =
|
||||
/* {add_style} */
|
||||
{{0},
|
||||
{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
|
||||
{{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
|
||||
{ 1, 1, 1, LB_ERR}, {0,0,0,0},
|
||||
{ 2, 2, 2, LB_ERR}, {0,0,0,0},
|
||||
{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
|
||||
|
||||
/* {selected, anchor, caret, selcount}{TODO fields} */
|
||||
static const struct listbox_test SS_NS =
|
||||
{{LBS_NOSEL},
|
||||
{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
|
||||
{{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
|
||||
{ 1, 1, 1, LB_ERR}, {0,0,0,0},
|
||||
{ 2, 2, 2, LB_ERR}, {0,0,0,0},
|
||||
{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
|
||||
|
||||
static const struct listbox_test MS =
|
||||
{{LBS_MULTIPLESEL},
|
||||
{ 0, LB_ERR, 0, 0}, {0,0,0,0},
|
||||
{{ 0, LB_ERR, 0, 0}, {0,0,0,0},
|
||||
{ 1, 1, 1, 1}, {0,0,0,0},
|
||||
{ 2, 1, 2, 1}, {0,0,0,0},
|
||||
{ 0, LB_ERR, 0, 2}, {0,0,0,0}};
|
||||
|
||||
static const struct listbox_test MS_NS =
|
||||
{{LBS_MULTIPLESEL | LBS_NOSEL},
|
||||
{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
|
||||
{{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
|
||||
{ 1, 1, 1, LB_ERR}, {0,0,0,0},
|
||||
{ 2, 2, 2, LB_ERR}, {0,0,0,0},
|
||||
{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
|
||||
|
||||
static const struct listbox_test ES =
|
||||
{{LBS_EXTENDEDSEL},
|
||||
{ 0, LB_ERR, 0, 0}, {0,0,0,0},
|
||||
{{ 0, LB_ERR, 0, 0}, {0,0,0,0},
|
||||
{ 1, 1, 1, 1}, {0,0,0,0},
|
||||
{ 2, 2, 2, 1}, {0,0,0,0},
|
||||
{ 0, LB_ERR, 0, 2}, {0,0,0,0}};
|
||||
|
||||
static const struct listbox_test ES_NS =
|
||||
{{LBS_EXTENDEDSEL | LBS_NOSEL},
|
||||
{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
|
||||
{{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
|
||||
{ 1, 1, 1, LB_ERR}, {0,0,0,0},
|
||||
{ 2, 2, 2, LB_ERR}, {0,0,0,0},
|
||||
{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
|
||||
|
||||
static const struct listbox_test EMS =
|
||||
{{LBS_EXTENDEDSEL | LBS_MULTIPLESEL},
|
||||
{ 0, LB_ERR, 0, 0}, {0,0,0,0},
|
||||
{{ 0, LB_ERR, 0, 0}, {0,0,0,0},
|
||||
{ 1, 1, 1, 1}, {0,0,0,0},
|
||||
{ 2, 2, 2, 1}, {0,0,0,0},
|
||||
{ 0, LB_ERR, 0, 2}, {0,0,0,0}};
|
||||
|
||||
static const struct listbox_test EMS_NS =
|
||||
{{LBS_EXTENDEDSEL | LBS_MULTIPLESEL | LBS_NOSEL},
|
||||
{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
|
||||
{{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0},
|
||||
{ 1, 1, 1, LB_ERR}, {0,0,0,0},
|
||||
{ 2, 2, 2, LB_ERR}, {0,0,0,0},
|
||||
{LB_ERR, LB_ERR, 0, LB_ERR}, {0,0,0,0}};
|
||||
|
||||
run_test(SS);
|
||||
run_test(SS_NS);
|
||||
run_test(MS);
|
||||
run_test(MS_NS);
|
||||
run_test(ES);
|
||||
run_test(ES_NS);
|
||||
run_test(EMS);
|
||||
run_test(EMS_NS);
|
||||
run_test(0, SS);
|
||||
run_test(LBS_NOSEL, SS_NS);
|
||||
run_test(LBS_MULTIPLESEL, MS);
|
||||
run_test(LBS_MULTIPLESEL | LBS_NOSEL, MS_NS);
|
||||
run_test(LBS_EXTENDEDSEL, ES);
|
||||
run_test(LBS_EXTENDEDSEL | LBS_NOSEL, ES_NS);
|
||||
run_test(LBS_EXTENDEDSEL | LBS_MULTIPLESEL, EMS);
|
||||
run_test(LBS_EXTENDEDSEL | LBS_MULTIPLESEL | LBS_NOSEL, EMS_NS);
|
||||
|
||||
run_test(LBS_NODATA | LBS_OWNERDRAWFIXED, SS);
|
||||
run_test(LBS_NODATA | LBS_OWNERDRAWFIXED | LBS_NOSEL, SS_NS);
|
||||
run_test(LBS_NODATA | LBS_OWNERDRAWFIXED | LBS_MULTIPLESEL, MS);
|
||||
run_test(LBS_NODATA | LBS_OWNERDRAWFIXED | LBS_MULTIPLESEL | LBS_NOSEL, MS_NS);
|
||||
run_test(LBS_NODATA | LBS_OWNERDRAWFIXED | LBS_EXTENDEDSEL, ES);
|
||||
run_test(LBS_NODATA | LBS_OWNERDRAWFIXED | LBS_EXTENDEDSEL | LBS_NOSEL, ES_NS);
|
||||
run_test(LBS_NODATA | LBS_OWNERDRAWFIXED | LBS_EXTENDEDSEL | LBS_MULTIPLESEL, EMS);
|
||||
run_test(LBS_NODATA | LBS_OWNERDRAWFIXED | LBS_EXTENDEDSEL | LBS_MULTIPLESEL | LBS_NOSEL, EMS_NS);
|
||||
}
|
||||
|
||||
static const struct message lb_addstring_ownerdraw_parent_seq[] =
|
||||
{
|
||||
{ WM_MEASUREITEM, sent|wparam|lparam, 0x1012, 0xf30604ed },
|
||||
{ WM_MEASUREITEM, sent|wparam|lparam, 0x1112, 0xf30604ee },
|
||||
{ WM_MEASUREITEM, sent|wparam|lparam, 0x1212, 0xf30604ef },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message lb_addstring_sort_parent_seq[] =
|
||||
{
|
||||
{ WM_MEASUREITEM, sent|wparam|lparam, 0x1012, 0xf30604ed },
|
||||
{ WM_COMPAREITEM, sent|wparam|lparam, 0xf30604ed, 0xf30604ee },
|
||||
{ WM_MEASUREITEM, sent|wparam|lparam, 0x1112, 0xf30604ee },
|
||||
{ WM_COMPAREITEM, sent|wparam|lparam, 0xf30604ed, 0xf30604ef },
|
||||
{ WM_COMPAREITEM, sent|wparam|lparam, 0xf30604ee, 0xf30604ef },
|
||||
{ WM_MEASUREITEM, sent|wparam|lparam, 0x1212, 0xf30604ef },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message empty_seq[] =
|
||||
{
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static void test_WM_MEASUREITEM(void)
|
||||
{
|
||||
HWND parent, listbox;
|
||||
LRESULT data;
|
||||
LRESULT data, ret;
|
||||
|
||||
parent = create_parent();
|
||||
listbox = create_listbox(WS_CHILD | LBS_OWNERDRAWVARIABLE, parent);
|
||||
|
@ -1888,6 +2220,187 @@ static void test_WM_MEASUREITEM(void)
|
|||
|
||||
data = SendMessageA(listbox, LB_GETITEMDATA, 0, 0);
|
||||
ok(!data, "data = %08lx\n", data);
|
||||
|
||||
/* LBS_HASSTRINGS */
|
||||
parent = create_parent();
|
||||
listbox = CreateWindowExA(WS_EX_NOPARENTNOTIFY, WC_LISTBOXA, NULL,
|
||||
WS_CHILD | LBS_NOTIFY | LBS_OWNERDRAWVARIABLE | LBS_HASSTRINGS | WS_VISIBLE,
|
||||
10, 10, 80, 80, parent, (HMENU)ID_LISTBOX, 0, NULL);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 0");
|
||||
ok(ret == 0, "expected 0, got %ld\n", ret);
|
||||
ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 1");
|
||||
ok(ret == 1, "expected 1, got %ld\n", ret);
|
||||
ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2");
|
||||
ok(ret == 2, "expected 2, got %ld\n", ret);
|
||||
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, lb_addstring_ownerdraw_parent_seq,
|
||||
"LB_ADDSTRING (LBS_HASSTRINGS, ownerdraw)", FALSE);
|
||||
DestroyWindow(listbox);
|
||||
|
||||
/* LBS_SORT, no LBS_HASSTRINGS */
|
||||
listbox = CreateWindowExA(WS_EX_NOPARENTNOTIFY, WC_LISTBOXA, NULL,
|
||||
WS_CHILD | LBS_NOTIFY | LBS_OWNERDRAWVARIABLE | LBS_SORT | WS_VISIBLE,
|
||||
10, 10, 80, 80, parent, (HMENU)ID_LISTBOX, 0, NULL);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 0");
|
||||
ok(ret == 0, "expected 0, got %ld\n", ret);
|
||||
ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 1");
|
||||
ok(ret == 1, "expected 1, got %ld\n", ret);
|
||||
ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2");
|
||||
ok(ret == 2, "expected 2, got %ld\n", ret);
|
||||
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, lb_addstring_sort_parent_seq, "LB_ADDSTRING (LBS_SORT)", FALSE);
|
||||
DestroyWindow(listbox);
|
||||
|
||||
/* LBS_HASSTRINGS */
|
||||
listbox = CreateWindowExA(WS_EX_NOPARENTNOTIFY, WC_LISTBOXA, NULL,
|
||||
WS_CHILD | LBS_NOTIFY | LBS_HASSTRINGS | WS_VISIBLE,
|
||||
10, 10, 80, 80, parent, (HMENU)ID_LISTBOX, 0, NULL);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2");
|
||||
ok(ret == 0, "expected 0, got %ld\n", ret);
|
||||
ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 0");
|
||||
ok(ret == 1, "expected 1, got %ld\n", ret);
|
||||
ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 1");
|
||||
ok(ret == 2, "expected 2, got %ld\n", ret);
|
||||
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "LB_ADDSTRING (LBS_HASSTRINGS)", FALSE);
|
||||
DestroyWindow(listbox);
|
||||
|
||||
/* LBS_HASSTRINGS, LBS_SORT */
|
||||
listbox = CreateWindowExA(WS_EX_NOPARENTNOTIFY, WC_LISTBOXA, NULL,
|
||||
WS_CHILD | LBS_NOTIFY | LBS_HASSTRINGS | LBS_SORT | WS_VISIBLE,
|
||||
10, 10, 80, 80, parent, (HMENU)ID_LISTBOX, 0, NULL);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2");
|
||||
ok(ret == 0, "expected 0, got %ld\n", ret);
|
||||
ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 0");
|
||||
ok(ret == 0, "expected 0, got %ld\n", ret);
|
||||
ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 1");
|
||||
ok(ret == 1, "expected 1, got %ld\n", ret);
|
||||
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "LB_ADDSTRING (LBS_HASSTRINGS, LBS_SORT)", FALSE);
|
||||
DestroyWindow(listbox);
|
||||
|
||||
DestroyWindow(parent);
|
||||
}
|
||||
|
||||
static void test_LBS_NODATA(void)
|
||||
{
|
||||
static const DWORD invalid_styles[] =
|
||||
{
|
||||
0,
|
||||
LBS_OWNERDRAWVARIABLE,
|
||||
LBS_SORT,
|
||||
LBS_HASSTRINGS,
|
||||
LBS_OWNERDRAWFIXED | LBS_SORT,
|
||||
LBS_OWNERDRAWFIXED | LBS_HASSTRINGS,
|
||||
};
|
||||
static const UINT invalid_idx[] = { -2, 2 };
|
||||
static const UINT valid_idx[] = { 0, 1 };
|
||||
static const ULONG_PTR zero_data;
|
||||
HWND listbox, parent;
|
||||
INT ret, text_len;
|
||||
unsigned int i;
|
||||
ULONG_PTR data;
|
||||
BOOL is_wow64;
|
||||
|
||||
listbox = CreateWindowA(WC_LISTBOXA, "TestList", LBS_NODATA | LBS_OWNERDRAWFIXED | WS_VISIBLE,
|
||||
0, 0, 100, 100, NULL, NULL, NULL, 0);
|
||||
ok(listbox != NULL, "Failed to create ListBox window.\n");
|
||||
|
||||
ret = SendMessageA(listbox, LB_INSERTSTRING, -1, 0);
|
||||
ok(ret == 0, "Unexpected return value %d.\n", ret);
|
||||
ret = SendMessageA(listbox, LB_INSERTSTRING, -1, 0);
|
||||
ok(ret == 1, "Unexpected return value %d.\n", ret);
|
||||
ret = SendMessageA(listbox, LB_GETCOUNT, 0, 0);
|
||||
ok(ret == 2, "Unexpected return value %d.\n", ret);
|
||||
|
||||
/* Invalid indices. */
|
||||
for (i = 0; i < ARRAY_SIZE(invalid_idx); ++i)
|
||||
{
|
||||
ret = SendMessageA(listbox, LB_SETITEMDATA, invalid_idx[i], 42);
|
||||
ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
|
||||
ret = SendMessageA(listbox, LB_GETTEXTLEN, invalid_idx[i], 0);
|
||||
ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
|
||||
if (ret == LB_ERR)
|
||||
{
|
||||
ret = SendMessageA(listbox, LB_GETTEXT, invalid_idx[i], (LPARAM)&data);
|
||||
ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
|
||||
}
|
||||
ret = SendMessageA(listbox, LB_GETITEMDATA, invalid_idx[i], 0);
|
||||
ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
|
||||
}
|
||||
|
||||
IsWow64Process(GetCurrentProcess(), &is_wow64);
|
||||
#ifdef _WIN64
|
||||
text_len = 8;
|
||||
#else
|
||||
text_len = is_wow64 ? 8 : 4;
|
||||
#endif
|
||||
|
||||
/* Valid indices. */
|
||||
for (i = 0; i < ARRAY_SIZE(valid_idx); ++i)
|
||||
{
|
||||
ret = SendMessageA(listbox, LB_SETITEMDATA, valid_idx[i], 42);
|
||||
ok(ret == TRUE, "Unexpected return value %d.\n", ret);
|
||||
ret = SendMessageA(listbox, LB_GETTEXTLEN, valid_idx[i], 0);
|
||||
todo_wine_if(is_wow64)
|
||||
ok(ret == text_len, "Unexpected return value %d.\n", ret);
|
||||
|
||||
memset(&data, 0xee, sizeof(data));
|
||||
ret = SendMessageA(listbox, LB_GETTEXT, valid_idx[i], (LPARAM)&data);
|
||||
ok(ret == sizeof(data), "Unexpected return value %d.\n", ret);
|
||||
ok(!memcmp(&data, &zero_data, sizeof(data)), "Unexpected item data.\n");
|
||||
|
||||
ret = SendMessageA(listbox, LB_GETITEMDATA, valid_idx[i], 0);
|
||||
ok(ret == 0, "Unexpected return value %d.\n", ret);
|
||||
}
|
||||
|
||||
/* More messages that don't work with LBS_NODATA. */
|
||||
ret = SendMessageA(listbox, LB_FINDSTRING, 1, 0);
|
||||
ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
|
||||
ret = SendMessageA(listbox, LB_FINDSTRING, 1, 42);
|
||||
ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
|
||||
ret = SendMessageA(listbox, LB_FINDSTRINGEXACT, 1, 0);
|
||||
ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
|
||||
ret = SendMessageA(listbox, LB_FINDSTRINGEXACT, 1, 42);
|
||||
ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
|
||||
ret = SendMessageA(listbox, LB_SELECTSTRING, 1, 0);
|
||||
ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
|
||||
ret = SendMessageA(listbox, LB_SELECTSTRING, 1, 42);
|
||||
ok(ret == LB_ERR, "Unexpected return value %d.\n", ret);
|
||||
|
||||
DestroyWindow(listbox);
|
||||
|
||||
/* Invalid window style combinations. */
|
||||
parent = create_parent();
|
||||
ok(parent != NULL, "Failed to create parent window.\n");
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(invalid_styles); ++i)
|
||||
{
|
||||
DWORD style;
|
||||
|
||||
listbox = CreateWindowA(WC_LISTBOXA, "TestList", LBS_NODATA | WS_CHILD | invalid_styles[i],
|
||||
0, 0, 100, 100, parent, (HMENU)ID_LISTBOX, NULL, 0);
|
||||
ok(listbox != NULL, "Failed to create a listbox.\n");
|
||||
|
||||
style = GetWindowLongA(listbox, GWL_STYLE);
|
||||
ok((style & invalid_styles[i]) == invalid_styles[i], "%u: unexpected window styles %#x.\n", i, style);
|
||||
ret = SendMessageA(listbox, LB_SETCOUNT, 100, 0);
|
||||
ok(ret == LB_ERR, "%u: unexpected return value %d.\n", i, ret);
|
||||
DestroyWindow(listbox);
|
||||
}
|
||||
|
||||
DestroyWindow(parent);
|
||||
}
|
||||
|
||||
|
@ -1899,6 +2412,8 @@ START_TEST(listbox)
|
|||
if (!load_v6_module(&ctx_cookie, &hCtx))
|
||||
return;
|
||||
|
||||
init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
test_listbox();
|
||||
test_item_height();
|
||||
test_ownerdraw();
|
||||
|
@ -1914,6 +2429,8 @@ START_TEST(listbox)
|
|||
test_missing_lbuttonup();
|
||||
test_extents();
|
||||
test_WM_MEASUREITEM();
|
||||
test_LB_SETSEL();
|
||||
test_LBS_NODATA();
|
||||
|
||||
unload_v6_module(ctx_cookie, hCtx);
|
||||
}
|
||||
|
|
|
@ -75,6 +75,8 @@ static BOOL g_disp_A_to_W;
|
|||
static NMLVDISPINFOA g_editbox_disp_info;
|
||||
/* when this is set focus will be tested on LVN_DELETEITEM */
|
||||
static BOOL g_focus_test_LVN_DELETEITEM;
|
||||
/* Whether to send WM_KILLFOCUS to the edit control during LVN_ENDLABELEDIT */
|
||||
static BOOL g_WM_KILLFOCUS_on_LVN_ENDLABELEDIT;
|
||||
|
||||
static HWND subclass_editbox(HWND hwndListview);
|
||||
|
||||
|
@ -445,6 +447,25 @@ static const struct message parent_list_cd_seq[] = {
|
|||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message listview_end_label_edit[] = {
|
||||
{ WM_NOTIFY, sent|id, 0, 0, LVN_ENDLABELEDITA },
|
||||
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING},
|
||||
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
|
||||
{ WM_NOTIFY, sent|id|optional, 0, 0, NM_CUSTOMDRAW }, /* XP */
|
||||
{ WM_NOTIFY, sent|id, 0, 0, NM_SETFOCUS },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message listview_end_label_edit_kill_focus[] = {
|
||||
{ WM_NOTIFY, sent|id, 0, 0, LVN_ENDLABELEDITA },
|
||||
{ WM_COMMAND, sent|id|optional, 0, 0, EN_KILLFOCUS }, /* todo: not sent by wine yet */
|
||||
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGING },
|
||||
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
|
||||
{ WM_NOTIFY, sent|id|optional, 0, 0, NM_CUSTOMDRAW }, /* XP */
|
||||
{ WM_NOTIFY, sent|id, 0, 0, NM_SETFOCUS },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static LONG defwndproc_counter = 0;
|
||||
|
@ -457,6 +478,7 @@ static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LP
|
|||
msg.wParam = wParam;
|
||||
msg.lParam = lParam;
|
||||
if (message == WM_NOTIFY && lParam) msg.id = ((NMHDR*)lParam)->code;
|
||||
if (message == WM_COMMAND) msg.id = HIWORD(wParam);
|
||||
|
||||
/* log system messages, except for painting */
|
||||
if (message < WM_USER &&
|
||||
|
@ -503,24 +525,17 @@ static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LP
|
|||
/* always accept new item text */
|
||||
NMLVDISPINFOA *di = (NMLVDISPINFOA*)lParam;
|
||||
g_editbox_disp_info = *di;
|
||||
trace("LVN_ENDLABELEDIT: text=%s\n", di->item.pszText ? di->item.pszText : "(null)");
|
||||
|
||||
/* edit control still available from this notification */
|
||||
edit = (HWND)SendMessageA(((NMHDR*)lParam)->hwndFrom, LVM_GETEDITCONTROL, 0, 0);
|
||||
ok(IsWindow(edit), "expected valid edit control handle\n");
|
||||
ok((GetWindowLongA(edit, GWL_STYLE) & ES_MULTILINE) == 0, "edit is multiline\n");
|
||||
|
||||
if (g_WM_KILLFOCUS_on_LVN_ENDLABELEDIT)
|
||||
SendMessageA(edit, WM_KILLFOCUS, 0, 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
case LVN_BEGINSCROLL:
|
||||
case LVN_ENDSCROLL:
|
||||
{
|
||||
NMLVSCROLL *pScroll = (NMLVSCROLL*)lParam;
|
||||
|
||||
trace("LVN_%sSCROLL: (%d,%d)\n", pScroll->hdr.code == LVN_BEGINSCROLL ?
|
||||
"BEGIN" : "END", pScroll->dx, pScroll->dy);
|
||||
}
|
||||
break;
|
||||
case LVN_ITEMCHANGING:
|
||||
{
|
||||
NMLISTVIEW *nmlv = (NMLISTVIEW*)lParam;
|
||||
|
@ -1781,6 +1796,7 @@ static void test_redraw(void)
|
|||
HDC hdc;
|
||||
BOOL res;
|
||||
DWORD r;
|
||||
RECT rect;
|
||||
|
||||
hwnd = create_listview_control(LVS_REPORT);
|
||||
subclass_header(hwnd);
|
||||
|
@ -1838,6 +1854,13 @@ static void test_redraw(void)
|
|||
|
||||
ReleaseDC(hwndparent, hdc);
|
||||
|
||||
/* test setting the window style to what it already was */
|
||||
UpdateWindow(hwnd);
|
||||
SetWindowLongA(hwnd, GWL_STYLE, GetWindowLongA(hwnd, GWL_STYLE));
|
||||
GetUpdateRect(hwnd, &rect, FALSE);
|
||||
ok(rect.left == 0 && rect.top == 0 && rect.right == 0 && rect.bottom == 0,
|
||||
"Expected empty update rect, got %s\n", wine_dbgstr_rect(&rect));
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
|
@ -2337,7 +2360,7 @@ static void test_multiselect(void)
|
|||
r = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
|
||||
ok(r == 0, "got %d\n", r);
|
||||
|
||||
for (i = 0; i < sizeof(task_list)/sizeof(task_list[0]); i++) {
|
||||
for (i = 0; i < ARRAY_SIZE(task_list); i++) {
|
||||
DWORD selected_count;
|
||||
LVITEMA item;
|
||||
|
||||
|
@ -3490,7 +3513,7 @@ static void test_norecompute(void)
|
|||
item.mask = LVIF_TEXT | LVIF_NORECOMPUTE;
|
||||
item.iItem = 0;
|
||||
item.pszText = buff;
|
||||
item.cchTextMax = sizeof(buff)/sizeof(CHAR);
|
||||
item.cchTextMax = ARRAY_SIZE(buff);
|
||||
res = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item);
|
||||
expect(TRUE, res);
|
||||
ok(lstrcmpA(buff, testA) == 0, "Expected (%s), got (%s)\n", testA, buff);
|
||||
|
@ -3504,7 +3527,7 @@ static void test_norecompute(void)
|
|||
item.mask = LVIF_TEXT | LVIF_NORECOMPUTE;
|
||||
item.iItem = 1;
|
||||
item.pszText = buff;
|
||||
item.cchTextMax = sizeof(buff)/sizeof(CHAR);
|
||||
item.cchTextMax = ARRAY_SIZE(buff);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
res = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item);
|
||||
|
@ -3529,7 +3552,7 @@ static void test_norecompute(void)
|
|||
item.mask = LVIF_TEXT | LVIF_NORECOMPUTE;
|
||||
item.iItem = 0;
|
||||
item.pszText = buff;
|
||||
item.cchTextMax = sizeof(buff)/sizeof(CHAR);
|
||||
item.cchTextMax = ARRAY_SIZE(buff);
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
res = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item);
|
||||
expect(TRUE, res);
|
||||
|
@ -4671,7 +4694,7 @@ static void test_canceleditlabel(void)
|
|||
ok(!IsWindow(hwndedit), "Expected edit control to be destroyed\n");
|
||||
memset(&itema, 0, sizeof(itema));
|
||||
itema.pszText = buff;
|
||||
itema.cchTextMax = sizeof(buff)/sizeof(CHAR);
|
||||
itema.cchTextMax = ARRAY_SIZE(buff);
|
||||
ret = SendMessageA(hwnd, LVM_GETITEMTEXTA, 0, (LPARAM)&itema);
|
||||
expect(5, ret);
|
||||
ok(strcmp(buff, test1) == 0, "Expected label text not to change\n");
|
||||
|
@ -5499,7 +5522,7 @@ static void test_header_notification2(void)
|
|||
memset(&itemW, 0, sizeof(itemW));
|
||||
itemW.mask = HDI_WIDTH | HDI_ORDER | HDI_TEXT;
|
||||
itemW.pszText = buffer;
|
||||
itemW.cchTextMax = sizeof(buffer);
|
||||
itemW.cchTextMax = ARRAY_SIZE(buffer);
|
||||
ret = SendMessageW(header, HDM_GETITEMW, 0, (LPARAM)&itemW);
|
||||
expect(1, ret);
|
||||
|
||||
|
@ -5667,7 +5690,7 @@ static void test_dispinfo(void)
|
|||
|
||||
g_disp_A_to_W = TRUE;
|
||||
item.pszText = (char*)buff;
|
||||
item.cchTextMax = sizeof(buff)/sizeof(WCHAR);
|
||||
item.cchTextMax = ARRAY_SIZE(buff);
|
||||
ret = SendMessageA(hwnd, LVM_GETITEMTEXTA, 0, (LPARAM)&item);
|
||||
ok(ret == sizeof(testA)-1, "got %d, expected 4\n", ret);
|
||||
g_disp_A_to_W = FALSE;
|
||||
|
@ -6186,7 +6209,7 @@ static void test_state_image(void)
|
|||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(styles)/sizeof(styles[0]); i++)
|
||||
for (i = 0; i < ARRAY_SIZE(styles); i++)
|
||||
{
|
||||
static char text[] = "Item";
|
||||
static char subtext[] = "Subitem";
|
||||
|
@ -6331,6 +6354,127 @@ static void test_LVSCW_AUTOSIZE(void)
|
|||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
static void test_LVN_ENDLABELEDIT(void)
|
||||
{
|
||||
WCHAR text[] = {'l','a','l','a',0};
|
||||
HWND hwnd, hwndedit;
|
||||
LVITEMW item = {0};
|
||||
DWORD ret;
|
||||
|
||||
hwnd = create_listview_control(LVS_REPORT | LVS_EDITLABELS);
|
||||
|
||||
insert_column(hwnd, 0);
|
||||
|
||||
item.mask = LVIF_TEXT;
|
||||
item.pszText = text;
|
||||
SendMessageW(hwnd, LVM_INSERTITEMW, 0, (LPARAM)&item);
|
||||
|
||||
/* Test normal editing */
|
||||
SetFocus(hwnd);
|
||||
hwndedit = (HWND)SendMessageW(hwnd, LVM_EDITLABELW, 0, 0);
|
||||
ok(hwndedit != NULL, "Failed to get edit control.\n");
|
||||
|
||||
ret = SendMessageA(hwndedit, WM_SETTEXT, 0, (LPARAM)"test");
|
||||
ok(ret, "Failed to set edit text.\n");
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
ret = SendMessageA(hwndedit, WM_KEYDOWN, VK_RETURN, 0);
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, listview_end_label_edit, "Label edit", FALSE);
|
||||
|
||||
/* Test editing with kill focus */
|
||||
SetFocus(hwnd);
|
||||
hwndedit = (HWND)SendMessageW(hwnd, LVM_EDITLABELW, 0, 0);
|
||||
ok(hwndedit != NULL, "Failed to get edit control.\n");
|
||||
|
||||
ret = SendMessageA(hwndedit, WM_SETTEXT, 0, (LPARAM)"test2");
|
||||
ok(ret, "Failed to set edit text.\n");
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
g_WM_KILLFOCUS_on_LVN_ENDLABELEDIT = TRUE;
|
||||
ret = SendMessageA(hwndedit, WM_KEYDOWN, VK_RETURN, 0);
|
||||
g_WM_KILLFOCUS_on_LVN_ENDLABELEDIT = FALSE;
|
||||
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, listview_end_label_edit_kill_focus,
|
||||
"Label edit, kill focus", FALSE);
|
||||
ok(GetFocus() == hwnd, "Unexpected focused window.\n");
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK create_item_height_wndproc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (msg == WM_CREATE)
|
||||
return 0;
|
||||
|
||||
return CallWindowProcA(listviewWndProc, hwnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
static void test_LVM_GETCOUNTPERPAGE(void)
|
||||
{
|
||||
static const DWORD styles[] = { LVS_ICON, LVS_LIST, LVS_REPORT, LVS_SMALLICON };
|
||||
unsigned int i, j;
|
||||
WNDCLASSEXA cls;
|
||||
ATOM class;
|
||||
HWND hwnd;
|
||||
BOOL ret;
|
||||
|
||||
cls.cbSize = sizeof(WNDCLASSEXA);
|
||||
ret = GetClassInfoExA(GetModuleHandleA(NULL), WC_LISTVIEWA, &cls);
|
||||
ok(ret, "Failed to get class info.\n");
|
||||
listviewWndProc = cls.lpfnWndProc;
|
||||
cls.lpfnWndProc = create_item_height_wndproc;
|
||||
cls.lpszClassName = "CountPerPageClass";
|
||||
class = RegisterClassExA(&cls);
|
||||
ok(class, "Failed to register class.\n");
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(styles); i++)
|
||||
{
|
||||
static char text[] = "item text";
|
||||
LVITEMA item = { 0 };
|
||||
UINT count, count2;
|
||||
|
||||
hwnd = create_listview_control(styles[i]);
|
||||
ok(hwnd != NULL, "Failed to create listview window.\n");
|
||||
|
||||
count = SendMessageA(hwnd, LVM_GETCOUNTPERPAGE, 0, 0);
|
||||
if (styles[i] == LVS_LIST || styles[i] == LVS_REPORT)
|
||||
ok(count > 0 || broken(styles[i] == LVS_LIST && count == 0), "%u: unexpected count %u.\n", i, count);
|
||||
else
|
||||
ok(count == 0, "%u: unexpected count %u.\n", i, count);
|
||||
|
||||
for (j = 0; j < 10; j++)
|
||||
{
|
||||
item.mask = LVIF_TEXT;
|
||||
item.pszText = text;
|
||||
SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&item);
|
||||
}
|
||||
|
||||
count2 = SendMessageA(hwnd, LVM_GETCOUNTPERPAGE, 0, 0);
|
||||
if (styles[i] == LVS_LIST || styles[i] == LVS_REPORT)
|
||||
ok(count == count2, "%u: unexpected count %u.\n", i, count2);
|
||||
else
|
||||
ok(count2 == 10, "%u: unexpected count %u.\n", i, count2);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
hwnd = CreateWindowA("CountPerPageClass", "Test", WS_VISIBLE | styles[i], 0, 0, 100, 100, NULL, NULL,
|
||||
GetModuleHandleA(NULL), 0);
|
||||
ok(hwnd != NULL, "Failed to create a window.\n");
|
||||
|
||||
count = SendMessageA(hwnd, LVM_GETCOUNTPERPAGE, 0, 0);
|
||||
ok(count == 0, "%u: unexpected count %u.\n", i, count);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
ret = UnregisterClassA("CountPerPageClass", NULL);
|
||||
ok(ret, "Failed to unregister test class.\n");
|
||||
}
|
||||
|
||||
START_TEST(listview)
|
||||
{
|
||||
ULONG_PTR ctx_cookie;
|
||||
|
@ -6392,6 +6536,8 @@ START_TEST(listview)
|
|||
test_callback_mask();
|
||||
test_state_image();
|
||||
test_LVSCW_AUTOSIZE();
|
||||
test_LVN_ENDLABELEDIT();
|
||||
test_LVM_GETCOUNTPERPAGE();
|
||||
|
||||
if (!load_v6_module(&ctx_cookie, &hCtx))
|
||||
{
|
||||
|
@ -6434,6 +6580,8 @@ START_TEST(listview)
|
|||
test_oneclickactivate();
|
||||
test_state_image();
|
||||
test_LVSCW_AUTOSIZE();
|
||||
test_LVN_ENDLABELEDIT();
|
||||
test_LVM_GETCOUNTPERPAGE();
|
||||
|
||||
unload_v6_module(ctx_cookie, hCtx);
|
||||
|
||||
|
|
|
@ -269,8 +269,7 @@ static void test_LoadIconWithScaleDown(void)
|
|||
|
||||
/* non-existing filename */
|
||||
hr = pLoadIconMetric(NULL, nonexisting_fileW, LIM_LARGE, &icon);
|
||||
todo_wine
|
||||
ok(hr == HRESULT_FROM_WIN32(ERROR_RESOURCE_TYPE_NOT_FOUND),
|
||||
ok(hr == HRESULT_FROM_WIN32(ERROR_RESOURCE_TYPE_NOT_FOUND) || hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) /* Win7 */,
|
||||
"Expected HRESULT_FROM_WIN32(ERROR_RESOURCE_TYPE_NOT_FOUND), got %x\n", hr);
|
||||
|
||||
hr = pLoadIconWithScaleDown(NULL, nonexisting_fileW, 32, 32, &icon);
|
||||
|
@ -343,23 +342,32 @@ static void test_LoadIconWithScaleDown(void)
|
|||
FreeLibrary(hinst);
|
||||
}
|
||||
|
||||
static void check_class( const char *name, int must_exist, UINT style, UINT ignore )
|
||||
static void check_class( const char *name, int must_exist, UINT style, UINT ignore, BOOL v6 )
|
||||
{
|
||||
WNDCLASSA wc;
|
||||
|
||||
if (GetClassInfoA( 0, name, &wc ))
|
||||
{
|
||||
todo_wine_if(strcmp(name, "Button") &&
|
||||
strcmp(name, "ComboBox") &&
|
||||
strcmp(name, "Edit") &&
|
||||
strcmp(name, "Static") &&
|
||||
strcmp(name, "ListBox") &&
|
||||
strcmp(name, "ComboLBox"))
|
||||
char buff[64];
|
||||
HWND hwnd;
|
||||
|
||||
todo_wine_if(!strcmp(name, "SysLink") && !must_exist && !v6)
|
||||
ok( must_exist, "System class %s should %sexist\n", name, must_exist ? "" : "NOT " );
|
||||
if (!must_exist) return;
|
||||
|
||||
todo_wine_if(!strcmp(name, "ScrollBar") || (!strcmp(name, "tooltips_class32") && v6))
|
||||
ok( !(~wc.style & style & ~ignore), "System class %s is missing bits %x (%08x/%08x)\n",
|
||||
name, ~wc.style & style, wc.style, style );
|
||||
todo_wine_if((!strcmp(name, "tooltips_class32") && v6) || !strcmp(name, "SysLink"))
|
||||
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 );
|
||||
|
||||
hwnd = CreateWindowA(name, 0, 0, 0, 0, 0, 0, 0, NULL, GetModuleHandleA(NULL), 0);
|
||||
ok( hwnd != NULL, "Failed to create window for class %s.\n", name );
|
||||
GetClassNameA(hwnd, buff, ARRAY_SIZE(buff));
|
||||
ok( !strcmp(name, buff), "Unexpected class name %s, expected %s.\n", buff, name );
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
else
|
||||
ok( !must_exist, "System class %s does not exist\n", name );
|
||||
|
@ -369,13 +377,40 @@ todo_wine_if(strcmp(name, "Button") &&
|
|||
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 );
|
||||
check_class( "Button", 1, CS_PARENTDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS, 0, FALSE );
|
||||
check_class( "ComboBox", 1, CS_PARENTDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS, 0, FALSE );
|
||||
check_class( "Edit", 1, CS_PARENTDC | CS_DBLCLKS | CS_GLOBALCLASS, 0, FALSE );
|
||||
check_class( "ListBox", 1, CS_PARENTDC | CS_DBLCLKS | CS_GLOBALCLASS, 0, FALSE );
|
||||
check_class( "ScrollBar", 1, CS_PARENTDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS, 0, FALSE );
|
||||
check_class( "Static", 1, CS_PARENTDC | CS_DBLCLKS | CS_GLOBALCLASS, 0, FALSE );
|
||||
check_class( "ComboLBox", 1, CS_SAVEBITS | CS_DBLCLKS | CS_DROPSHADOW | CS_GLOBALCLASS, CS_DROPSHADOW, FALSE );
|
||||
}
|
||||
|
||||
static void test_comctl32_classes(BOOL v6)
|
||||
{
|
||||
check_class(ANIMATE_CLASSA, 1, CS_DBLCLKS | CS_GLOBALCLASS, 0, FALSE);
|
||||
check_class(WC_COMBOBOXEXA, 1, CS_GLOBALCLASS, 0, FALSE);
|
||||
check_class(DATETIMEPICK_CLASSA, 1, CS_GLOBALCLASS, 0, FALSE);
|
||||
check_class(WC_HEADERA, 1, CS_DBLCLKS | CS_GLOBALCLASS, 0, FALSE);
|
||||
check_class(HOTKEY_CLASSA, 1, CS_GLOBALCLASS, 0, FALSE);
|
||||
check_class(WC_IPADDRESSA, 1, CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS, 0, FALSE);
|
||||
check_class(WC_LISTVIEWA, 1, CS_DBLCLKS | CS_GLOBALCLASS, 0, FALSE);
|
||||
check_class(MONTHCAL_CLASSA, 1, CS_GLOBALCLASS, 0, FALSE);
|
||||
check_class(WC_NATIVEFONTCTLA, 1, CS_GLOBALCLASS, 0, FALSE);
|
||||
check_class(WC_PAGESCROLLERA, 1, CS_GLOBALCLASS, 0, FALSE);
|
||||
check_class(PROGRESS_CLASSA, 1, CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS, 0, FALSE);
|
||||
check_class(REBARCLASSNAMEA, 1, CS_DBLCLKS | CS_GLOBALCLASS, 0, FALSE);
|
||||
check_class(STATUSCLASSNAMEA, 1, CS_DBLCLKS | CS_VREDRAW | CS_GLOBALCLASS, 0, FALSE);
|
||||
check_class(WC_TABCONTROLA, 1, CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS, 0, FALSE);
|
||||
check_class(TOOLBARCLASSNAMEA, 1, CS_DBLCLKS | CS_GLOBALCLASS, 0, FALSE);
|
||||
if (v6)
|
||||
check_class(TOOLTIPS_CLASSA, 1, CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS | CS_DROPSHADOW, CS_SAVEBITS | CS_HREDRAW | CS_VREDRAW /* XP */, TRUE);
|
||||
else
|
||||
check_class(TOOLTIPS_CLASSA, 1, CS_DBLCLKS | CS_GLOBALCLASS | CS_SAVEBITS, CS_HREDRAW | CS_VREDRAW /* XP */, FALSE);
|
||||
check_class(TRACKBAR_CLASSA, 1, CS_GLOBALCLASS, 0, FALSE);
|
||||
check_class(WC_TREEVIEWA, 1, CS_DBLCLKS | CS_GLOBALCLASS, 0, FALSE);
|
||||
check_class(UPDOWN_CLASSA, 1, CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS, 0, FALSE);
|
||||
check_class("SysLink", v6, CS_GLOBALCLASS, 0, FALSE);
|
||||
}
|
||||
|
||||
START_TEST(misc)
|
||||
|
@ -389,9 +424,12 @@ START_TEST(misc)
|
|||
test_GetPtrAW();
|
||||
test_Alloc();
|
||||
|
||||
test_comctl32_classes(FALSE);
|
||||
|
||||
if (!load_v6_module(&ctx_cookie, &hCtx))
|
||||
return;
|
||||
|
||||
test_comctl32_classes(TRUE);
|
||||
test_builtin_classes();
|
||||
test_LoadIconWithScaleDown();
|
||||
|
||||
|
|
|
@ -1216,7 +1216,7 @@ if (0)
|
|||
} else {
|
||||
title_index++;
|
||||
|
||||
if (sizeof(title_hits) / sizeof(title_hits[0]) <= title_index)
|
||||
if (ARRAY_SIZE(title_hits) <= title_index)
|
||||
break;
|
||||
|
||||
todo_wine_if(title_hits[title_index].todo)
|
||||
|
@ -1241,8 +1241,7 @@ if (0)
|
|||
|
||||
todo_wine ok(month_count + year_count >= 1, "Not enough month and year items\n");
|
||||
|
||||
ok(r.right <= x && title_index + 1 == sizeof(title_hits) / sizeof(title_hits[0]),
|
||||
"Wrong title layout\n");
|
||||
ok(r.right <= x && title_index + 1 == ARRAY_SIZE(title_hits), "Wrong title layout\n");
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
@ -1799,7 +1798,7 @@ static void test_hittest_v6(void)
|
|||
mchit.iOffset = -1;
|
||||
mchit.iCol = mchit.iRow = -1;
|
||||
mchit.uHit = 0;
|
||||
mchit.rc.left = mchit.rc.right = mchit.rc.top = mchit.rc.bottom = -1;
|
||||
SetRect(&mchit.rc, -1, -1, -1, -1);
|
||||
ret = SendMessageA(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit);
|
||||
expect_hex(MCHT_CALENDARDATE, ret);
|
||||
expect_hex(MCHT_CALENDARDATE, mchit.uHit);
|
||||
|
@ -1816,7 +1815,7 @@ static void test_hittest_v6(void)
|
|||
mchit.iOffset = -1;
|
||||
mchit.iCol = mchit.iRow = -1;
|
||||
mchit.uHit = 0;
|
||||
mchit.rc.left = mchit.rc.right = mchit.rc.top = mchit.rc.bottom = -1;
|
||||
SetRect(&mchit.rc, -1, -1, -1, -1);
|
||||
ret = SendMessageA(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit);
|
||||
expect_hex(MCHT_TITLE, ret);
|
||||
expect_hex(MCHT_TITLE, mchit.uHit);
|
||||
|
@ -1835,7 +1834,7 @@ static void test_hittest_v6(void)
|
|||
mchit.iOffset = -2;
|
||||
mchit.iCol = mchit.iRow = -2;
|
||||
mchit.uHit = ~0;
|
||||
mchit.rc.left = mchit.rc.right = mchit.rc.top = mchit.rc.bottom = -1;
|
||||
SetRect(&mchit.rc, -1, -1, -1, -1);
|
||||
ret = SendMessageA(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit);
|
||||
todo_wine expect_hex(MCHT_NOWHERE, ret);
|
||||
todo_wine expect_hex(MCHT_NOWHERE, mchit.uHit);
|
||||
|
@ -2016,7 +2015,7 @@ static void test_sel_notify(void)
|
|||
};
|
||||
int i;
|
||||
|
||||
for(i = 0; i < sizeof styles / sizeof styles[0]; i++)
|
||||
for(i = 0; i < ARRAY_SIZE(styles); i++)
|
||||
{
|
||||
hwnd = create_monthcal_control(styles[i].val);
|
||||
SetWindowLongPtrA(hwnd, GWLP_ID, SEL_NOTIFY_TEST_ID);
|
||||
|
|
|
@ -118,7 +118,7 @@ static LSTATUS mru_RegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey)
|
|||
dwMaxSubkeyLen++;
|
||||
dwMaxValueLen++;
|
||||
dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen);
|
||||
if (dwMaxLen > sizeof(szNameBuf)/sizeof(CHAR))
|
||||
if (dwMaxLen > ARRAY_SIZE(szNameBuf))
|
||||
{
|
||||
/* Name too big: alloc a buffer for it */
|
||||
if (!(lpszName = heap_alloc(dwMaxLen * sizeof(CHAR))))
|
||||
|
@ -480,7 +480,7 @@ static void test_CreateMRUListLazyA(void)
|
|||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(create_lazyA)/sizeof(create_lazya_t); i++)
|
||||
for (i = 0; i < ARRAY_SIZE(create_lazyA); i++)
|
||||
{
|
||||
const create_lazya_t *ptr = &create_lazyA[i];
|
||||
HANDLE hMRU;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -258,7 +258,7 @@ static void test_PBM_STEPIT(void)
|
|||
HWND progress;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < sizeof(stepit_tests)/sizeof(stepit_tests[0]); i++)
|
||||
for (i = 0; i < ARRAY_SIZE(stepit_tests); i++)
|
||||
{
|
||||
struct stepit_test *test = &stepit_tests[i];
|
||||
LRESULT ret;
|
||||
|
|
|
@ -280,7 +280,6 @@ static void test_disableowner(void)
|
|||
psh.pfnCallback = disableowner_callback;
|
||||
|
||||
p = pPropertySheetA(&psh);
|
||||
todo_wine
|
||||
ok(p == 0, "Expected 0, got %ld\n", p);
|
||||
ok(IsWindowEnabled(parenthwnd) != 0, "parent window should be enabled\n");
|
||||
DestroyWindow(parenthwnd);
|
||||
|
@ -1147,6 +1146,46 @@ static void test_CreatePropertySheetPage(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void test_bad_control_class(void)
|
||||
{
|
||||
PROPSHEETPAGEA psp;
|
||||
PROPSHEETHEADERA psh;
|
||||
HPROPSHEETPAGE hpsp;
|
||||
INT_PTR ret;
|
||||
|
||||
memset(&psp, 0, sizeof(psp));
|
||||
psp.dwSize = sizeof(psp);
|
||||
psp.hInstance = GetModuleHandleA(NULL);
|
||||
U(psp).pszTemplate = (LPCSTR)MAKEINTRESOURCE(IDD_PROP_PAGE_BAD_CONTROL);
|
||||
psp.pfnDlgProc = page_dlg_proc;
|
||||
|
||||
hpsp = pCreatePropertySheetPageA(&psp);
|
||||
ok(hpsp != 0, "CreatePropertySheetPage failed\n");
|
||||
|
||||
memset(&psh, 0, sizeof(psh));
|
||||
psh.dwSize = PROPSHEETHEADERA_V1_SIZE;
|
||||
psh.nPages = 1;
|
||||
psh.hwndParent = GetDesktopWindow();
|
||||
U3(psh).phpage = &hpsp;
|
||||
|
||||
#ifndef __REACTOS__ /* FIXME: Inspect why this causes a hang */
|
||||
ret = pPropertySheetA(&psh);
|
||||
ok(ret == 0, "got %ld\n", ret);
|
||||
#endif
|
||||
|
||||
/* Need to recreate hpsp otherwise the test fails under Windows */
|
||||
hpsp = pCreatePropertySheetPageA(&psp);
|
||||
ok(hpsp != 0, "CreatePropertySheetPage failed\n");
|
||||
U3(psh).phpage = &hpsp;
|
||||
|
||||
psh.dwFlags = PSH_MODELESS;
|
||||
ret = pPropertySheetA(&psh);
|
||||
ok(ret != 0, "got %ld\n", ret);
|
||||
|
||||
ok(IsWindow((HWND)ret), "bad window handle %#lx\n", ret);
|
||||
DestroyWindow((HWND)ret);
|
||||
}
|
||||
|
||||
static void init_functions(void)
|
||||
{
|
||||
HMODULE hComCtl32 = LoadLibraryA("comctl32.dll");
|
||||
|
@ -1172,6 +1211,7 @@ START_TEST(propsheet)
|
|||
|
||||
init_functions();
|
||||
|
||||
test_bad_control_class();
|
||||
test_title();
|
||||
test_nopage();
|
||||
test_disableowner();
|
||||
|
|
|
@ -828,7 +828,7 @@ static DWORD resize_numtests = 0;
|
|||
RECT r; \
|
||||
int value; \
|
||||
const rbresize_test_result_t *res = &resize_results[resize_numtests++]; \
|
||||
assert(resize_numtests <= sizeof(resize_results)/sizeof(resize_results[0])); \
|
||||
assert(resize_numtests <= ARRAY_SIZE(resize_results)); \
|
||||
GetWindowRect(hRebar, &r); \
|
||||
MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2); \
|
||||
if ((dwStyles[i] & (CCS_NOPARENTALIGN|CCS_NODIVIDER)) == CCS_NOPARENTALIGN) {\
|
||||
|
@ -855,7 +855,7 @@ static void test_resize(void)
|
|||
CCS_TOP | WS_BORDER, CCS_NOPARENTALIGN | CCS_NODIVIDER | WS_BORDER, CCS_NORESIZE | WS_BORDER,
|
||||
CCS_NOMOVEY | WS_BORDER};
|
||||
|
||||
const int styles_count = sizeof(dwStyles) / sizeof(dwStyles[0]);
|
||||
const int styles_count = ARRAY_SIZE(dwStyles);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < styles_count; i++)
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#define IDD_PROP_PAGE_WITH_CUSTOM_DEFAULT_BUTTON 34
|
||||
#define IDD_PROP_PAGE_MESSAGE_TEST 35
|
||||
#define IDD_PROP_PAGE_ERROR 36
|
||||
#define IDD_PROP_PAGE_BAD_CONTROL 37
|
||||
|
||||
#define IDC_PS_EDIT1 1000
|
||||
#define IDC_PS_EDIT2 1001
|
||||
|
|
|
@ -78,6 +78,13 @@ FONT 8, "MS Shell Dlg"
|
|||
{
|
||||
}
|
||||
|
||||
IDD_PROP_PAGE_BAD_CONTROL DIALOG 0, 0, 100, 100
|
||||
STYLE WS_POPUP | WS_CAPTION | WS_CLIPSIBLINGS | WS_VISIBLE
|
||||
FONT 8, "MS Shell Dlg"
|
||||
{
|
||||
CONTROL "", -1, "invalid class", 0, 0, 0, 0, 0
|
||||
}
|
||||
|
||||
STRINGTABLE
|
||||
{
|
||||
IDS_TBADD1 "abc"
|
||||
|
|
|
@ -127,7 +127,7 @@ static int CALLBACK check_height_font_enumproc(ENUMLOGFONTEXA *enumlf, NEWTEXTME
|
|||
if (type != TRUETYPE_FONTTYPE)
|
||||
facename = enumlf->elfLogFont.lfFaceName;
|
||||
|
||||
for (i = 0; i < sizeof(sizes)/sizeof(sizes[0]); i++)
|
||||
for (i = 0; i < ARRAY_SIZE(sizes); i++)
|
||||
{
|
||||
HFONT hFont;
|
||||
TEXTMETRICA tm;
|
||||
|
@ -586,6 +586,131 @@ static void test_notify(void)
|
|||
ok(g_got_contextmenu, "WM_RBUTTONUP did not activate the context menu!\n");
|
||||
}
|
||||
|
||||
static void test_sizegrip(void)
|
||||
{
|
||||
HWND hwndStatus;
|
||||
LONG style;
|
||||
RECT rc, rcClient;
|
||||
POINT pt;
|
||||
int width, r;
|
||||
|
||||
hwndStatus = CreateWindowA(SUBCLASS_NAME, "", WS_CHILD|WS_VISIBLE|SBARS_SIZEGRIP,
|
||||
0, 0, 100, 100, g_hMainWnd, NULL, NULL, NULL);
|
||||
|
||||
style = GetWindowLongPtrA(g_hMainWnd, GWL_STYLE);
|
||||
width = GetSystemMetrics(SM_CXVSCROLL);
|
||||
|
||||
GetClientRect(hwndStatus, &rcClient);
|
||||
|
||||
pt.x = rcClient.right;
|
||||
pt.y = rcClient.top;
|
||||
ClientToScreen(hwndStatus, &pt);
|
||||
rc.left = pt.x - width;
|
||||
rc.right = pt.x;
|
||||
rc.top = pt.y;
|
||||
|
||||
pt.y = rcClient.bottom;
|
||||
ClientToScreen(hwndStatus, &pt);
|
||||
rc.bottom = pt.y;
|
||||
|
||||
/* check bounds when not maximized */
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.left, rc.top));
|
||||
expect(HTBOTTOMRIGHT, r);
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.left - 1, rc.top));
|
||||
expect(HTCLIENT, r);
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.left, rc.top - 1));
|
||||
expect(HTBOTTOMRIGHT, r);
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.right, rc.bottom));
|
||||
expect(HTBOTTOMRIGHT, r);
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.right + 1, rc.bottom));
|
||||
expect(HTBOTTOMRIGHT, r);
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.right, rc.bottom + 1));
|
||||
expect(HTBOTTOMRIGHT, r);
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.right - 1, rc.bottom - 1));
|
||||
expect(HTBOTTOMRIGHT, r);
|
||||
|
||||
/* not maximized and right-to-left */
|
||||
SetWindowLongA(hwndStatus, GWL_EXSTYLE, WS_EX_LAYOUTRTL);
|
||||
|
||||
pt.x = rcClient.right;
|
||||
ClientToScreen(hwndStatus, &pt);
|
||||
rc.left = pt.x + width;
|
||||
rc.right = pt.x;
|
||||
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.left, rc.top));
|
||||
expect(HTBOTTOMLEFT, r);
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.left + 1, rc.top));
|
||||
expect(HTCLIENT, r);
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.left, rc.top - 1));
|
||||
expect(HTBOTTOMLEFT, r);
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.right, rc.bottom));
|
||||
expect(HTBOTTOMLEFT, r);
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.right - 1, rc.bottom));
|
||||
expect(HTBOTTOMLEFT, r);
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.right, rc.bottom + 1));
|
||||
expect(HTBOTTOMLEFT, r);
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.right + 1, rc.bottom - 1));
|
||||
expect(HTBOTTOMLEFT, r);
|
||||
|
||||
/* maximize with left-to-right */
|
||||
SetWindowLongA(g_hMainWnd, GWL_STYLE, style|WS_MAXIMIZE);
|
||||
SetWindowLongA(hwndStatus, GWL_EXSTYLE, 0);
|
||||
|
||||
GetClientRect(hwndStatus, &rcClient);
|
||||
|
||||
pt.x = rcClient.right;
|
||||
pt.y = rcClient.top;
|
||||
ClientToScreen(hwndStatus, &pt);
|
||||
rc.left = pt.x - width;
|
||||
rc.right = pt.x;
|
||||
rc.top = pt.y;
|
||||
|
||||
pt.y = rcClient.bottom;
|
||||
ClientToScreen(hwndStatus, &pt);
|
||||
rc.bottom = pt.y;
|
||||
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.left, rc.top));
|
||||
expect(HTCLIENT, r);
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.left - 1, rc.top));
|
||||
expect(HTCLIENT, r);
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.left, rc.top - 1));
|
||||
expect(HTNOWHERE, r);
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.right, rc.bottom));
|
||||
expect(HTNOWHERE, r);
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.right + 1, rc.bottom));
|
||||
expect(HTNOWHERE, r);
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.right, rc.bottom + 1));
|
||||
expect(HTNOWHERE, r);
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.right - 1, rc.bottom - 1));
|
||||
expect(HTCLIENT, r);
|
||||
|
||||
/* maximized with right-to-left */
|
||||
SetWindowLongA(hwndStatus, GWL_EXSTYLE, WS_EX_LAYOUTRTL);
|
||||
|
||||
pt.x = rcClient.right;
|
||||
ClientToScreen(hwndStatus, &pt);
|
||||
rc.left = pt.x + width;
|
||||
rc.right = pt.x;
|
||||
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.left, rc.top));
|
||||
expect(HTCLIENT, r);
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.left + 1, rc.top));
|
||||
expect(HTCLIENT, r);
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.left, rc.top - 1));
|
||||
expect(HTNOWHERE, r);
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.right, rc.bottom));
|
||||
expect(HTNOWHERE, r);
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.right - 1, rc.bottom));
|
||||
expect(HTNOWHERE, r);
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.right, rc.bottom + 1));
|
||||
expect(HTNOWHERE, r);
|
||||
r = SendMessageA(hwndStatus, WM_NCHITTEST, 0, MAKELPARAM(rc.right + 1, rc.bottom - 1));
|
||||
expect(HTCLIENT, r);
|
||||
|
||||
SetWindowLongA(g_hMainWnd, GWL_STYLE, style);
|
||||
DestroyWindow(hwndStatus);
|
||||
}
|
||||
|
||||
static void init_functions(void)
|
||||
{
|
||||
HMODULE hComCtl32 = LoadLibraryA("comctl32.dll");
|
||||
|
@ -620,4 +745,5 @@ START_TEST(status)
|
|||
test_status_ownerdraw();
|
||||
test_gettext();
|
||||
test_notify();
|
||||
test_sizegrip();
|
||||
}
|
||||
|
|
|
@ -218,46 +218,61 @@ static LRESULT WINAPI wnd_proc_sub(HWND hwnd, UINT message, WPARAM wParam, LPARA
|
|||
|
||||
static void test_subclass(void)
|
||||
{
|
||||
BOOL ret;
|
||||
HWND hwnd = CreateWindowExA(0, "TestSubclass", "Test subclass", WS_OVERLAPPEDWINDOW,
|
||||
100, 100, 200, 200, 0, 0, 0, NULL);
|
||||
ok(hwnd != NULL, "failed to create test subclass wnd\n");
|
||||
|
||||
pSetWindowSubclass(hwnd, wnd_proc_sub, 2, 0);
|
||||
ret = pSetWindowSubclass(hwnd, wnd_proc_sub, 2, 0);
|
||||
ok(ret == TRUE, "Expected TRUE\n");
|
||||
SendMessageA(hwnd, WM_USER, 1, 0);
|
||||
SendMessageA(hwnd, WM_USER, 2, 0);
|
||||
ok_sequence(Sub_BasicTest, "Basic");
|
||||
|
||||
pSetWindowSubclass(hwnd, wnd_proc_sub, 2, DELETE_SELF);
|
||||
ret = pSetWindowSubclass(hwnd, wnd_proc_sub, 2, DELETE_SELF);
|
||||
ok(ret == TRUE, "Expected TRUE\n");
|
||||
SendMessageA(hwnd, WM_USER, 1, 1);
|
||||
ok_sequence(Sub_DeletedTest, "Deleted");
|
||||
|
||||
SendMessageA(hwnd, WM_USER, 1, 0);
|
||||
ok_sequence(Sub_AfterDeletedTest, "After Deleted");
|
||||
|
||||
pSetWindowSubclass(hwnd, wnd_proc_sub, 2, 0);
|
||||
ret = pSetWindowSubclass(hwnd, wnd_proc_sub, 2, 0);
|
||||
ok(ret == TRUE, "Expected TRUE\n");
|
||||
orig_proc_3 = (WNDPROC)SetWindowLongPtrA(hwnd, GWLP_WNDPROC, (LONG_PTR)wnd_proc_3);
|
||||
SendMessageA(hwnd, WM_USER, 1, 0);
|
||||
SendMessageA(hwnd, WM_USER, 2, 0);
|
||||
ok_sequence(Sub_OldAfterNewTest, "Old after New");
|
||||
|
||||
pSetWindowSubclass(hwnd, wnd_proc_sub, 4, 0);
|
||||
ret = pSetWindowSubclass(hwnd, wnd_proc_sub, 4, 0);
|
||||
ok(ret == TRUE, "Expected TRUE\n");
|
||||
SendMessageA(hwnd, WM_USER, 1, 0);
|
||||
ok_sequence(Sub_MixTest, "Mix");
|
||||
|
||||
/* Now the fun starts */
|
||||
pSetWindowSubclass(hwnd, wnd_proc_sub, 4, SEND_NEST);
|
||||
ret = pSetWindowSubclass(hwnd, wnd_proc_sub, 4, SEND_NEST);
|
||||
ok(ret == TRUE, "Expected TRUE\n");
|
||||
SendMessageA(hwnd, WM_USER, 1, 1);
|
||||
ok_sequence(Sub_MixAndNestTest, "Mix and nest");
|
||||
|
||||
pSetWindowSubclass(hwnd, wnd_proc_sub, 4, SEND_NEST | DELETE_SELF);
|
||||
ret = pSetWindowSubclass(hwnd, wnd_proc_sub, 4, SEND_NEST | DELETE_SELF);
|
||||
ok(ret == TRUE, "Expected TRUE\n");
|
||||
SendMessageA(hwnd, WM_USER, 1, 1);
|
||||
ok_sequence(Sub_MixNestDelTest, "Mix, nest, del");
|
||||
|
||||
pSetWindowSubclass(hwnd, wnd_proc_sub, 4, 0);
|
||||
pSetWindowSubclass(hwnd, wnd_proc_sub, 5, DELETE_PREV);
|
||||
ret = pSetWindowSubclass(hwnd, wnd_proc_sub, 4, 0);
|
||||
ok(ret == TRUE, "Expected TRUE\n");
|
||||
ret = pSetWindowSubclass(hwnd, wnd_proc_sub, 5, DELETE_PREV);
|
||||
ok(ret == TRUE, "Expected TRUE\n");
|
||||
SendMessageA(hwnd, WM_USER, 1, 1);
|
||||
ok_sequence(Sub_MixDelPrevTest, "Mix and del prev");
|
||||
|
||||
ret = pSetWindowSubclass(NULL, wnd_proc_sub, 1, 0);
|
||||
ok(ret == FALSE, "Expected FALSE\n");
|
||||
|
||||
ret = pSetWindowSubclass(hwnd, NULL, 1, 0);
|
||||
ok(ret == FALSE, "Expected FALSE\n");
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,15 +29,21 @@
|
|||
#include "v6util.h"
|
||||
#include "msg.h"
|
||||
|
||||
#ifdef __REACTOS__
|
||||
#define WM_KEYF1 0x004d
|
||||
#endif
|
||||
|
||||
#define WM_TD_CALLBACK (WM_APP) /* Custom dummy message to wrap callback notifications */
|
||||
|
||||
#define NUM_MSG_SEQUENCES 1
|
||||
#define TASKDIALOG_SEQ_INDEX 0
|
||||
|
||||
#define TEST_NUM_BUTTONS 10 /* Number of custom buttons to test with */
|
||||
#define TEST_NUM_RADIO_BUTTONS 3
|
||||
|
||||
#define ID_START 20 /* Lower IDs might be used by the system */
|
||||
#define ID_START_BUTTON (ID_START + 0)
|
||||
#define ID_START_RADIO_BUTTON (ID_START + 20)
|
||||
|
||||
static HRESULT (WINAPI *pTaskDialogIndirect)(const TASKDIALOGCONFIG *, int *, int *, BOOL *);
|
||||
static HRESULT (WINAPI *pTaskDialog)(HWND, HINSTANCE, const WCHAR *, const WCHAR *, const WCHAR *,
|
||||
|
@ -121,6 +127,261 @@ static const struct message_info msg_return_press_custom10[] =
|
|||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_send_click_ok[] =
|
||||
{
|
||||
{ TDM_CLICK_BUTTON, IDOK, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_send_f1[] =
|
||||
{
|
||||
{ WM_KEYF1, 0, 0, 0},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_got_tdn_help[] =
|
||||
{
|
||||
{ TDN_CREATED, 0, 0, S_OK, msg_send_f1 },
|
||||
{ TDN_HELP, 0, 0, S_OK, msg_send_click_ok },
|
||||
{ TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
/* Three radio buttons */
|
||||
static const struct message_info msg_return_default_radio_button_1[] =
|
||||
{
|
||||
{ TDN_CREATED, 0, 0, S_OK, NULL },
|
||||
{ TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, msg_send_click_ok },
|
||||
{ TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_return_default_radio_button_2[] =
|
||||
{
|
||||
{ TDN_CREATED, 0, 0, S_OK, NULL },
|
||||
{ TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON + 1, 0, S_OK, msg_send_click_ok },
|
||||
{ TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_return_default_radio_button_3[] =
|
||||
{
|
||||
{ TDN_CREATED, 0, 0, S_OK, NULL },
|
||||
{ TDN_RADIO_BUTTON_CLICKED, -2, 0, S_OK, msg_send_click_ok },
|
||||
{ TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_select_first_radio_button[] =
|
||||
{
|
||||
{ TDM_CLICK_RADIO_BUTTON, ID_START_RADIO_BUTTON, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_return_first_radio_button[] =
|
||||
{
|
||||
{ TDN_CREATED, 0, 0, S_OK, NULL },
|
||||
{ TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON + 1, 0, S_OK, msg_select_first_radio_button },
|
||||
{ TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, msg_send_click_ok },
|
||||
{ TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_select_first_disabled_radio_button_and_press_ok[] =
|
||||
{
|
||||
{ TDM_ENABLE_RADIO_BUTTON, ID_START_RADIO_BUTTON, 0 },
|
||||
{ TDM_CLICK_RADIO_BUTTON, ID_START_RADIO_BUTTON, 0 },
|
||||
{ TDM_CLICK_BUTTON, IDOK, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_return_default_radio_button_clicking_disabled[] =
|
||||
{
|
||||
{ TDN_CREATED, 0, 0, S_OK, NULL },
|
||||
{ TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON + 1, 0, S_OK, msg_select_first_disabled_radio_button_and_press_ok },
|
||||
{ TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, NULL },
|
||||
{ TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_return_no_default_radio_button_flag[] =
|
||||
{
|
||||
{ TDN_CREATED, 0, 0, S_OK, msg_send_click_ok },
|
||||
{ TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, NULL },
|
||||
{ TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_return_no_default_radio_button_id_and_flag[] =
|
||||
{
|
||||
{ TDN_CREATED, 0, 0, S_OK, msg_send_click_ok },
|
||||
{ TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_select_negative_id_radio_button[] =
|
||||
{
|
||||
{ TDM_CLICK_RADIO_BUTTON, -2, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_return_press_negative_id_radio_button[] =
|
||||
{
|
||||
{ TDN_CREATED, 0, 0, S_OK, msg_select_negative_id_radio_button },
|
||||
{ TDN_RADIO_BUTTON_CLICKED, -2, 0, S_OK, msg_send_click_ok },
|
||||
{ TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_send_all_common_button_click[] =
|
||||
{
|
||||
{ TDM_CLICK_BUTTON, IDOK, 0 },
|
||||
{ TDM_CLICK_BUTTON, IDYES, 0 },
|
||||
{ TDM_CLICK_BUTTON, IDNO, 0 },
|
||||
{ TDM_CLICK_BUTTON, IDCANCEL, 0 },
|
||||
{ TDM_CLICK_BUTTON, IDRETRY, 0 },
|
||||
{ TDM_CLICK_BUTTON, IDCLOSE, 0 },
|
||||
{ TDM_CLICK_BUTTON, ID_START_BUTTON + 99, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_press_nonexistent_buttons[] =
|
||||
{
|
||||
{ TDN_CREATED, 0, 0, S_OK, msg_send_all_common_button_click },
|
||||
{ TDN_BUTTON_CLICKED, IDOK, 0, S_FALSE, NULL },
|
||||
{ TDN_BUTTON_CLICKED, IDYES, 0, S_FALSE, NULL },
|
||||
{ TDN_BUTTON_CLICKED, IDNO, 0, S_FALSE, NULL },
|
||||
{ TDN_BUTTON_CLICKED, IDCANCEL, 0, S_FALSE, NULL },
|
||||
{ TDN_BUTTON_CLICKED, IDRETRY, 0, S_FALSE, NULL },
|
||||
{ TDN_BUTTON_CLICKED, IDCLOSE, 0, S_FALSE, NULL },
|
||||
{ TDN_BUTTON_CLICKED, ID_START_BUTTON + 99, 0, S_OK, NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_send_all_common_button_click_with_command[] =
|
||||
{
|
||||
{ WM_COMMAND, MAKEWORD(IDOK, BN_CLICKED), 0 },
|
||||
{ WM_COMMAND, MAKEWORD(IDYES, BN_CLICKED), 0 },
|
||||
{ WM_COMMAND, MAKEWORD(IDNO, BN_CLICKED), 0 },
|
||||
{ WM_COMMAND, MAKEWORD(IDCANCEL, BN_CLICKED), 0 },
|
||||
{ WM_COMMAND, MAKEWORD(IDRETRY, BN_CLICKED), 0 },
|
||||
{ WM_COMMAND, MAKEWORD(IDCLOSE, BN_CLICKED), 0 },
|
||||
{ WM_COMMAND, MAKEWORD(ID_START_BUTTON + 99, BN_CLICKED), 0 },
|
||||
{ WM_COMMAND, MAKEWORD(IDOK, BN_CLICKED), 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_press_nonexistent_buttons_with_command[] =
|
||||
{
|
||||
{ TDN_CREATED, 0, 0, S_OK, msg_send_all_common_button_click_with_command },
|
||||
{ TDN_BUTTON_CLICKED, ID_START_BUTTON, 0, S_FALSE, NULL },
|
||||
{ TDN_BUTTON_CLICKED, ID_START_BUTTON, 0, S_OK, NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_send_nonexistent_radio_button_click[] =
|
||||
{
|
||||
{ TDM_CLICK_RADIO_BUTTON, ID_START_RADIO_BUTTON + 99, 0 },
|
||||
{ TDM_CLICK_BUTTON, IDOK, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_press_nonexistent_radio_button[] =
|
||||
{
|
||||
{ TDN_CREATED, 0, 0, S_OK, msg_send_nonexistent_radio_button_click },
|
||||
{ TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_return_default_verification_unchecked[] =
|
||||
{
|
||||
{ TDN_CREATED, 0, 0, S_OK, msg_send_click_ok },
|
||||
{ TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_return_default_verification_checked[] =
|
||||
{
|
||||
{ TDN_CREATED, 0, 0, S_OK, msg_send_click_ok },
|
||||
{ TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_uncheck_verification[] =
|
||||
{
|
||||
{ TDM_CLICK_VERIFICATION, FALSE, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_return_verification_unchecked[] =
|
||||
{
|
||||
{ TDN_CREATED, 0, 0, S_OK, msg_uncheck_verification },
|
||||
{ TDN_VERIFICATION_CLICKED, FALSE, 0, S_OK, msg_send_click_ok },
|
||||
{ TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_check_verification[] =
|
||||
{
|
||||
{ TDM_CLICK_VERIFICATION, TRUE, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_return_verification_checked[] =
|
||||
{
|
||||
{ TDN_CREATED, 0, 0, S_OK, msg_check_verification },
|
||||
{ TDN_VERIFICATION_CLICKED, TRUE, 0, S_OK, msg_send_click_ok },
|
||||
{ TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static TASKDIALOGCONFIG navigated_info = {0};
|
||||
|
||||
static const struct message_info msg_send_navigate[] =
|
||||
{
|
||||
{ TDM_NAVIGATE_PAGE, 0, (LPARAM)&navigated_info, 0},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_return_navigated_page[] =
|
||||
{
|
||||
{ TDN_CREATED, 0, 0, S_OK, NULL },
|
||||
{ TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, msg_send_navigate },
|
||||
{ TDN_DIALOG_CONSTRUCTED, 0, 0, S_OK, NULL },
|
||||
{ TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, NULL },
|
||||
{ TDN_NAVIGATED, 0, 0, S_OK, msg_send_click_ok },
|
||||
{ TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_send_close[] =
|
||||
{
|
||||
{ WM_CLOSE, 0, 0, 0},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_handle_wm_close[] =
|
||||
{
|
||||
{ TDN_CREATED, 0, 0, S_OK, msg_send_close },
|
||||
{ TDN_BUTTON_CLICKED, IDCANCEL, 0, S_FALSE, msg_send_close },
|
||||
{ TDN_BUTTON_CLICKED, IDCANCEL, 0, S_OK, NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_send_close_then_ok[] =
|
||||
{
|
||||
{ WM_CLOSE, 0, 0, 0},
|
||||
{ TDM_CLICK_BUTTON, IDOK, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message_info msg_handle_wm_close_without_cancel_button[] =
|
||||
{
|
||||
{ TDN_CREATED, 0, 0, S_OK, msg_send_close_then_ok },
|
||||
{ TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static void init_test_message(UINT message, WPARAM wParam, LPARAM lParam, struct message *msg)
|
||||
{
|
||||
msg->message = WM_TD_CALLBACK;
|
||||
|
@ -131,16 +392,18 @@ static void init_test_message(UINT message, WPARAM wParam, LPARAM lParam, struct
|
|||
msg->stage = 0;
|
||||
}
|
||||
|
||||
#define run_test(info, expect_button, seq, context) \
|
||||
run_test_(info, expect_button, seq, context, \
|
||||
sizeof(seq)/sizeof(seq[0]) - 1, __FILE__, __LINE__)
|
||||
#define run_test(info, expect_button, expect_radio_button, verification_checked, seq, context) \
|
||||
run_test_(info, expect_button, expect_radio_button, verification_checked, seq, context, \
|
||||
ARRAY_SIZE(seq) - 1, __FILE__, __LINE__)
|
||||
|
||||
static void run_test_(TASKDIALOGCONFIG *info, int expect_button, const struct message_info *test_messages,
|
||||
const char *context, int test_messages_len, const char *file, int line)
|
||||
static void run_test_(TASKDIALOGCONFIG *info, int expect_button, int expect_radio_button, BOOL verification_checked,
|
||||
const struct message_info *test_messages, const char *context, int test_messages_len,
|
||||
const char *file, int line)
|
||||
{
|
||||
struct message *msg, *msg_start;
|
||||
int ret_button = 0;
|
||||
int ret_radio = 0;
|
||||
BOOL ret_verification = FALSE;
|
||||
HRESULT hr;
|
||||
int i;
|
||||
|
||||
|
@ -157,12 +420,14 @@ static void run_test_(TASKDIALOGCONFIG *info, int expect_button, const struct me
|
|||
current_message_info = test_messages;
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
hr = pTaskDialogIndirect(info, &ret_button, &ret_radio, NULL);
|
||||
hr = pTaskDialogIndirect(info, &ret_button, &ret_radio, &ret_verification);
|
||||
ok_(file, line)(hr == S_OK, "TaskDialogIndirect() failed, got %#x.\n", hr);
|
||||
|
||||
ok_sequence_(sequences, TASKDIALOG_SEQ_INDEX, msg_start, context, FALSE, file, line);
|
||||
ok_(file, line)(ret_button == expect_button,
|
||||
"Wrong button. Expected %d, got %d\n", expect_button, ret_button);
|
||||
ok_(file, line)(ret_radio == expect_radio_button,
|
||||
"Wrong radio button. Expected %d, got %d\n", expect_radio_button, ret_radio);
|
||||
|
||||
heap_free(msg_start);
|
||||
}
|
||||
|
@ -220,16 +485,17 @@ static void test_callback(void)
|
|||
info.pfCallback = taskdialog_callback_proc;
|
||||
info.lpCallbackData = test_ref_data;
|
||||
|
||||
run_test(&info, IDOK, msg_return_press_ok, "Press VK_RETURN.");
|
||||
run_test(&info, IDOK, 0, FALSE, msg_return_press_ok, "Press VK_RETURN.");
|
||||
}
|
||||
|
||||
static void test_buttons(void)
|
||||
{
|
||||
TASKDIALOGCONFIG info = {0};
|
||||
|
||||
TASKDIALOG_BUTTON custom_buttons[TEST_NUM_BUTTONS];
|
||||
static const DWORD command_link_flags[] = {0, TDF_USE_COMMAND_LINKS, TDF_USE_COMMAND_LINKS_NO_ICON};
|
||||
TASKDIALOG_BUTTON custom_buttons[TEST_NUM_BUTTONS], radio_buttons[TEST_NUM_RADIO_BUTTONS];
|
||||
const WCHAR button_format[] = {'%','0','2','d',0};
|
||||
WCHAR button_titles[TEST_NUM_BUTTONS * 3]; /* Each button has two digits as title, plus null-terminator */
|
||||
/* Each button has two digits as title, plus null-terminator */
|
||||
WCHAR button_titles[TEST_NUM_BUTTONS * 3], radio_button_titles[TEST_NUM_BUTTONS * 3];
|
||||
int i;
|
||||
|
||||
info.cbSize = sizeof(TASKDIALOGCONFIG);
|
||||
|
@ -247,48 +513,359 @@ static void test_buttons(void)
|
|||
}
|
||||
custom_buttons[TEST_NUM_BUTTONS - 1].nButtonID = -1;
|
||||
|
||||
/* Init radio buttons */
|
||||
for (i = 0; i < TEST_NUM_RADIO_BUTTONS; i++)
|
||||
{
|
||||
WCHAR *text = &radio_button_titles[i * 3];
|
||||
wsprintfW(text, button_format, i);
|
||||
|
||||
radio_buttons[i].pszButtonText = text;
|
||||
radio_buttons[i].nButtonID = ID_START_RADIO_BUTTON + i;
|
||||
}
|
||||
radio_buttons[TEST_NUM_RADIO_BUTTONS - 1].nButtonID = -2;
|
||||
|
||||
/* Test nDefaultButton */
|
||||
|
||||
/* Test common buttons with invalid default ID */
|
||||
info.nDefaultButton = 0; /* Should default to first created button */
|
||||
info.dwCommonButtons = TDCBF_OK_BUTTON | TDCBF_YES_BUTTON | TDCBF_NO_BUTTON
|
||||
| TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
|
||||
run_test(&info, IDOK, msg_return_press_ok, "default button: unset default");
|
||||
run_test(&info, IDOK, 0, FALSE, msg_return_press_ok, "default button: unset default");
|
||||
info.dwCommonButtons = TDCBF_YES_BUTTON | TDCBF_NO_BUTTON
|
||||
| TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
|
||||
run_test(&info, IDYES, msg_return_press_yes, "default button: unset default");
|
||||
run_test(&info, IDYES, 0, FALSE, msg_return_press_yes, "default button: unset default");
|
||||
info.dwCommonButtons = TDCBF_NO_BUTTON | TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
|
||||
run_test(&info, IDNO, msg_return_press_no, "default button: unset default");
|
||||
run_test(&info, IDNO, 0, FALSE, msg_return_press_no, "default button: unset default");
|
||||
info.dwCommonButtons = TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
|
||||
run_test(&info, IDRETRY, msg_return_press_retry, "default button: unset default");
|
||||
run_test(&info, IDRETRY, 0, FALSE, msg_return_press_retry, "default button: unset default");
|
||||
info.dwCommonButtons = TDCBF_CANCEL_BUTTON | TDCBF_CLOSE_BUTTON;
|
||||
run_test(&info, IDCANCEL, msg_return_press_cancel, "default button: unset default");
|
||||
run_test(&info, IDCANCEL, 0, FALSE, msg_return_press_cancel, "default button: unset default");
|
||||
|
||||
/* Test with all common and custom buttons and invalid default ID */
|
||||
info.nDefaultButton = 0xff; /* Random ID, should also default to first created button */
|
||||
/* Custom buttons could be command links */
|
||||
for (i = 0; i < ARRAY_SIZE(command_link_flags); i++)
|
||||
{
|
||||
info.dwFlags = command_link_flags[i];
|
||||
|
||||
/* Test with all common and custom buttons and invalid default ID */
|
||||
info.nDefaultButton = 0xff; /* Random ID, should also default to first created button */
|
||||
info.cButtons = TEST_NUM_BUTTONS;
|
||||
info.pButtons = custom_buttons;
|
||||
run_test(&info, ID_START_BUTTON, 0, FALSE, msg_return_press_custom1,
|
||||
"default button: invalid default, with common buttons - 1");
|
||||
|
||||
info.nDefaultButton = -1; /* Should work despite button ID -1 */
|
||||
run_test(&info, -1, 0, FALSE, msg_return_press_custom10, "default button: invalid default, with common buttons - 2");
|
||||
|
||||
info.nDefaultButton = -2; /* Should also default to first created button */
|
||||
run_test(&info, ID_START_BUTTON, 0, FALSE, msg_return_press_custom1,
|
||||
"default button: invalid default, with common buttons - 3");
|
||||
|
||||
/* Test with only custom buttons and invalid default ID */
|
||||
info.dwCommonButtons = 0;
|
||||
run_test(&info, ID_START_BUTTON, 0, FALSE, msg_return_press_custom1,
|
||||
"default button: invalid default, no common buttons");
|
||||
|
||||
/* Test with common and custom buttons and valid default ID */
|
||||
info.dwCommonButtons = TDCBF_OK_BUTTON | TDCBF_YES_BUTTON | TDCBF_NO_BUTTON | TDCBF_CANCEL_BUTTON
|
||||
| TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
|
||||
info.nDefaultButton = IDRETRY;
|
||||
run_test(&info, IDRETRY, 0, FALSE, msg_return_press_retry, "default button: valid default - 1");
|
||||
|
||||
/* Test with common and custom buttons and valid default ID */
|
||||
info.nDefaultButton = ID_START_BUTTON + 3;
|
||||
run_test(&info, ID_START_BUTTON + 3, 0, FALSE, msg_return_press_custom4, "default button: valid default - 2");
|
||||
}
|
||||
|
||||
/* Test radio buttons */
|
||||
info.nDefaultButton = 0;
|
||||
info.cButtons = 0;
|
||||
info.pButtons = 0;
|
||||
info.dwCommonButtons = TDCBF_OK_BUTTON;
|
||||
info.cRadioButtons = TEST_NUM_RADIO_BUTTONS;
|
||||
info.pRadioButtons = radio_buttons;
|
||||
|
||||
/* Test default first radio button */
|
||||
run_test(&info, IDOK, ID_START_RADIO_BUTTON, FALSE, msg_return_default_radio_button_1,
|
||||
"default radio button: default first radio button");
|
||||
|
||||
/* Test default radio button */
|
||||
info.nDefaultRadioButton = ID_START_RADIO_BUTTON + 1;
|
||||
run_test(&info, IDOK, info.nDefaultRadioButton, FALSE, msg_return_default_radio_button_2,
|
||||
"default radio button: default radio button");
|
||||
|
||||
/* Test default radio button with -2 */
|
||||
info.nDefaultRadioButton = -2;
|
||||
run_test(&info, IDOK, info.nDefaultRadioButton, FALSE, msg_return_default_radio_button_3,
|
||||
"default radio button: default radio button with id -2");
|
||||
|
||||
/* Test default radio button after clicking the first, messages still work even radio button is disabled */
|
||||
info.nDefaultRadioButton = ID_START_RADIO_BUTTON + 1;
|
||||
run_test(&info, IDOK, ID_START_RADIO_BUTTON, FALSE, msg_return_first_radio_button,
|
||||
"default radio button: radio button after clicking");
|
||||
|
||||
/* Test radio button after disabling and clicking the first */
|
||||
info.nDefaultRadioButton = ID_START_RADIO_BUTTON + 1;
|
||||
run_test(&info, IDOK, ID_START_RADIO_BUTTON, FALSE, msg_return_default_radio_button_clicking_disabled,
|
||||
"default radio button: disable radio button before clicking");
|
||||
|
||||
/* Test no default radio button, TDF_NO_DEFAULT_RADIO_BUTTON is set, TDN_RADIO_BUTTON_CLICKED will still be received, just radio button not selected */
|
||||
info.nDefaultRadioButton = ID_START_RADIO_BUTTON;
|
||||
info.dwFlags = TDF_NO_DEFAULT_RADIO_BUTTON;
|
||||
run_test(&info, IDOK, info.nDefaultRadioButton, FALSE, msg_return_no_default_radio_button_flag,
|
||||
"default radio button: no default radio flag");
|
||||
|
||||
/* Test no default radio button, TDF_NO_DEFAULT_RADIO_BUTTON is set and nDefaultRadioButton is 0.
|
||||
* TDN_RADIO_BUTTON_CLICKED will not be sent, and just radio button not selected */
|
||||
info.nDefaultRadioButton = 0;
|
||||
info.dwFlags = TDF_NO_DEFAULT_RADIO_BUTTON;
|
||||
run_test(&info, IDOK, 0, FALSE, msg_return_no_default_radio_button_id_and_flag,
|
||||
"default radio button: no default radio id and flag");
|
||||
|
||||
/* Test no default radio button, TDF_NO_DEFAULT_RADIO_BUTTON is set and nDefaultRadioButton is invalid.
|
||||
* TDN_RADIO_BUTTON_CLICKED will not be sent, and just radio button not selected */
|
||||
info.nDefaultRadioButton = 0xff;
|
||||
info.dwFlags = TDF_NO_DEFAULT_RADIO_BUTTON;
|
||||
run_test(&info, IDOK, 0, FALSE, msg_return_no_default_radio_button_id_and_flag,
|
||||
"default radio button: no default flag, invalid id");
|
||||
|
||||
info.nDefaultRadioButton = 0;
|
||||
info.dwFlags = TDF_NO_DEFAULT_RADIO_BUTTON;
|
||||
run_test(&info, IDOK, -2, FALSE, msg_return_press_negative_id_radio_button,
|
||||
"radio button: manually click radio button with negative id");
|
||||
|
||||
/* Test sending clicks to non-existent buttons. Notification of non-existent buttons will be sent */
|
||||
info.cButtons = TEST_NUM_BUTTONS;
|
||||
info.pButtons = custom_buttons;
|
||||
run_test(&info, ID_START_BUTTON, msg_return_press_custom1, "default button: invalid default, with common buttons - 1");
|
||||
|
||||
info.nDefaultButton = -1; /* Should work despite button ID -1 */
|
||||
run_test(&info, -1, msg_return_press_custom10, "default button: invalid default, with common buttons - 2");
|
||||
|
||||
info.nDefaultButton = -2; /* Should also default to first created button */
|
||||
run_test(&info, ID_START_BUTTON, msg_return_press_custom1, "default button: invalid default, with common buttons - 3");
|
||||
|
||||
/* Test with only custom buttons and invalid default ID */
|
||||
info.cRadioButtons = TEST_NUM_RADIO_BUTTONS;
|
||||
info.pRadioButtons = radio_buttons;
|
||||
info.dwCommonButtons = 0;
|
||||
run_test(&info, ID_START_BUTTON, msg_return_press_custom1, "default button: invalid default, no common buttons");
|
||||
info.dwFlags = TDF_NO_DEFAULT_RADIO_BUTTON;
|
||||
run_test(&info, ID_START_BUTTON + 99, 0, FALSE, msg_press_nonexistent_buttons, "sends click to non-existent buttons");
|
||||
|
||||
/* Test with common and custom buttons and valid default ID */
|
||||
info.dwCommonButtons = TDCBF_OK_BUTTON | TDCBF_YES_BUTTON | TDCBF_NO_BUTTON
|
||||
| TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
|
||||
info.nDefaultButton = IDRETRY;
|
||||
run_test(&info, IDRETRY, msg_return_press_retry, "default button: valid default - 1");
|
||||
/* Non-existent button clicks sent by WM_COMMAND won't generate TDN_BUTTON_CLICKED except IDOK.
|
||||
* And will get the first existent button identifier instead of IDOK */
|
||||
run_test(&info, ID_START_BUTTON, 0, FALSE, msg_press_nonexistent_buttons_with_command,
|
||||
"sends click to non-existent buttons with WM_COMMAND");
|
||||
|
||||
/* Test with common and custom buttons and valid default ID */
|
||||
info.nDefaultButton = ID_START_BUTTON + 3;
|
||||
run_test(&info, ID_START_BUTTON + 3, msg_return_press_custom4, "default button: valid default - 2");
|
||||
/* Non-existent radio button won't get notifications */
|
||||
run_test(&info, IDOK, 0, FALSE, msg_press_nonexistent_radio_button, "sends click to non-existent radio buttons");
|
||||
}
|
||||
|
||||
static void test_help(void)
|
||||
{
|
||||
TASKDIALOGCONFIG info = {0};
|
||||
|
||||
info.cbSize = sizeof(TASKDIALOGCONFIG);
|
||||
info.pfCallback = taskdialog_callback_proc;
|
||||
info.lpCallbackData = test_ref_data;
|
||||
info.dwCommonButtons = TDCBF_OK_BUTTON;
|
||||
|
||||
run_test(&info, IDOK, 0, FALSE, msg_got_tdn_help, "send f1");
|
||||
}
|
||||
|
||||
struct timer_notification_data
|
||||
{
|
||||
DWORD last_elapsed_ms;
|
||||
DWORD num_fired;
|
||||
};
|
||||
|
||||
static HRESULT CALLBACK taskdialog_callback_proc_timer(HWND hwnd, UINT notification,
|
||||
WPARAM wParam, LPARAM lParam, LONG_PTR ref_data)
|
||||
{
|
||||
struct timer_notification_data *data = (struct timer_notification_data *)ref_data;
|
||||
|
||||
if (notification == TDN_TIMER)
|
||||
{
|
||||
DWORD elapsed_ms;
|
||||
int delta;
|
||||
|
||||
elapsed_ms = (DWORD)wParam;
|
||||
|
||||
if (data->num_fired == 3)
|
||||
ok(data->last_elapsed_ms > elapsed_ms, "Expected reference time update.\n");
|
||||
else
|
||||
{
|
||||
delta = elapsed_ms - data->last_elapsed_ms;
|
||||
ok(delta > 0, "Expected positive time tick difference.\n");
|
||||
}
|
||||
data->last_elapsed_ms = elapsed_ms;
|
||||
|
||||
if (data->num_fired == 3)
|
||||
PostMessageW(hwnd, TDM_CLICK_BUTTON, IDOK, 0);
|
||||
|
||||
++data->num_fired;
|
||||
return data->num_fired == 3 ? S_FALSE : S_OK;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void test_timer(void)
|
||||
{
|
||||
struct timer_notification_data data = { 0 };
|
||||
TASKDIALOGCONFIG info = { 0 };
|
||||
|
||||
info.cbSize = sizeof(TASKDIALOGCONFIG);
|
||||
info.pfCallback = taskdialog_callback_proc_timer;
|
||||
info.lpCallbackData = (LONG_PTR)&data;
|
||||
info.dwFlags = TDF_CALLBACK_TIMER;
|
||||
info.dwCommonButtons = TDCBF_OK_BUTTON;
|
||||
|
||||
pTaskDialogIndirect(&info, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static HRESULT CALLBACK taskdialog_callback_proc_progress_bar(HWND hwnd, UINT notification, WPARAM wParam,
|
||||
LPARAM lParam, LONG_PTR ref_data)
|
||||
{
|
||||
unsigned long ret;
|
||||
LONG flags = (LONG)ref_data;
|
||||
if (notification == TDN_CREATED)
|
||||
{
|
||||
/* TDM_SET_PROGRESS_BAR_STATE */
|
||||
ret = SendMessageW(hwnd, TDM_SET_PROGRESS_BAR_STATE, PBST_NORMAL, 0);
|
||||
ok(ret == PBST_NORMAL, "Expect state: %d got state: %lx\n", PBST_NORMAL, ret);
|
||||
ret = SendMessageW(hwnd, TDM_SET_PROGRESS_BAR_STATE, PBST_PAUSED, 0);
|
||||
ok(ret == PBST_NORMAL, "Expect state: %d got state: %lx\n", PBST_NORMAL, ret);
|
||||
ret = SendMessageW(hwnd, TDM_SET_PROGRESS_BAR_STATE, PBST_ERROR, 0);
|
||||
/* Progress bar has fixme on handling PBM_SETSTATE message */
|
||||
todo_wine ok(ret == PBST_PAUSED, "Expect state: %d got state: %lx\n", PBST_PAUSED, ret);
|
||||
ret = SendMessageW(hwnd, TDM_SET_PROGRESS_BAR_STATE, PBST_NORMAL, 0);
|
||||
todo_wine ok(ret == PBST_ERROR, "Expect state: %d got state: %lx\n", PBST_ERROR, ret);
|
||||
|
||||
/* TDM_SET_PROGRESS_BAR_RANGE */
|
||||
ret = SendMessageW(hwnd, TDM_SET_PROGRESS_BAR_RANGE, 0, MAKELPARAM(0, 200));
|
||||
ok(ret == MAKELONG(0, 100), "Expect range:%x got:%lx\n", MAKELONG(0, 100), ret);
|
||||
ret = SendMessageW(hwnd, TDM_SET_PROGRESS_BAR_RANGE, 0, MAKELPARAM(0, 200));
|
||||
ok(ret == MAKELONG(0, 200), "Expect range:%x got:%lx\n", MAKELONG(0, 200), ret);
|
||||
|
||||
/* TDM_SET_PROGRESS_BAR_POS */
|
||||
if (flags & TDF_SHOW_MARQUEE_PROGRESS_BAR)
|
||||
{
|
||||
ret = SendMessageW(hwnd, TDM_SET_PROGRESS_BAR_POS, 1, 0);
|
||||
ok(ret == 0, "Expect position:%x got:%lx\n", 0, ret);
|
||||
ret = SendMessageW(hwnd, TDM_SET_PROGRESS_BAR_POS, 2, 0);
|
||||
ok(ret == 0, "Expect position:%x got:%lx\n", 0, ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = SendMessageW(hwnd, TDM_SET_PROGRESS_BAR_POS, 1, 0);
|
||||
ok(ret == 0, "Expect position:%x got:%lx\n", 0, ret);
|
||||
ret = SendMessageW(hwnd, TDM_SET_PROGRESS_BAR_POS, 2, 0);
|
||||
ok(ret == 1, "Expect position:%x got:%lx\n", 1, ret);
|
||||
}
|
||||
|
||||
SendMessageW(hwnd, TDM_CLICK_BUTTON, IDOK, 0);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void test_progress_bar(void)
|
||||
{
|
||||
TASKDIALOGCONFIG info = {0};
|
||||
|
||||
info.cbSize = sizeof(TASKDIALOGCONFIG);
|
||||
info.dwFlags = TDF_SHOW_PROGRESS_BAR;
|
||||
info.pfCallback = taskdialog_callback_proc_progress_bar;
|
||||
info.lpCallbackData = (LONG_PTR)info.dwFlags;
|
||||
info.dwCommonButtons = TDCBF_OK_BUTTON;
|
||||
pTaskDialogIndirect(&info, NULL, NULL, NULL);
|
||||
|
||||
info.dwFlags = TDF_SHOW_MARQUEE_PROGRESS_BAR;
|
||||
info.lpCallbackData = (LONG_PTR)info.dwFlags;
|
||||
pTaskDialogIndirect(&info, NULL, NULL, NULL);
|
||||
|
||||
info.dwFlags = TDF_SHOW_PROGRESS_BAR | TDF_SHOW_MARQUEE_PROGRESS_BAR;
|
||||
info.lpCallbackData = (LONG_PTR)info.dwFlags;
|
||||
pTaskDialogIndirect(&info, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static void test_verification_box(void)
|
||||
{
|
||||
TASKDIALOGCONFIG info = {0};
|
||||
WCHAR textW[] = {'t', 'e', 'x', 't', 0};
|
||||
|
||||
info.cbSize = sizeof(TASKDIALOGCONFIG);
|
||||
info.pfCallback = taskdialog_callback_proc;
|
||||
info.lpCallbackData = test_ref_data;
|
||||
info.dwCommonButtons = TDCBF_OK_BUTTON;
|
||||
|
||||
/* TDF_VERIFICATION_FLAG_CHECKED works even if pszVerificationText is not set */
|
||||
run_test(&info, IDOK, 0, FALSE, msg_return_default_verification_unchecked, "default verification box: unchecked");
|
||||
|
||||
info.dwFlags = TDF_VERIFICATION_FLAG_CHECKED;
|
||||
run_test(&info, IDOK, 0, FALSE, msg_return_default_verification_checked, "default verification box: checked");
|
||||
|
||||
info.pszVerificationText = textW;
|
||||
run_test(&info, IDOK, 0, FALSE, msg_return_default_verification_unchecked, "default verification box: unchecked");
|
||||
|
||||
info.dwFlags = TDF_VERIFICATION_FLAG_CHECKED;
|
||||
run_test(&info, IDOK, 0, FALSE, msg_return_default_verification_checked, "default verification box: checked");
|
||||
|
||||
run_test(&info, IDOK, 0, FALSE, msg_return_verification_unchecked,
|
||||
"default verification box: default checked and then unchecked");
|
||||
|
||||
info.dwFlags = 0;
|
||||
run_test(&info, IDOK, 0, FALSE, msg_return_verification_checked,
|
||||
"default verification box: default unchecked and then checked");
|
||||
}
|
||||
|
||||
static void test_navigate_page(void)
|
||||
{
|
||||
TASKDIALOGCONFIG info = {0};
|
||||
static const WCHAR textW[] = {'t', 'e', 'x', 't', 0};
|
||||
static const WCHAR button_format[] = {'%', '0', '2', 'd', 0};
|
||||
TASKDIALOG_BUTTON radio_buttons[TEST_NUM_RADIO_BUTTONS];
|
||||
WCHAR radio_button_titles[TEST_NUM_BUTTONS * 3];
|
||||
int i;
|
||||
|
||||
/* Init radio buttons */
|
||||
for (i = 0; i < TEST_NUM_RADIO_BUTTONS; i++)
|
||||
{
|
||||
WCHAR *text = &radio_button_titles[i * 3];
|
||||
wsprintfW(text, button_format, i);
|
||||
|
||||
radio_buttons[i].pszButtonText = text;
|
||||
radio_buttons[i].nButtonID = ID_START_RADIO_BUTTON + i;
|
||||
}
|
||||
|
||||
info.cbSize = sizeof(TASKDIALOGCONFIG);
|
||||
info.pfCallback = taskdialog_callback_proc;
|
||||
info.lpCallbackData = test_ref_data;
|
||||
info.dwCommonButtons = TDCBF_OK_BUTTON;
|
||||
info.cRadioButtons = TEST_NUM_RADIO_BUTTONS;
|
||||
info.pRadioButtons = radio_buttons;
|
||||
|
||||
navigated_info = info;
|
||||
navigated_info.pszVerificationText = textW;
|
||||
navigated_info.dwFlags = TDF_VERIFICATION_FLAG_CHECKED;
|
||||
|
||||
run_test(&info, IDOK, ID_START_RADIO_BUTTON, TRUE, msg_return_navigated_page, "navigate page: default");
|
||||
|
||||
/* TDM_NAVIGATE_PAGE doesn't check cbSize.
|
||||
* And null taskconfig pointer crash applicatioin, thus doesn't check pointer either */
|
||||
navigated_info.cbSize = 0;
|
||||
run_test(&info, IDOK, ID_START_RADIO_BUTTON, TRUE, msg_return_navigated_page, "navigate page: invalid taskconfig cbSize");
|
||||
}
|
||||
|
||||
static void test_wm_close(void)
|
||||
{
|
||||
TASKDIALOGCONFIG info = {0};
|
||||
|
||||
info.cbSize = sizeof(TASKDIALOGCONFIG);
|
||||
info.pfCallback = taskdialog_callback_proc;
|
||||
info.lpCallbackData = test_ref_data;
|
||||
|
||||
/* WM_CLOSE can end the dialog only when a cancel button is present or dwFlags has TDF_ALLOW_DIALOG_CANCELLATION */
|
||||
info.dwCommonButtons = TDCBF_OK_BUTTON;
|
||||
run_test(&info, IDOK, 0, FALSE, msg_handle_wm_close_without_cancel_button, "send WM_CLOSE without cancel button");
|
||||
|
||||
info.dwFlags = TDF_ALLOW_DIALOG_CANCELLATION;
|
||||
run_test(&info, IDCANCEL, 0, FALSE, msg_handle_wm_close, "send WM_CLOSE with TDF_ALLOW_DIALOG_CANCELLATION");
|
||||
|
||||
info.dwFlags = 0;
|
||||
info.dwCommonButtons = TDCBF_CANCEL_BUTTON;
|
||||
run_test(&info, IDCANCEL, 0, FALSE, msg_handle_wm_close, "send WM_CLOSE with a cancel button");
|
||||
}
|
||||
|
||||
START_TEST(taskdialog)
|
||||
|
@ -327,6 +904,12 @@ START_TEST(taskdialog)
|
|||
test_invalid_parameters();
|
||||
test_callback();
|
||||
test_buttons();
|
||||
test_help();
|
||||
test_timer();
|
||||
test_progress_bar();
|
||||
test_verification_box();
|
||||
test_navigate_page();
|
||||
test_wm_close();
|
||||
|
||||
unload_v6_module(ctx_cookie, hCtx);
|
||||
}
|
||||
|
|
|
@ -56,7 +56,6 @@ static BOOL g_ResetDispTextPtr;
|
|||
|
||||
static const struct message ttgetdispinfo_parent_seq[] = {
|
||||
{ WM_NOTIFY, sent|id, 0, 0, TBN_GETINFOTIPA },
|
||||
/* next line is todo, currently TTN_GETDISPINFOW is raised here */
|
||||
{ WM_NOTIFY, sent|id, 0, 0, TTN_GETDISPINFOA },
|
||||
{ 0 }
|
||||
};
|
||||
|
@ -388,7 +387,7 @@ static void basic_test(void)
|
|||
WS_CHILD | TBSTYLE_LIST,
|
||||
100,
|
||||
0, NULL, 0,
|
||||
buttons, sizeof(buttons)/sizeof(buttons[0]),
|
||||
buttons, ARRAY_SIZE(buttons),
|
||||
0, 0, 20, 16, sizeof(TBBUTTON));
|
||||
ok(hToolbar != NULL, "Toolbar creation\n");
|
||||
SendMessageA(hToolbar, TB_ADDSTRINGA, 0, (LPARAM)"test\000");
|
||||
|
@ -1316,7 +1315,7 @@ static DWORD tbsize_alt_numtests = 0;
|
|||
compare(buttonCount, res->nButtons, "%d"); \
|
||||
for (i=0; i<min(buttonCount, res->nButtons); i++) { \
|
||||
ok(SendMessageA(hToolbar, TB_GETITEMRECT, i, (LPARAM)&rc) == 1, "TB_GETITEMRECT\n"); \
|
||||
if (broken(tbsize_alt_numtests < sizeof(tbsize_alt_results)/sizeof(tbsize_alt_results[0]) && \
|
||||
if (broken(tbsize_alt_numtests < ARRAY_SIZE(tbsize_alt_results) && \
|
||||
EqualRect(&rc, &tbsize_alt_results[tbsize_alt_numtests].rcButton))) { \
|
||||
win_skip("Alternate rect found\n"); \
|
||||
tbsize_alt_numtests++; \
|
||||
|
@ -1940,13 +1939,13 @@ static void test_setrows(void)
|
|||
| CCS_NOMOVEY | CCS_TOP,
|
||||
0,
|
||||
0, NULL, 0,
|
||||
buttons, sizeof(buttons)/sizeof(buttons[0]),
|
||||
buttons, ARRAY_SIZE(buttons),
|
||||
20, 20, 0, 0, sizeof(TBBUTTON));
|
||||
ok(hToolbar != NULL, "Toolbar creation\n");
|
||||
ok(SendMessageA(hToolbar, TB_AUTOSIZE, 0, 0) == 0, "TB_AUTOSIZE failed\n");
|
||||
|
||||
/* test setting rows to each of 1-10 with bLarger true and false */
|
||||
for (i=0; i<(sizeof(tbrows_results) / sizeof(tbrows_result_t)); i++) {
|
||||
for (i=0; i<ARRAY_SIZE(tbrows_results); i++) {
|
||||
RECT rc;
|
||||
int rows;
|
||||
|
||||
|
@ -2026,7 +2025,7 @@ static void test_tooltip(void)
|
|||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
SendMessageA(hToolbar, WM_NOTIFY, 0, (LPARAM)&nmtti);
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, ttgetdispinfo_parent_seq,
|
||||
"dispinfo from tooltip", TRUE);
|
||||
"dispinfo from tooltip", FALSE);
|
||||
|
||||
g_ResetDispTextPtr = TRUE;
|
||||
SendMessageA(hToolbar, WM_NOTIFY, 0, (LPARAM)&nmtti);
|
||||
|
@ -2059,7 +2058,7 @@ static void test_get_set_style(void)
|
|||
WS_CHILD | TBSTYLE_LIST,
|
||||
100,
|
||||
0, NULL, 0,
|
||||
buttons, sizeof(buttons)/sizeof(buttons[0]),
|
||||
buttons, ARRAY_SIZE(buttons),
|
||||
0, 0, 20, 16, sizeof(TBBUTTON));
|
||||
ok(hToolbar != NULL, "Toolbar creation\n");
|
||||
SendMessageA(hToolbar, TB_ADDSTRINGA, 0, (LPARAM)"test\000");
|
||||
|
@ -2277,7 +2276,7 @@ static void test_TB_GET_SET_EXTENDEDSTYLE(void)
|
|||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(extended_style_test)/sizeof(extended_style_t); i++)
|
||||
for (i = 0; i < ARRAY_SIZE(extended_style_test); i++)
|
||||
{
|
||||
ptr = &extended_style_test[i];
|
||||
|
||||
|
@ -2398,7 +2397,7 @@ static void test_save(void)
|
|||
params.pszValueName = value;
|
||||
|
||||
rebuild_toolbar_with_buttons( &wnd );
|
||||
SendMessageW( wnd, TB_ADDBUTTONSW, sizeof(more_btns) / sizeof(more_btns[0]), (LPARAM)more_btns );
|
||||
SendMessageW(wnd, TB_ADDBUTTONSW, ARRAY_SIZE(more_btns), (LPARAM)more_btns);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
res = SendMessageW( wnd, TB_SAVERESTOREW, TRUE, (LPARAM)¶ms );
|
||||
|
@ -2424,7 +2423,7 @@ static void test_save(void)
|
|||
ok( res, "restoring failed\n" );
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, restore_parent_seq, "restore", FALSE);
|
||||
count = SendMessageW( wnd, TB_BUTTONCOUNT, 0, 0 );
|
||||
ok( count == sizeof(expect_btns) / sizeof(expect_btns[0]), "got %d\n", count );
|
||||
ok( count == ARRAY_SIZE(expect_btns), "got %d\n", count );
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
|
|
|
@ -183,7 +183,7 @@ static void test_customdraw(void) {
|
|||
GetCursorPos(&orig_pos);
|
||||
|
||||
for (iterationNumber = 0;
|
||||
iterationNumber < sizeof(expectedResults)/sizeof(expectedResults[0]);
|
||||
iterationNumber < ARRAY_SIZE(expectedResults);
|
||||
iterationNumber++) {
|
||||
|
||||
HWND parent, hwndTip;
|
||||
|
@ -821,7 +821,7 @@ static void test_longtextW(void)
|
|||
toolinfoW.hinst = GetModuleHandleW(NULL);
|
||||
toolinfoW.uFlags = 0;
|
||||
toolinfoW.uId = 0x1234ABCD;
|
||||
MultiByteToWideChar(CP_ACP, 0, longtextA, -1, bufW, sizeof(bufW)/sizeof(bufW[0]));
|
||||
MultiByteToWideChar(CP_ACP, 0, longtextA, -1, bufW, ARRAY_SIZE(bufW));
|
||||
lenW = lstrlenW(bufW);
|
||||
toolinfoW.lpszText = bufW;
|
||||
toolinfoW.lParam = 0xdeadbeef;
|
||||
|
|
|
@ -577,6 +577,58 @@ static void test_page_size(void)
|
|||
hWndTrackbar = create_trackbar(defaultstyle, hWndParent);
|
||||
ok(hWndTrackbar != NULL, "Expected non NULL value\n");
|
||||
|
||||
r = SendMessageA(hWndTrackbar, TBM_GETPAGESIZE, 0, 0);
|
||||
ok(r == 20, "Unexpected page size %d.\n", r);
|
||||
|
||||
SendMessageA(hWndTrackbar, TBM_SETRANGE, 0, MAKELPARAM(0, 65));
|
||||
|
||||
r = SendMessageA(hWndTrackbar, TBM_GETPAGESIZE, 0, 0);
|
||||
ok(r == 13, "Unexpected page size %d.\n", r);
|
||||
|
||||
SendMessageA(hWndTrackbar, TBM_SETRANGEMIN, 0, 10);
|
||||
|
||||
r = SendMessageA(hWndTrackbar, TBM_GETPAGESIZE, 0, 0);
|
||||
ok(r == 11, "Unexpected page size %d.\n", r);
|
||||
|
||||
SendMessageA(hWndTrackbar, TBM_SETRANGEMAX, 0, 50);
|
||||
|
||||
r = SendMessageA(hWndTrackbar, TBM_GETPAGESIZE, 0, 0);
|
||||
ok(r == 8, "Unexpected page size %d.\n", r);
|
||||
|
||||
r = SendMessageA(hWndTrackbar, TBM_SETPAGESIZE, 0, 10);
|
||||
ok(r == 8, "Unexpected page size %d.\n", r);
|
||||
|
||||
SendMessageA(hWndTrackbar, TBM_SETRANGE, 0, MAKELPARAM(0, 30));
|
||||
|
||||
r = SendMessageA(hWndTrackbar, TBM_GETPAGESIZE, 0, 0);
|
||||
ok(r == 10, "Unexpected page size %d.\n", r);
|
||||
|
||||
SendMessageA(hWndTrackbar, TBM_SETRANGEMIN, 0, 5);
|
||||
|
||||
r = SendMessageA(hWndTrackbar, TBM_GETPAGESIZE, 0, 0);
|
||||
ok(r == 10, "Unexpected page size %d.\n", r);
|
||||
|
||||
SendMessageA(hWndTrackbar, TBM_SETRANGEMAX, 0, 40);
|
||||
|
||||
r = SendMessageA(hWndTrackbar, TBM_GETPAGESIZE, 0, 0);
|
||||
ok(r == 10, "Unexpected page size %d.\n", r);
|
||||
|
||||
r = SendMessageA(hWndTrackbar, TBM_SETPAGESIZE, 0, -1);
|
||||
ok(r == 10, "Unexpected page size %d.\n", r);
|
||||
|
||||
r = SendMessageA(hWndTrackbar, TBM_GETPAGESIZE, 0, 0);
|
||||
ok(r == 7, "Unexpected page size %d.\n", r);
|
||||
|
||||
SendMessageA(hWndTrackbar, TBM_SETRANGEMAX, 0, 100);
|
||||
|
||||
r = SendMessageA(hWndTrackbar, TBM_GETPAGESIZE, 0, 0);
|
||||
ok(r == 19, "Unexpected page size %d.\n", r);
|
||||
|
||||
DestroyWindow(hWndTrackbar);
|
||||
|
||||
hWndTrackbar = create_trackbar(defaultstyle, hWndParent);
|
||||
ok(hWndTrackbar != NULL, "Failed to create trackbar window.\n");
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCE);
|
||||
|
||||
/* test TBM_SETPAGESIZE */
|
||||
|
|
|
@ -527,7 +527,7 @@ static void test_callback(void)
|
|||
tvi.hItem = hRoot;
|
||||
tvi.mask = TVIF_TEXT;
|
||||
tvi.pszText = buf;
|
||||
tvi.cchTextMax = sizeof(buf)/sizeof(buf[0]);
|
||||
tvi.cchTextMax = ARRAY_SIZE(buf);
|
||||
ret = TreeView_GetItemA(hTree, &tvi);
|
||||
expect(TRUE, ret);
|
||||
ok(strcmp(tvi.pszText, TEST_CALLBACK_TEXT) == 0, "Callback item text mismatch %s vs %s\n",
|
||||
|
@ -706,7 +706,7 @@ static void test_getitemtext(void)
|
|||
HWND hTree;
|
||||
|
||||
CHAR szBuffer[80] = "Blah";
|
||||
int nBufferSize = sizeof(szBuffer)/sizeof(CHAR);
|
||||
int nBufferSize = ARRAY_SIZE(szBuffer);
|
||||
|
||||
hTree = create_treeview_control(0);
|
||||
fill_tree(hTree);
|
||||
|
@ -1528,6 +1528,49 @@ static void test_expandinvisible(void)
|
|||
DestroyWindow(hTree);
|
||||
}
|
||||
|
||||
static void test_expand(void)
|
||||
{
|
||||
HTREEITEM first, second, last, child;
|
||||
TVINSERTSTRUCTA ins;
|
||||
BOOL visible;
|
||||
RECT rect;
|
||||
HWND tv;
|
||||
int i;
|
||||
|
||||
tv = create_treeview_control(0);
|
||||
|
||||
ins.hParent = TVI_ROOT;
|
||||
ins.hInsertAfter = TVI_LAST;
|
||||
U(ins).item.mask = 0;
|
||||
first = TreeView_InsertItemA(tv, &ins);
|
||||
ok(first != NULL, "failed to insert first node\n");
|
||||
second = TreeView_InsertItemA(tv, &ins);
|
||||
ok(second != NULL, "failed to insert second node\n");
|
||||
for (i=0; i<100; i++)
|
||||
{
|
||||
last = TreeView_InsertItemA(tv, &ins);
|
||||
ok(last != NULL, "failed to insert %d node\n", i);
|
||||
}
|
||||
|
||||
ins.hParent = second;
|
||||
child = TreeView_InsertItemA(tv, &ins);
|
||||
ok(child != NULL, "failed to insert child node\n");
|
||||
|
||||
ok(SendMessageA(tv, TVM_SELECTITEM, TVGN_CARET, (LPARAM)last), "last node selection failed\n");
|
||||
ok(SendMessageA(tv, TVM_EXPAND, TVE_EXPAND, (LPARAM)second), "expand of second node failed\n");
|
||||
ok(SendMessageA(tv, TVM_SELECTITEM, TVGN_CARET, (LPARAM)first), "first node selection failed\n");
|
||||
|
||||
*(HTREEITEM *)&rect = first;
|
||||
visible = SendMessageA(tv, TVM_GETITEMRECT, FALSE, (LPARAM)&rect);
|
||||
ok(visible, "first node should be visible\n");
|
||||
ok(!rect.left, "rect.left = %d\n", rect.left);
|
||||
ok(!rect.top, "rect.top = %d\n", rect.top);
|
||||
ok(rect.right, "rect.right = 0\n");
|
||||
ok(rect.bottom, "rect.bottom = 0\n");
|
||||
|
||||
DestroyWindow(tv);
|
||||
}
|
||||
|
||||
static void test_itemedit(void)
|
||||
{
|
||||
DWORD r;
|
||||
|
@ -1587,7 +1630,7 @@ static void test_itemedit(void)
|
|||
item.mask = TVIF_TEXT;
|
||||
item.hItem = hRoot;
|
||||
item.pszText = buffA;
|
||||
item.cchTextMax = sizeof(buffA)/sizeof(CHAR);
|
||||
item.cchTextMax = ARRAY_SIZE(buffA);
|
||||
r = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item);
|
||||
expect(TRUE, r);
|
||||
ok(!strcmp("x", buffA), "Expected item text to change\n");
|
||||
|
@ -1621,7 +1664,7 @@ static void test_itemedit(void)
|
|||
ok(IsWindow(edit), "Expected valid handle\n");
|
||||
g_beginedit_alter_text = FALSE;
|
||||
|
||||
GetWindowTextA(edit, buffA, sizeof(buffA)/sizeof(CHAR));
|
||||
GetWindowTextA(edit, buffA, ARRAY_SIZE(buffA));
|
||||
ok(!strcmp(buffA, "<edittextaltered>"), "got string %s\n", buffA);
|
||||
|
||||
DestroyWindow(hTree);
|
||||
|
@ -1948,7 +1991,7 @@ static void test_TVS_SINGLEEXPAND(void)
|
|||
SetWindowLongA(hTree, GWL_STYLE, GetWindowLongA(hTree, GWL_STYLE) | TVS_SINGLEEXPAND);
|
||||
/* to avoid painting related notifications */
|
||||
ShowWindow(hTree, SW_HIDE);
|
||||
for (i = 0; i < sizeof(items)/sizeof(items[0]); i++)
|
||||
for (i = 0; i < ARRAY_SIZE(items); i++)
|
||||
{
|
||||
ins.hParent = items[i].parent ? *items[i].parent : TVI_ROOT;
|
||||
ins.hInsertAfter = TVI_FIRST;
|
||||
|
@ -1957,7 +2000,7 @@ static void test_TVS_SINGLEEXPAND(void)
|
|||
*items[i].handle = TreeView_InsertItemA(hTree, &ins);
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(sequence_tests)/sizeof(sequence_tests[0]); i++)
|
||||
for (i = 0; i < ARRAY_SIZE(sequence_tests); i++)
|
||||
{
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
ret = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)(*sequence_tests[i].select));
|
||||
|
@ -1966,7 +2009,7 @@ static void test_TVS_SINGLEEXPAND(void)
|
|||
ok_sequence(sequences, PARENT_SEQ_INDEX, sequence_tests[i].sequence, context, FALSE);
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(items)/sizeof(items[0]); i++)
|
||||
for (i = 0; i < ARRAY_SIZE(items); i++)
|
||||
{
|
||||
ret = SendMessageA(hTree, TVM_GETITEMSTATE, (WPARAM)(*items[i].handle), 0xFFFF);
|
||||
ok(ret == items[i].final_state, "singleexpand items[%d]: expected state 0x%x got 0x%x\n",
|
||||
|
@ -2132,20 +2175,64 @@ struct _ITEM_DATA
|
|||
HTREEITEM parent; /* for root value of parent field is unidetified */
|
||||
HTREEITEM nextsibling;
|
||||
HTREEITEM firstchild;
|
||||
void *unk[2];
|
||||
DWORD unk2;
|
||||
WORD pad;
|
||||
WORD width;
|
||||
};
|
||||
|
||||
static void _check_item(HTREEITEM item, HTREEITEM parent, HTREEITEM nextsibling, HTREEITEM firstchild, int line)
|
||||
struct _ITEM_DATA_V6
|
||||
{
|
||||
struct _ITEM_DATA *data = (struct _ITEM_DATA*)item;
|
||||
HTREEITEM parent; /* for root value of parent field is unidetified */
|
||||
HTREEITEM nextsibling;
|
||||
HTREEITEM firstchild;
|
||||
void *unk[3];
|
||||
DWORD unk2[2];
|
||||
WORD pad;
|
||||
WORD width;
|
||||
};
|
||||
|
||||
ok_(__FILE__, line)(data->parent == parent, "parent %p, got %p\n", parent, data->parent);
|
||||
ok_(__FILE__, line)(data->nextsibling == nextsibling, "sibling %p, got %p\n", nextsibling, data->nextsibling);
|
||||
ok_(__FILE__, line)(data->firstchild == firstchild, "firstchild %p, got %p\n", firstchild, data->firstchild);
|
||||
static void _check_item(HWND hwnd, HTREEITEM item, BOOL is_version_6, int line)
|
||||
{
|
||||
struct _ITEM_DATA *data = (struct _ITEM_DATA *)item;
|
||||
HTREEITEM parent, nextsibling, firstchild, root;
|
||||
RECT rect;
|
||||
BOOL ret;
|
||||
|
||||
root = (HTREEITEM)SendMessageA(hwnd, TVM_GETNEXTITEM, TVGN_ROOT, (LPARAM)item);
|
||||
parent = (HTREEITEM)SendMessageA(hwnd, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)item);
|
||||
nextsibling = (HTREEITEM)SendMessageA(hwnd, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)item);
|
||||
firstchild = (HTREEITEM)SendMessageA(hwnd, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)item);
|
||||
|
||||
*(HTREEITEM*)&rect = item;
|
||||
ret = SendMessageA(hwnd, TVM_GETITEMRECT, TRUE, (LPARAM)&rect);
|
||||
|
||||
ok_(__FILE__, line)(item == root ? data->parent != NULL : data->parent == parent,
|
||||
"Unexpected parent item %p, got %p, %p\n", parent, data->parent, hwnd);
|
||||
ok_(__FILE__, line)(data->nextsibling == nextsibling, "Unexpected sibling %p, got %p\n",
|
||||
nextsibling, data->nextsibling);
|
||||
ok_(__FILE__, line)(data->firstchild == firstchild, "Unexpected first child %p, got %p\n",
|
||||
firstchild, data->firstchild);
|
||||
if (ret)
|
||||
{
|
||||
WORD width;
|
||||
|
||||
if (is_version_6)
|
||||
{
|
||||
struct _ITEM_DATA_V6 *data_v6 = (struct _ITEM_DATA_V6 *)item;
|
||||
width = data_v6->width;
|
||||
}
|
||||
else
|
||||
width = data->width;
|
||||
todo_wine
|
||||
ok_(__FILE__, line)(width == (rect.right - rect.left) || broken(is_version_6 && width == 0) /* XP */,
|
||||
"Width %d, rect width %d.\n", width, rect.right - rect.left);
|
||||
}
|
||||
}
|
||||
|
||||
#define check_item(a, b, c, d) _check_item(a, b, c, d, __LINE__)
|
||||
#define CHECK_ITEM(a, b) _check_item(a, b, is_version_6, __LINE__)
|
||||
|
||||
static void test_htreeitem_layout(void)
|
||||
static void test_htreeitem_layout(BOOL is_version_6)
|
||||
{
|
||||
TVINSERTSTRUCTA ins;
|
||||
HTREEITEM item1, item2;
|
||||
|
@ -2155,27 +2242,27 @@ static void test_htreeitem_layout(void)
|
|||
fill_tree(hTree);
|
||||
|
||||
/* root has some special pointer in parent field */
|
||||
check_item(hRoot, ((struct _ITEM_DATA*)hRoot)->parent, 0, hChild);
|
||||
check_item(hChild, hRoot, 0, 0);
|
||||
CHECK_ITEM(hTree, hRoot);
|
||||
CHECK_ITEM(hTree, hChild);
|
||||
|
||||
ins.hParent = hChild;
|
||||
ins.hInsertAfter = TVI_FIRST;
|
||||
U(ins).item.mask = 0;
|
||||
item1 = TreeView_InsertItemA(hTree, &ins);
|
||||
|
||||
check_item(item1, hChild, 0, 0);
|
||||
CHECK_ITEM(hTree, item1);
|
||||
|
||||
ins.hParent = hRoot;
|
||||
ins.hInsertAfter = TVI_FIRST;
|
||||
U(ins).item.mask = 0;
|
||||
item2 = TreeView_InsertItemA(hTree, &ins);
|
||||
|
||||
check_item(item2, hRoot, hChild, 0);
|
||||
CHECK_ITEM(hTree, item2);
|
||||
|
||||
SendMessageA(hTree, TVM_DELETEITEM, 0, (LPARAM)hChild);
|
||||
|
||||
/* without children now */
|
||||
check_item(hRoot, ((struct _ITEM_DATA*)hRoot)->parent, 0, item2);
|
||||
CHECK_ITEM(hTree, hRoot);
|
||||
|
||||
DestroyWindow(hTree);
|
||||
}
|
||||
|
@ -2722,15 +2809,7 @@ static void test_right_click(void)
|
|||
HTREEITEM selected;
|
||||
RECT rc;
|
||||
LRESULT result;
|
||||
POINT pt;
|
||||
|
||||
#ifdef __REACTOS__
|
||||
if (!winetest_interactive)
|
||||
{
|
||||
skip("test_right_click() (set WINETEST_INTERACTIVE=1), until CORE-14975 is fixed upstream and WINESYNC\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
POINT pt, orig_pos;
|
||||
|
||||
hTree = create_treeview_control(0);
|
||||
fill_tree(hTree);
|
||||
|
@ -2749,6 +2828,8 @@ static void test_right_click(void)
|
|||
pt.x = (rc.left + rc.right) / 2;
|
||||
pt.y = (rc.top + rc.bottom) / 2;
|
||||
ClientToScreen(hMainWnd, &pt);
|
||||
GetCursorPos(&orig_pos);
|
||||
SetCursorPos(pt.x, pt.y);
|
||||
|
||||
flush_events();
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
@ -2764,6 +2845,7 @@ static void test_right_click(void)
|
|||
selected = (HTREEITEM)SendMessageA(hTree, TVM_GETNEXTITEM, TVGN_CARET, 0);
|
||||
ok(selected == hChild, "child item should still be selected\n");
|
||||
|
||||
SetCursorPos(orig_pos.x, orig_pos.y);
|
||||
DestroyWindow(hTree);
|
||||
}
|
||||
|
||||
|
@ -2835,7 +2917,7 @@ START_TEST(treeview)
|
|||
test_WM_PAINT();
|
||||
test_delete_items();
|
||||
test_cchildren();
|
||||
test_htreeitem_layout();
|
||||
test_htreeitem_layout(FALSE);
|
||||
test_TVS_CHECKBOXES();
|
||||
test_TVM_GETNEXTITEM();
|
||||
test_TVM_HITTEST();
|
||||
|
@ -2867,11 +2949,12 @@ START_TEST(treeview)
|
|||
test_get_set_tooltips();
|
||||
test_get_set_unicodeformat();
|
||||
test_expandinvisible();
|
||||
test_expand();
|
||||
test_itemedit();
|
||||
test_treeview_classinfo();
|
||||
test_delete_items();
|
||||
test_cchildren();
|
||||
test_htreeitem_layout();
|
||||
test_htreeitem_layout(TRUE);
|
||||
test_TVM_GETNEXTITEM();
|
||||
test_TVM_HITTEST();
|
||||
test_WM_GETDLGCODE();
|
||||
|
|
|
@ -697,13 +697,13 @@ static void test_updown_base(void)
|
|||
r = SendMessageA(updown, UDM_SETPOS, 0, 10);
|
||||
expect(50, r);
|
||||
|
||||
GetWindowTextA(g_edit, text, sizeof(text)/sizeof(CHAR));
|
||||
GetWindowTextA(g_edit, text, ARRAY_SIZE(text));
|
||||
ok(lstrcmpA(text, "10") == 0, "Expected '10', got '%s'\n", text);
|
||||
|
||||
r = SendMessageA(updown, UDM_SETBASE, 16, 0);
|
||||
expect(10, r);
|
||||
|
||||
GetWindowTextA(g_edit, text, sizeof(text)/sizeof(CHAR));
|
||||
GetWindowTextA(g_edit, text, ARRAY_SIZE(text));
|
||||
/* FIXME: currently hex output isn't properly formatted, but for this
|
||||
test only change from initial text matters */
|
||||
ok(lstrcmpA(text, "10") != 0, "Expected '0x000A', got '%s'\n", text);
|
||||
|
@ -837,20 +837,20 @@ static void test_UDS_SETBUDDYINT(void)
|
|||
style = GetWindowLongA(updown, GWL_STYLE);
|
||||
ok(style & UDS_SETBUDDYINT, "Expected UDS_SETBUDDY to be set\n");
|
||||
SendMessageA(updown, UDM_SETPOS, 0, 20);
|
||||
GetWindowTextA(g_edit, text, sizeof(text)/sizeof(CHAR));
|
||||
GetWindowTextA(g_edit, text, ARRAY_SIZE(text));
|
||||
ok(lstrlenA(text) == 0, "Expected empty string\n");
|
||||
DestroyWindow(updown);
|
||||
|
||||
/* creating with UDS_SETBUDDYINT */
|
||||
updown = create_updown_control(UDS_SETBUDDYINT | UDS_ALIGNRIGHT, g_edit);
|
||||
GetWindowTextA(g_edit, text, sizeof(text)/sizeof(CHAR));
|
||||
GetWindowTextA(g_edit, text, ARRAY_SIZE(text));
|
||||
/* 50 is initial value here */
|
||||
ok(lstrcmpA(text, "50") == 0, "Expected '50', got '%s'\n", text);
|
||||
/* now remove style flag */
|
||||
style = GetWindowLongA(updown, GWL_STYLE);
|
||||
SetWindowLongA(updown, GWL_STYLE, style & ~UDS_SETBUDDYINT);
|
||||
SendMessageA(updown, UDM_SETPOS, 0, 20);
|
||||
GetWindowTextA(g_edit, text, sizeof(text)/sizeof(CHAR));
|
||||
GetWindowTextA(g_edit, text, ARRAY_SIZE(text));
|
||||
ok(lstrcmpA(text, "20") == 0, "Expected '20', got '%s'\n", text);
|
||||
/* set edit text directly, check position */
|
||||
strcpy(text, "10");
|
||||
|
@ -872,7 +872,7 @@ static void test_UDS_SETBUDDYINT(void)
|
|||
style = GetWindowLongA(updown, GWL_STYLE);
|
||||
SetWindowLongA(updown, GWL_STYLE, style | UDS_SETBUDDYINT);
|
||||
SendMessageA(updown, UDM_SETPOS, 0, 30);
|
||||
GetWindowTextA(g_edit, text, sizeof(text)/sizeof(CHAR));
|
||||
GetWindowTextA(g_edit, text, ARRAY_SIZE(text));
|
||||
ok(lstrcmpA(text, "30") == 0, "Expected '30', got '%s'\n", text);
|
||||
DestroyWindow(updown);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue