From d558fc75a234a98c954f91f5bb8ef4831ab152bd Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Tue, 3 Apr 2018 13:49:56 +0100 Subject: [PATCH] [USER32_WINETEST] Sync everything except win.c with Wine Staging 3.3. CORE-14434 --- modules/rostests/winetests/user32/broadcast.c | 88 ++-- modules/rostests/winetests/user32/class.c | 340 ++++++++++++- modules/rostests/winetests/user32/clipboard.c | 415 +++------------- modules/rostests/winetests/user32/combo.c | 184 +++++-- .../rostests/winetests/user32/cursoricon.c | 21 +- modules/rostests/winetests/user32/dce.c | 137 ++++- modules/rostests/winetests/user32/dde.c | 14 +- modules/rostests/winetests/user32/dialog.c | 467 +++++++++++++++++- modules/rostests/winetests/user32/edit.c | 267 ++++++++-- modules/rostests/winetests/user32/generated.c | 12 +- modules/rostests/winetests/user32/input.c | 152 +++++- modules/rostests/winetests/user32/listbox.c | 67 ++- modules/rostests/winetests/user32/menu.c | 27 +- modules/rostests/winetests/user32/monitor.c | 5 +- modules/rostests/winetests/user32/msg.c | 237 +++++++-- modules/rostests/winetests/user32/precomp.h | 10 +- modules/rostests/winetests/user32/resource.c | 5 +- modules/rostests/winetests/user32/scroll.c | 7 +- modules/rostests/winetests/user32/static.c | 10 +- modules/rostests/winetests/user32/sysparams.c | 34 +- modules/rostests/winetests/user32/text.c | 9 +- modules/rostests/winetests/user32/uitools.c | 6 +- .../rostests/winetests/user32/winstation.c | 9 +- modules/rostests/winetests/user32/wsprintf.c | 8 +- 24 files changed, 1947 insertions(+), 584 deletions(-) diff --git a/modules/rostests/winetests/user32/broadcast.c b/modules/rostests/winetests/user32/broadcast.c index d4041500fa2..949d1e865f8 100644 --- a/modules/rostests/winetests/user32/broadcast.c +++ b/modules/rostests/winetests/user32/broadcast.c @@ -18,14 +18,23 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#ifndef __REACTOS__ +#define _WIN32_WINNT 0x0501 +#endif + +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "winnls.h" + +#include "wine/test.h" typedef LONG (WINAPI *PBROADCAST)( DWORD,LPDWORD,UINT,WPARAM,LPARAM ); typedef LONG (WINAPI *PBROADCASTEX)( DWORD,LPDWORD,UINT,WPARAM,LPARAM,PBSMINFO ); -static PBROADCAST pBroadcastA; -static PBROADCAST pBroadcastW; -static PBROADCASTEX pBroadcastExA; -static PBROADCASTEX pBroadcastExW; static HANDLE hevent; static LRESULT WINAPI main_window_procA(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) @@ -48,20 +57,6 @@ static LRESULT WINAPI main_window_procA(HWND hwnd, UINT msg, WPARAM wparam, LPAR static BOOL init_procs(void) { WNDCLASSA cls; - HANDLE user32 = GetModuleHandleA("user32.dll"); - pBroadcastA = (PBROADCAST)GetProcAddress(user32, "BroadcastSystemMessageA"); - if (!pBroadcastA) - pBroadcastA = (PBROADCAST)GetProcAddress(user32, "BroadcastSystemMessage"); - ok(pBroadcastA != NULL, "No BroadcastSystemMessage found\n"); - if (!pBroadcastA) - { - win_skip("BroadcastA is not available\n"); - return FALSE; - } - - pBroadcastW = (PBROADCAST)GetProcAddress(user32, "BroadcastSystemMessageW"); - pBroadcastExA = (PBROADCASTEX)GetProcAddress(user32, "BroadcastSystemMessageExA"); - pBroadcastExW = (PBROADCASTEX)GetProcAddress(user32, "BroadcastSystemMessageExW"); hevent = CreateEventA(NULL, TRUE, FALSE, "Asynchronous checking event"); @@ -253,12 +248,8 @@ if (0) /* TODO: Check the hang flags */ PulseEvent(hevent); } -static BOOL (WINAPI *pOpenProcessToken)(HANDLE, DWORD, HANDLE*); -static BOOL (WINAPI *pAdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD); - static void test_noprivileges(void) { - HANDLE advapi32 = GetModuleHandleA("advapi32"); HANDLE token; DWORD recips; BOOL ret; @@ -266,14 +257,12 @@ static void test_noprivileges(void) static const DWORD BSM_ALL_RECIPS = BSM_VXDS | BSM_NETDRIVER | BSM_INSTALLABLEDRIVERS | BSM_APPLICATIONS; - pOpenProcessToken = (void *)GetProcAddress(advapi32, "OpenProcessToken"); - pAdjustTokenPrivileges = (void *)GetProcAddress(advapi32, "AdjustTokenPrivileges"); - if (!pOpenProcessToken || !pAdjustTokenPrivileges || !pOpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) { skip("Can't open security token for process\n"); return; } - if (!pAdjustTokenPrivileges(token, TRUE, NULL, 0, NULL, NULL)) + if (!AdjustTokenPrivileges(token, TRUE, NULL, 0, NULL, NULL)) { skip("Can't adjust security token for process\n"); return; @@ -283,7 +272,7 @@ static void test_noprivileges(void) SetLastError(0xcafebabe); recips = BSM_ALLDESKTOPS; ResetEvent(hevent); - ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL ); + ret = BroadcastSystemMessageExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL ); ok(ret==1, "Returned: %d error %u\n", ret, GetLastError()); ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n"); ok(recips == BSM_ALLDESKTOPS || @@ -294,7 +283,7 @@ static void test_noprivileges(void) SetLastError(0xcafebabe); recips = BSM_ALLCOMPONENTS; ResetEvent(hevent); - ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL ); + ret = BroadcastSystemMessageExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL ); ok(ret==1, "Returned: %d error %u\n", ret, GetLastError()); ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n"); ok(recips == BSM_ALLCOMPONENTS || @@ -305,7 +294,7 @@ static void test_noprivileges(void) SetLastError(0xcafebabe); recips = BSM_ALLDESKTOPS|BSM_APPLICATIONS; ResetEvent(hevent); - ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL ); + ret = BroadcastSystemMessageExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL ); ok(ret==1, "Returned: %d error %u\n", ret, GetLastError()); ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n"); ok(recips == (BSM_ALLDESKTOPS|BSM_APPLICATIONS) || @@ -316,7 +305,7 @@ static void test_noprivileges(void) SetLastError(0xcafebabe); recips = BSM_ALLDESKTOPS|BSM_APPLICATIONS; ResetEvent(hevent); - ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY, NULL ); + ret = BroadcastSystemMessageExW( BSF_QUERY, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY, NULL ); ok(!ret, "Returned: %d\n", ret); ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n"); ok(recips == (BSM_ALLDESKTOPS|BSM_APPLICATIONS) || @@ -331,28 +320,17 @@ START_TEST(broadcast) return; trace("Running BroadcastSystemMessageA tests\n"); - test_parameters(pBroadcastA, "BroadcastSystemMessageA"); - if (pBroadcastW) - { - trace("Running BroadcastSystemMessageW tests\n"); - test_parameters(pBroadcastW, "BroadcastSystemMessageW"); - } - else - win_skip("No BroadcastSystemMessageW, skipping\n"); - if (pBroadcastExA) - { - trace("Running BroadcastSystemMessageExA tests\n"); - test_parametersEx(pBroadcastExA); - } - else - win_skip("No BroadcastSystemMessageExA, skipping\n"); - if (pBroadcastExW) - { - trace("Running BroadcastSystemMessageExW tests\n"); - test_parametersEx(pBroadcastExW); - trace("Attempting privileges checking tests\n"); - test_noprivileges(); - } - else - win_skip("No BroadcastSystemMessageExW, skipping\n"); + test_parameters(BroadcastSystemMessageA, "BroadcastSystemMessageA"); + + trace("Running BroadcastSystemMessageW tests\n"); + test_parameters(BroadcastSystemMessageW, "BroadcastSystemMessageW"); + + trace("Running BroadcastSystemMessageExA tests\n"); + test_parametersEx(BroadcastSystemMessageExA); + + trace("Running BroadcastSystemMessageExW tests\n"); + test_parametersEx(BroadcastSystemMessageExW); + + trace("Attempting privileges checking tests\n"); + test_noprivileges(); } diff --git a/modules/rostests/winetests/user32/class.c b/modules/rostests/winetests/user32/class.c index 0d358c2ad9b..934ea0bfee3 100755 --- a/modules/rostests/winetests/user32/class.c +++ b/modules/rostests/winetests/user32/class.c @@ -18,14 +18,64 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +/* To get CS_DROPSHADOW with the MSVC headers */ +#ifndef __REACTOS__ +#define _WIN32_WINNT 0x0501 +#endif -#include +#include +#include +#include + +#include "wine/test.h" +#include "windef.h" +#include "winbase.h" +#include "winnls.h" +#include "winreg.h" +#include "wingdi.h" +#include "winuser.h" +#include "commctrl.h" #define NUMCLASSWORDS 4 #define IS_WNDPROC_HANDLE(x) (((ULONG_PTR)(x) >> 16) == (~0u >> 16)) +#ifdef __i386__ +#define ARCH "x86" +#elif defined __x86_64__ +#define ARCH "amd64" +#elif defined __arm__ +#define ARCH "arm" +#elif defined __aarch64__ +#define ARCH "arm64" +#else +#define ARCH "none" +#endif + +static const char comctl32_manifest[] = +"\n" +"\n" +" \n" +"Wine comctl32 test suite\n" +"\n" +" \n" +" \n" +"\n" +"\n" +"\n"; + static LRESULT WINAPI ClassTest_WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (msg == WM_NCCREATE) return 1; @@ -1029,6 +1079,45 @@ static void test_icons(void) DestroyWindow(hwnd); } +static void create_manifest_file(const char *filename, const char *manifest) +{ + WCHAR path[MAX_PATH]; + HANDLE file; + DWORD size; + + MultiByteToWideChar( CP_ACP, 0, filename, -1, path, MAX_PATH ); + file = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError()); + WriteFile(file, manifest, strlen(manifest), &size, NULL); + CloseHandle(file); +} + +static HANDLE create_test_actctx(const char *file) +{ + WCHAR path[MAX_PATH]; + ACTCTXW actctx; + HANDLE handle; + + MultiByteToWideChar(CP_ACP, 0, file, -1, path, MAX_PATH); + memset(&actctx, 0, sizeof(ACTCTXW)); + actctx.cbSize = sizeof(ACTCTXW); + actctx.lpSource = path; + + handle = CreateActCtxW(&actctx); + ok(handle != INVALID_HANDLE_VALUE, "failed to create context, error %u\n", GetLastError()); + + ok(actctx.cbSize == sizeof(actctx), "cbSize=%d\n", actctx.cbSize); + ok(actctx.dwFlags == 0, "dwFlags=%d\n", actctx.dwFlags); + ok(actctx.lpSource == path, "lpSource=%p\n", actctx.lpSource); + ok(actctx.wProcessorArchitecture == 0, "wProcessorArchitecture=%d\n", actctx.wProcessorArchitecture); + ok(actctx.wLangId == 0, "wLangId=%d\n", actctx.wLangId); + ok(actctx.lpAssemblyDirectory == NULL, "lpAssemblyDirectory=%p\n", actctx.lpAssemblyDirectory); + ok(actctx.lpResourceName == NULL, "lpResourceName=%p\n", actctx.lpResourceName); + ok(actctx.lpApplicationName == NULL, "lpApplicationName=%p\n", actctx.lpApplicationName); + ok(actctx.hModule == NULL, "hModule=%p\n", actctx.hModule); + + return handle; +} static void test_comctl32_class( const char *name ) { WNDCLASSA wcA; @@ -1038,23 +1127,82 @@ static void test_comctl32_class( const char *name ) WCHAR nameW[20]; HWND hwnd; - module = GetModuleHandleA( "comctl32" ); - ok( !module, "comctl32 already loaded\n" ); - ret = GetClassInfoA( 0, name, &wcA ); - ok( ret || broken(!ret) /* <= winxp */, "GetClassInfoA failed for %s\n", name ); - if (!ret) return; - MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, sizeof(nameW)/sizeof(WCHAR) ); - ret = GetClassInfoW( 0, nameW, &wcW ); - ok( ret, "GetClassInfoW failed for %s\n", name ); - module = GetModuleHandleA( "comctl32" ); - ok( module != 0, "comctl32 not loaded\n" ); - FreeLibrary( module ); - module = GetModuleHandleA( "comctl32" ); - ok( !module, "comctl32 still loaded\n" ); - hwnd = CreateWindowA( name, "test", WS_OVERLAPPEDWINDOW, 0, 0, 10, 10, NULL, NULL, NULL, 0 ); - ok( hwnd != 0, "failed to create window for %s\n", name ); - module = GetModuleHandleA( "comctl32" ); - ok( module != 0, "comctl32 not loaded\n" ); + if (name[0] == '!') + { + char path[MAX_PATH]; + ULONG_PTR cookie; + HANDLE context; + + name++; + + GetTempPathA(sizeof(path)/sizeof(path[0]), path); + strcat(path, "comctl32_class.manifest"); + + create_manifest_file(path, comctl32_manifest); + context = create_test_actctx(path); + ret = DeleteFileA(path); + ok(ret, "Failed to delete manifest file, error %d.\n", GetLastError()); + + module = GetModuleHandleA( "comctl32" ); + ok( !module, "comctl32 already loaded\n" ); + + ret = ActivateActCtx(context, &cookie); + ok(ret, "Failed to activate context.\n"); + + /* Some systems load modules during context activation. In this case skip the rest of the test. */ + module = GetModuleHandleA( "comctl32" ); + ok( !module || broken(module != NULL) /* Vista/Win7 */, "comctl32 already loaded\n" ); + if (module) + { + win_skip("Module loaded during context activation. Skipping tests.\n"); + goto skiptest; + } + + ret = GetClassInfoA( 0, name, &wcA ); + ok( ret || broken(!ret) /* WinXP */, "GetClassInfoA failed for %s\n", name ); + if (!ret) + goto skiptest; + + MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, sizeof(nameW)/sizeof(WCHAR) ); + ret = GetClassInfoW( 0, nameW, &wcW ); + ok( ret, "GetClassInfoW failed for %s\n", name ); + module = GetModuleHandleA( "comctl32" ); + ok( module != 0, "comctl32 not loaded\n" ); + FreeLibrary( module ); + module = GetModuleHandleA( "comctl32" ); + ok( !module || broken(module != NULL) /* Vista */, "comctl32 still loaded\n" ); + hwnd = CreateWindowA( name, "test", WS_OVERLAPPEDWINDOW, 0, 0, 10, 10, NULL, NULL, NULL, 0 ); + ok( hwnd != 0, "failed to create window for %s\n", name ); + module = GetModuleHandleA( "comctl32" ); + ok( module != 0, "comctl32 not loaded\n" ); + DestroyWindow( hwnd ); + + skiptest: + ret = DeactivateActCtx(0, cookie); + ok(ret, "Failed to deactivate context.\n"); + ReleaseActCtx(context); + } + else + { + module = GetModuleHandleA( "comctl32" ); + ok( !module, "comctl32 already loaded\n" ); + ret = GetClassInfoA( 0, name, &wcA ); + ok( ret || broken(!ret) /* <= winxp */, "GetClassInfoA failed for %s\n", name ); + if (!ret) return; + MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, sizeof(nameW)/sizeof(WCHAR) ); + ret = GetClassInfoW( 0, nameW, &wcW ); + ok( ret, "GetClassInfoW failed for %s\n", name ); + module = GetModuleHandleA( "comctl32" ); + ok( module != 0, "comctl32 not loaded\n" ); + FreeLibrary( module ); + module = GetModuleHandleA( "comctl32" ); + ok( !module, "comctl32 still loaded\n" ); + hwnd = CreateWindowA( name, "test", WS_OVERLAPPEDWINDOW, 0, 0, 10, 10, NULL, NULL, NULL, 0 ); + ok( hwnd != 0, "failed to create window for %s\n", name ); + module = GetModuleHandleA( "comctl32" ); + ok( module != 0, "comctl32 not loaded\n" ); + DestroyWindow( hwnd ); + } } /* verify that comctl32 classes are automatically loaded by user32 */ @@ -1081,12 +1229,19 @@ static void test_comctl32_classes(void) PROGRESS_CLASSA, REBARCLASSNAMEA, STATUSCLASSNAMEA, + "SysLink", WC_TABCONTROLA, TOOLBARCLASSNAMEA, TOOLTIPS_CLASSA, TRACKBAR_CLASSA, WC_TREEVIEWA, - UPDOWN_CLASSA + UPDOWN_CLASSA, + "!Button", + "!Edit", + "!Static", + "!Listbox", + "!ComboBox", + "!ComboLBox", }; winetest_get_mainargs( &argv ); @@ -1149,6 +1304,150 @@ static void test_IME(void) ok(!lstrcmpiA(ptr, "user32.dll") || !lstrcmpiA(ptr, "ntdll.dll"), "IME window proc implemented in %s\n", ptr); } +static void test_actctx_classes(void) +{ + static const char main_manifest[] = + "" + "" + "" + "MyTestClass" + "" + ""; + static const char *testclass = "MyTestClass"; + WNDCLASSA wc; + ULONG_PTR cookie; + HANDLE context; + BOOL ret; + ATOM class; + HINSTANCE hinst; + char buff[64]; + HWND hwnd; + char path[MAX_PATH]; + + GetTempPathA(sizeof(path)/sizeof(path[0]), path); + strcat(path, "actctx_classes.manifest"); + + create_manifest_file(path, main_manifest); + context = create_test_actctx(path); + ret = DeleteFileA(path); + ok(ret, "Failed to delete manifest file, error %d.\n", GetLastError()); + + ret = ActivateActCtx(context, &cookie); + ok(ret, "Failed to activate context.\n"); + + memset(&wc, 0, sizeof(wc)); + wc.lpfnWndProc = ClassTest_WndProc; + wc.hIcon = LoadIconW(0, (LPCWSTR)IDI_APPLICATION); + wc.lpszClassName = testclass; + + hinst = GetModuleHandleW(0); + + ret = GetClassInfoA(hinst, testclass, &wc); + ok(!ret, "Expected failure.\n"); + + class = RegisterClassA(&wc); + ok(class != 0, "Failed to register class.\n"); + + /* Class info is available by versioned and regular names. */ + ret = GetClassInfoA(hinst, testclass, &wc); + ok(ret, "Failed to get class info.\n"); + + hwnd = CreateWindowExA(0, testclass, "test", 0, 0, 0, 0, 0, 0, 0, hinst, 0); + ok(hwnd != NULL, "Failed to create a window.\n"); + + ret = GetClassNameA(hwnd, buff, sizeof(buff)); + ok(ret, "Failed to get class name.\n"); + ok(!strcmp(buff, testclass), "Unexpected class name.\n"); + + ret = GetClassInfoA(hinst, "4.3.2.1!MyTestClass", &wc); + ok(ret, "Failed to get class info.\n"); + + ret = UnregisterClassA(testclass, hinst); + ok(!ret, "Failed to unregister class.\n"); + + ret = DeactivateActCtx(0, cookie); + ok(ret, "Failed to deactivate context.\n"); + + ret = GetClassInfoA(hinst, testclass, &wc); + ok(!ret, "Unexpected ret val %d.\n", ret); + + ret = GetClassInfoA(hinst, "4.3.2.1!MyTestClass", &wc); + ok(ret, "Failed to get class info.\n"); + + ret = GetClassNameA(hwnd, buff, sizeof(buff)); + ok(ret, "Failed to get class name.\n"); + ok(!strcmp(buff, testclass), "Unexpected class name.\n"); + + DestroyWindow(hwnd); + + ret = UnregisterClassA("MyTestClass", hinst); + ok(!ret, "Unexpected ret value %d.\n", ret); + + ret = UnregisterClassA("4.3.2.1!MyTestClass", hinst); + ok(ret, "Failed to unregister class.\n"); + + /* Register versioned class without active context. */ + wc.lpszClassName = "4.3.2.1!MyTestClass"; + class = RegisterClassA(&wc); + ok(class != 0, "Failed to register class.\n"); + + ret = ActivateActCtx(context, &cookie); + ok(ret, "Failed to activate context.\n"); + + wc.lpszClassName = "MyTestClass"; + class = RegisterClassA(&wc); + ok(class == 0, "Expected failure.\n"); + + ret = DeactivateActCtx(0, cookie); + ok(ret, "Failed to deactivate context.\n"); + + ret = UnregisterClassA("4.3.2.1!MyTestClass", hinst); + ok(ret, "Failed to unregister class.\n"); + + /* Only versioned name is registered. */ + ret = ActivateActCtx(context, &cookie); + ok(ret, "Failed to activate context.\n"); + + wc.lpszClassName = "MyTestClass"; + class = RegisterClassA(&wc); + ok(class != 0, "Failed to register class\n"); + + ret = DeactivateActCtx(0, cookie); + ok(ret, "Failed to deactivate context.\n"); + + ret = GetClassInfoA(hinst, "MyTestClass", &wc); + ok(!ret, "Expected failure.\n"); + + ret = GetClassInfoA(hinst, "4.3.2.1!MyTestClass", &wc); + ok(ret, "Failed to get class info.\n"); + + ret = UnregisterClassA("4.3.2.1!MyTestClass", hinst); + ok(ret, "Failed to unregister class.\n"); + + /* Register regular name first, it's not considered when versioned name is registered. */ + wc.lpszClassName = "MyTestClass"; + class = RegisterClassA(&wc); + ok(class != 0, "Failed to register class.\n"); + + ret = ActivateActCtx(context, &cookie); + ok(ret, "Failed to activate context.\n"); + + wc.lpszClassName = "MyTestClass"; + class = RegisterClassA(&wc); + ok(class != 0, "Failed to register class.\n"); + + ret = DeactivateActCtx(0, cookie); + ok(ret, "Failed to deactivate context.\n"); + + ret = UnregisterClassA("4.3.2.1!MyTestClass", hinst); + ok(ret, "Failed to unregister class.\n"); + + ret = UnregisterClassA("MyTestClass", hinst); + ok(ret, "Failed to unregister class.\n"); + + ReleaseActCtx(context); +} + START_TEST(class) { char **argv; @@ -1178,6 +1477,7 @@ START_TEST(class) test_builtinproc(); test_icons(); test_comctl32_classes(); + test_actctx_classes(); /* this test unregisters the Button class so it should be executed at the end */ test_instances(); diff --git a/modules/rostests/winetests/user32/clipboard.c b/modules/rostests/winetests/user32/clipboard.c index f4aa4a60a3e..2dced095b2a 100755 --- a/modules/rostests/winetests/user32/clipboard.c +++ b/modules/rostests/winetests/user32/clipboard.c @@ -18,9 +18,17 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include +#include "wine/test.h" +#include "winbase.h" +#include "winerror.h" +#include "wingdi.h" +#include "winuser.h" +#include "winnls.h" +#ifdef __REACTOS__ #define WM_CLIPBOARDUPDATE 0x031D +#endif static BOOL (WINAPI *pAddClipboardFormatListener)(HWND hwnd); static BOOL (WINAPI *pRemoveClipboardFormatListener)(HWND hwnd); @@ -381,6 +389,9 @@ static void test_RegisterClipboardFormatA(void) ok(len == lstrlenA("my_cool_clipboard_format"), "wrong format name length %d\n", len); ok(!lstrcmpA(buf, "my_cool_clipboard_format"), "wrong format name \"%s\"\n", buf); + len = GetClipboardFormatNameA(format_id, NULL, 0); + ok(len == 0, "wrong format name length %d\n", len); + lstrcpyA(buf, "foo"); SetLastError(0xdeadbeef); len = GetAtomNameA((ATOM)format_id, buf, 256); @@ -888,6 +899,7 @@ static UINT wm_renderformat; static UINT nb_formats; static BOOL cross_thread; static BOOL do_render_format; +static HANDLE update_event; static LRESULT CALLBACK clipboard_wnd_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { @@ -946,6 +958,7 @@ static LRESULT CALLBACK clipboard_wnd_proc(HWND hwnd, UINT msg, WPARAM wp, LPARA ok( msg_flags == ISMEX_NOSEND, "WM_CLIPBOARDUPDATE wrong flags %x\n", msg_flags ); EnterCriticalSection(&clipboard_cs); wm_clipboardupdate++; + SetEvent(update_event); LeaveCriticalSection(&clipboard_cs); break; case WM_USER: @@ -988,13 +1001,44 @@ static void get_clipboard_data_process(void) ok(r, "CloseClipboard failed: %d\n", GetLastError()); } +static UINT old_seq; + +static void check_messages_(int line, HWND win, UINT seq_diff, UINT draw, UINT update, UINT destroy, UINT render) +{ + MSG msg; + UINT count, fmt, seq; + + seq = GetClipboardSequenceNumber(); + ok_(__FILE__, line)(seq - old_seq == seq_diff, "sequence diff %d\n", seq - old_seq); + old_seq = seq; + + if (!cross_thread) + { + while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg ); + } + + if (update && !broken(!pAddClipboardFormatListener)) + ok(WaitForSingleObject(update_event, 1000) == WAIT_OBJECT_0, "wait failed\n"); + + count = SendMessageA( win, WM_USER + 1, 0, 0 ); + ok_(__FILE__, line)(count == draw, "WM_DRAWCLIPBOARD %sreceived\n", draw ? "not " : ""); + count = SendMessageA( win, WM_USER + 2, 0, 0 ); + ok_(__FILE__, line)(count == update || broken(!pAddClipboardFormatListener), + "WM_CLIPBOARDUPDATE %sreceived\n", update ? "not " : ""); + count = SendMessageA( win, WM_USER + 3, 0, 0 ); + ok_(__FILE__, line)(count == destroy, "WM_DESTROYCLIPBOARD %sreceived\n", destroy ? "not " : ""); + fmt = SendMessageA( win, WM_USER + 4, 0, 0 ); + ok_(__FILE__, line)(fmt == render, "WM_RENDERFORMAT received %04x, expected %04x\n", fmt, render); +} +#define check_messages(a,b,c,d,e,f) check_messages_(__LINE__,a,b,c,d,e,f) + static DWORD WINAPI clipboard_thread(void *param) { HWND ret, win = param; BOOL r; MSG msg; HANDLE handle; - UINT count, fmt, formats, old_seq = 0, seq; + UINT count, fmt, formats; cross_thread = (GetWindowThreadProcessId( win, NULL ) != GetCurrentThreadId()); trace( "%s-threaded test\n", cross_thread ? "multi" : "single" ); @@ -1038,21 +1082,7 @@ static DWORD WINAPI clipboard_thread(void *param) ok( r, "RemoveClipboardFormatListener failed err %d\n", GetLastError()); } - seq = GetClipboardSequenceNumber(); - ok( seq == old_seq, "sequence changed\n" ); - if (!cross_thread) - { - ok( wm_drawclipboard == 1, "WM_DRAWCLIPBOARD not received\n" ); - ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" ); - ok( !wm_renderformat, "WM_RENDERFORMAT received\n" ); - while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg ); - } - count = SendMessageA( win, WM_USER + 1, 0, 0 ); - ok( count == 1, "WM_DRAWCLIPBOARD not received\n" ); - count = SendMessageA( win, WM_USER+2, 0, 0 ); - ok( !count, "WM_CLIPBOARDUPDATE received\n" ); - fmt = SendMessageA( win, WM_USER+4, 0, 0 ); - ok( !fmt, "WM_RENDERFORMAT received\n" ); + check_messages(win, 0, 1, 0, 0, 0); SetLastError( 0xdeadbeef ); r = OpenClipboard( (HWND)0xdead ); @@ -1062,125 +1092,32 @@ static DWORD WINAPI clipboard_thread(void *param) r = OpenClipboard(win); ok(r, "OpenClipboard failed: %d\n", GetLastError()); - seq = GetClipboardSequenceNumber(); - ok( seq == old_seq, "sequence changed\n" ); - if (!cross_thread) - { - ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" ); - ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" ); - ok( !wm_renderformat, "WM_RENDERFORMAT received\n" ); - while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg ); - } - count = SendMessageA( win, WM_USER+1, 0, 0 ); - ok( !count, "WM_DRAWCLIPBOARD received\n" ); - count = SendMessageA( win, WM_USER+2, 0, 0 ); - ok( !count, "WM_CLIPBOARDUPDATE received\n" ); - fmt = SendMessageA( win, WM_USER+4, 0, 0 ); - ok( !fmt, "WM_RENDERFORMAT received\n" ); + check_messages(win, 0, 0, 0, 0, 0); r = EmptyClipboard(); ok(r, "EmptyClipboard failed: %d\n", GetLastError()); - seq = GetClipboardSequenceNumber(); - ok( (int)(seq - old_seq) == 1, "sequence diff %d\n", seq - old_seq ); - old_seq = seq; - if (!cross_thread) - { - ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" ); - ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" ); - ok( !wm_renderformat, "WM_RENDERFORMAT received\n" ); - while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg ); - } - count = SendMessageA( win, WM_USER+1, 0, 0 ); - ok( !count, "WM_DRAWCLIPBOARD received\n" ); - count = SendMessageA( win, WM_USER+2, 0, 0 ); - ok( !count, "WM_CLIPBOARDUPDATE received\n" ); - count = SendMessageA( win, WM_USER+3, 0, 0 ); - ok( !count, "WM_DESTROYCLIPBOARD received\n" ); - fmt = SendMessageA( win, WM_USER+4, 0, 0 ); - ok( !fmt, "WM_RENDERFORMAT received\n" ); + check_messages(win, 1, 0, 0, 0, 0); r = EmptyClipboard(); ok(r, "EmptyClipboard failed: %d\n", GetLastError()); /* sequence changes again, even though it was already empty */ - seq = GetClipboardSequenceNumber(); - ok( (int)(seq - old_seq) == 1, "sequence diff %d\n", seq - old_seq ); - old_seq = seq; - if (!cross_thread) - { - ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" ); - ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" ); - ok( !wm_renderformat, "WM_RENDERFORMAT received\n" ); - while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg ); - } - count = SendMessageA( win, WM_USER+1, 0, 0 ); - ok( !count, "WM_DRAWCLIPBOARD received\n" ); - count = SendMessageA( win, WM_USER+2, 0, 0 ); - ok( !count, "WM_CLIPBOARDUPDATE received\n" ); - count = SendMessageA( win, WM_USER+3, 0, 0 ); - ok( count, "WM_DESTROYCLIPBOARD not received\n" ); - fmt = SendMessageA( win, WM_USER+4, 0, 0 ); - ok( !fmt, "WM_RENDERFORMAT received\n" ); + check_messages(win, 1, 0, 0, 1, 0); count = SendMessageA( win, WM_USER+5, 0, 0 ); ok( !count, "wrong format count %u on WM_DESTROYCLIPBOARD\n", count ); handle = SetClipboardData( CF_TEXT, create_textA() ); ok(handle != 0, "SetClipboardData failed: %d\n", GetLastError()); - seq = GetClipboardSequenceNumber(); - ok( (int)(seq - old_seq) == 1, "sequence diff %d\n", seq - old_seq ); - old_seq = seq; - if (!cross_thread) - { - ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" ); - ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" ); - ok( !wm_renderformat, "WM_RENDERFORMAT received\n" ); - while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg ); - } - count = SendMessageA( win, WM_USER+1, 0, 0 ); - ok( !count, "WM_DRAWCLIPBOARD received\n" ); - count = SendMessageA( win, WM_USER+2, 0, 0 ); - ok( !count, "WM_CLIPBOARDUPDATE received\n" ); - fmt = SendMessageA( win, WM_USER+4, 0, 0 ); - ok( !fmt, "WM_RENDERFORMAT received\n" ); + check_messages(win, 1, 0, 0, 0, 0); SetClipboardData( CF_UNICODETEXT, 0 ); - seq = GetClipboardSequenceNumber(); - ok( (int)(seq - old_seq) == 1, "sequence diff %d\n", seq - old_seq ); - old_seq = seq; - if (!cross_thread) - { - ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" ); - ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" ); - ok( !wm_renderformat, "WM_RENDERFORMAT received\n" ); - while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg ); - } - count = SendMessageA( win, WM_USER+1, 0, 0 ); - ok( !count, "WM_DRAWCLIPBOARD received\n" ); - count = SendMessageA( win, WM_USER+2, 0, 0 ); - ok( !count, "WM_CLIPBOARDUPDATE received\n" ); - fmt = SendMessageA( win, WM_USER+4, 0, 0 ); - ok( !fmt, "WM_RENDERFORMAT received\n" ); + check_messages(win, 1, 0, 0, 0, 0); SetClipboardData( CF_UNICODETEXT, 0 ); /* same data again */ - seq = GetClipboardSequenceNumber(); - ok( (int)(seq - old_seq) == 1, "sequence diff %d\n", seq - old_seq ); - old_seq = seq; - if (!cross_thread) - { - ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" ); - ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" ); - ok( !wm_renderformat, "WM_RENDERFORMAT received\n" ); - while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg ); - } - count = SendMessageA( win, WM_USER+1, 0, 0 ); - ok( !count, "WM_DRAWCLIPBOARD received\n" ); - count = SendMessageA( win, WM_USER+2, 0, 0 ); - ok( !count, "WM_CLIPBOARDUPDATE received\n" ); - fmt = SendMessageA( win, WM_USER+4, 0, 0 ); - ok( !fmt, "WM_RENDERFORMAT received\n" ); + check_messages(win, 1, 0, 0, 0, 0); ok( IsClipboardFormatAvailable( CF_TEXT ), "CF_TEXT available\n" ); ok( IsClipboardFormatAvailable( CF_UNICODETEXT ), "CF_UNICODETEXT available\n" ); @@ -1191,40 +1128,12 @@ static DWORD WINAPI clipboard_thread(void *param) ok(r, "CloseClipboard failed: %d\n", GetLastError()); LeaveCriticalSection(&clipboard_cs); - seq = GetClipboardSequenceNumber(); - ok( (int)(seq - old_seq) == 2, "sequence diff %d\n", seq - old_seq ); - old_seq = seq; - if (!cross_thread) - { - ok( wm_drawclipboard == 1, "WM_DRAWCLIPBOARD not received\n" ); - ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" ); - ok( !wm_renderformat, "WM_RENDERFORMAT received\n" ); - while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg ); - } - count = SendMessageA( win, WM_USER+1, 0, 0 ); - ok( count == 1, "WM_DRAWCLIPBOARD not received\n" ); - count = SendMessageA( win, WM_USER+2, 0, 0 ); - ok( count == 1 || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" ); - fmt = SendMessageA( win, WM_USER+4, 0, 0 ); - ok( !fmt, "WM_RENDERFORMAT received %04x\n", fmt ); + check_messages(win, 2, 1, 1, 0, 0); r = OpenClipboard(win); ok(r, "OpenClipboard failed: %d\n", GetLastError()); - seq = GetClipboardSequenceNumber(); - ok( seq == old_seq, "sequence changed\n" ); - if (!cross_thread) - { - ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" ); - ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" ); - ok( !wm_renderformat, "WM_RENDERFORMAT received\n" ); - } - count = SendMessageA( win, WM_USER+1, 0, 0 ); - ok( !count, "WM_DRAWCLIPBOARD received\n" ); - count = SendMessageA( win, WM_USER+2, 0, 0 ); - ok( !count, "WM_CLIPBOARDUPDATE received\n" ); - fmt = SendMessageA( win, WM_USER+4, 0, 0 ); - ok( !fmt, "WM_RENDERFORMAT received\n" ); + check_messages(win, 0, 0, 0, 0, 0); ok( IsClipboardFormatAvailable( CF_TEXT ), "CF_TEXT available\n" ); ok( IsClipboardFormatAvailable( CF_UNICODETEXT ), "CF_UNICODETEXT available\n" ); @@ -1244,65 +1153,19 @@ static DWORD WINAPI clipboard_thread(void *param) do_render_format = FALSE; SetClipboardData( CF_WAVE, 0 ); - seq = GetClipboardSequenceNumber(); - ok( (int)(seq - old_seq) == 1, "sequence diff %d\n", seq - old_seq ); - old_seq = seq; - if (!cross_thread) - { - ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" ); - ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" ); - ok( !wm_renderformat, "WM_RENDERFORMAT received\n" ); - while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg ); - } - count = SendMessageA( win, WM_USER+1, 0, 0 ); - ok( !count, "WM_DRAWCLIPBOARD received\n" ); - count = SendMessageA( win, WM_USER+2, 0, 0 ); - ok( !count, "WM_CLIPBOARDUPDATE received\n" ); - fmt = SendMessageA( win, WM_USER+4, 0, 0 ); - ok( !fmt, "WM_RENDERFORMAT received %04x\n", fmt ); + check_messages(win, 1, 0, 0, 0, 0); r = CloseClipboard(); ok(r, "CloseClipboard failed: %d\n", GetLastError()); /* no synthesized format, so CloseClipboard doesn't change the sequence */ - seq = GetClipboardSequenceNumber(); - ok( seq == old_seq, "sequence changed\n" ); - old_seq = seq; - if (!cross_thread) - { - ok( wm_drawclipboard == 1, "WM_DRAWCLIPBOARD not received\n" ); - ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" ); - ok( !wm_renderformat, "WM_RENDERFORMAT received\n" ); - while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg ); - } - count = SendMessageA( win, WM_USER+1, 0, 0 ); - ok( count == 1, "WM_DRAWCLIPBOARD not received\n" ); - count = SendMessageA( win, WM_USER+2, 0, 0 ); - ok( count == 1 || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" ); - fmt = SendMessageA( win, WM_USER+4, 0, 0 ); - ok( !fmt, "WM_RENDERFORMAT received %04x\n", fmt ); + check_messages(win, 0, 1, 1, 0, 0); r = OpenClipboard(win); ok(r, "OpenClipboard failed: %d\n", GetLastError()); r = CloseClipboard(); ok(r, "CloseClipboard failed: %d\n", GetLastError()); /* nothing changed */ - seq = GetClipboardSequenceNumber(); - ok( seq == old_seq, "sequence changed\n" ); - if (!cross_thread) - { - ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" ); - ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" ); - ok( !wm_renderformat, "WM_RENDERFORMAT received\n" ); - while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg ); - } - count = SendMessageA( win, WM_USER+1, 0, 0 ); - ok( !count, "WM_DRAWCLIPBOARD received\n" ); - count = SendMessageA( win, WM_USER+2, 0, 0 ); - ok( !count, "WM_CLIPBOARDUPDATE received\n" ); - count = SendMessageA( win, WM_USER+3, 0, 0 ); - ok( !count, "WM_DESTROYCLIPBOARD received\n" ); - fmt = SendMessageA( win, WM_USER+4, 0, 0 ); - ok( !fmt, "WM_RENDERFORMAT received %04x\n", fmt ); + check_messages(win, 0, 0, 0, 0, 0); formats = CountClipboardFormats(); r = OpenClipboard(0); @@ -1312,195 +1175,67 @@ static DWORD WINAPI clipboard_thread(void *param) r = CloseClipboard(); ok(r, "CloseClipboard failed: %d\n", GetLastError()); - if (!cross_thread) - { - ok( wm_drawclipboard == 1, "WM_DRAWCLIPBOARD not received\n" ); - ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" ); - ok( !wm_renderformat, "WM_RENDERFORMAT received\n" ); - while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg ); - } - count = SendMessageA( win, WM_USER+1, 0, 0 ); - ok( count == 1, "WM_DRAWCLIPBOARD not received\n" ); - count = SendMessageA( win, WM_USER+2, 0, 0 ); - ok( count == 1 || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" ); - count = SendMessageA( win, WM_USER+3, 0, 0 ); - ok( count == 1, "WM_DESTROYCLIPBOARD not received\n" ); - fmt = SendMessageA( win, WM_USER+4, 0, 0 ); - ok( !fmt, "WM_RENDERFORMAT received %04x\n", fmt ); + check_messages(win, 1, 1, 1, 1, 0); count = SendMessageA( win, WM_USER+5, 0, 0 ); ok( count == formats, "wrong format count %u on WM_DESTROYCLIPBOARD\n", count ); r = OpenClipboard(win); ok(r, "OpenClipboard failed: %d\n", GetLastError()); SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_FIXED, 1 )); - seq = GetClipboardSequenceNumber(); - ok( (int)(seq - old_seq) == 2, "sequence diff %d\n", seq - old_seq ); - old_seq = seq; - if (!cross_thread) - { - ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" ); - ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" ); - ok( !wm_renderformat, "WM_RENDERFORMAT received\n" ); - while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg ); - } - count = SendMessageA( win, WM_USER+1, 0, 0 ); - ok( !count, "WM_DRAWCLIPBOARD received\n" ); - count = SendMessageA( win, WM_USER+2, 0, 0 ); - ok( !count, "WM_CLIPBOARDUPDATE received\n" ); - count = SendMessageA( win, WM_USER+3, 0, 0 ); - ok( !count, "WM_DESTROYCLIPBOARD received\n" ); - fmt = SendMessageA( win, WM_USER+4, 0, 0 ); - ok( !fmt, "WM_RENDERFORMAT received %04x\n", fmt ); + check_messages(win, 1, 0, 0, 0, 0); EnterCriticalSection(&clipboard_cs); r = CloseClipboard(); ok(r, "CloseClipboard failed: %d\n", GetLastError()); LeaveCriticalSection(&clipboard_cs); - seq = GetClipboardSequenceNumber(); - ok( seq == old_seq, "sequence changed\n" ); - old_seq = seq; - if (!cross_thread) - { - ok( wm_drawclipboard == 1, "WM_DRAWCLIPBOARD not received\n" ); - ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" ); - ok( !wm_renderformat, "WM_RENDERFORMAT received\n" ); - while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg ); - } - count = SendMessageA( win, WM_USER+1, 0, 0 ); - ok( count == 1, "WM_DRAWCLIPBOARD not received\n" ); - count = SendMessageA( win, WM_USER+2, 0, 0 ); - ok( count == 1 || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" ); - fmt = SendMessageA( win, WM_USER+4, 0, 0 ); - ok( !fmt, "WM_RENDERFORMAT received\n" ); + check_messages(win, 0, 1, 1, 0, 0); run_process( "grab_clipboard 0" ); - seq = GetClipboardSequenceNumber(); - ok( (int)(seq - old_seq) == 1, "sequence diff %d\n", seq - old_seq ); - old_seq = seq; if (!cross_thread) { - ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" ); - ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" ); - ok( !wm_renderformat, "WM_RENDERFORMAT received\n" ); /* in this case we get a cross-thread WM_DRAWCLIPBOARD */ cross_thread = TRUE; while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg ); cross_thread = FALSE; } - count = SendMessageA( win, WM_USER+1, 0, 0 ); - ok( count == 1, "WM_DRAWCLIPBOARD not received\n" ); - count = SendMessageA( win, WM_USER+2, 0, 0 ); - ok( count == 1 || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" ); - fmt = SendMessageA( win, WM_USER+4, 0, 0 ); - ok( !fmt, "WM_RENDERFORMAT received\n" ); + check_messages(win, 1, 1, 1, 0, 0); r = OpenClipboard(0); ok(r, "OpenClipboard failed: %d\n", GetLastError()); SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_FIXED, 1 )); - seq = GetClipboardSequenceNumber(); - ok( (int)(seq - old_seq) == 1, "sequence diff %d\n", seq - old_seq ); - old_seq = seq; - if (!cross_thread) - { - ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" ); - ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" ); - ok( !wm_renderformat, "WM_RENDERFORMAT received\n" ); - while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg ); - } - count = SendMessageA( win, WM_USER+1, 0, 0 ); - ok( !count, "WM_DRAWCLIPBOARD received\n" ); - count = SendMessageA( win, WM_USER+2, 0, 0 ); - ok( !count, "WM_CLIPBOARDUPDATE received\n" ); - fmt = SendMessageA( win, WM_USER+4, 0, 0 ); - ok( !fmt, "WM_RENDERFORMAT received\n" ); + check_messages(win, 1, 0, 0, 0, 0); EnterCriticalSection(&clipboard_cs); r = CloseClipboard(); ok(r, "CloseClipboard failed: %d\n", GetLastError()); LeaveCriticalSection(&clipboard_cs); - seq = GetClipboardSequenceNumber(); - ok( seq == old_seq, "sequence changed\n" ); - old_seq = seq; - if (!cross_thread) - { - ok( wm_drawclipboard == 1, "WM_DRAWCLIPBOARD received\n" ); - ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" ); - ok( !wm_renderformat, "WM_RENDERFORMAT received\n" ); - while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg ); - } - count = SendMessageA( win, WM_USER+1, 0, 0 ); - ok( count == 1, "WM_DRAWCLIPBOARD not received\n" ); - count = SendMessageA( win, WM_USER+2, 0, 0 ); - ok( count == 1 || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" ); - fmt = SendMessageA( win, WM_USER+4, 0, 0 ); - ok( !fmt, "WM_RENDERFORMAT received\n" ); + check_messages(win, 0, 1, 1, 0, 0); run_process( "grab_clipboard 1" ); - seq = GetClipboardSequenceNumber(); - ok( (int)(seq - old_seq) == 2, "sequence diff %d\n", seq - old_seq ); - old_seq = seq; if (!cross_thread) { - ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" ); - ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" ); - ok( !wm_renderformat, "WM_RENDERFORMAT received\n" ); /* in this case we get a cross-thread WM_DRAWCLIPBOARD */ cross_thread = TRUE; while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg ); cross_thread = FALSE; } - count = SendMessageA( win, WM_USER+1, 0, 0 ); - ok( count == 1, "WM_DRAWCLIPBOARD not received\n" ); - count = SendMessageA( win, WM_USER+2, 0, 0 ); - ok( count == 1 || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" ); - fmt = SendMessageA( win, WM_USER+4, 0, 0 ); - ok( !fmt, "WM_RENDERFORMAT received\n" ); + check_messages(win, 2, 1, 1, 0, 0); r = OpenClipboard(0); ok(r, "OpenClipboard failed: %d\n", GetLastError()); SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_FIXED, 1 )); - seq = GetClipboardSequenceNumber(); - ok( (int)(seq - old_seq) == 1, "sequence diff %d\n", seq - old_seq ); - old_seq = seq; - if (!cross_thread) - { - ok( !wm_drawclipboard, "WM_DRAWCLIPBOARD received\n" ); - ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" ); - ok( !wm_renderformat, "WM_RENDERFORMAT received\n" ); - while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg ); - } - count = SendMessageA( win, WM_USER+1, 0, 0 ); - ok( !count, "WM_DRAWCLIPBOARD received\n" ); - count = SendMessageA( win, WM_USER+2, 0, 0 ); - ok( !count, "WM_CLIPBOARDUPDATE received\n" ); - fmt = SendMessageA( win, WM_USER+4, 0, 0 ); - ok( !fmt, "WM_RENDERFORMAT received\n" ); + check_messages(win, 1, 0, 0, 0, 0); EnterCriticalSection(&clipboard_cs); r = CloseClipboard(); ok(r, "CloseClipboard failed: %d\n", GetLastError()); LeaveCriticalSection(&clipboard_cs); - seq = GetClipboardSequenceNumber(); - ok( seq == old_seq, "sequence changed\n" ); - old_seq = seq; - if (!cross_thread) - { - ok( wm_drawclipboard == 1, "WM_DRAWCLIPBOARD not received\n" ); - ok( !wm_clipboardupdate, "WM_CLIPBOARDUPDATE received\n" ); - ok( !wm_renderformat, "WM_RENDERFORMAT received\n" ); - while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg ); - } - count = SendMessageA( win, WM_USER+1, 0, 0 ); - ok( count == 1, "WM_DRAWCLIPBOARD not received\n" ); - count = SendMessageA( win, WM_USER+2, 0, 0 ); - ok( count == 1 || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" ); - fmt = SendMessageA( win, WM_USER+4, 0, 0 ); - ok( !fmt, "WM_RENDERFORMAT received\n" ); + check_messages(win, 0, 1, 1, 0, 0); if (cross_thread) { @@ -1515,16 +1250,9 @@ static DWORD WINAPI clipboard_thread(void *param) do_render_format = TRUE; old_seq = GetClipboardSequenceNumber(); run_process( "get_clipboard_data" ); - seq = GetClipboardSequenceNumber(); - ok( seq == old_seq, "sequence changed\n" ); do_render_format = FALSE; - count = SendMessageA( win, WM_USER+1, 0, 0 ); - ok( count == 1, "WM_DRAWCLIPBOARD not received\n" ); - count = SendMessageA( win, WM_USER+2, 0, 0 ); - ok( count == 1 || broken(!pAddClipboardFormatListener) /* < Vista */, "WM_CLIPBOARDUPDATE not received\n" ); - fmt = SendMessageA( win, WM_USER+4, 0, 0 ); - ok( fmt == CF_TEXT, "WM_RENDERFORMAT received\n" ); + check_messages(win, 0, 1, 1, 0, CF_TEXT); } r = PostMessageA(win, WM_USER, 0, 0); @@ -1555,6 +1283,7 @@ static void test_messages(void) DWORD tid; InitializeCriticalSection(&clipboard_cs); + update_event = CreateEventW(NULL, FALSE, FALSE, NULL); memset(&cls, 0, sizeof(cls)); cls.lpfnWndProc = clipboard_wnd_proc; @@ -1755,10 +1484,8 @@ static void test_handles( HWND hwnd ) h = SetClipboardData( 0xdeadbeef, hfixed ); ok( h == hfixed, "got %p\n", h ); ok( is_fixed( h ), "expected fixed mem %p\n", h ); -#ifndef _WIN64 - /* testing if hfixed2 is freed triggers an exception on Win64 */ - ok( is_freed( hfixed2 ) || broken( !is_freed( hfixed2 )) /* < Vista */, "expected freed mem %p\n", hfixed2 ); -#endif + if (0) /* this test is unreliable / crashes */ + ok( is_freed( hfixed2 ), "expected freed mem %p\n", hfixed2 ); r = CloseClipboard(); ok( r, "gle %d\n", GetLastError() ); diff --git a/modules/rostests/winetests/user32/combo.c b/modules/rostests/winetests/user32/combo.c index 6f42108bb96..ad706ea7540 100644 --- a/modules/rostests/winetests/user32/combo.c +++ b/modules/rostests/winetests/user32/combo.c @@ -17,10 +17,20 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include +#include +#include + +#define STRICT +#define WIN32_LEAN_AND_MEAN +#include + +#include "wine/test.h" #define COMBO_ID 1995 +#define COMBO_YBORDERSIZE() 2 + static HWND hMainWnd; #define expect_eq(expr, value, type, fmt); { type val = expr; ok(val == (value), #expr " expected " #fmt " got " #fmt "\n", (value), val); } @@ -277,13 +287,6 @@ static void test_WM_LBUTTONDOWN(void) static const UINT choices[] = {8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72}; static const CHAR stringFormat[] = "%2d"; BOOL ret; - BOOL (WINAPI *pGetComboBoxInfo)(HWND, PCOMBOBOXINFO); - - pGetComboBoxInfo = (void*)GetProcAddress(GetModuleHandleA("user32.dll"), "GetComboBoxInfo"); - if (!pGetComboBoxInfo){ - win_skip("GetComboBoxInfo is not available\n"); - return; - } hCombo = CreateWindowA("ComboBox", "Combo", WS_VISIBLE|WS_CHILD|CBS_DROPDOWN, 0, 0, 200, 150, hMainWnd, (HMENU)COMBO_ID, NULL, 0); @@ -297,7 +300,7 @@ static void test_WM_LBUTTONDOWN(void) cbInfo.cbSize = sizeof(COMBOBOXINFO); SetLastError(0xdeadbeef); - ret = pGetComboBoxInfo(hCombo, &cbInfo); + ret = GetComboBoxInfo(hCombo, &cbInfo); ok(ret, "Failed to get combobox info structure. LastError=%d\n", GetLastError()); hEdit = cbInfo.hwndItem; @@ -438,20 +441,13 @@ static void test_editselection(void) COMBOBOXINFO cbInfo; BOOL ret; DWORD len; - BOOL (WINAPI *pGetComboBoxInfo)(HWND, PCOMBOBOXINFO); char edit[20]; - pGetComboBoxInfo = (void*)GetProcAddress(GetModuleHandleA("user32.dll"), "GetComboBoxInfo"); - if (!pGetComboBoxInfo){ - win_skip("GetComboBoxInfo is not available\n"); - return; - } - /* Build a combo */ hCombo = build_combo(CBS_SIMPLE); cbInfo.cbSize = sizeof(COMBOBOXINFO); SetLastError(0xdeadbeef); - ret = pGetComboBoxInfo(hCombo, &cbInfo); + ret = GetComboBoxInfo(hCombo, &cbInfo); ok(ret, "Failed to get combobox info structure. LastError=%d\n", GetLastError()); hEdit = cbInfo.hwndItem; @@ -505,7 +501,7 @@ static void test_editselection(void) hCombo = build_combo(CBS_SIMPLE); cbInfo.cbSize = sizeof(COMBOBOXINFO); SetLastError(0xdeadbeef); - ret = pGetComboBoxInfo(hCombo, &cbInfo); + ret = GetComboBoxInfo(hCombo, &cbInfo); ok(ret, "Failed to get combobox info structure. LastError=%d\n", GetLastError()); hEdit = cbInfo.hwndItem; @@ -574,7 +570,6 @@ static LRESULT CALLBACK test_window_proc(HWND hwnd, UINT msg, WPARAM wParam, LPA static void test_editselection_focus(DWORD style) { - BOOL (WINAPI *pGetComboBoxInfo)(HWND, PCOMBOBOXINFO); HWND hCombo, hEdit, hButton; COMBOBOXINFO cbInfo; BOOL ret; @@ -582,17 +577,10 @@ static void test_editselection_focus(DWORD style) char buffer[16] = {0}; DWORD len; - pGetComboBoxInfo = (void *)GetProcAddress(GetModuleHandleA("user32.dll"), "GetComboBoxInfo"); - if (!pGetComboBoxInfo) - { - win_skip("GetComboBoxInfo is not available\n"); - return; - } - hCombo = build_combo(style); cbInfo.cbSize = sizeof(COMBOBOXINFO); SetLastError(0xdeadbeef); - ret = pGetComboBoxInfo(hCombo, &cbInfo); + ret = GetComboBoxInfo(hCombo, &cbInfo); ok(ret, "Failed to get COMBOBOXINFO structure; LastError: %u\n", GetLastError()); hEdit = cbInfo.hwndItem; @@ -639,18 +627,11 @@ static void test_editselection_focus(DWORD style) static void test_listbox_styles(DWORD cb_style) { - BOOL (WINAPI *pGetComboBoxInfo)(HWND, PCOMBOBOXINFO); HWND combo; COMBOBOXINFO info; DWORD style, exstyle, expect_style, expect_exstyle; BOOL ret; - pGetComboBoxInfo = (void*)GetProcAddress(GetModuleHandleA("user32.dll"), "GetComboBoxInfo"); - if (!pGetComboBoxInfo){ - win_skip("GetComboBoxInfo is not available\n"); - return; - } - expect_style = WS_CHILD|WS_CLIPSIBLINGS|LBS_COMBOBOX|LBS_HASSTRINGS|LBS_NOTIFY; if (cb_style == CBS_SIMPLE) { @@ -666,7 +647,7 @@ static void test_listbox_styles(DWORD cb_style) combo = build_combo(cb_style); info.cbSize = sizeof(COMBOBOXINFO); SetLastError(0xdeadbeef); - ret = pGetComboBoxInfo(combo, &info); + ret = GetComboBoxInfo(combo, &info); ok(ret, "Failed to get combobox info structure.\n"); style = GetWindowLongW( info.hwndList, GWL_STYLE ); @@ -692,11 +673,143 @@ static void test_listbox_styles(DWORD cb_style) DestroyWindow(combo); } +static void test_listbox_size(DWORD style) +{ + HWND hCombo, hList; + COMBOBOXINFO cbInfo; + UINT x, y; + BOOL ret; + int i, test; + const char wine_test[] = "Wine Test"; + + static const struct list_size_info + { + int num_items; + int height_combo; + BOOL todo; + } info_height[] = { + {2, 24, TRUE}, + {2, 41, TRUE}, + {2, 42, TRUE}, + {2, 50, TRUE}, + {2, 60}, + {2, 80}, + {2, 89}, + {2, 90}, + {2, 100}, + + {10, 24, TRUE}, + {10, 41, TRUE}, + {10, 42, TRUE}, + {10, 50, TRUE}, + {10, 60, TRUE}, + {10, 80, TRUE}, + {10, 89, TRUE}, + {10, 90, TRUE}, + {10, 100, TRUE}, + }; + + for(test = 0; test < sizeof(info_height) / sizeof(info_height[0]); test++) + { + const struct list_size_info *info_test = &info_height[test]; + int height_item; /* Height of a list item */ + int height_list; /* Height of the list we got */ + int expected_count_list; + int expected_height_list; + int list_height_nonclient; + int list_height_calculated; + RECT rect_list_client, rect_list_complete; + + hCombo = CreateWindowA("ComboBox", "Combo", WS_VISIBLE|WS_CHILD|style, 5, 5, 100, + info_test->height_combo, hMainWnd, (HMENU)COMBO_ID, NULL, 0); + + cbInfo.cbSize = sizeof(COMBOBOXINFO); + SetLastError(0xdeadbeef); + ret = GetComboBoxInfo(hCombo, &cbInfo); + ok(ret, "Failed to get COMBOBOXINFO structure; LastError: %u\n", GetLastError()); + + hList = cbInfo.hwndList; + for (i = 0; i < info_test->num_items; i++) + SendMessageA(hCombo, CB_ADDSTRING, 0, (LPARAM) wine_test); + + /* Click on the button to drop down the list */ + x = cbInfo.rcButton.left + (cbInfo.rcButton.right-cbInfo.rcButton.left)/2; + y = cbInfo.rcButton.top + (cbInfo.rcButton.bottom-cbInfo.rcButton.top)/2; + ret = SendMessageA(hCombo, WM_LBUTTONDOWN, 0, MAKELPARAM(x, y)); + ok(ret, "WM_LBUTTONDOWN was not processed. LastError=%d\n", + GetLastError()); + ok(SendMessageA(hCombo, CB_GETDROPPEDSTATE, 0, 0), + "The dropdown list should have appeared after clicking the button.\n"); + + GetClientRect(hList, &rect_list_client); + GetWindowRect(hList, &rect_list_complete); + height_list = rect_list_client.bottom - rect_list_client.top; + height_item = (int)SendMessageA(hList, LB_GETITEMHEIGHT, 0, 0); + + list_height_nonclient = (rect_list_complete.bottom - rect_list_complete.top) + - (rect_list_client.bottom - rect_list_client.top); + + /* Calculate the expected client size of the listbox popup from the size of the combobox. */ + list_height_calculated = info_test->height_combo + - (cbInfo.rcItem.bottom + COMBO_YBORDERSIZE()) + - list_height_nonclient + - 1; + + expected_count_list = list_height_calculated / height_item; + if(expected_count_list < 0) + expected_count_list = 0; + expected_count_list = min(expected_count_list, info_test->num_items); + expected_height_list = expected_count_list * height_item; + + todo_wine_if(info_test->todo) + ok(expected_height_list == height_list, + "Test %d, expected list height to be %d, got %d\n", test, expected_height_list, height_list); + + DestroyWindow(hCombo); + } +} + +static void test_WS_VSCROLL(void) +{ + HWND hCombo, hList; + COMBOBOXINFO info; + DWORD style; + BOOL ret; + int i; + + info.cbSize = sizeof(info); + hCombo = build_combo(CBS_DROPDOWNLIST); + + SetLastError(0xdeadbeef); + ret = GetComboBoxInfo(hCombo, &info); + ok(ret, "Failed to get COMBOBOXINFO structure; LastError: %u\n", GetLastError()); + hList = info.hwndList; + + for(i = 0; i < 3; i++) + { + char buffer[2]; + sprintf(buffer, "%d", i); + SendMessageA(hCombo, CB_ADDSTRING, 0, (LPARAM)buffer); + } + + style = GetWindowLongA(info.hwndList, GWL_STYLE); + SetWindowLongA(hList, GWL_STYLE, style | WS_VSCROLL); + + SendMessageA(hCombo, CB_SHOWDROPDOWN, TRUE, 0); + SendMessageA(hCombo, CB_SHOWDROPDOWN, FALSE, 0); + + style = GetWindowLongA(hList, GWL_STYLE); + ok((style & WS_VSCROLL) != 0, "Style does not include WS_VSCROLL\n"); + + DestroyWindow(hCombo); +} + START_TEST(combo) { hMainWnd = CreateWindowA("static", "Test", WS_OVERLAPPEDWINDOW, 10, 10, 300, 300, NULL, NULL, NULL, 0); ShowWindow(hMainWnd, SW_SHOW); + test_WS_VSCROLL(); test_setfont(CBS_DROPDOWN); test_setfont(CBS_DROPDOWNLIST); test_setitemheight(CBS_DROPDOWN); @@ -711,6 +824,7 @@ START_TEST(combo) test_listbox_styles(CBS_SIMPLE); test_listbox_styles(CBS_DROPDOWN); test_listbox_styles(CBS_DROPDOWNLIST); + test_listbox_size(CBS_DROPDOWN); DestroyWindow(hMainWnd); } diff --git a/modules/rostests/winetests/user32/cursoricon.c b/modules/rostests/winetests/user32/cursoricon.c index 11c89c35fe9..5099c08d708 100644 --- a/modules/rostests/winetests/user32/cursoricon.c +++ b/modules/rostests/winetests/user32/cursoricon.c @@ -20,7 +20,16 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include +#include +#include + +#include "wine/test.h" +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "wingdi.h" +#include "winuser.h" #include "pshpack1.h" @@ -1022,6 +1031,12 @@ static const unsigned char gif4pixel[42] = { 0x02,0x00,0x00,0x02,0x03,0x14,0x16,0x05,0x00,0x3b }; +/* An invalid cursor with an invalid dwDIBOffset */ +static const unsigned char invalid_dwDIBOffset[] = { + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 +}; + static const DWORD biSize_tests[] = { 0, sizeof(BITMAPCOREHEADER) - 1, @@ -1061,6 +1076,8 @@ static void test_LoadImageBitmap(const char * test_desc, HBITMAP hbm) ok(ret == bm.bmHeight, "%s: %d lines were converted, not %d\n", test_desc, ret, bm.bmHeight); ok(color_match(pixel, 0x00ffffff), "%s: Pixel is 0x%08x\n", test_desc, pixel); + + ReleaseDC(NULL, hdc); } static void test_LoadImageFile(const char * test_desc, const unsigned char * image_data, @@ -1309,6 +1326,8 @@ static void test_LoadImage(void) test_LoadImageFile("BMP (broken biSize)", bmpimage, sizeof(bmpimage), "bmp", 0); } bitmap_header->biSize = sizeof(BITMAPINFOHEADER); + + test_LoadImageFile("Cursor (invalid dwDIBOffset)", invalid_dwDIBOffset, sizeof(invalid_dwDIBOffset), "cur", 0); } #undef ARRAY_SIZE diff --git a/modules/rostests/winetests/user32/dce.c b/modules/rostests/winetests/user32/dce.c index 92f320cfd0b..18ded3357de 100755 --- a/modules/rostests/winetests/user32/dce.c +++ b/modules/rostests/winetests/user32/dce.c @@ -18,7 +18,16 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" + +#include "wine/test.h" #ifndef DCX_USESTYLE #define DCX_USESTYLE 0x00010000 @@ -31,7 +40,7 @@ static void test_dc_attributes(void) { HDC hdc, old_hdc; HDC hdcs[20]; - INT i, rop, def_rop; + INT i, rop, def_rop, caps; BOOL found_dc; /* test cache DC */ @@ -43,11 +52,14 @@ static void test_dc_attributes(void) rop = GetROP2( hdc ); ok( rop == R2_WHITE, "wrong ROP2 %d\n", rop ); + ok( WindowFromDC( hdc ) == hwnd_cache, "wrong window\n" ); ReleaseDC( hwnd_cache, hdc ); + ok( WindowFromDC( hdc ) == 0, "wrong window\n" ); hdc = GetDC( hwnd_cache ); rop = GetROP2( hdc ); ok( rop == def_rop, "wrong ROP2 %d after release\n", rop ); SetROP2( hdc, R2_WHITE ); + ok( WindowFromDC( hdc ) == hwnd_cache, "wrong window\n" ); ReleaseDC( hwnd_cache, hdc ); old_hdc = hdc; @@ -106,6 +118,28 @@ static void test_dc_attributes(void) ok( rop == 0, "got %d\n", rop ); rop = GetROP2( old_hdc ); ok( rop == 0, "got %d\n", rop ); + caps = GetDeviceCaps( old_hdc, HORZRES ); + ok( caps == 0, "got %d\n", caps ); + caps = GetDeviceCaps( old_hdc, VERTRES ); + ok( caps == 0, "got %d\n", caps ); + caps = GetDeviceCaps( old_hdc, NUMCOLORS ); + ok( caps == 0, "got %d\n", caps ); + ok( WindowFromDC( old_hdc ) == 0, "wrong window\n" ); + + hdc = GetDC(0); + caps = GetDeviceCaps( hdc, HORZRES ); + ok( caps != 0, "got %d\n", caps ); + caps = GetDeviceCaps( hdc, VERTRES ); + ok( caps != 0, "got %d\n", caps ); + caps = GetDeviceCaps( hdc, NUMCOLORS ); + ok( caps != 0, "got %d\n", caps ); + ReleaseDC( 0, hdc ); + caps = GetDeviceCaps( hdc, HORZRES ); + ok( caps == 0, "got %d\n", caps ); + caps = GetDeviceCaps( hdc, VERTRES ); + ok( caps == 0, "got %d\n", caps ); + caps = GetDeviceCaps( hdc, NUMCOLORS ); + ok( caps == 0, "got %d\n", caps ); /* test own DC */ @@ -115,11 +149,14 @@ static void test_dc_attributes(void) ok( rop == R2_WHITE, "wrong ROP2 %d\n", rop ); old_hdc = hdc; + ok( WindowFromDC( hdc ) == hwnd_owndc, "wrong window\n" ); ReleaseDC( hwnd_owndc, hdc ); + ok( WindowFromDC( hdc ) == hwnd_owndc, "wrong window\n" ); hdc = GetDC( hwnd_owndc ); ok( old_hdc == hdc, "didn't get same DC %p/%p\n", old_hdc, hdc ); rop = GetROP2( hdc ); ok( rop == R2_WHITE, "wrong ROP2 %d after release\n", rop ); + ok( WindowFromDC( hdc ) == hwnd_owndc, "wrong window\n" ); ReleaseDC( hwnd_owndc, hdc ); rop = GetROP2( hdc ); ok( rop == R2_WHITE, "wrong ROP2 %d after second release\n", rop ); @@ -132,11 +169,14 @@ static void test_dc_attributes(void) ok( rop == R2_WHITE, "wrong ROP2 %d\n", rop ); old_hdc = hdc; + ok( WindowFromDC( hdc ) == hwnd_classdc, "wrong window\n" ); ReleaseDC( hwnd_classdc, hdc ); + ok( WindowFromDC( hdc ) == hwnd_classdc, "wrong window\n" ); hdc = GetDC( hwnd_classdc ); ok( old_hdc == hdc, "didn't get same DC %p/%p\n", old_hdc, hdc ); rop = GetROP2( hdc ); ok( rop == R2_WHITE, "wrong ROP2 %d after release\n", rop ); + ok( WindowFromDC( hdc ) == hwnd_classdc, "wrong window\n" ); ReleaseDC( hwnd_classdc, hdc ); rop = GetROP2( hdc ); ok( rop == R2_WHITE, "wrong ROP2 %d after second release\n", rop ); @@ -145,12 +185,15 @@ static void test_dc_attributes(void) old_hdc = GetDC( hwnd_classdc ); SetROP2( old_hdc, R2_BLACK ); + ok( WindowFromDC( old_hdc ) == hwnd_classdc, "wrong window\n" ); hdc = GetDC( hwnd_classdc2 ); ok( old_hdc == hdc, "didn't get same DC %p/%p\n", old_hdc, hdc ); rop = GetROP2( hdc ); ok( rop == R2_BLACK, "wrong ROP2 %d for other window\n", rop ); + ok( WindowFromDC( hdc ) == hwnd_classdc2, "wrong window\n" ); ReleaseDC( hwnd_classdc, old_hdc ); ReleaseDC( hwnd_classdc, hdc ); + ok( WindowFromDC( hdc ) == hwnd_classdc2, "wrong window\n" ); rop = GetROP2( hdc ); ok( rop == R2_BLACK, "wrong ROP2 %d after release\n", rop ); } @@ -588,19 +631,83 @@ static void test_dc_layout(void) static void test_destroyed_window(void) { - HDC dc; + HDC dc, old_dc; + HDC hdcs[30]; + int i, rop; - dc = GetDCEx(hwnd_cache, 0, DCX_USESTYLE); - ok(!dc, "Got a non-NULL DC (%p) for a destroyed window.\n", dc); + dc = GetDC( hwnd_cache ); + SetROP2( dc, R2_WHITE ); + rop = GetROP2( dc ); + ok( rop == R2_WHITE, "wrong ROP2 %d\n", rop ); + ok( WindowFromDC( dc ) == hwnd_cache, "wrong window\n" ); + old_dc = dc; - dc = GetDCEx(hwnd_owndc, 0, DCX_USESTYLE); - ok(!dc, "Got a non-NULL DC (%p) for a destroyed window.\n", dc); + DestroyWindow( hwnd_cache ); + rop = GetROP2( dc ); + ok( rop == 0, "wrong ROP2 %d\n", rop ); + ok( WindowFromDC( dc ) == 0, "wrong window\n" ); + ok( !ReleaseDC( hwnd_cache, dc ), "ReleaseDC succeeded\n" ); + dc = GetDC( hwnd_cache ); + ok( !dc, "Got a non-NULL DC (%p) for a destroyed window\n", dc ); - dc = GetDCEx(hwnd_classdc, 0, DCX_USESTYLE); - ok(!dc, "Got a non-NULL DC (%p) for a destroyed window.\n", dc); + for (i = 0; i < 30; i++) + { + dc = hdcs[i] = GetDCEx( hwnd_parent, 0, DCX_CACHE | DCX_USESTYLE ); + if (dc == old_dc) break; + } + ok( i < 30, "DC for destroyed window not reused\n" ); + while (i > 0) ReleaseDC( hwnd_parent, hdcs[--i] ); - dc = GetDCEx(hwnd_classdc2, 0, DCX_USESTYLE); - ok(!dc, "Got a non-NULL DC (%p) for a destroyed window.\n", dc); + dc = GetDC( hwnd_classdc ); + SetROP2( dc, R2_WHITE ); + rop = GetROP2( dc ); + ok( rop == R2_WHITE, "wrong ROP2 %d\n", rop ); + ok( WindowFromDC( dc ) == hwnd_classdc, "wrong window\n" ); + old_dc = dc; + + dc = GetDC( hwnd_classdc2 ); + ok( old_dc == dc, "wrong DC\n" ); + rop = GetROP2( dc ); + ok( rop == R2_WHITE, "wrong ROP2 %d\n", rop ); + ok( WindowFromDC( dc ) == hwnd_classdc2, "wrong window\n" ); + DestroyWindow( hwnd_classdc2 ); + + rop = GetROP2( dc ); + ok( rop == R2_WHITE, "wrong ROP2 %d\n", rop ); + ok( WindowFromDC( dc ) == 0, "wrong window\n" ); + ok( !ReleaseDC( hwnd_classdc2, dc ), "ReleaseDC succeeded\n" ); + dc = GetDC( hwnd_classdc2 ); + ok( !dc, "Got a non-NULL DC (%p) for a destroyed window\n", dc ); + + dc = GetDC( hwnd_classdc ); + ok( dc != 0, "Got NULL DC\n" ); + rop = GetROP2( dc ); + ok( rop == R2_WHITE, "wrong ROP2 %d\n", rop ); + ok( WindowFromDC( dc ) == hwnd_classdc, "wrong window\n" ); + DestroyWindow( hwnd_classdc ); + + rop = GetROP2( dc ); + ok( rop == R2_WHITE, "wrong ROP2 %d\n", rop ); + ok( WindowFromDC( dc ) == 0, "wrong window\n" ); + ok( !ReleaseDC( hwnd_classdc, dc ), "ReleaseDC succeeded\n" ); + dc = GetDC( hwnd_classdc ); + ok( !dc, "Got a non-NULL DC (%p) for a destroyed window\n", dc ); + + dc = GetDC( hwnd_owndc ); + ok( dc != 0, "Got NULL DC\n" ); + rop = GetROP2( dc ); + ok( rop == R2_WHITE, "wrong ROP2 %d\n", rop ); + ok( WindowFromDC( dc ) == hwnd_owndc, "wrong window\n" ); + DestroyWindow( hwnd_owndc ); + + rop = GetROP2( dc ); + ok( rop == 0, "wrong ROP2 %d\n", rop ); + ok( WindowFromDC( dc ) == 0, "wrong window\n" ); + ok( !ReleaseDC( hwnd_owndc, dc ), "ReleaseDC succeeded\n" ); + dc = GetDC( hwnd_owndc ); + ok( !dc, "Got a non-NULL DC (%p) for a destroyed window\n", dc ); + + DestroyWindow( hwnd_parent ); } START_TEST(dce) @@ -652,12 +759,6 @@ START_TEST(dce) test_scroll_window(); test_invisible_create(); test_dc_layout(); - - DestroyWindow(hwnd_parent); - DestroyWindow(hwnd_classdc2); - DestroyWindow(hwnd_classdc); - DestroyWindow(hwnd_owndc); - DestroyWindow(hwnd_cache); - + /* this should be last */ test_destroyed_window(); } diff --git a/modules/rostests/winetests/user32/dde.c b/modules/rostests/winetests/user32/dde.c index ab76117654a..d63a0f65aa2 100755 --- a/modules/rostests/winetests/user32/dde.c +++ b/modules/rostests/winetests/user32/dde.c @@ -19,10 +19,18 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include +#include -#include -#include +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winnls.h" +#include "dde.h" +#include "ddeml.h" +#include "winerror.h" + +#include "wine/test.h" static const WCHAR TEST_DDE_SERVICE[] = {'T','e','s','t','D','D','E','S','e','r','v','i','c','e',0}; diff --git a/modules/rostests/winetests/user32/dialog.c b/modules/rostests/winetests/user32/dialog.c index f18e626d550..679a76204c8 100755 --- a/modules/rostests/winetests/user32/dialog.c +++ b/modules/rostests/winetests/user32/dialog.c @@ -29,7 +29,19 @@ * normally be met. */ -#include "precomp.h" +#ifndef __REACTOS__ +#define WINVER 0x0600 /* For NONCLIENTMETRICS with padding */ +#endif + +#include +#include +#include + +#include "wine/test.h" +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" #define MAXHWNDS 1024 static HWND hwnd [MAXHWNDS]; @@ -1249,8 +1261,441 @@ static INT_PTR CALLBACK TestControlStyleDlgProc(HWND hdlg, UINT msg, return FALSE; } -static void test_DialogBoxParamA(void) +static const WCHAR testtextW[] = {'W','n','d','T','e','x','t',0}; +static const char *testtext = "WndText"; + +enum defdlgproc_text { + DLGPROCTEXT_SNDMSGA = 0, + DLGPROCTEXT_SNDMSGW, + DLGPROCTEXT_DLGPROCA, + DLGPROCTEXT_DLGPROCW, + DLGPROCTEXT_SETTEXTA, + DLGPROCTEXT_SETTEXTW, +}; + +static const char *testmodes[] = +{ + "SNDMSGA", + "SNDMSGW", + "DLGPROCA", + "DLGPROCW", + "SETTEXTA", + "SETTEXTW", +}; + +static INT_PTR CALLBACK test_aw_conversion_dlgprocA(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam) +{ + int mode = HandleToULong(GetPropA(hdlg, "test_mode")); + WCHAR *text = (WCHAR *)lparam; + char *textA = (char *)lparam; + + switch (msg) + { + case WM_SETTEXT: + case WM_WININICHANGE: + case WM_DEVMODECHANGE: + case CB_DIR: + case LB_DIR: + case LB_ADDFILE: + case EM_REPLACESEL: + switch (mode) + { + case DLGPROCTEXT_DLGPROCA: + ok(textA == testtext, "%s: %s, unexpected text %s.\n", IsWindowUnicode(hdlg) ? "U" : "A", + testmodes[mode], textA); + break; + case DLGPROCTEXT_DLGPROCW: + ok(text == testtextW, "%s: %s, unexpected text %s.\n", IsWindowUnicode(hdlg) ? "U" : "A", testmodes[mode], + wine_dbgstr_w(text)); + break; + case DLGPROCTEXT_SNDMSGA: + case DLGPROCTEXT_SETTEXTA: + if (IsWindowUnicode(hdlg)) + { + ok(text != testtextW && !lstrcmpW(text, testtextW), + "U: %s, unexpected text %s.\n", testmodes[mode], wine_dbgstr_w(text)); + } + else + ok(textA == testtext, "A: %s, unexpected text %s.\n", testmodes[mode], textA); + break; + case DLGPROCTEXT_SNDMSGW: + case DLGPROCTEXT_SETTEXTW: + if (IsWindowUnicode(hdlg)) + ok(text == testtextW, "U: %s, unexpected text %s.\n", testmodes[mode], wine_dbgstr_w(text)); + else + ok(textA != testtext && !strcmp(textA, testtext), "A: %s, unexpected text %s.\n", + testmodes[mode], textA); + break; + } + break; + }; + + return DefWindowProcW(hdlg, msg, wparam, lparam); +} + +static INT_PTR CALLBACK test_aw_conversion_dlgprocW(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam) +{ + int mode = HandleToULong(GetPropA(hdlg, "test_mode")); + WCHAR *text = (WCHAR *)lparam; + char *textA = (char *)lparam; + + switch (msg) + { + case WM_SETTEXT: + case WM_WININICHANGE: + case WM_DEVMODECHANGE: + case CB_DIR: + case LB_DIR: + case LB_ADDFILE: + case EM_REPLACESEL: + switch (mode) + { + case DLGPROCTEXT_DLGPROCA: + ok(textA == testtext, "%s: %s, unexpected text %s.\n", IsWindowUnicode(hdlg) ? "U" : "A", + testmodes[mode], textA); + break; + case DLGPROCTEXT_DLGPROCW: + ok(text == testtextW, "%s: %s, unexpected text %s.\n", IsWindowUnicode(hdlg) ? "U" : "A", testmodes[mode], + wine_dbgstr_w(text)); + break; + case DLGPROCTEXT_SNDMSGA: + case DLGPROCTEXT_SETTEXTA: + if (IsWindowUnicode(hdlg)) + ok(text != testtextW && !lstrcmpW(text, testtextW), + "U: %s, unexpected text %s.\n", testmodes[mode], wine_dbgstr_w(text)); + else + ok(textA == testtext, "A: %s, unexpected text %s.\n", testmodes[mode], textA); + break; + case DLGPROCTEXT_SNDMSGW: + case DLGPROCTEXT_SETTEXTW: + if (IsWindowUnicode(hdlg)) + ok(text == testtextW, "U: %s, unexpected text %s.\n", testmodes[mode], wine_dbgstr_w(text)); + else + ok(textA != testtext && !strcmp(textA, testtext), "A: %s, unexpected text %s.\n", + testmodes[mode], textA); + break; + } + break; + } + + return DefWindowProcA(hdlg, msg, wparam, lparam); +} + +static void dlg_test_aw_message(HWND hdlg, UINT msg) +{ + SetPropA(hdlg, "test_mode", ULongToHandle(DLGPROCTEXT_SNDMSGA)); + SendMessageA(hdlg, msg, 0, (LPARAM)testtext); + + SetPropA(hdlg, "test_mode", ULongToHandle(DLGPROCTEXT_SNDMSGW)); + SendMessageW(hdlg, msg, 0, (LPARAM)testtextW); + + SetPropA(hdlg, "test_mode", ULongToHandle(DLGPROCTEXT_DLGPROCA)); + DefDlgProcA(hdlg, msg, 0, (LPARAM)testtext); + + SetPropA(hdlg, "test_mode", ULongToHandle(DLGPROCTEXT_DLGPROCW)); + DefDlgProcW(hdlg, msg, 0, (LPARAM)testtextW); +} + +static INT_PTR CALLBACK test_aw_conversion_dlgproc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam) +{ + ULONG_PTR dlgproc, originalproc; + WCHAR buffW[64]; + char buff[64]; + BOOL ret; + INT len; + + switch (msg) + { + case WM_INITDIALOG: + ok(IsWindowUnicode(hdlg), "Expected unicode window.\n"); + + dlg_test_aw_message(hdlg, WM_WININICHANGE); + dlg_test_aw_message(hdlg, WM_DEVMODECHANGE); + dlg_test_aw_message(hdlg, CB_DIR); + dlg_test_aw_message(hdlg, LB_DIR); + dlg_test_aw_message(hdlg, LB_ADDFILE); + dlg_test_aw_message(hdlg, EM_REPLACESEL); + dlg_test_aw_message(hdlg, WM_SETTEXT); + + /* WM_SETTEXT/WM_GETTEXT */ + originalproc = GetWindowLongPtrW(hdlg, DWLP_DLGPROC); + ok(originalproc == (ULONG_PTR)test_aw_conversion_dlgproc, "Unexpected dlg proc %#lx.\n", originalproc); + + dlgproc = GetWindowLongPtrA(hdlg, DWLP_DLGPROC); + ok(dlgproc != (ULONG_PTR)test_aw_conversion_dlgproc, "Unexpected dlg proc %#lx.\n", dlgproc); + + dlgproc = SetWindowLongPtrA(hdlg, DWLP_DLGPROC, (UINT_PTR)test_aw_conversion_dlgprocA); + ok(IsWindowUnicode(hdlg), "Expected unicode window.\n"); + + dlgproc = GetWindowLongPtrW(hdlg, DWLP_DLGPROC); + ok(dlgproc != (ULONG_PTR)test_aw_conversion_dlgprocA, "Unexpected dlg proc %#lx.\n", dlgproc); + + dlgproc = GetWindowLongPtrA(hdlg, DWLP_DLGPROC); + ok(dlgproc == (ULONG_PTR)test_aw_conversion_dlgprocA, "Unexpected dlg proc %#lx.\n", dlgproc); + + SetPropA(hdlg, "test_mode", ULongToHandle(DLGPROCTEXT_SETTEXTA)); + ret = SetWindowTextA(hdlg, testtext); + todo_wine + ok(ret, "Failed to set window text.\n"); + + SetPropA(hdlg, "test_mode", ULongToHandle(DLGPROCTEXT_SETTEXTW)); + ret = SetWindowTextW(hdlg, testtextW); + todo_wine + ok(ret, "Failed to set window text.\n"); + + memset(buff, 'A', sizeof(buff)); + len = GetWindowTextA(hdlg, buff, sizeof(buff)); + ok(buff[0] == 0 && buff[1] == 'A' && len == 0, "Unexpected window text %#x, %#x, len %d\n", + (BYTE)buff[0], (BYTE)buff[1], len); + + memset(buffW, 0xff, sizeof(buffW)); + len = GetWindowTextW(hdlg, buffW, 64); + ok(!lstrcmpW(buffW, testtextW) && len == 0, "Unexpected window text %s, len %d\n", wine_dbgstr_w(buffW), len); + + dlg_test_aw_message(hdlg, WM_WININICHANGE); + dlg_test_aw_message(hdlg, WM_DEVMODECHANGE); + dlg_test_aw_message(hdlg, CB_DIR); + dlg_test_aw_message(hdlg, LB_DIR); + dlg_test_aw_message(hdlg, LB_ADDFILE); + dlg_test_aw_message(hdlg, EM_REPLACESEL); + dlg_test_aw_message(hdlg, WM_SETTEXT); + + dlgproc = SetWindowLongPtrW(hdlg, DWLP_DLGPROC, (UINT_PTR)test_aw_conversion_dlgprocW); + ok(IsWindowUnicode(hdlg), "Expected unicode window.\n"); + + dlgproc = GetWindowLongPtrW(hdlg, DWLP_DLGPROC); + ok(dlgproc == (ULONG_PTR)test_aw_conversion_dlgprocW, "Unexpected dlg proc %#lx.\n", dlgproc); + + dlgproc = GetWindowLongPtrA(hdlg, DWLP_DLGPROC); + ok(dlgproc != (ULONG_PTR)test_aw_conversion_dlgprocW, "Unexpected dlg proc %#lx.\n", dlgproc); + + SetPropA(hdlg, "test_mode", ULongToHandle(DLGPROCTEXT_SETTEXTA)); + ret = SetWindowTextA(hdlg, testtext); + todo_wine + ok(ret, "Failed to set window text.\n"); + + SetPropA(hdlg, "test_mode", ULongToHandle(DLGPROCTEXT_SETTEXTW)); + ret = SetWindowTextW(hdlg, testtextW); + todo_wine + ok(ret, "Failed to set window text.\n"); + + memset(buff, 'A', sizeof(buff)); + len = GetWindowTextA(hdlg, buff, sizeof(buff)); + ok(buff[0] == 0 && buff[1] == 'A' && len == 0, "Unexpected window text %#x, %#x, len %d\n", + (BYTE)buff[0], (BYTE)buff[1], len); + + memset(buffW, 0xff, sizeof(buffW)); + len = GetWindowTextW(hdlg, buffW, sizeof(buffW)/sizeof(buffW[0])); + ok(buffW[0] == 'W' && buffW[1] == 0xffff && len == 0, "Unexpected window text %#x, %#x, len %d\n", + buffW[0], buffW[1], len); + + dlg_test_aw_message(hdlg, WM_WININICHANGE); + dlg_test_aw_message(hdlg, WM_DEVMODECHANGE); + dlg_test_aw_message(hdlg, CB_DIR); + dlg_test_aw_message(hdlg, LB_DIR); + dlg_test_aw_message(hdlg, LB_ADDFILE); + dlg_test_aw_message(hdlg, EM_REPLACESEL); + dlg_test_aw_message(hdlg, WM_SETTEXT); + + SetWindowLongPtrA(hdlg, DWLP_DLGPROC, originalproc); + EndDialog(hdlg, -123); + return TRUE; + } + return FALSE; +} + +static INT_PTR CALLBACK test_aw_conversion_dlgproc2(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam) +{ + ULONG_PTR dlgproc, originalproc; + WCHAR buffW[64]; + char buff[64]; + BOOL ret; + INT len; + + switch (msg) + { + case WM_INITDIALOG: + ok(!IsWindowUnicode(hdlg), "Unexpected unicode window.\n"); + + dlg_test_aw_message(hdlg, WM_WININICHANGE); + dlg_test_aw_message(hdlg, WM_DEVMODECHANGE); + dlg_test_aw_message(hdlg, CB_DIR); + dlg_test_aw_message(hdlg, LB_DIR); + dlg_test_aw_message(hdlg, LB_ADDFILE); + dlg_test_aw_message(hdlg, EM_REPLACESEL); + dlg_test_aw_message(hdlg, WM_SETTEXT); + + originalproc = GetWindowLongPtrW(hdlg, DWLP_DLGPROC); + ok(originalproc != (ULONG_PTR)test_aw_conversion_dlgproc2, "Unexpected dlg proc %#lx.\n", originalproc); + + dlgproc = GetWindowLongPtrA(hdlg, DWLP_DLGPROC); + ok(dlgproc == (ULONG_PTR)test_aw_conversion_dlgproc2, "Unexpected dlg proc %#lx.\n", dlgproc); + + dlgproc = SetWindowLongPtrA(hdlg, DWLP_DLGPROC, (UINT_PTR)test_aw_conversion_dlgprocW); + ok(!IsWindowUnicode(hdlg), "Unexpected unicode window.\n"); + + dlgproc = GetWindowLongPtrW(hdlg, DWLP_DLGPROC); + ok(dlgproc != (ULONG_PTR)test_aw_conversion_dlgprocW, "Unexpected dlg proc %#lx.\n", dlgproc); + + dlgproc = GetWindowLongPtrA(hdlg, DWLP_DLGPROC); + ok(dlgproc == (ULONG_PTR)test_aw_conversion_dlgprocW, "Unexpected dlg proc %#lx.\n", dlgproc); + + SetPropA(hdlg, "test_mode", ULongToHandle(DLGPROCTEXT_SETTEXTA)); + ret = SetWindowTextA(hdlg, testtext); + todo_wine + ok(ret, "Failed to set window text.\n"); + + SetPropA(hdlg, "test_mode", ULongToHandle(DLGPROCTEXT_SETTEXTW)); + ret = SetWindowTextW(hdlg, testtextW); + todo_wine + ok(ret, "Failed to set window text.\n"); + + memset(buff, 'A', sizeof(buff)); + len = GetWindowTextA(hdlg, buff, sizeof(buff)); + ok(!strcmp(buff, testtext) && len == 0, "Unexpected window text %s, len %d\n", buff, len); + + memset(buffW, 0xff, sizeof(buffW)); + len = GetWindowTextW(hdlg, buffW, 64); + ok(buffW[0] == 0 && buffW[1] == 0xffff && len == 0, "Unexpected window text %s, len %d\n", + wine_dbgstr_w(buffW), len); + + dlg_test_aw_message(hdlg, WM_WININICHANGE); + dlg_test_aw_message(hdlg, WM_DEVMODECHANGE); + dlg_test_aw_message(hdlg, CB_DIR); + dlg_test_aw_message(hdlg, LB_DIR); + dlg_test_aw_message(hdlg, LB_ADDFILE); + dlg_test_aw_message(hdlg, EM_REPLACESEL); + dlg_test_aw_message(hdlg, WM_SETTEXT); + + dlgproc = SetWindowLongPtrW(hdlg, DWLP_DLGPROC, (UINT_PTR)test_aw_conversion_dlgprocA); + ok(!IsWindowUnicode(hdlg), "Unexpected unicode window.\n"); + + dlgproc = GetWindowLongPtrW(hdlg, DWLP_DLGPROC); + ok(dlgproc == (ULONG_PTR)test_aw_conversion_dlgprocA, "Unexpected dlg proc %#lx.\n", dlgproc); + + dlgproc = GetWindowLongPtrA(hdlg, DWLP_DLGPROC); + ok(dlgproc != (ULONG_PTR)test_aw_conversion_dlgprocA, "Unexpected dlg proc %#lx.\n", dlgproc); + + SetPropA(hdlg, "test_mode", ULongToHandle(DLGPROCTEXT_SETTEXTA)); + ret = SetWindowTextA(hdlg, testtext); + todo_wine + ok(ret, "Failed to set window text.\n"); + + SetPropA(hdlg, "test_mode", ULongToHandle(DLGPROCTEXT_SETTEXTW)); + ret = SetWindowTextW(hdlg, testtextW); + todo_wine + ok(ret, "Failed to set window text.\n"); + + memset(buff, 'A', sizeof(buff)); + len = GetWindowTextA(hdlg, buff, sizeof(buff)); + ok(!strcmp(buff, testtext) && len == 0, "Unexpected window text %s, len %d\n", buff, len); + + memset(buffW, 0xff, sizeof(buffW)); + len = GetWindowTextW(hdlg, buffW, sizeof(buffW)/sizeof(buffW[0])); + ok(buffW[0] == 0 && buffW[1] == 0xffff && len == 0, "Unexpected window text %#x, %#x, len %d\n", + buffW[0], buffW[1], len); + + dlg_test_aw_message(hdlg, WM_WININICHANGE); + dlg_test_aw_message(hdlg, WM_DEVMODECHANGE); + dlg_test_aw_message(hdlg, CB_DIR); + dlg_test_aw_message(hdlg, LB_DIR); + dlg_test_aw_message(hdlg, LB_ADDFILE); + dlg_test_aw_message(hdlg, EM_REPLACESEL); + dlg_test_aw_message(hdlg, WM_SETTEXT); + + SetWindowLongPtrA(hdlg, DWLP_DLGPROC, originalproc); + EndDialog(hdlg, -123); + return TRUE; + } + return FALSE; +} + +static LRESULT CALLBACK test_aw_conversion_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) +{ + WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); + int mode = HandleToULong(GetPropA(hwnd, "test_mode")); + WCHAR *text = (WCHAR *)lparam; + char *textA = (char *)lparam; + + switch (msg) + { + case WM_SETTEXT: + case WM_WININICHANGE: + case WM_DEVMODECHANGE: + case CB_DIR: + case LB_DIR: + case LB_ADDFILE: + case EM_REPLACESEL: + switch (mode) + { + case DLGPROCTEXT_SNDMSGA: + if (IsWindowUnicode(hwnd)) + ok(text != testtextW && !lstrcmpW(text, testtextW), + "U: %s, unexpected text %s.\n", testmodes[mode], wine_dbgstr_w(text)); + else + ok(textA == testtext, "A: %s, unexpected text %s.\n", testmodes[mode], textA); + break; + case DLGPROCTEXT_SNDMSGW: + if (IsWindowUnicode(hwnd)) + ok(text == testtextW, "U: %s, unexpected text %s.\n", testmodes[mode], wine_dbgstr_w(text)); + else + ok(textA != testtext && !strcmp(textA, testtext), "A: %s, unexpected text %s.\n", + testmodes[mode], textA); + break; + default: + ok(0, "Unexpected test mode %d.\n", mode); + } + break; + } + + return IsWindowUnicode(hwnd) ? CallWindowProcW(oldproc, hwnd, msg, wparam, lparam) : + CallWindowProcA(oldproc, hwnd, msg, wparam, lparam); +} + +static INT_PTR CALLBACK test_aw_conversion_dlgproc3(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam) +{ + BOOL is_unicode = !!lparam; + LONG_PTR oldproc; + + switch (msg) + { + case WM_INITDIALOG: + ok(is_unicode == IsWindowUnicode(hdlg), "Unexpected unicode window property.\n"); + + oldproc = SetWindowLongPtrA(hdlg, GWLP_WNDPROC, (LONG_PTR)test_aw_conversion_wndproc); + SetWindowLongPtrA(hdlg, GWLP_USERDATA, oldproc); + ok(!IsWindowUnicode(hdlg), "Unexpected unicode window.\n"); + + dlg_test_aw_message(hdlg, WM_WININICHANGE); + dlg_test_aw_message(hdlg, WM_DEVMODECHANGE); + dlg_test_aw_message(hdlg, CB_DIR); + dlg_test_aw_message(hdlg, LB_DIR); + dlg_test_aw_message(hdlg, LB_ADDFILE); + dlg_test_aw_message(hdlg, EM_REPLACESEL); + dlg_test_aw_message(hdlg, WM_SETTEXT); + + SetWindowLongPtrW(hdlg, GWLP_WNDPROC, (LONG_PTR)test_aw_conversion_wndproc); + ok(IsWindowUnicode(hdlg), "Expected unicode window.\n"); + + dlg_test_aw_message(hdlg, WM_WININICHANGE); + dlg_test_aw_message(hdlg, WM_DEVMODECHANGE); + dlg_test_aw_message(hdlg, CB_DIR); + dlg_test_aw_message(hdlg, LB_DIR); + dlg_test_aw_message(hdlg, LB_ADDFILE); + dlg_test_aw_message(hdlg, EM_REPLACESEL); + dlg_test_aw_message(hdlg, WM_SETTEXT); + + SetWindowLongPtrA(hdlg, GWLP_WNDPROC, oldproc); + EndDialog(hdlg, -123); + return TRUE; + } + return FALSE; +} + +static void test_DialogBoxParam(void) +{ + static const WCHAR nameW[] = {'T','E','S','T','_','E','M','P','T','Y','_','D','I','A','L','O','G',0}; INT_PTR ret; HWND hwnd_invalid = (HWND)0x4444; @@ -1302,7 +1747,21 @@ static void test_DialogBoxParamA(void) ret = DialogBoxParamA(GetModuleHandleA(NULL), "TEST_EMPTY_DIALOG", 0, TestDefButtonDlgProc, 0); ok(ret == IDOK, "Expected IDOK\n"); - DialogBoxParamA(GetModuleHandleA(NULL), "TEST_EMPTY_DIALOG", 0, TestReturnKeyDlgProc, 0); + ret = DialogBoxParamA(GetModuleHandleA(NULL), "TEST_EMPTY_DIALOG", 0, TestReturnKeyDlgProc, 0); + ok(ret == 0, "Unexpected ret value %ld.\n", ret); + + /* WM_SETTEXT handling in case of A/W dialog procedures vs A/W dialog window. */ + ret = DialogBoxParamW(GetModuleHandleA(NULL), nameW, 0, test_aw_conversion_dlgproc, 0); + ok(ret == -123, "Unexpected ret value %ld.\n", ret); + + ret = DialogBoxParamA(GetModuleHandleA(NULL), "TEST_EMPTY_DIALOG", 0, test_aw_conversion_dlgproc2, 0); + ok(ret == -123, "Unexpected ret value %ld.\n", ret); + + ret = DialogBoxParamW(GetModuleHandleA(NULL), nameW, 0, test_aw_conversion_dlgproc3, 1); + ok(ret == -123, "Unexpected ret value %ld.\n", ret); + + ret = DialogBoxParamA(GetModuleHandleA(NULL), "TEST_EMPTY_DIALOG", 0, test_aw_conversion_dlgproc3, 0); + ok(ret == -123, "Unexpected ret value %ld.\n", ret); } static void test_DisabledDialogTest(void) @@ -1713,7 +2172,7 @@ START_TEST(dialog) test_focus(); test_GetDlgItem(); test_GetDlgItemText(); - test_DialogBoxParamA(); + test_DialogBoxParam(); test_DisabledDialogTest(); test_MessageBoxFontTest(); test_SaveRestoreFocus(); diff --git a/modules/rostests/winetests/user32/edit.c b/modules/rostests/winetests/user32/edit.c index 012051cc673..01418bf551a 100755 --- a/modules/rostests/winetests/user32/edit.c +++ b/modules/rostests/winetests/user32/edit.c @@ -18,7 +18,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include +#include +#include + +#include "wine/test.h" #ifndef ES_COMBO #define ES_COMBO 0x200 @@ -34,17 +38,6 @@ struct edit_notify { static struct edit_notify notifications; -static BOOL (WINAPI *pEndMenu) (void); -static BOOL (WINAPI *pGetMenuBarInfo)(HWND,LONG,LONG,PMENUBARINFO); - -static void init_function_pointers(void) -{ - HMODULE hdll = GetModuleHandleA("user32"); - - pEndMenu = (void*)GetProcAddress(hdll, "EndMenu"); - pGetMenuBarInfo = (void*)GetProcAddress(hdll, "GetMenuBarInfo"); -} - static INT_PTR CALLBACK multi_edit_dialog_proc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam) { static int num_ok_commands = 0; @@ -564,6 +557,18 @@ static HWND create_editcontrol (DWORD style, DWORD exstyle) return handle; } +static HWND create_editcontrolW(DWORD style, DWORD exstyle) +{ + static const WCHAR testtextW[] = {'T','e','s','t',' ','t','e','x','t',0}; + static const WCHAR editW[] = {'E','d','i','t',0}; + HWND handle; + + handle = CreateWindowExW(exstyle, editW, testtextW, style, 10, 10, 300, 300, + NULL, NULL, hinst, NULL); + ok(handle != NULL, "Failed to create Edit control.\n"); + return handle; +} + static HWND create_child_editcontrol (DWORD style, DWORD exstyle) { HWND parentWnd; @@ -863,7 +868,7 @@ static LRESULT CALLBACK edit3_wnd_procA(HWND hWnd, UINT msg, WPARAM wParam, LPAR return DefWindowProcA(hWnd, msg, wParam, lParam); } -/* Test behaviour of WM_SETTEXT, WM_REPLACESEL and notificatisons sent in response +/* Test behaviour of WM_SETTEXT, WM_REPLACESEL and notifications sent in response * to these messages. */ static void test_edit_control_3(void) @@ -965,6 +970,19 @@ static void test_edit_control_3(void) ok(lstrlenA(str) == len, "text shouldn't have been truncated\n"); test_notify(1, 0, 1); + SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)""); + zero_notify(); + SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2); + len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0); + ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n"); + test_notify(1, 0, 1); + + zero_notify(); + SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2); + len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0); + ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n"); + test_notify(1, 0, 1); + SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0); SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)""); @@ -2277,7 +2295,7 @@ static LRESULT CALLBACK edit4_wnd_procA(HWND hWnd, UINT msg, WPARAM wParam, LPAR if (hWnd != (HWND)lParam) { got_wm_capturechanged = TRUE; - pEndMenu(); + EndMenu(); } break; } @@ -2295,9 +2313,8 @@ static LRESULT CALLBACK edit_proc_proxy(HWND hWnd, UINT msg, WPARAM wParam, LPAR memset(&mbi, 0, sizeof(mbi)); mbi.cbSize = sizeof(mbi); SetLastError(0xdeadbeef); - ret = pGetMenuBarInfo(ctx_menu, OBJID_CLIENT, 0, &mbi); - ok(ret || broken(!ret && GetLastError()==ERROR_INVALID_WINDOW_HANDLE) /* NT */, - "GetMenuBarInfo failed\n"); + ret = GetMenuBarInfo(ctx_menu, OBJID_CLIENT, 0, &mbi); + ok(ret, "GetMenuBarInfo failed\n"); if (ret) { ok(mbi.hMenu != NULL, "mbi.hMenu = NULL\n"); @@ -2309,9 +2326,8 @@ static LRESULT CALLBACK edit_proc_proxy(HWND hWnd, UINT msg, WPARAM wParam, LPAR memset(&mbi, 0, sizeof(mbi)); mbi.cbSize = sizeof(mbi); SetLastError(0xdeadbeef); - ret = pGetMenuBarInfo(ctx_menu, OBJID_CLIENT, 1, &mbi); - ok(ret || broken(!ret && GetLastError()==ERROR_INVALID_WINDOW_HANDLE) /* NT */, - "GetMenuBarInfo failed\n"); + ret = GetMenuBarInfo(ctx_menu, OBJID_CLIENT, 1, &mbi); + ok(ret, "GetMenuBarInfo failed\n"); if (ret) { ok(mbi.hMenu != NULL, "mbi.hMenu = NULL\n"); @@ -2320,7 +2336,7 @@ static LRESULT CALLBACK edit_proc_proxy(HWND hWnd, UINT msg, WPARAM wParam, LPAR ok(!mbi.fFocused, "mbi.fFocused = TRUE\n"); } - pEndMenu(); + EndMenu(); break; } } @@ -2341,7 +2357,7 @@ static LRESULT CALLBACK child_edit_menu_proc(HWND hwnd, UINT msg, WPARAM wParam, if (wParam == MSGF_MENU) { HWND hwndMenu = (HWND)lParam; MENUBARINFO mbi = { sizeof(MENUBARINFO) }; - if (pGetMenuBarInfo(hwndMenu, OBJID_CLIENT, 0, &mbi)) { + if (GetMenuBarInfo(hwndMenu, OBJID_CLIENT, 0, &mbi)) { MENUITEMINFOA mii = { sizeof(MENUITEMINFOA), MIIM_STATE }; if (GetMenuItemInfoA(mbi.hMenu, EM_SETSEL, FALSE, &mii)) { if (mii.fState & MFS_HILITE) { @@ -2387,11 +2403,8 @@ static void test_contextmenu(void) ok(got_en_setfocus, "edit box didn't get focused\n"); ok(got_wm_capturechanged, "main window capture did not change\n"); - if (pGetMenuBarInfo) - { - p_edit_proc = (void*)SetWindowLongPtrA(hwndEdit, GWLP_WNDPROC, (ULONG_PTR)edit_proc_proxy); - SendMessageA(hwndEdit, WM_CONTEXTMENU, (WPARAM)hwndEdit, MAKEWORD(10, 10)); - } + p_edit_proc = (void*)SetWindowLongPtrA(hwndEdit, GWLP_WNDPROC, (ULONG_PTR)edit_proc_proxy); + SendMessageA(hwndEdit, WM_CONTEXTMENU, (WPARAM)hwndEdit, MAKEWORD(10, 10)); DestroyWindow (hwndEdit); @@ -2718,6 +2731,7 @@ static void test_EM_GETHANDLE(void) { static const char str0[] = "untouched"; static const char str1[] = "1111+1111+1111#"; + static const char str1_1[] = "2111+1111+1111#"; static const char str2[] = "2222-2222-2222-2222#"; static const char str3[] = "3333*3333*3333*3333*3333#"; CHAR current[42]; @@ -2766,6 +2780,44 @@ static void test_EM_GETHANDLE(void) "got %d and \"%s\" (expected %d and \"%s\")\n", len, buffer, lstrlenA(str1), str1); LocalUnlock(hmem); + /* See if WM_GETTEXTLENGTH/WM_GETTEXT still work. */ + len = SendMessageA(hEdit, WM_GETTEXTLENGTH, 0, 0); + ok(len == lstrlenA(str1), "Unexpected text length %d.\n", len); + + lstrcpyA(current, str0); + r = SendMessageA(hEdit, WM_GETTEXT, sizeof(current), (LPARAM)current); + ok((r == lstrlenA(str1)) && !lstrcmpA(current, str1), + "Unexpected retval %d and text \"%s\" (expected %d and \"%s\")\n", r, current, lstrlenA(str1), str1); + + /* Application altered buffer contents, see if WM_GETTEXTLENGTH/WM_GETTEXT pick that up. */ + buffer = LocalLock(hmem); + ok(buffer != NULL, "got %p (expected != NULL)\n", buffer); + buffer[0] = '2'; + LocalUnlock(hmem); + + len = SendMessageA(hEdit, WM_GETTEXTLENGTH, 0, 0); + ok(len == lstrlenA(str1_1), "Unexpected text length %d.\n", len); + + lstrcpyA(current, str0); + r = SendMessageA(hEdit, WM_GETTEXT, sizeof(current), (LPARAM)current); + ok((r == lstrlenA(str1_1)) && !lstrcmpA(current, str1_1), + "Unexpected retval %d and text \"%s\" (expected %d and \"%s\")\n", r, current, lstrlenA(str1_1), str1_1); + + /* See if WM_SETTEXT/EM_REPLACESEL work. */ + r = SendMessageA(hEdit, WM_SETTEXT, 0, (LPARAM)str1); + ok(r, "Failed to set text.\n"); + + buffer = LocalLock(hmem); + ok(buffer != NULL && buffer[0] == '1', "Unexpected buffer contents\n"); + LocalUnlock(hmem); + + r = SendMessageA(hEdit, EM_REPLACESEL, 0, (LPARAM)str1_1); + ok(r, "Failed to replace selection.\n"); + + buffer = LocalLock(hmem); + ok(buffer != NULL && buffer[0] == '2', "Unexpected buffer contents\n"); + LocalUnlock(hmem); + /* use LocalAlloc first to get a different handle */ halloc = LocalAlloc(LMEM_MOVEABLE, 42); ok(halloc != NULL, "got %p (expected != NULL)\n", halloc); @@ -2827,13 +2879,161 @@ static void test_EM_GETHANDLE(void) DestroyWindow(hEdit); } +static void test_paste(void) +{ + HWND hEdit, hMultilineEdit; + HANDLE hmem, hmem_ret; + char *buffer; + int r, len; + static const char *str = "this is a simple text"; + static const char *str2 = "first line\r\nsecond line"; + + hEdit = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0); + hMultilineEdit = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE, 0); + + /* Prepare clipboard data with simple text */ + hmem = GlobalAlloc(GMEM_MOVEABLE, 255); + ok(hmem != NULL, "got %p (expected != NULL)\n", hmem); + buffer = GlobalLock(hmem); + ok(buffer != NULL, "got %p (expected != NULL)\n", buffer); + strcpy(buffer, str); + GlobalUnlock(hmem); + + r = OpenClipboard(hEdit); + ok(r == TRUE, "expected %d, got %d\n", TRUE, r); + r = EmptyClipboard(); + ok(r == TRUE, "expected %d, got %d\n", TRUE, r); + hmem_ret = SetClipboardData(CF_TEXT, hmem); + ok(hmem_ret == hmem, "expected %p, got %p\n", hmem, hmem_ret); + r = CloseClipboard(); + ok(r == TRUE, "expected %d, got %d\n", TRUE, r); + + /* Paste single line */ + SendMessageA(hEdit, WM_SETTEXT, 0, (LPARAM)""); + r = SendMessageA(hEdit, WM_PASTE, 0, 0); + len = SendMessageA(hEdit, WM_GETTEXTLENGTH, 0, 0); + ok(strlen(str) == len, "got %d\n", len); + + /* Prepare clipboard data with multiline text */ + hmem = GlobalAlloc(GMEM_MOVEABLE, 255); + ok(hmem != NULL, "got %p (expected != NULL)\n", hmem); + buffer = GlobalLock(hmem); + ok(buffer != NULL, "got %p (expected != NULL)\n", buffer); + strcpy(buffer, str2); + GlobalUnlock(hmem); + + r = OpenClipboard(hEdit); + ok(r == TRUE, "expected %d, got %d\n", TRUE, r); + r = EmptyClipboard(); + ok(r == TRUE, "expected %d, got %d\n", TRUE, r); + hmem_ret = SetClipboardData(CF_TEXT, hmem); + ok(hmem_ret == hmem, "expected %p, got %p\n", hmem, hmem_ret); + r = CloseClipboard(); + ok(r == TRUE, "expected %d, got %d\n", TRUE, r); + + /* Paste multiline text in singleline edit - should be cut */ + SendMessageA(hEdit, WM_SETTEXT, 0, (LPARAM)""); + r = SendMessageA(hEdit, WM_PASTE, 0, 0); + len = SendMessageA(hEdit, WM_GETTEXTLENGTH, 0, 0); + ok(strlen("first line") == len, "got %d\n", len); + + /* Paste multiline text in multiline edit */ + SendMessageA(hMultilineEdit, WM_SETTEXT, 0, (LPARAM)""); + r = SendMessageA(hMultilineEdit, WM_PASTE, 0, 0); + len = SendMessageA(hMultilineEdit, WM_GETTEXTLENGTH, 0, 0); + ok(strlen(str2) == len, "got %d\n", len); + + /* Cleanup */ + DestroyWindow(hEdit); + DestroyWindow(hMultilineEdit); +} + +static void test_EM_GETLINE(void) +{ + HWND hwnd[2]; + int i; + + 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++) + { + static const WCHAR strW[] = {'t','e','x','t',0}; + static const char *str = "text"; + WCHAR buffW[16]; + char buff[16]; + int r; + + if (i == 0) + ok(!IsWindowUnicode(hwnd[i]), "Expected ansi window.\n"); + else + ok(IsWindowUnicode(hwnd[i]), "Expected unicode window.\n"); + + SendMessageA(hwnd[i], WM_SETTEXT, 0, (LPARAM)str); + + memset(buff, 0, sizeof(buff)); + *(WORD *)buff = sizeof(buff); + r = SendMessageA(hwnd[i], EM_GETLINE, 0, (LPARAM)buff); + ok(r == strlen(str), "Failed to get a line %d.\n", r); + ok(!strcmp(buff, str), "Unexpected line data %s.\n", buff); + + memset(buff, 0, sizeof(buff)); + *(WORD *)buff = sizeof(buff); + r = SendMessageA(hwnd[i], EM_GETLINE, 1, (LPARAM)buff); + ok(r == strlen(str), "Failed to get a line %d.\n", r); + ok(!strcmp(buff, str), "Unexpected line data %s.\n", buff); + + memset(buffW, 0, sizeof(buffW)); + *(WORD *)buffW = sizeof(buffW)/sizeof(buffW[0]); + 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]); + 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)); + + DestroyWindow(hwnd[i]); + } +} + +static int CALLBACK test_wordbreak_procA(char *text, int current, int length, int code) +{ + return -1; +} + +static void test_wordbreak_proc(void) +{ + EDITWORDBREAKPROCA proc; + LRESULT ret; + HWND hwnd; + + hwnd = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0); + + proc = (void *)SendMessageA(hwnd, EM_GETWORDBREAKPROC, 0, 0); + ok(proc == NULL, "Unexpected wordbreak proc %p.\n", proc); + + ret = SendMessageA(hwnd, EM_SETWORDBREAKPROC, 0, (LPARAM)test_wordbreak_procA); + ok(ret == 1, "Unexpected return value %ld.\n", ret); + + proc = (void *)SendMessageA(hwnd, EM_GETWORDBREAKPROC, 0, 0); + ok(proc == test_wordbreak_procA, "Unexpected wordbreak proc %p.\n", proc); + + ret = SendMessageA(hwnd, EM_SETWORDBREAKPROC, 0, 0); + ok(ret == 1, "Unexpected return value %ld.\n", ret); + + proc = (void *)SendMessageA(hwnd, EM_GETWORDBREAKPROC, 0, 0); + ok(proc == NULL, "Unexpected wordbreak proc %p.\n", proc); + + DestroyWindow(hwnd); +} START_TEST(edit) { BOOL b; - init_function_pointers(); - hinst = GetModuleHandleA(NULL); b = RegisterWindowClasses(); ok (b, "RegisterWindowClasses failed\n"); @@ -2861,12 +3061,11 @@ START_TEST(edit) test_child_edit_wmkeydown(); test_fontsize(); test_dialogmode(); - if (pEndMenu) - test_contextmenu(); - else - win_skip("EndMenu is not available\n"); - + test_contextmenu(); test_EM_GETHANDLE(); + test_paste(); + test_EM_GETLINE(); + test_wordbreak_proc(); UnregisterWindowClasses(); } diff --git a/modules/rostests/winetests/user32/generated.c b/modules/rostests/winetests/user32/generated.c index e80277ce1a2..87dda5ec115 100644 --- a/modules/rostests/winetests/user32/generated.c +++ b/modules/rostests/winetests/user32/generated.c @@ -5,7 +5,17 @@ * Unit tests for data structure packing */ -#include "precomp.h" +#ifndef __REACTOS__ +#define WINVER 0x0501 +#define _WIN32_IE 0x0501 +#define _WIN32_WINNT 0x0501 +#endif + +#define WINE_NOWINSOCK + +#include "windows.h" + +#include "wine/test.h" /*********************************************************************** * Compatibility macros diff --git a/modules/rostests/winetests/user32/input.c b/modules/rostests/winetests/user32/input.c index 239cc09e9ed..37fe0cee877 100755 --- a/modules/rostests/winetests/user32/input.c +++ b/modules/rostests/winetests/user32/input.c @@ -44,7 +44,25 @@ * */ -#include "precomp.h" +#ifndef __REACTOS__ +#define _WIN32_WINNT 0x401 +#define _WIN32_IE 0x0500 +#endif + +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "wingdi.h" +#include "winnls.h" + +#include "wine/test.h" + +#ifdef __REACTOS__ +#include +#endif /* globals */ static HWND hWndTest; @@ -924,8 +942,7 @@ static void test_Input_blackbox(void) empty_message_queue(); prevWndProc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR) WndProc2); - ok(prevWndProc != 0 || (prevWndProc == 0 && GetLastError() == 0), - "error: %d\n", (int) GetLastError()); + ok(prevWndProc != 0 || GetLastError() == 0, "error: %d\n", (int) GetLastError()); i.type = INPUT_KEYBOARD; i.u.ki.time = 0; @@ -1266,6 +1283,19 @@ static LRESULT CALLBACK hook_proc2( int code, WPARAM wparam, LPARAM lparam ) return CallNextHookEx( 0, code, wparam, lparam ); } +static LRESULT CALLBACK hook_proc3( int code, WPARAM wparam, LPARAM lparam ) +{ + POINT pt; + + if (code == HC_ACTION) + { + /* MSLLHOOKSTRUCT does not seem to be reliable and contains different data on each run. */ + GetCursorPos(&pt); + ok(pt.x == pt_old.x && pt.y == pt_old.y, "GetCursorPos: (%d,%d)\n", pt.x, pt.y); + } + return CallNextHookEx( 0, code, wparam, lparam ); +} + static void test_mouse_ll_hook(void) { HWND hwnd; @@ -1339,6 +1369,62 @@ static void test_mouse_ll_hook(void) ok(pt.x == pt_new.x && pt.y == pt_new.y, "Position changed: (%d,%d)\n", pt.x, pt.y); UnhookWindowsHookEx(hook2); + hook1 = SetWindowsHookExA(WH_MOUSE_LL, hook_proc3, GetModuleHandleA(0), 0); + + SetRect(&rc, 150, 150, 150, 150); + ClipCursor(&rc); + clipped = TRUE; + + SetCursorPos(140, 140); + GetCursorPos(&pt_old); + ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y); + SetCursorPos(160, 160); + GetCursorPos(&pt_old); + todo_wine + ok(pt_old.x == 149 && pt_old.y == 149, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y); + mouse_event(MOUSEEVENTF_MOVE, -STEP, -STEP, 0, 0); + GetCursorPos(&pt_old); + ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y); + mouse_event(MOUSEEVENTF_MOVE, +STEP, +STEP, 0, 0); + GetCursorPos(&pt_old); + todo_wine + ok(pt_old.x == 149 && pt_old.y == 149, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y); + mouse_event(MOUSEEVENTF_MOVE, 0, 0, 0, 0); + GetCursorPos(&pt_old); + ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y); + mouse_event(MOUSEEVENTF_MOVE, 0, 0, 0, 0); + GetCursorPos(&pt_old); + todo_wine + ok(pt_old.x == 149 && pt_old.y == 149, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y); + + clipped = FALSE; + ClipCursor(NULL); + + SetCursorPos(140, 140); + SetRect(&rc, 150, 150, 150, 150); + ClipCursor(&rc); + GetCursorPos(&pt_old); + ok(pt_old.x == 150 && pt_old.y == 150, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y); + ClipCursor(NULL); + + SetCursorPos(160, 160); + SetRect(&rc, 150, 150, 150, 150); + ClipCursor(&rc); + GetCursorPos(&pt_old); + todo_wine + ok(pt_old.x == 149 && pt_old.y == 149, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y); + ClipCursor(NULL); + + SetCursorPos(150, 150); + SetRect(&rc, 150, 150, 150, 150); + ClipCursor(&rc); + GetCursorPos(&pt_old); + todo_wine + ok(pt_old.x == 149 && pt_old.y == 149, "Wrong new pos: (%d,%d)\n", pt_old.x, pt_old.y); + ClipCursor(NULL); + + UnhookWindowsHookEx(hook1); + done: DestroyWindow(hwnd); SetCursorPos(pt_org.x, pt_org.y); @@ -1911,6 +1997,23 @@ static DWORD WINAPI create_static_win(void *arg) return 0; } +static void get_dc_region(RECT *region, HWND hwnd, DWORD flags) +{ + int region_type; + HRGN hregion; + HDC hdc; + + hdc = GetDCEx(hwnd, 0, flags); + ok(hdc != NULL, "GetDCEx failed\n"); + hregion = CreateRectRgn(40, 40, 60, 60); + ok(hregion != NULL, "CreateRectRgn failed\n"); + GetRandomRgn(hdc, hregion, SYSRGN); + region_type = GetRgnBox(hregion, region); + ok(region_type == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", region_type); + DeleteObject(hregion); + ReleaseDC(hwnd, hdc); +} + static void test_Input_mouse(void) { BOOL got_button_down, got_button_up; @@ -1923,10 +2026,18 @@ static void test_Input_mouse(void) int region_type; HRGN hregion; RECT region; - BOOL ret; MSG msg; + BOOL ret; - GetCursorPos(&pt_org); + SetLastError(0xdeadbeef); + ret = GetCursorPos(NULL); + ok(!ret, "GetCursorPos succeed\n"); + ok(GetLastError() == 0xdeadbeef || GetLastError() == ERROR_NOACCESS, "error %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = GetCursorPos(&pt_org); + ok(ret, "GetCursorPos failed\n"); + ok(GetLastError() == 0xdeadbeef, "error %u\n", GetLastError()); button_win = CreateWindowA("button", "button", WS_VISIBLE | WS_POPUP, 100, 100, 100, 100, 0, NULL, NULL, NULL); @@ -2043,6 +2154,7 @@ static void test_Input_mouse(void) } SetEvent(thread_data.end_event); WaitForSingleObject(thread, INFINITE); + CloseHandle(thread); ok(hittest_no && hittest_no<50, "expected WM_NCHITTEST message\n"); ok(!got_button_down, "unexpected WM_RBUTTONDOWN message\n"); ok(!got_button_up, "unexpected WM_RBUTTONUP message\n"); @@ -2145,6 +2257,10 @@ static void test_Input_mouse(void) WS_VISIBLE | WS_POPUP, 100, 100, 100, 100, button_win, NULL, NULL, NULL); ok(hwnd != NULL, "CreateWindowEx failed\n"); + static_win = CreateWindowA("static", "Title", WS_VISIBLE | WS_CHILD, + 10, 10, 20, 20, hwnd, NULL, NULL, NULL); + ok(static_win != NULL, "CreateWindowA failed %u\n", GetLastError()); + SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); SetWindowLongA(hwnd, GWL_EXSTYLE, GetWindowLongA(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED); ret = SetLayeredWindowAttributes(hwnd, 0, 255, LWA_ALPHA); @@ -2256,6 +2372,25 @@ static void test_Input_mouse(void) ok(region_type == ERROR, "expected ERROR, got %d\n", region_type); } + get_dc_region(®ion, hwnd, DCX_PARENTCLIP); + ok(region.left == 100 && region.top == 100 && region.right == 200 && region.bottom == 200, + "expected region (100,100)-(200,200), got %s\n", wine_dbgstr_rect(®ion)); + get_dc_region(®ion, hwnd, DCX_WINDOW | DCX_USESTYLE); + ok(region.left == 100 && region.top == 100 && region.right == 200 && region.bottom == 200, + "expected region (100,100)-(200,200), got %s\n", wine_dbgstr_rect(®ion)); + get_dc_region(®ion, hwnd, DCX_USESTYLE); + ok(region.left == 100 && region.top == 100 && region.right == 200 && region.bottom == 200, + "expected region (100,100)-(200,200), got %s\n", wine_dbgstr_rect(®ion)); + get_dc_region(®ion, static_win, DCX_PARENTCLIP); + ok(region.left == 100 && region.top == 100 && region.right == 200 && region.bottom == 200, + "expected region (100,100)-(200,200), got %s\n", wine_dbgstr_rect(®ion)); + get_dc_region(®ion, static_win, DCX_WINDOW | DCX_USESTYLE); + ok(region.left == 110 && region.top == 110 && region.right == 130 && region.bottom == 130, + "expected region (110,110)-(130,130), got %s\n", wine_dbgstr_rect(®ion)); + get_dc_region(®ion, static_win, DCX_USESTYLE); + ok(region.left == 100 && region.top == 100 && region.right == 200 && region.bottom == 200, + "expected region (100,100)-(200,200), got %s\n", wine_dbgstr_rect(®ion)); + got_button_down = got_button_up = FALSE; simulate_click(TRUE, 150, 150); while (wait_for_message(&msg)) @@ -2343,6 +2478,7 @@ static void test_Input_mouse(void) ok(got_button_down, "expected WM_LBUTTONDOWN message\n"); ok(got_button_up, "expected WM_LBUTTONUP message\n"); + DestroyWindow(static_win); DestroyWindow(hwnd); SetCursorPos(pt_org.x, pt_org.y); @@ -2726,7 +2862,11 @@ static void test_OemKeyScan(void) ret = OemKeyScan( oem ); oem_char = LOBYTE( oem ); - if (!OemToCharBuffW( &oem_char, &wchr, 1 )) + /* OemKeyScan returns -1 for any character that cannot be mapped, + * whereas OemToCharBuff changes unmappable characters to question + * marks. The ASCII characters 0-127, including the real question mark + * character, are all mappable and are the same in all OEM codepages. */ + if (!OemToCharBuffW( &oem_char, &wchr, 1 ) || (wchr == '?' && oem_char < 0)) expect = -1; else { diff --git a/modules/rostests/winetests/user32/listbox.c b/modules/rostests/winetests/user32/listbox.c index 7033aa65cdf..88d3adb728e 100644 --- a/modules/rostests/winetests/user32/listbox.c +++ b/modules/rostests/winetests/user32/listbox.c @@ -17,7 +17,17 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "winnls.h" + +#include "wine/test.h" #ifdef VISIBLE #define WAIT Sleep (1000) @@ -36,6 +46,15 @@ static const char * const strings[4] = { static const char BAD_EXTENSION[] = "*.badtxt"; +static int strcmp_aw(LPCWSTR strw, const char *stra) +{ + WCHAR buf[1024]; + + if (!stra) return 1; + MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, sizeof(buf)/sizeof(WCHAR)); + return lstrcmpW(strw, buf); +} + static HWND create_listbox (DWORD add_style, HWND parent) { @@ -229,6 +248,31 @@ static LRESULT WINAPI main_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARA { switch (msg) { + case WM_MEASUREITEM: + { + DWORD style = GetWindowLongA(GetWindow(hwnd, GW_CHILD), GWL_STYLE); + MEASUREITEMSTRUCT *mi = (void*)lparam; + + 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) + { + ok(!strcmp_aw((WCHAR*)mi->itemData, strings[mi->itemID]), + "mi->itemData = %s (%d)\n", wine_dbgstr_w((WCHAR*)mi->itemData), mi->itemID); + } + else + { + ok((void*)mi->itemData == strings[mi->itemID], + "mi->itemData = %08lx, expected %p\n", mi->itemData, strings[mi->itemID]); + } + break; + } case WM_DRAWITEM: { RECT rc_item, rc_client, rc_clip; @@ -1812,6 +1856,26 @@ static void test_extents(void) DestroyWindow(parent); } +static void test_WM_MEASUREITEM(void) +{ + HWND parent, listbox; + LRESULT data; + + parent = create_parent(); + listbox = create_listbox(WS_CHILD | LBS_OWNERDRAWVARIABLE, parent); + + data = SendMessageA(listbox, LB_GETITEMDATA, 0, 0); + ok(data == (LRESULT)strings[0], "data = %08lx, expected %p\n", data, strings[0]); + DestroyWindow(parent); + + parent = create_parent(); + listbox = create_listbox(WS_CHILD | LBS_OWNERDRAWVARIABLE | LBS_HASSTRINGS, parent); + + data = SendMessageA(listbox, LB_GETITEMDATA, 0, 0); + ok(!data, "data = %08lx\n", data); + DestroyWindow(parent); +} + START_TEST(listbox) { const struct listbox_test SS = @@ -1895,4 +1959,5 @@ START_TEST(listbox) test_GetListBoxInfo(); test_missing_lbuttonup(); test_extents(); + test_WM_MEASUREITEM(); } diff --git a/modules/rostests/winetests/user32/menu.c b/modules/rostests/winetests/user32/menu.c index f3aac556098..3430ed687ef 100755 --- a/modules/rostests/winetests/user32/menu.c +++ b/modules/rostests/winetests/user32/menu.c @@ -19,7 +19,23 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#ifndef __REACTOS__ +#define _WIN32_WINNT 0x0501 +#endif + +#include +#include +#include +#include + +#define OEMRESOURCE /* For OBM_MNARROW */ + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" + +#include "wine/test.h" static ATOM atomMenuCheckClass; @@ -27,7 +43,6 @@ static BOOL (WINAPI *pGetMenuInfo)(HMENU,LPCMENUINFO); static BOOL (WINAPI *pGetMenuBarInfo)(HWND,LONG,LONG,PMENUBARINFO); static UINT (WINAPI *pSendInput)(UINT, INPUT*, size_t); static BOOL (WINAPI *pSetMenuInfo)(HMENU,LPCMENUINFO); -static BOOL (WINAPI *pEndMenu) (void); static void init_function_pointers(void) { @@ -42,7 +57,6 @@ static void init_function_pointers(void) GET_PROC(GetMenuBarInfo) GET_PROC(SendInput) GET_PROC(SetMenuInfo) - GET_PROC(EndMenu) #undef GET_PROC } @@ -3504,7 +3518,7 @@ static LRESULT WINAPI menu_cancelmode_wnd_proc(HWND hwnd, UINT msg, PostMessageA( hwnd, WM_MOUSEMOVE, 0, 0); return SendMessageA( g_hwndtosend, WM_CANCELMODE, 0, 0); } - pEndMenu(); + EndMenu(); return TRUE; } } @@ -3517,10 +3531,7 @@ static void test_menu_cancelmode(void) HWND hwnd, hwndchild; HMENU menu, menubar; MSG msg; - if( !pEndMenu) { /* win95 */ - win_skip( "EndMenu is not available\n"); - return; - } + hwnd = CreateWindowExA( 0, (LPCSTR)MAKEINTATOM(atomMenuCheckClass), NULL, WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 200, 200, NULL, NULL, NULL, NULL); diff --git a/modules/rostests/winetests/user32/monitor.c b/modules/rostests/winetests/user32/monitor.c index 313e78ce450..886d63ccfe2 100644 --- a/modules/rostests/winetests/user32/monitor.c +++ b/modules/rostests/winetests/user32/monitor.c @@ -19,7 +19,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include "wine/test.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" static HMODULE hdll; static LONG (WINAPI *pChangeDisplaySettingsExA)(LPCSTR, LPDEVMODEA, HWND, DWORD, LPVOID); diff --git a/modules/rostests/winetests/user32/msg.c b/modules/rostests/winetests/user32/msg.c index 722f8d4efef..39ce1525825 100755 --- a/modules/rostests/winetests/user32/msg.c +++ b/modules/rostests/winetests/user32/msg.c @@ -20,9 +20,24 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#ifndef __REACTOS__ +#define _WIN32_WINNT 0x0600 /* For WM_CHANGEUISTATE,QS_RAWINPUT,WM_DWMxxxx */ +#define WINVER 0x0600 /* for WM_GETTITLEBARINFOEX */ +#endif -#include +#include +#include +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "winnls.h" +#include "dbt.h" + +#include "wine/test.h" #define MDI_FIRST_CHILD_ID 2004 @@ -6568,15 +6583,13 @@ static void test_button_messages(void) prevfont = SelectObject(hdc, hfont2); ok(prevfont == GetStockObject(SYSTEM_FONT), "Unexpected default font\n"); SendMessageA(hwnd, WM_PRINTCLIENT, (WPARAM)hdc, 0); - todo_wine - ok(GetStockObject(SYSTEM_FONT) == GetCurrentObject(hdc, OBJ_FONT), "button[%u]: unexpected font selected after WM_PRINTCLIENT\n", i); + ok(hfont2 != GetCurrentObject(hdc, OBJ_FONT), "button[%u]: unexpected font selected after WM_PRINTCLIENT\n", i); SelectObject(hdc, prevfont); prevfont = SelectObject(hdc, hfont2); ok(prevfont == GetStockObject(SYSTEM_FONT), "Unexpected default font\n"); SendMessageA(hwnd, WM_PAINT, (WPARAM)hdc, 0); - todo_wine - ok(GetStockObject(SYSTEM_FONT) == GetCurrentObject(hdc, OBJ_FONT), "button[%u]: unexpected font selected after WM_PAINT\n", i); + ok(hfont2 != GetCurrentObject(hdc, OBJ_FONT), "button[%u]: unexpected font selected after WM_PAINT\n", i); SelectObject(hdc, prevfont); DeleteDC(hdc); @@ -7131,6 +7144,41 @@ static void test_static_messages(void) /****************** ComboBox message test *************************/ #define ID_COMBOBOX 0x000f +static const struct message SetCurSelComboSeq[] = +{ + { CB_SETCURSEL, sent|wparam|lparam, 0, 0 }, + { LB_SETCURSEL, sent|wparam|lparam, 0, 0 }, + { LB_SETTOPINDEX, sent|wparam|lparam, 0, 0 }, + { LB_GETCURSEL, sent|wparam|lparam, 0, 0 }, + { LB_GETTEXTLEN, sent|wparam|lparam, 0, 0 }, + { LB_GETTEXTLEN, sent|wparam|lparam|optional, 0, 0 }, /* TODO: it's sent on all Windows versions */ + { LB_GETTEXT, sent|wparam, 0 }, + { WM_CTLCOLOREDIT, sent|parent }, + { LB_GETITEMDATA, sent|wparam|lparam, 0, 0 }, + { WM_DRAWITEM, sent|wparam|lparam|parent, ID_COMBOBOX, 0x100010f3 }, + { 0 } +}; + +static const struct message SetCurSelComboSeq2[] = +{ + { CB_SETCURSEL, sent|wparam|lparam, 0, 0 }, + { LB_SETCURSEL, sent|wparam|lparam, 0, 0 }, + { LB_SETTOPINDEX, sent|wparam|lparam, 0, 0 }, + { LB_GETCURSEL, sent|wparam|lparam, 0, 0 }, + { LB_GETTEXTLEN, sent|wparam|lparam, 0, 0 }, + { LB_GETTEXTLEN, sent|wparam|lparam|optional, 0, 0 }, /* TODO: it's sent on all Windows versions */ + { LB_GETTEXT, sent|wparam, 0 }, + { 0 } +}; + +static const struct message SetCurSelComboSeq_edit[] = +{ + { CB_SETCURSEL, sent|wparam|lparam, 0, 0 }, + { WM_SETTEXT, sent|wparam, 0 }, + { EM_SETSEL, sent|wparam|lparam, 0, INT_MAX }, + { 0 } +}; + static const struct message WmKeyDownComboSeq[] = { { WM_KEYDOWN, sent|wparam|lparam, VK_DOWN, 0 }, @@ -7214,9 +7262,10 @@ static const struct message SetFocusButtonSeq2[] = { 0 } }; -static WNDPROC old_combobox_proc, edit_window_proc; +static WNDPROC old_combobox_proc, edit_window_proc, lbox_window_proc; -static LRESULT CALLBACK combobox_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +static LRESULT CALLBACK combobox_edit_subclass_proc(HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam) { static LONG defwndproc_counter = 0; LRESULT ret; @@ -7237,7 +7286,7 @@ static LRESULT CALLBACK combobox_subclass_proc(HWND hwnd, UINT message, WPARAM w if (defwndproc_counter) msg.flags |= defwinproc; msg.wParam = wParam; msg.lParam = lParam; - msg.descr = "combo"; + msg.descr = "combo edit"; add_message(&msg); } @@ -7248,6 +7297,38 @@ static LRESULT CALLBACK combobox_subclass_proc(HWND hwnd, UINT message, WPARAM w return ret; } +static LRESULT CALLBACK combobox_lbox_subclass_proc(HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam) +{ + static LONG defwndproc_counter = 0; + LRESULT ret; + struct recvd_message msg; + + /* do not log painting messages */ + if (message != WM_PAINT && + message != WM_NCPAINT && + message != WM_SYNCPAINT && + message != WM_ERASEBKGND && + message != WM_NCHITTEST && + !ignore_message( message )) + { + msg.hwnd = hwnd; + msg.message = message; + msg.flags = sent|wparam|lparam; + if (defwndproc_counter) msg.flags |= defwinproc; + msg.wParam = wParam; + msg.lParam = lParam; + msg.descr = "combo lbox"; + add_message(&msg); + } + + defwndproc_counter++; + ret = CallWindowProcA(lbox_window_proc, hwnd, message, wParam, lParam); + defwndproc_counter--; + + return ret; +} + static LRESULT CALLBACK combobox_hook_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static LONG defwndproc_counter = 0; @@ -7297,9 +7378,8 @@ static void subclass_combobox(void) static void test_combobox_messages(void) { - HWND parent, combo, button, edit; + HWND parent, combo, button, edit, lbox; LRESULT ret; - BOOL (WINAPI *pGetComboBoxInfo)(HWND, PCOMBOBOXINFO); COMBOBOXINFO cbInfo; BOOL res; @@ -7344,13 +7424,6 @@ static void test_combobox_messages(void) DestroyWindow(parent); /* Start again. Test combobox text selection when getting and losing focus */ - pGetComboBoxInfo = (void *)GetProcAddress(GetModuleHandleA("user32.dll"), "GetComboBoxInfo"); - if (!pGetComboBoxInfo) - { - win_skip("GetComboBoxInfo is not available\n"); - return; - } - parent = CreateWindowExA(0, "TestParentClass", "Parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 10, 10, 300, 300, NULL, NULL, NULL, NULL); ok(parent != 0, "Failed to create parent window\n"); @@ -7361,11 +7434,12 @@ static void test_combobox_messages(void) cbInfo.cbSize = sizeof(COMBOBOXINFO); SetLastError(0xdeadbeef); - res = pGetComboBoxInfo(combo, &cbInfo); + res = GetComboBoxInfo(combo, &cbInfo); ok(res, "Failed to get COMBOBOXINFO structure; LastError: %u\n", GetLastError()); edit = cbInfo.hwndItem; - edit_window_proc = (WNDPROC)SetWindowLongPtrA(edit, GWLP_WNDPROC, (ULONG_PTR)combobox_subclass_proc); + edit_window_proc = (WNDPROC)SetWindowLongPtrA(edit, GWLP_WNDPROC, + (ULONG_PTR)combobox_edit_subclass_proc); button = CreateWindowExA(0, "Button", "OK", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 5, 50, 100, 20, parent, NULL, @@ -7398,7 +7472,46 @@ static void test_combobox_messages(void) log_all_parent_messages--; ok_sequence(SetFocusButtonSeq2, "SetFocus on a Button (2)", TRUE); + SetFocus(combo); + SendMessageA(combo, WM_SETREDRAW, FALSE, 0); + flush_sequence(); + log_all_parent_messages++; + SendMessageA(combo, CB_SETCURSEL, 0, 0); + log_all_parent_messages--; + ok_sequence(SetCurSelComboSeq_edit, "CB_SETCURSEL on a ComboBox with edit control", FALSE); + DestroyWindow(button); + DestroyWindow(combo); + + combo = CreateWindowExA(0, "my_combobox_class", "test", + WS_CHILD | WS_VISIBLE | CBS_OWNERDRAWFIXED | CBS_DROPDOWNLIST, + 5, 5, 100, 100, parent, (HMENU)ID_COMBOBOX, NULL, NULL); + ok(combo != 0, "Failed to create combobox window\n"); + + ret = SendMessageA(combo, CB_ADDSTRING, 0, (LPARAM)"item 0"); + ok(ret == 0, "expected 0, got %ld\n", ret); + + cbInfo.cbSize = sizeof(COMBOBOXINFO); + SetLastError(0xdeadbeef); + res = GetComboBoxInfo(combo, &cbInfo); + ok(res, "Failed to get COMBOBOXINFO structure; LastError: %u\n", GetLastError()); + lbox = cbInfo.hwndList; + lbox_window_proc = (WNDPROC)SetWindowLongPtrA(lbox, GWLP_WNDPROC, + (ULONG_PTR)combobox_lbox_subclass_proc); + flush_sequence(); + + log_all_parent_messages++; + SendMessageA(combo, CB_SETCURSEL, 0, 0); + log_all_parent_messages--; + ok_sequence(SetCurSelComboSeq, "CB_SETCURSEL on a ComboBox", FALSE); + + ShowWindow(combo, SW_HIDE); + flush_sequence(); + log_all_parent_messages++; + SendMessageA(combo, CB_SETCURSEL, 0, 0); + log_all_parent_messages--; + ok_sequence(SetCurSelComboSeq2, "CB_SETCURSEL on a ComboBox", FALSE); + DestroyWindow(combo); DestroyWindow(parent); } @@ -9029,7 +9142,8 @@ static void test_accelerators(void) keybd_event(VK_MENU, 0, 0, 0); keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP, 0); pump_msg_loop(hwnd, 0); - ok_sequence(WmAltPressRelease, "Alt press/release", FALSE); + /* this test doesn't pass in Wine for managed windows */ + ok_sequence(WmAltPressRelease, "Alt press/release", TRUE); trace("testing VK_F1 press/release\n"); keybd_event(VK_F1, 0, 0, 0); @@ -9049,7 +9163,7 @@ static void test_accelerators(void) keybd_event(VK_F10, 0, 0, 0); keybd_event(VK_F10, 0, KEYEVENTF_KEYUP, 0); pump_msg_loop(hwnd, 0); - ok_sequence(WmVkF10Seq, "VK_F10 press/release", FALSE); + ok_sequence(WmVkF10Seq, "VK_F10 press/release", TRUE); trace("testing SHIFT+F10 press/release\n"); keybd_event(VK_SHIFT, 0, 0, 0); @@ -14468,6 +14582,13 @@ static const struct message wm_lb_deletestring_reset[] = { 0 } }; static const struct message wm_lb_addstring[] = +{ + { LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ef }, + { LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ed }, + { LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ee }, + { 0 } +}; +static const struct message wm_lb_addstring_ownerdraw[] = { { LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ed }, { WM_MEASUREITEM, sent|wparam|lparam|parent, 0xf0f2, 0xf30604ed }, @@ -14477,7 +14598,7 @@ static const struct message wm_lb_addstring[] = { WM_MEASUREITEM, sent|wparam|lparam|parent, 0xf2f2, 0xf30604ef }, { 0 } }; -static const struct message wm_lb_addstring_sort[] = +static const struct message wm_lb_addstring_sort_ownerdraw[] = { { LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ed }, { WM_MEASUREITEM, sent|wparam|lparam|parent, 0xf0f2, 0xf30604ed }, @@ -14565,6 +14686,8 @@ static void test_listbox_messages(void) flush_sequence(); + log_all_parent_messages++; + 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"); @@ -14572,13 +14695,11 @@ static void test_listbox_messages(void) ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2"); ok(ret == 2, "expected 2, got %ld\n", ret); - ok_sequence(wm_lb_addstring, "LB_ADDSTRING", FALSE); + ok_sequence(wm_lb_addstring_ownerdraw, "LB_ADDSTRING", FALSE); check_lb_state(listbox, 3, LB_ERR, 0, 0); flush_sequence(); - log_all_parent_messages++; - trace("selecting item 0\n"); ret = SendMessageA(listbox, LB_SETCURSEL, 0, 0); ok(ret == 0, "expected 0, got %ld\n", ret); @@ -14657,7 +14778,59 @@ static void test_listbox_messages(void) ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2"); ok(ret == 2, "expected 2, got %ld\n", ret); - ok_sequence(wm_lb_addstring_sort, "LB_ADDSTRING", FALSE); + ok_sequence(wm_lb_addstring_sort_ownerdraw, "LB_ADDSTRING", FALSE); + check_lb_state(listbox, 3, LB_ERR, 0, 0); + + log_all_parent_messages--; + + DestroyWindow(listbox); + + /* with LBS_HASSTRINGS */ + listbox = CreateWindowExA(WS_EX_NOPARENTNOTIFY, "ListBox", NULL, + WS_CHILD | LBS_NOTIFY | LBS_HASSTRINGS | WS_VISIBLE, + 10, 10, 80, 80, parent, (HMENU)ID_LISTBOX, 0, NULL); + listbox_orig_proc = (WNDPROC)SetWindowLongPtrA(listbox, GWLP_WNDPROC, (ULONG_PTR)listbox_hook_proc); + + check_lb_state(listbox, 0, LB_ERR, 0, 0); + + flush_sequence(); + + log_all_parent_messages++; + + 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(wm_lb_addstring, "LB_ADDSTRING", FALSE); + check_lb_state(listbox, 3, LB_ERR, 0, 0); + + log_all_parent_messages--; + + DestroyWindow(listbox); + + /* with LBS_HASSTRINGS and LBS_SORT */ + listbox = CreateWindowExA(WS_EX_NOPARENTNOTIFY, "ListBox", NULL, + WS_CHILD | LBS_NOTIFY | LBS_HASSTRINGS | LBS_SORT | WS_VISIBLE, + 10, 10, 80, 80, parent, (HMENU)ID_LISTBOX, 0, NULL); + listbox_orig_proc = (WNDPROC)SetWindowLongPtrA(listbox, GWLP_WNDPROC, (ULONG_PTR)listbox_hook_proc); + + check_lb_state(listbox, 0, LB_ERR, 0, 0); + + flush_sequence(); + + log_all_parent_messages++; + + 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(wm_lb_addstring, "LB_ADDSTRING", FALSE); check_lb_state(listbox, 3, LB_ERR, 0, 0); log_all_parent_messages--; @@ -16919,9 +17092,6 @@ static const struct message send_message_2[] = { }; static const struct message send_message_3[] = { { WM_USER+3, sent|wparam|lparam, 0, 0 }, - { 0 } -}; -static const struct message send_message_4[] = { { WM_USER+1, sent|wparam|lparam, 0, 0 }, { 0 } }; @@ -17027,16 +17197,11 @@ static void test_SendMessage_other_thread(int thread_n) ret = GetQueueStatus(QS_SENDMESSAGE|QS_POSTMESSAGE); ok(ret == MAKELONG(QS_SENDMESSAGE, QS_SENDMESSAGE|QS_POSTMESSAGE), "wrong status %08x\n", ret); - trace("main: call PeekMessage\n"); - ok(PeekMessageA(&msg, 0, 0, 0, PM_NOREMOVE), "PeekMessage should not fail\n"); - ok(msg.message == WM_USER+1, "expected WM_USER+1, got %04x\n", msg.message); - ok_sequence(send_message_3, "SendMessage from other thread 3", thread_n == 2); - trace("main: call PeekMessage\n"); ok(PeekMessageA(&msg, 0, 0, 0, PM_REMOVE), "PeekMessage should not fail\n"); ok(msg.message == WM_USER+1, "expected WM_USER+1, got %04x\n", msg.message); DispatchMessageA(&msg); - ok_sequence(send_message_4, "SendMessage from other thread 4", FALSE); + ok_sequence(send_message_3, "SendMessage from other thread 3", thread_n == 2); /* intentionally yield */ MsgWaitForMultipleObjects(0, NULL, FALSE, 100, qs_all_input); diff --git a/modules/rostests/winetests/user32/precomp.h b/modules/rostests/winetests/user32/precomp.h index 79309febc7b..a379831662e 100644 --- a/modules/rostests/winetests/user32/precomp.h +++ b/modules/rostests/winetests/user32/precomp.h @@ -1,16 +1,18 @@ -#ifndef _USER32_APITEST_PRECOMP_H_ -#define _USER32_APITEST_PRECOMP_H_ + +#ifndef _USER32_WINETEST_PRECOMP_H_ +#define _USER32_WINETEST_PRECOMP_H_ #include #include #include #define STRICT -#define WIN32_LEAN_AND_MEAN #define WINE_NOWINSOCK #include #define WINE_NO_INLINE_RECT #include -#endif /* _USER32_APITEST_PRECOMP_H_ */ +#include + +#endif /* !_USER32_WINETEST_PRECOMP_H_ */ diff --git a/modules/rostests/winetests/user32/resource.c b/modules/rostests/winetests/user32/resource.c index 049f6653b82..2388adb64f3 100755 --- a/modules/rostests/winetests/user32/resource.c +++ b/modules/rostests/winetests/user32/resource.c @@ -18,7 +18,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include +#include + +#include "wine/test.h" static UINT (WINAPI *pPrivateExtractIconsA)(LPCSTR, int, int, int, HICON *, UINT *, UINT, UINT) = NULL; diff --git a/modules/rostests/winetests/user32/scroll.c b/modules/rostests/winetests/user32/scroll.c index f95cbb700e7..0bda5dd0f44 100644 --- a/modules/rostests/winetests/user32/scroll.c +++ b/modules/rostests/winetests/user32/scroll.c @@ -18,7 +18,12 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include +#include +#include +#include + +#include "wine/test.h" static HWND hScroll; static BOOL bThemeActive = FALSE; diff --git a/modules/rostests/winetests/user32/static.c b/modules/rostests/winetests/user32/static.c index 0a58b38fe7b..8776c3a9e07 100644 --- a/modules/rostests/winetests/user32/static.c +++ b/modules/rostests/winetests/user32/static.c @@ -17,7 +17,14 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include +#include + +#define STRICT +#define WIN32_LEAN_AND_MEAN +#include + +#include "wine/test.h" #define TODO_COUNT 1 @@ -92,6 +99,7 @@ static void test_updates(int style, int flags) HDC hdc = GetDC( hStatic); COLORREF colour = GetPixel( hdc, 10, 10); ok ( colour != 0, "pixel should NOT be painted black!\n"); + ReleaseDC(hStatic, hdc); } if (style != SS_ETCHEDHORZ && style != SS_ETCHEDVERT) exp = 4; diff --git a/modules/rostests/winetests/user32/sysparams.c b/modules/rostests/winetests/user32/sysparams.c index e9a69e67030..9ed85a24d08 100755 --- a/modules/rostests/winetests/user32/sysparams.c +++ b/modules/rostests/winetests/user32/sysparams.c @@ -17,7 +17,24 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#ifndef __REACTOS__ +#define _WIN32_WINNT 0x0600 /* For SPI_GETMOUSEHOVERWIDTH and more */ +#define _WIN32_IE 0x0700 +#define WINVER 0x0600 /* For COLOR_MENUBAR, NONCLIENTMETRICS with padding */ +#endif + +#include +#include +#include +#include + +#include "wine/test.h" +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winreg.h" +#include "winuser.h" +#include "winnls.h" #ifndef SPI_GETDESKWALLPAPER # define SPI_GETDESKWALLPAPER 0x0073 @@ -2682,6 +2699,14 @@ static BOOL is_font_enumerated(const char *name) return ret; } +static int get_cursor_size( int size ) +{ + /* only certain sizes are allowed for cursors */ + if (size >= 64) return 64; + if (size >= 48) return 48; + return 32; +} + static void test_GetSystemMetrics( void) { TEXTMETRICA tmMenuFont; @@ -2760,8 +2785,8 @@ static void test_GetSystemMetrics( void) /* These don't depend on the Shell Icon Size registry value */ ok_gsm( SM_CXICON, MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI ) ); ok_gsm( SM_CYICON, MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI ) ); - /* SM_CXCURSOR */ - /* SM_CYCURSOR */ + ok_gsm( SM_CXCURSOR, get_cursor_size( MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI ))); + ok_gsm( SM_CYCURSOR, get_cursor_size( MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI ))); ok_gsm( SM_CYMENU, ncm.iMenuHeight + 1); ok_gsm( SM_CXFULLSCREEN, GetSystemMetrics( SM_CXMAXIMIZED) - 2 * GetSystemMetrics( SM_CXFRAME)); @@ -2896,7 +2921,8 @@ static void test_GetSystemMetrics( void) trace( "Captionfontchar width %d MenuFont %d,%d CaptionWidth from registry: %d screen %d,%d\n", avcwCaption, tmMenuFont.tmHeight, tmMenuFont.tmExternalLeading, CaptionWidthfromreg, screen.cx, screen.cy); } - ReleaseDC( 0, hdc); + + DeleteDC(hdc); } static void test_EnumDisplaySettings(void) diff --git a/modules/rostests/winetests/user32/text.c b/modules/rostests/winetests/user32/text.c index ce60c64b56d..3cc95715217 100755 --- a/modules/rostests/winetests/user32/text.c +++ b/modules/rostests/winetests/user32/text.c @@ -19,7 +19,14 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include + +#include "wine/test.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "winerror.h" +#include "winnls.h" #define MODIFIED(rect) (rect.left == 10 && rect.right != 100 && rect.top == 10 && rect.bottom != 100) #define EMPTY(rect) (rect.left == rect.right && rect.bottom == rect.top) diff --git a/modules/rostests/winetests/user32/uitools.c b/modules/rostests/winetests/user32/uitools.c index 05bc45c78a1..b52fe3a03ae 100644 --- a/modules/rostests/winetests/user32/uitools.c +++ b/modules/rostests/winetests/user32/uitools.c @@ -17,7 +17,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#define WINE_NO_INLINE_RECT +#include "wine/test.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" static void test_FillRect(void) { diff --git a/modules/rostests/winetests/user32/winstation.c b/modules/rostests/winetests/user32/winstation.c index 3e0fe936b52..8522825a21c 100755 --- a/modules/rostests/winetests/user32/winstation.c +++ b/modules/rostests/winetests/user32/winstation.c @@ -18,9 +18,12 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" - -#include +#include "wine/test.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "winnls.h" +#include "wine/winternl.h" static NTSTATUS (WINAPI *pNtQueryObject)(HANDLE, OBJECT_INFORMATION_CLASS, PVOID, ULONG, PULONG); diff --git a/modules/rostests/winetests/user32/wsprintf.c b/modules/rostests/winetests/user32/wsprintf.c index 694814db5f0..f0e80b2ad65 100755 --- a/modules/rostests/winetests/user32/wsprintf.c +++ b/modules/rostests/winetests/user32/wsprintf.c @@ -17,7 +17,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include + +#include "wine/test.h" +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winnls.h" static const struct {