diff --git a/apitests/ntdll/NtFreeVirtualMemory.c b/apitests/ntdll/NtFreeVirtualMemory.c
index 416e54b6e2d..075b4f41b00 100644
--- a/apitests/ntdll/NtFreeVirtualMemory.c
+++ b/apitests/ntdll/NtFreeVirtualMemory.c
@@ -15,15 +15,15 @@ static void Test_NtFreeVirtualMemory(void)
&Length,
MEM_RESERVE,
PAGE_READWRITE);
- ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed : 0x%08x\n", Status);
- ok(Length == PAGE_SIZE, "Length mismatch : 0x08x\n", Length);
+ ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed : 0x%08lx\n", Status);
+ ok(Length == PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
ok(((ULONG_PTR)Buffer % PAGE_SIZE) == 0, "The buffer is not aligned to PAGE_SIZE.\n");
Status = NtFreeVirtualMemory(NtCurrentProcess(),
&Buffer,
&Length,
MEM_DECOMMIT);
- ok(Status == STATUS_SUCCESS, "NtFreeVirtualMemory failed : 0x%08x\n", Status);
+ ok(Status == STATUS_SUCCESS, "NtFreeVirtualMemory failed : 0x%08lx\n", Status);
/* Now try to free more than we got */
Length++;
@@ -31,13 +31,13 @@ static void Test_NtFreeVirtualMemory(void)
&Buffer,
&Length,
MEM_DECOMMIT);
- ok(Status == STATUS_UNABLE_TO_FREE_VM, "NtFreeVirtualMemory returned status : 0x%08x\n", Status);
+ ok(Status == STATUS_UNABLE_TO_FREE_VM, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
Status = NtFreeVirtualMemory(NtCurrentProcess(),
&Buffer,
&Length,
MEM_RELEASE);
- ok(Status == STATUS_UNABLE_TO_FREE_VM, "NtFreeVirtualMemory returned status : 0x%08x\n", Status);
+ ok(Status == STATUS_UNABLE_TO_FREE_VM, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
/* Free out of bounds from the wrong origin */
Length = PAGE_SIZE;
@@ -47,7 +47,7 @@ static void Test_NtFreeVirtualMemory(void)
&Buffer2,
&Length,
MEM_DECOMMIT);
- ok(Status == STATUS_UNABLE_TO_FREE_VM, "NtFreeVirtualMemory returned status : 0x%08x\n", Status);
+ ok(Status == STATUS_UNABLE_TO_FREE_VM, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
Buffer2 = (PVOID)((ULONG_PTR)Buffer+1);
Length = PAGE_SIZE;
@@ -55,7 +55,7 @@ static void Test_NtFreeVirtualMemory(void)
&Buffer2,
&Length,
MEM_RELEASE);
- ok(Status == STATUS_UNABLE_TO_FREE_VM, "NtFreeVirtualMemory returned status : 0x%08x\n", Status);
+ ok(Status == STATUS_UNABLE_TO_FREE_VM, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
/* Same but in bounds */
Length = PAGE_SIZE - 1;
@@ -65,7 +65,7 @@ static void Test_NtFreeVirtualMemory(void)
&Buffer2,
&Length,
MEM_DECOMMIT);
- ok(Status == STATUS_SUCCESS, "NtFreeVirtualMemory returned status : 0x%08x\n", Status);
+ ok(Status == STATUS_SUCCESS, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
ok(Buffer2 == Buffer, "NtFreeVirtualMemory set wrong buffer.\n");
ok(Length == PAGE_SIZE, "NtFreeVirtualMemory did not round Length to PAGE_SIZE.\n");
@@ -75,7 +75,7 @@ static void Test_NtFreeVirtualMemory(void)
&Buffer2,
&Length,
MEM_RELEASE);
- ok(Status == STATUS_SUCCESS, "NtFreeVirtualMemory returned status : 0x%08x\n", Status);
+ ok(Status == STATUS_SUCCESS, "NtFreeVirtualMemory returned status : 0x%08lx\n", Status);
ok(Buffer2 == Buffer, "NtFreeVirtualMemory set wrong buffer.\n");
ok(Length == PAGE_SIZE, "NtFreeVirtualMemory did not round Length to PAGE_SIZE.\n");
@@ -87,8 +87,8 @@ static void Test_NtFreeVirtualMemory(void)
&Length,
MEM_RESERVE,
PAGE_READWRITE);
- ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed : 0x%08x\n", Status);
- ok(Length == 2*PAGE_SIZE, "Length mismatch : 0x08x\n", Length);
+ ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed : 0x%08lx\n", Status);
+ ok(Length == 2*PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
ok(((ULONG_PTR)Buffer % PAGE_SIZE) == 0, "The buffer is not aligned to PAGE_SIZE.\n");
Buffer2 = Buffer;
@@ -97,8 +97,8 @@ static void Test_NtFreeVirtualMemory(void)
&Buffer2,
&Length,
MEM_RELEASE);
- ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed : 0x%08x\n", Status);
- ok(Length == PAGE_SIZE, "Length mismatch : 0x08x\n", Length);
+ ok(NT_SUCCESS(Status), "NtFreeVirtualMemory failed : 0x%08lx\n", Status);
+ ok(Length == PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
ok(Buffer2 == Buffer, "The buffer is not aligned to PAGE_SIZE.\n");
Buffer2 = (PVOID)((ULONG_PTR)Buffer+PAGE_SIZE);
@@ -107,8 +107,8 @@ static void Test_NtFreeVirtualMemory(void)
&Buffer2,
&Length,
MEM_RELEASE);
- ok(NT_SUCCESS(Status), "NtFreeVirtualMemory failed : 0x%08x\n", Status);
- ok(Length == PAGE_SIZE, "Length mismatch : 0x08x\n", Length);
+ ok(NT_SUCCESS(Status), "NtFreeVirtualMemory failed : 0x%08lx\n", Status);
+ ok(Length == PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
ok(Buffer2 == (PVOID)((ULONG_PTR)Buffer+PAGE_SIZE), "The buffer is not aligned to PAGE_SIZE.\n");
/* Same, but try to free the second page before the first one */
@@ -119,8 +119,8 @@ static void Test_NtFreeVirtualMemory(void)
&Length,
MEM_RESERVE,
PAGE_READWRITE);
- ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed : 0x%08x\n", Status);
- ok(Length == 2*PAGE_SIZE, "Length mismatch : 0x08x\n", Length);
+ ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed : 0x%08lx\n", Status);
+ ok(Length == 2*PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
ok(((ULONG_PTR)Buffer % PAGE_SIZE) == 0, "The buffer is not aligned to PAGE_SIZE.\n");
Buffer2 = (PVOID)((ULONG_PTR)Buffer+PAGE_SIZE);
@@ -129,8 +129,8 @@ static void Test_NtFreeVirtualMemory(void)
&Buffer2,
&Length,
MEM_RELEASE);
- ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed : 0x%08x\n", Status);
- ok(Length == PAGE_SIZE, "Length mismatch : 0x08x\n", Length);
+ ok(NT_SUCCESS(Status), "NtFreeVirtualMemory failed : 0x%08lx\n", Status);
+ ok(Length == PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
ok(Buffer2 == (PVOID)((ULONG_PTR)Buffer+PAGE_SIZE), "The buffer is not aligned to PAGE_SIZE.\n");
Buffer2 = Buffer;
@@ -139,8 +139,8 @@ static void Test_NtFreeVirtualMemory(void)
&Buffer2,
&Length,
MEM_RELEASE);
- ok(NT_SUCCESS(Status), "NtFreeVirtualMemory failed : 0x%08x\n", Status);
- ok(Length == PAGE_SIZE, "Length mismatch : 0x08x\n", Length);
+ ok(NT_SUCCESS(Status), "NtFreeVirtualMemory failed : 0x%08lx\n", Status);
+ ok(Length == PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
ok(Buffer2 == Buffer, "The buffer is not aligned to PAGE_SIZE.\n");
/* Now allocate two pages and try to free them in the middle */
@@ -151,8 +151,8 @@ static void Test_NtFreeVirtualMemory(void)
&Length,
MEM_RESERVE,
PAGE_READWRITE);
- ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed : 0x%08x\n", Status);
- ok(Length == 2*PAGE_SIZE, "Length mismatch : 0x08x\n", Length);
+ ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed : 0x%08lx\n", Status);
+ ok(Length == 2*PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
ok(((ULONG_PTR)Buffer % PAGE_SIZE) == 0, "The buffer is not aligned to PAGE_SIZE.\n");
Buffer2 = (PVOID)((ULONG_PTR)Buffer+1);
@@ -161,8 +161,8 @@ static void Test_NtFreeVirtualMemory(void)
&Buffer2,
&Length,
MEM_RELEASE);
- ok(NT_SUCCESS(Status), "NtAllocateVirtualMemory failed : 0x%08x\n", Status);
- ok(Length == 2*PAGE_SIZE, "Length mismatch : 0x08x\n", Length);
+ ok(NT_SUCCESS(Status), "NtFreeVirtualMemory failed : 0x%08lx\n", Status);
+ ok(Length == 2*PAGE_SIZE, "Length mismatch : 0x%08lx\n", (ULONG)Length);
ok(Buffer2 == Buffer, "The buffer is not aligned to PAGE_SIZE.\n");
}
diff --git a/apitests/user32/WndProc.c b/apitests/user32/WndProc.c
index bc5437088fc..e9c70f1210a 100644
--- a/apitests/user32/WndProc.c
+++ b/apitests/user32/WndProc.c
@@ -32,7 +32,7 @@ static LRESULT WINAPI redraw_window_procA(HWND hwnd, UINT msg, WPARAM wparam, LP
{
PAINTSTRUCT ps;
BeginPaint(hwnd, &ps);
- EndPaint(hwnd, &ps);
+ EndPaint(hwnd, &ps);
return 1;
}
/*
@@ -43,7 +43,7 @@ static LRESULT WINAPI redraw_window_procA(HWND hwnd, UINT msg, WPARAM wparam, LP
asm ("movl $0, %eax\n\t"
"leave\n\t"
"ret");
-#else
+#elif defined(_M_IX86)
//#ifdef _MSC_VER
__asm
{
@@ -51,6 +51,8 @@ static LRESULT WINAPI redraw_window_procA(HWND hwnd, UINT msg, WPARAM wparam, LP
leave
ret
}
+#else
+ trace("unimplemented\n");
#endif
}
return DefWindowProc(hwnd, msg, wparam, lparam);
@@ -64,7 +66,7 @@ static void test_wndproc(void)
cls.style = CS_DBLCLKS;
cls.lpfnWndProc = (WNDPROC)redraw_window_procA;
cls.cbClsExtra = 0;
- cls.cbWndExtra = 0;
+ cls.cbWndExtra = 0;
cls.hInstance = GetModuleHandleA(0);
cls.hIcon = 0;
cls.hCursor = LoadCursorA(0, IDC_ARROW);
diff --git a/rosautotest/CMakeLists.txt b/rosautotest/CMakeLists.txt
index a0a4795299e..e77ec8c744f 100644
--- a/rosautotest/CMakeLists.txt
+++ b/rosautotest/CMakeLists.txt
@@ -1,5 +1,4 @@
-set_unicode()
set_cpp()
list(APPEND SOURCE
@@ -21,7 +20,7 @@ list(APPEND SOURCE
add_executable(rosautotest ${SOURCE})
-set_module_type(rosautotest win32cui)
+set_module_type(rosautotest win32cui UNICODE)
add_importlibs(rosautotest advapi32 shell32 user32 wininet msvcrt kernel32 ntdll)
add_pch(rosautotest precomp.h)
diff --git a/winetests/CMakeLists.txt b/winetests/CMakeLists.txt
index 40cffd8be17..4866549724f 100644
--- a/winetests/CMakeLists.txt
+++ b/winetests/CMakeLists.txt
@@ -75,9 +75,7 @@ add_subdirectory(quartz)
add_subdirectory(rasapi32)
add_subdirectory(riched20)
add_subdirectory(riched32)
-if(NOT MSVC)
- add_subdirectory(rpcrt4) # FIXME: msvc build.
-endif()
+add_subdirectory(rpcrt4)
add_subdirectory(rsabase)
add_subdirectory(rsaenh)
add_subdirectory(schannel)
diff --git a/winetests/advapi32/service.c b/winetests/advapi32/service.c
index aae8c6ea9b1..269ff6156af 100644
--- a/winetests/advapi32/service.c
+++ b/winetests/advapi32/service.c
@@ -32,7 +32,8 @@
#include "wine/test.h"
-static const CHAR spooler[] = "Spooler"; /* Should be available on all platforms */
+//static const CHAR spooler[] = "Spooler"; /* Should be available on all platforms */
+static const CHAR spooler[] = "Eventlog"; /* All platform except reactos :-/ */
static BOOL (WINAPI *pChangeServiceConfig2A)(SC_HANDLE,DWORD,LPVOID);
static BOOL (WINAPI *pEnumServicesStatusExA)(SC_HANDLE, SC_ENUM_TYPE, DWORD,
diff --git a/winetests/rpcrt4/CMakeLists.txt b/winetests/rpcrt4/CMakeLists.txt
index d28a9e1ea1b..75b418df0f9 100644
--- a/winetests/rpcrt4/CMakeLists.txt
+++ b/winetests/rpcrt4/CMakeLists.txt
@@ -6,8 +6,17 @@ add_definitions(
-D__ROS_LONG64__
-D_DLL -D__USE_CRTIMP)
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+if(MSVC)
+ set(IDL_FLAGS ${IDL_FLAGS} /prefix server s_ /app_config)
+else()
+ set(IDL_FLAGS ${IDL_FLAGS} --prefix-server=s_)
+endif()
+
add_rpc_files(client server.idl)
add_rpc_files(server server.idl)
+unset(IDL_FLAGS)
list(APPEND SOURCE
cstub.c
@@ -21,6 +30,11 @@ list(APPEND SOURCE
${CMAKE_CURRENT_BINARY_DIR}/server_c.c
${CMAKE_CURRENT_BINARY_DIR}/server_s.c)
+if(MSVC)
+ # The nmake generator misses this dependency, so set it explicitly until this bug is fixed.
+ set_source_files_properties(server.c PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/server_s.h)
+endif()
+
add_executable(rpcrt4_winetest ${SOURCE})
target_link_libraries(rpcrt4_winetest
uuid
diff --git a/winetests/rpcrt4/rpcrt4.rbuild b/winetests/rpcrt4/rpcrt4.rbuild
index fc366d0284e..dea00074b0e 100644
--- a/winetests/rpcrt4/rpcrt4.rbuild
+++ b/winetests/rpcrt4/rpcrt4.rbuild
@@ -12,6 +12,8 @@
.
0x0500
+
+ IServer_v0_0_s_ifspec
wine
pseh
ole32
diff --git a/winetests/rpcrt4/server.c b/winetests/rpcrt4/server.c
index 21b0cedf6ab..ccf995623ba 100644
--- a/winetests/rpcrt4/server.c
+++ b/winetests/rpcrt4/server.c
@@ -1542,12 +1542,12 @@ server(void)
if (pRpcServerRegisterIfEx)
{
trace("Using RpcServerRegisterIfEx\n");
- status = pRpcServerRegisterIfEx(IServer_v0_0_s_ifspec, NULL, NULL,
+ status = pRpcServerRegisterIfEx(s_IServer_v0_0_s_ifspec, NULL, NULL,
RPC_IF_ALLOW_CALLBACKS_WITH_NO_AUTH,
RPC_C_LISTEN_MAX_CALLS_DEFAULT, NULL);
}
else
- status = RpcServerRegisterIf(IServer_v0_0_s_ifspec, NULL, NULL);
+ status = RpcServerRegisterIf(s_IServer_v0_0_s_ifspec, NULL, NULL);
ok(status == RPC_S_OK, "RpcServerRegisterIf failed with status %d\n", status);
status = RpcServerListen(1, 20, TRUE);
ok(status == RPC_S_OK, "RpcServerListen failed with status %d\n", status);
diff --git a/winetests/shell32/CMakeLists.txt b/winetests/shell32/CMakeLists.txt
index b2ab6170b1b..0433f2a7cdf 100644
--- a/winetests/shell32/CMakeLists.txt
+++ b/winetests/shell32/CMakeLists.txt
@@ -1,6 +1,5 @@
-remove_definitions(-D_WIN32_WINNT=0x502)
-add_definitions(-D_WIN32_WINNT=0x501)
+remove_definitions(-DWINVER=0x502 -D_WIN32_IE=0x600 -D_WIN32_WINNT=0x502)
add_definitions(
-D__ROS_LONG64__
diff --git a/winetests/shell32/shlfileop.c b/winetests/shell32/shlfileop.c
index 08867c87d6c..3e9a2e49e14 100644
--- a/winetests/shell32/shlfileop.c
+++ b/winetests/shell32/shlfileop.c
@@ -2309,8 +2309,6 @@ static void test_unicode(void)
ok(!file_existsW(UNICODE_PATH), "The directory should have been removed\n");
}
-extern HRESULT WINAPI Shell_MergeMenus (HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uIDAdjust, UINT uIDAdjustMax, ULONG uFlags);
-
static void
test_shlmenu(void) {
HRESULT hres;
diff --git a/winetests/shlwapi/CMakeLists.txt b/winetests/shlwapi/CMakeLists.txt
index a2dfd8ba474..807f11a2eb8 100644
--- a/winetests/shlwapi/CMakeLists.txt
+++ b/winetests/shlwapi/CMakeLists.txt
@@ -3,6 +3,8 @@ add_definitions(
-D__ROS_LONG64__
-D_DLL -D__USE_CRTIMP)
+remove_definitions(-DWINVER=0x502 -D_WIN32_IE=0x600 -D_WIN32_WINNT=0x502)
+
list(APPEND SOURCE
assoc.c
clist.c
diff --git a/winetests/user32/broadcast.c b/winetests/user32/broadcast.c
index 48f1318a879..21d38e3cc40 100644
--- a/winetests/user32/broadcast.c
+++ b/winetests/user32/broadcast.c
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#define _WIN32_WINNT 0x0501
+//#define _WIN32_WINNT 0x0501
#include
#include
diff --git a/winetests/user32/class.c b/winetests/user32/class.c
index 7149163fbd3..f9d1aef8325 100755
--- a/winetests/user32/class.c
+++ b/winetests/user32/class.c
@@ -617,6 +617,7 @@ static void test_builtinproc(void)
static const WCHAR classW[] = {'d','e','f','t','e','s','t',0};
WCHAR unistring[] = {0x142, 0x40e, 0x3b4, 0}; /* a string that would be destroyed by a W->A->W conversion */
WNDPROC pDefWindowProcA, pDefWindowProcW;
+ WNDPROC pNtdllDefWindowProcA, pNtdllDefWindowProcW;
WNDPROC oldproc;
WNDCLASSEXA cls; /* the memory layout of WNDCLASSEXA and WNDCLASSEXW is the same */
WCHAR buf[128];
@@ -626,45 +627,56 @@ static void test_builtinproc(void)
pDefWindowProcA = (void *)GetProcAddress(GetModuleHandle("user32.dll"), "DefWindowProcA");
pDefWindowProcW = (void *)GetProcAddress(GetModuleHandle("user32.dll"), "DefWindowProcW");
+ pNtdllDefWindowProcA = (void *)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtdllDefWindowProc_A");
+ pNtdllDefWindowProcW = (void *)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtdllDefWindowProc_W");
- for (i = 0; i < 4; i++)
+ /* On Vista+, the user32.dll export DefWindowProcA/W is forwarded to */
+ /* ntdll.NtdllDefWindowProc_A/W. However, the wndproc returned by */
+ /* GetClassLong/GetWindowLong points to an unexported user32 function */
+ if (pDefWindowProcA == pNtdllDefWindowProcA &&
+ pDefWindowProcW == pNtdllDefWindowProcW)
+ skip("user32.DefWindowProcX forwarded to ntdll.NtdllDefWindowProc_X\n");
+ else
{
- ZeroMemory(&cls, sizeof(cls));
- cls.cbSize = sizeof(cls);
- cls.hInstance = GetModuleHandle(NULL);
- cls.hbrBackground = GetStockObject (WHITE_BRUSH);
- if (i & 1)
- cls.lpfnWndProc = pDefWindowProcA;
- else
- cls.lpfnWndProc = pDefWindowProcW;
-
- if (i & 2)
+ for (i = 0; i < 4; i++)
{
- cls.lpszClassName = classA;
- atom = RegisterClassExA(&cls);
+ ZeroMemory(&cls, sizeof(cls));
+ cls.cbSize = sizeof(cls);
+ cls.hInstance = GetModuleHandle(NULL);
+ cls.hbrBackground = GetStockObject (WHITE_BRUSH);
+ if (i & 1)
+ cls.lpfnWndProc = pDefWindowProcA;
+ else
+ cls.lpfnWndProc = pDefWindowProcW;
+
+ if (i & 2)
+ {
+ cls.lpszClassName = classA;
+ atom = RegisterClassExA(&cls);
+ }
+ else
+ {
+ cls.lpszClassName = (LPCSTR)classW;
+ atom = RegisterClassExW((WNDCLASSEXW *)&cls);
+ }
+ ok(atom != 0, "Couldn't register class, i=%d, %d\n", i, GetLastError());
+
+ hwnd = CreateWindowA(classA, NULL, 0, 0, 0, 100, 100, NULL, NULL, GetModuleHandle(NULL), NULL);
+ ok(hwnd != NULL, "Couldn't create window i=%d\n", i);
+
+ ok(GetWindowLongPtrA(hwnd, GWLP_WNDPROC) == (LONG_PTR)pDefWindowProcA, "Wrong ANSI wndproc: %p vs %p\n",
+ (void *)GetWindowLongPtrA(hwnd, GWLP_WNDPROC), pDefWindowProcA);
+ ok(GetClassLongPtrA(hwnd, GCLP_WNDPROC) == (ULONG_PTR)pDefWindowProcA, "Wrong ANSI wndproc: %p vs %p\n",
+ (void *)GetClassLongPtrA(hwnd, GCLP_WNDPROC), pDefWindowProcA);
+
+ ok(GetWindowLongPtrW(hwnd, GWLP_WNDPROC) == (LONG_PTR)pDefWindowProcW, "Wrong Unicode wndproc: %p vs %p\n",
+ (void *)GetWindowLongPtrW(hwnd, GWLP_WNDPROC), pDefWindowProcW);
+ ok(GetClassLongPtrW(hwnd, GCLP_WNDPROC) == (ULONG_PTR)pDefWindowProcW, "Wrong Unicode wndproc: %p vs %p\n",
+ (void *)GetClassLongPtrW(hwnd, GCLP_WNDPROC), pDefWindowProcW);
+
+ DestroyWindow(hwnd);
+ UnregisterClass((LPSTR)(DWORD_PTR)atom, GetModuleHandle(NULL));
}
- else
- {
- cls.lpszClassName = (LPCSTR)classW;
- atom = RegisterClassExW((WNDCLASSEXW *)&cls);
- }
- ok(atom != 0, "Couldn't register class, i=%d, %d\n", i, GetLastError());
-
- hwnd = CreateWindowA(classA, NULL, 0, 0, 0, 100, 100, NULL, NULL, GetModuleHandle(NULL), NULL);
- ok(hwnd != NULL, "Couldn't create window i=%d\n", i);
-
- ok(GetWindowLongPtrA(hwnd, GWLP_WNDPROC) == (LONG_PTR)pDefWindowProcA, "Wrong ANSI wndproc: %p vs %p\n",
- (void *)GetWindowLongPtrA(hwnd, GWLP_WNDPROC), pDefWindowProcA);
- ok(GetClassLongPtrA(hwnd, GCLP_WNDPROC) == (ULONG_PTR)pDefWindowProcA, "Wrong ANSI wndproc: %p vs %p\n",
- (void *)GetClassLongPtrA(hwnd, GCLP_WNDPROC), pDefWindowProcA);
-
- ok(GetWindowLongPtrW(hwnd, GWLP_WNDPROC) == (LONG_PTR)pDefWindowProcW, "Wrong Unicode wndproc: %p vs %p\n",
- (void *)GetWindowLongPtrW(hwnd, GWLP_WNDPROC), pDefWindowProcW);
- ok(GetClassLongPtrW(hwnd, GCLP_WNDPROC) == (ULONG_PTR)pDefWindowProcW, "Wrong Unicode wndproc: %p vs %p\n",
- (void *)GetClassLongPtrW(hwnd, GCLP_WNDPROC), pDefWindowProcW);
-
- DestroyWindow(hwnd);
- UnregisterClass((LPSTR)(DWORD_PTR)atom, GetModuleHandle(NULL));
}
/* built-in winproc - window A/W type automatically detected */
@@ -942,22 +954,28 @@ if (0) { /* crashes under XP */
"expected ERROR_NOACCESS, got %d\n", GetLastError());
wcx.cbSize = 0;
+ wcx.lpfnWndProc = NULL;
SetLastError(0xdeadbeef);
ret = GetClassInfoExA(0, "static", &wcx);
ok(ret, "GetClassInfoExA() error %d\n", GetLastError());
ok(wcx.cbSize == 0, "expected 0, got %u\n", wcx.cbSize);
+ ok(wcx.lpfnWndProc != NULL, "got null proc\n");
wcx.cbSize = sizeof(wcx) - 1;
+ wcx.lpfnWndProc = NULL;
SetLastError(0xdeadbeef);
ret = GetClassInfoExA(0, "static", &wcx);
ok(ret, "GetClassInfoExA() error %d\n", GetLastError());
ok(wcx.cbSize == sizeof(wcx) - 1, "expected sizeof(wcx)-1, got %u\n", wcx.cbSize);
+ ok(wcx.lpfnWndProc != NULL, "got null proc\n");
wcx.cbSize = sizeof(wcx) + 1;
+ wcx.lpfnWndProc = NULL;
SetLastError(0xdeadbeef);
ret = GetClassInfoExA(0, "static", &wcx);
ok(ret, "GetClassInfoExA() error %d\n", GetLastError());
ok(wcx.cbSize == sizeof(wcx) + 1, "expected sizeof(wcx)+1, got %u\n", wcx.cbSize);
+ ok(wcx.lpfnWndProc != NULL, "got null proc\n");
}
START_TEST(class)
diff --git a/winetests/user32/clipboard.c b/winetests/user32/clipboard.c
index a0d0fe97745..266f629aa23 100755
--- a/winetests/user32/clipboard.c
+++ b/winetests/user32/clipboard.c
@@ -68,8 +68,8 @@ static void test_ClipboardOwner(void)
ok(OpenClipboard(hWnd1), "OpenClipboard failed\n");
SetLastError(0xdeadbeef);
- ok(!OpenClipboard(hWnd2) &&
- (GetLastError() == 0xdeadbeef || GetLastError() == ERROR_ACCESS_DENIED),
+ ret = OpenClipboard(hWnd2);
+ ok(!ret && (GetLastError() == 0xdeadbeef || GetLastError() == ERROR_ACCESS_DENIED),
"OpenClipboard should fail without setting last error value, or with ERROR_ACCESS_DENIED, got error %d\n", GetLastError());
SetLastError(0xdeadbeef);
@@ -79,9 +79,9 @@ static void test_ClipboardOwner(void)
ok(GetClipboardOwner() == hWnd1, "clipboard should be owned by %p, not by %p\n", hWnd1, GetClipboardOwner());
SetLastError(0xdeadbeef);
- ok(!OpenClipboard(hWnd2) &&
- (GetLastError() == 0xdeadbeef || GetLastError() == ERROR_ACCESS_DENIED),
- "OpenClipboard should fail without setting last error valuei, or with ERROR_ACCESS_DENIED, got error %d\n", GetLastError());
+ ret = OpenClipboard(hWnd2);
+ ok(!ret && (GetLastError() == 0xdeadbeef || GetLastError() == ERROR_ACCESS_DENIED),
+ "OpenClipboard should fail without setting last error value, or with ERROR_ACCESS_DENIED, got error %d\n", GetLastError());
ret = CloseClipboard();
ok( ret, "CloseClipboard error %d\n", GetLastError());
@@ -140,6 +140,7 @@ todo_wine
atom_id = GlobalFindAtomA("my_cool_clipboard_format");
ok(atom_id == 0, "GlobalFindAtomA should fail\n");
test_last_error(ERROR_FILE_NOT_FOUND);
+ }
for (format_id = 0; format_id < 0xffff; format_id++)
{
@@ -147,18 +148,9 @@ todo_wine
len = GetClipboardFormatNameA(format_id, buf, 256);
if (format_id < 0xc000)
- {
ok(!len, "GetClipboardFormatNameA should fail, but it returned %d (%s)\n", len, buf);
- test_last_error(ERROR_INVALID_PARAMETER);
- }
else
- {
- if (len)
- trace("%04x: %s\n", format_id, len ? buf : "");
- else
- test_last_error(ERROR_INVALID_HANDLE);
- }
- }
+ if (len) trace("%04x: %s\n", format_id, len ? buf : "");
}
ret = OpenClipboard(0);
@@ -191,6 +183,9 @@ todo_wine
ok(!EmptyClipboard(), "EmptyClipboard should fail if clipboard wasn't open\n");
ok(GetLastError() == ERROR_CLIPBOARD_NOT_OPEN || broken(GetLastError() == 0xdeadbeef), /* wow64 */
"Wrong error %u\n", GetLastError());
+
+ format_id = RegisterClipboardFormatA("#1234");
+ ok(format_id == 1234, "invalid clipboard format id %04x\n", format_id);
}
static HGLOBAL create_text(void)
@@ -216,6 +211,7 @@ static void test_synthesized(void)
HENHMETAFILE emf;
BOOL r;
UINT cf;
+ HANDLE data;
htext = create_text();
emf = create_emf();
@@ -235,15 +231,21 @@ static void test_synthesized(void)
ok(r, "gle %d\n", GetLastError());
cf = EnumClipboardFormats(0);
ok(cf == CF_TEXT, "cf %08x\n", cf);
+ data = GetClipboardData(cf);
+ ok(data != NULL, "couldn't get data, cf %08x\n", cf);
cf = EnumClipboardFormats(cf);
ok(cf == CF_ENHMETAFILE, "cf %08x\n", cf);
+ data = GetClipboardData(cf);
+ ok(data != NULL, "couldn't get data, cf %08x\n", cf);
cf = EnumClipboardFormats(cf);
todo_wine ok(cf == CF_LOCALE, "cf %08x\n", cf);
if(cf == CF_LOCALE)
cf = EnumClipboardFormats(cf);
ok(cf == CF_OEMTEXT, "cf %08x\n", cf);
+ data = GetClipboardData(cf);
+ ok(data != NULL, "couldn't get data, cf %08x\n", cf);
cf = EnumClipboardFormats(cf);
ok(cf == CF_UNICODETEXT ||
@@ -253,6 +255,8 @@ static void test_synthesized(void)
if(cf == CF_UNICODETEXT)
cf = EnumClipboardFormats(cf);
ok(cf == CF_METAFILEPICT, "cf %08x\n", cf);
+ data = GetClipboardData(cf);
+ todo_wine ok(data != NULL, "couldn't get data, cf %08x\n", cf);
cf = EnumClipboardFormats(cf);
ok(cf == 0, "cf %08x\n", cf);
diff --git a/winetests/user32/combo.c b/winetests/user32/combo.c
index b7fa63f8e3d..fd852d13df7 100644
--- a/winetests/user32/combo.c
+++ b/winetests/user32/combo.c
@@ -77,7 +77,7 @@ static void test_setitemheight(DWORD style)
trace("Style %x\n", style);
GetClientRect(hCombo, &r);
- expect_rect(r, 0, 0, 100, 24);
+ expect_rect(r, 0, 0, 100, font_height(GetStockObject(SYSTEM_FONT)) + 8);
SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&r);
MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2);
todo_wine expect_rect(r, 5, 5, 105, 105);
@@ -112,11 +112,15 @@ static void test_setfont(DWORD style)
hFont2 = CreateFont(8, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, SYMBOL_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, "Marlett");
GetClientRect(hCombo, &r);
- expect_rect(r, 0, 0, 100, 24);
+ expect_rect(r, 0, 0, 100, font_height(GetStockObject(SYSTEM_FONT)) + 8);
SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&r);
MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2);
todo_wine expect_rect(r, 5, 5, 105, 105);
+ /* The size of the dropped control is initially equal to the size
+ of the window when it was created. The size of the calculated
+ dropped area changes only by how much the selection area
+ changes, not by how much the list area changes. */
if (font_height(hFont1) == 10 && font_height(hFont2) == 8)
{
SendMessage(hCombo, WM_SETFONT, (WPARAM)hFont1, FALSE);
@@ -124,21 +128,21 @@ static void test_setfont(DWORD style)
expect_rect(r, 0, 0, 100, 18);
SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&r);
MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2);
- todo_wine expect_rect(r, 5, 5, 105, 99);
+ todo_wine expect_rect(r, 5, 5, 105, 105 - (font_height(GetStockObject(SYSTEM_FONT)) - font_height(hFont1)));
SendMessage(hCombo, WM_SETFONT, (WPARAM)hFont2, FALSE);
GetClientRect(hCombo, &r);
expect_rect(r, 0, 0, 100, 16);
SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&r);
MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2);
- todo_wine expect_rect(r, 5, 5, 105, 97);
+ todo_wine expect_rect(r, 5, 5, 105, 105 - (font_height(GetStockObject(SYSTEM_FONT)) - font_height(hFont2)));
SendMessage(hCombo, WM_SETFONT, (WPARAM)hFont1, FALSE);
GetClientRect(hCombo, &r);
expect_rect(r, 0, 0, 100, 18);
SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&r);
MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2);
- todo_wine expect_rect(r, 5, 5, 105, 99);
+ todo_wine expect_rect(r, 5, 5, 105, 105 - (font_height(GetStockObject(SYSTEM_FONT)) - font_height(hFont1)));
}
else
{
diff --git a/winetests/user32/cursoricon.c b/winetests/user32/cursoricon.c
index b2e1d842aa3..2cfbc22f149 100644
--- a/winetests/user32/cursoricon.c
+++ b/winetests/user32/cursoricon.c
@@ -54,6 +54,243 @@ typedef struct
CURSORICONFILEDIRENTRY idEntries[1];
} CURSORICONFILEDIR;
+#define RIFF_FOURCC( c0, c1, c2, c3 ) \
+ ( (DWORD)(BYTE)(c0) | ( (DWORD)(BYTE)(c1) << 8 ) | \
+ ( (DWORD)(BYTE)(c2) << 16 ) | ( (DWORD)(BYTE)(c3) << 24 ) )
+
+#define ANI_RIFF_ID RIFF_FOURCC('R', 'I', 'F', 'F')
+#define ANI_LIST_ID RIFF_FOURCC('L', 'I', 'S', 'T')
+#define ANI_ACON_ID RIFF_FOURCC('A', 'C', 'O', 'N')
+#define ANI_anih_ID RIFF_FOURCC('a', 'n', 'i', 'h')
+#define ANI_seq__ID RIFF_FOURCC('s', 'e', 'q', ' ')
+#define ANI_fram_ID RIFF_FOURCC('f', 'r', 'a', 'm')
+#define ANI_icon_ID RIFF_FOURCC('i', 'c', 'o', 'n')
+#define ANI_rate_ID RIFF_FOURCC('r', 'a', 't', 'e')
+
+#define ANI_FLAG_ICON 0x1
+#define ANI_FLAG_SEQUENCE 0x2
+
+typedef struct {
+ DWORD header_size;
+ DWORD num_frames;
+ DWORD num_steps;
+ DWORD width;
+ DWORD height;
+ DWORD bpp;
+ DWORD num_planes;
+ DWORD display_rate;
+ DWORD flags;
+} ani_header;
+
+typedef struct {
+ BYTE data[32*32*4];
+} ani_data32x32x32;
+
+typedef struct {
+ CURSORICONFILEDIR icon_info; /* animated cursor frame information */
+ BITMAPINFOHEADER bmi_header; /* animated cursor frame header */
+ ani_data32x32x32 bmi_data; /* animated cursor frame DIB data */
+} ani_frame32x32x32;
+
+typedef struct {
+ DWORD chunk_id; /* ANI_anih_ID */
+ DWORD chunk_size; /* actual size of data */
+ ani_header header; /* animated cursor header */
+} riff_header_t;
+
+typedef struct {
+ DWORD chunk_id; /* ANI_LIST_ID */
+ DWORD chunk_size; /* actual size of data */
+ DWORD chunk_type; /* ANI_fram_ID */
+} riff_list_t;
+
+typedef struct {
+ DWORD chunk_id; /* ANI_icon_ID */
+ DWORD chunk_size; /* actual size of data */
+ ani_frame32x32x32 data; /* animated cursor frame */
+} riff_icon32x32x32_t;
+
+typedef struct {
+ DWORD chunk_id; /* ANI_RIFF_ID */
+ DWORD chunk_size; /* actual size of data */
+ DWORD chunk_type; /* ANI_ACON_ID */
+ riff_header_t header; /* RIFF animated cursor header */
+ riff_list_t frame_list; /* RIFF animated cursor frame list info */
+ riff_icon32x32x32_t frames[1]; /* array of animated cursor frames */
+} riff_cursor1_t;
+
+typedef struct {
+ DWORD chunk_id; /* ANI_RIFF_ID */
+ DWORD chunk_size; /* actual size of data */
+ DWORD chunk_type; /* ANI_ACON_ID */
+ riff_header_t header; /* RIFF animated cursor header */
+ riff_list_t frame_list; /* RIFF animated cursor frame list info */
+ riff_icon32x32x32_t frames[3]; /* array of three animated cursor frames */
+} riff_cursor3_t;
+
+typedef struct {
+ DWORD chunk_id; /* ANI_rate_ID */
+ DWORD chunk_size; /* actual size of data */
+ DWORD rate[3]; /* animated cursor rate data */
+} riff_rate3_t;
+
+typedef struct {
+ DWORD chunk_id; /* ANI_seq__ID */
+ DWORD chunk_size; /* actual size of data */
+ DWORD order[3]; /* animated cursor sequence data */
+} riff_seq3_t;
+
+typedef struct {
+ DWORD chunk_id; /* ANI_RIFF_ID */
+ DWORD chunk_size; /* actual size of data */
+ DWORD chunk_type; /* ANI_ACON_ID */
+ riff_header_t header; /* RIFF animated cursor header */
+ riff_seq3_t seq; /* sequence data for three cursor frames */
+ riff_rate3_t rates; /* rate data for three cursor frames */
+ riff_list_t frame_list; /* RIFF animated cursor frame list info */
+ riff_icon32x32x32_t frames[3]; /* array of three animated cursor frames */
+} riff_cursor3_seq_t;
+
+#define EMPTY_ICON32 \
+{ \
+ ANI_icon_ID, \
+ sizeof(ani_frame32x32x32), \
+ { \
+ { \
+ 0x0, /* reserved */ \
+ 0, /* type: icon(1), cursor(2) */ \
+ 1, /* count */ \
+ { \
+ { \
+ 32, /* width */ \
+ 32, /* height */ \
+ 0, /* color count */ \
+ 0x0, /* reserved */ \
+ 16, /* x hotspot */ \
+ 16, /* y hotspot */ \
+ sizeof(ani_data32x32x32), /* DIB size */ \
+ sizeof(CURSORICONFILEDIR) /* DIB offset */ \
+ } \
+ } \
+ }, \
+ { \
+ sizeof(BITMAPINFOHEADER), /* structure for DIB-type data */ \
+ 32, /* width */ \
+ 32*2, /* actual height times two */ \
+ 1, /* planes */ \
+ 32, /* bpp */ \
+ BI_RGB, /* compression */ \
+ 0, /* image size */ \
+ 0, /* biXPelsPerMeter */ \
+ 0, /* biYPelsPerMeter */ \
+ 0, /* biClrUsed */ \
+ 0 /* biClrImportant */ \
+ }, \
+ /* DIB data: left uninitialized */ \
+ } \
+}
+
+riff_cursor1_t empty_anicursor = {
+ ANI_RIFF_ID,
+ sizeof(empty_anicursor) - sizeof(DWORD)*2,
+ ANI_ACON_ID,
+ {
+ ANI_anih_ID,
+ sizeof(ani_header),
+ {
+ sizeof(ani_header),
+ 1, /* frames */
+ 1, /* steps */
+ 32, /* width */
+ 32, /* height */
+ 32, /* depth */
+ 1, /* planes */
+ 10, /* display rate in jiffies */
+ ANI_FLAG_ICON /* flags */
+ }
+ },
+ {
+ ANI_LIST_ID,
+ sizeof(riff_icon32x32x32_t)*(1 /*frames*/) + sizeof(DWORD),
+ ANI_fram_ID,
+ },
+ {
+ EMPTY_ICON32
+ }
+};
+
+riff_cursor3_t empty_anicursor3 = {
+ ANI_RIFF_ID,
+ sizeof(empty_anicursor3) - sizeof(DWORD)*2,
+ ANI_ACON_ID,
+ {
+ ANI_anih_ID,
+ sizeof(ani_header),
+ {
+ sizeof(ani_header),
+ 3, /* frames */
+ 3, /* steps */
+ 32, /* width */
+ 32, /* height */
+ 32, /* depth */
+ 1, /* planes */
+ 0xbeef, /* display rate in jiffies */
+ ANI_FLAG_ICON /* flags */
+ }
+ },
+ {
+ ANI_LIST_ID,
+ sizeof(riff_icon32x32x32_t)*(3 /*frames*/) + sizeof(DWORD),
+ ANI_fram_ID,
+ },
+ {
+ EMPTY_ICON32,
+ EMPTY_ICON32,
+ EMPTY_ICON32
+ }
+};
+
+riff_cursor3_seq_t empty_anicursor3_seq = {
+ ANI_RIFF_ID,
+ sizeof(empty_anicursor3_seq) - sizeof(DWORD)*2,
+ ANI_ACON_ID,
+ {
+ ANI_anih_ID,
+ sizeof(ani_header),
+ {
+ sizeof(ani_header),
+ 3, /* frames */
+ 3, /* steps */
+ 32, /* width */
+ 32, /* height */
+ 32, /* depth */
+ 1, /* planes */
+ 0xbeef, /* display rate in jiffies */
+ ANI_FLAG_ICON|ANI_FLAG_SEQUENCE /* flags */
+ }
+ },
+ {
+ ANI_seq__ID,
+ sizeof(riff_seq3_t) - sizeof(DWORD)*2,
+ { 2, 0, 1} /* show frames in a uniquely identifiable order */
+ },
+ {
+ ANI_rate_ID,
+ sizeof(riff_rate3_t) - sizeof(DWORD)*2,
+ { 0xc0de, 0xcafe, 0xbabe}
+ },
+ {
+ ANI_LIST_ID,
+ sizeof(riff_icon32x32x32_t)*(3 /*frames*/) + sizeof(DWORD),
+ ANI_fram_ID,
+ },
+ {
+ EMPTY_ICON32,
+ EMPTY_ICON32,
+ EMPTY_ICON32
+ }
+};
+
#include "poppack.h"
static char **test_argv;
@@ -65,6 +302,10 @@ static HANDLE child_process;
#define PROC_INIT (WM_USER+1)
static BOOL (WINAPI *pGetCursorInfo)(CURSORINFO *);
+static BOOL (WINAPI *pGetIconInfoExA)(HICON,ICONINFOEXA *);
+static BOOL (WINAPI *pGetIconInfoExW)(HICON,ICONINFOEXW *);
+
+static const int is_win64 = (sizeof(void *) > sizeof(int));
static LRESULT CALLBACK callback_child(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
@@ -78,7 +319,7 @@ static LRESULT CALLBACK callback_child(HWND hwnd, UINT msg, WPARAM wParam, LPARA
SetLastError(0xdeadbeef);
ret = DestroyCursor((HCURSOR) lParam);
error = GetLastError();
- todo_wine ok(!ret || broken(ret) /* win9x */, "DestroyCursor on the active cursor succeeded.\n");
+ ok(!ret || broken(ret) /* win9x */, "DestroyCursor on the active cursor succeeded.\n");
ok(error == ERROR_DESTROY_OBJECT_OF_OTHER_THREAD ||
error == 0xdeadbeef, /* vista */
"Last error: %u\n", error);
@@ -504,6 +745,37 @@ static void test_icon_info_dbg(HICON hIcon, UINT exp_cx, UINT exp_cy, UINT exp_b
ok_(__FILE__, line)(bmMask.bmWidth == exp_cx, "bmMask.bmWidth = %d\n", bmMask.bmWidth);
ok_(__FILE__, line)(bmMask.bmHeight == exp_cy * 2, "bmMask.bmHeight = %d\n", bmMask.bmHeight);
}
+ if (pGetIconInfoExA)
+ {
+ ICONINFOEXA infoex;
+
+ memset( &infoex, 0xcc, sizeof(infoex) );
+ SetLastError( 0xdeadbeef );
+ infoex.cbSize = sizeof(infoex) - 1;
+ ret = pGetIconInfoExA( hIcon, &infoex );
+ ok_(__FILE__, line)(!ret, "GetIconInfoEx succeeded\n");
+ ok_(__FILE__, line)(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %d\n", GetLastError());
+
+ SetLastError( 0xdeadbeef );
+ infoex.cbSize = sizeof(infoex) + 1;
+ ret = pGetIconInfoExA( hIcon, &infoex );
+ ok_(__FILE__, line)(!ret, "GetIconInfoEx succeeded\n");
+ ok_(__FILE__, line)(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %d\n", GetLastError());
+
+ SetLastError( 0xdeadbeef );
+ infoex.cbSize = sizeof(infoex);
+ ret = pGetIconInfoExA( (HICON)0xdeadbabe, &infoex );
+ ok_(__FILE__, line)(!ret, "GetIconInfoEx succeeded\n");
+ ok_(__FILE__, line)(GetLastError() == ERROR_INVALID_CURSOR_HANDLE,
+ "wrong error %d\n", GetLastError());
+
+ infoex.cbSize = sizeof(infoex);
+ ret = pGetIconInfoExA( hIcon, &infoex );
+ ok_(__FILE__, line)(ret, "GetIconInfoEx failed err %d\n", GetLastError());
+ ok_(__FILE__, line)(infoex.wResID == 0, "GetIconInfoEx wrong resid %x\n", infoex.wResID);
+ ok_(__FILE__, line)(infoex.szModName[0] == 0, "GetIconInfoEx wrong module %s\n", infoex.szModName);
+ ok_(__FILE__, line)(infoex.szResName[0] == 0, "GetIconInfoEx wrong name %s\n", infoex.szResName);
+ }
}
#define test_icon_info(a,b,c,d) test_icon_info_dbg((a),(b),(c),(d),__LINE__)
@@ -730,6 +1002,24 @@ static unsigned char gif4pixel[42] = {
0x02,0x00,0x00,0x02,0x03,0x14,0x16,0x05,0x00,0x3b
};
+static const DWORD biSize_tests[] = {
+ 0,
+ sizeof(BITMAPCOREHEADER) - 1,
+ sizeof(BITMAPCOREHEADER) + 1,
+ sizeof(BITMAPINFOHEADER) - 1,
+ sizeof(BITMAPINFOHEADER) + 1,
+ sizeof(BITMAPV4HEADER) - 1,
+ sizeof(BITMAPV4HEADER) + 1,
+ sizeof(BITMAPV5HEADER) - 1,
+ sizeof(BITMAPV5HEADER) + 1,
+ (sizeof(BITMAPCOREHEADER) + sizeof(BITMAPINFOHEADER)) / 2,
+ (sizeof(BITMAPV4HEADER) + sizeof(BITMAPV5HEADER)) / 2,
+ 0xdeadbeef,
+ 0xffffffff
+};
+
+#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
+
static void test_LoadImageBitmap(const char * test_desc, HBITMAP hbm)
{
BITMAP bm;
@@ -819,8 +1109,9 @@ static void test_LoadImage(void)
DWORD error, bytes_written;
CURSORICONFILEDIR *icon_data;
CURSORICONFILEDIRENTRY *icon_entry;
- BITMAPINFOHEADER *icon_header;
+ BITMAPINFOHEADER *icon_header, *bitmap_header;
ICONINFO icon_info;
+ int i;
#define ICON_WIDTH 32
#define ICON_HEIGHT 32
@@ -889,6 +1180,18 @@ static void test_LoadImage(void)
ok(icon_info.hbmMask != NULL, "No hbmMask!\n");
}
+ if (pGetIconInfoExA)
+ {
+ ICONINFOEXA infoex;
+ infoex.cbSize = sizeof(infoex);
+ ret = pGetIconInfoExA( handle, &infoex );
+ ok( ret, "GetIconInfoEx failed err %d\n", GetLastError() );
+ ok( infoex.wResID == 0, "GetIconInfoEx wrong resid %x\n", infoex.wResID );
+ ok( infoex.szModName[0] == 0, "GetIconInfoEx wrong module %s\n", infoex.szModName );
+ ok( infoex.szResName[0] == 0, "GetIconInfoEx wrong name %s\n", infoex.szResName );
+ }
+ else win_skip( "GetIconInfoEx not available\n" );
+
/* Clean up. */
SetLastError(0xdeadbeef);
ret = DestroyCursor(handle);
@@ -899,21 +1202,62 @@ static void test_LoadImage(void)
HeapFree(GetProcessHeap(), 0, icon_data);
DeleteFileA("icon.ico");
+ /* Test a system icon */
+ handle = LoadIcon( 0, IDI_HAND );
+ ok(handle != NULL, "LoadImage() failed.\n");
+ if (pGetIconInfoExA)
+ {
+ ICONINFOEXA infoexA;
+ ICONINFOEXW infoexW;
+ infoexA.cbSize = sizeof(infoexA);
+ ret = pGetIconInfoExA( handle, &infoexA );
+ ok( ret, "GetIconInfoEx failed err %d\n", GetLastError() );
+ ok( infoexA.wResID == (UINT_PTR)IDI_HAND, "GetIconInfoEx wrong resid %x\n", infoexA.wResID );
+ /* the A version is broken on 64-bit, it truncates the string after the first char */
+ if (is_win64 && infoexA.szModName[0] && infoexA.szModName[1] == 0)
+ trace( "GetIconInfoExA broken on Win64\n" );
+ else
+ ok( GetModuleHandleA(infoexA.szModName) == GetModuleHandleA("user32.dll"),
+ "GetIconInfoEx wrong module %s\n", infoexA.szModName );
+ ok( infoexA.szResName[0] == 0, "GetIconInfoEx wrong name %s\n", infoexA.szResName );
+ infoexW.cbSize = sizeof(infoexW);
+ ret = pGetIconInfoExW( handle, &infoexW );
+ ok( ret, "GetIconInfoEx failed err %d\n", GetLastError() );
+ ok( infoexW.wResID == (UINT_PTR)IDI_HAND, "GetIconInfoEx wrong resid %x\n", infoexW.wResID );
+ ok( GetModuleHandleW(infoexW.szModName) == GetModuleHandleA("user32.dll"),
+ "GetIconInfoEx wrong module %s\n", wine_dbgstr_w(infoexW.szModName) );
+ ok( infoexW.szResName[0] == 0, "GetIconInfoEx wrong name %s\n", wine_dbgstr_w(infoexW.szResName) );
+ }
+ SetLastError(0xdeadbeef);
+ DestroyIcon(handle);
+
test_LoadImageFile("BMP", bmpimage, sizeof(bmpimage), "bmp", 1);
test_LoadImageFile("BMP (coreinfo)", bmpcoreimage, sizeof(bmpcoreimage), "bmp", 1);
test_LoadImageFile("GIF", gifimage, sizeof(gifimage), "gif", 0);
test_LoadImageFile("GIF (2x2 pixel)", gif4pixel, sizeof(gif4pixel), "gif", 0);
test_LoadImageFile("JPG", jpgimage, sizeof(jpgimage), "jpg", 0);
test_LoadImageFile("PNG", pngimage, sizeof(pngimage), "png", 0);
+
/* Check failure for broken BMP images */
- bmpimage[0x14]++; /* biHeight > 65535 */
+ bitmap_header = (BITMAPINFOHEADER *)(bmpimage + sizeof(BITMAPFILEHEADER));
+
+ bitmap_header->biHeight = 65536;
test_LoadImageFile("BMP (too high)", bmpimage, sizeof(bmpimage), "bmp", 0);
- bmpimage[0x14]--;
- bmpimage[0x18]++; /* biWidth > 65535 */
+ bitmap_header->biHeight = 1;
+
+ bitmap_header->biWidth = 65536;
test_LoadImageFile("BMP (too wide)", bmpimage, sizeof(bmpimage), "bmp", 0);
- bmpimage[0x18]--;
+ bitmap_header->biWidth = 1;
+
+ for (i = 0; i < ARRAY_SIZE(biSize_tests); i++) {
+ bitmap_header->biSize = biSize_tests[i];
+ test_LoadImageFile("BMP (broken biSize)", bmpimage, sizeof(bmpimage), "bmp", 0);
+ }
+ bitmap_header->biSize = sizeof(BITMAPINFOHEADER);
}
+#undef ARRAY_SIZE
+
static void test_CreateIconFromResource(void)
{
HANDLE handle;
@@ -968,6 +1312,17 @@ static void test_CreateIconFromResource(void)
ok(icon_info.hbmMask != NULL, "No hbmMask!\n");
}
+ if (pGetIconInfoExA)
+ {
+ ICONINFOEXA infoex;
+ infoex.cbSize = sizeof(infoex);
+ ret = pGetIconInfoExA( handle, &infoex );
+ ok( ret, "GetIconInfoEx failed err %d\n", GetLastError() );
+ ok( infoex.wResID == 0, "GetIconInfoEx wrong resid %x\n", infoex.wResID );
+ ok( infoex.szModName[0] == 0, "GetIconInfoEx wrong module %s\n", infoex.szModName );
+ ok( infoex.szResName[0] == 0, "GetIconInfoEx wrong name %s\n", infoex.szResName );
+ }
+
/* Clean up. */
SetLastError(0xdeadbeef);
ret = DestroyCursor(handle);
@@ -1005,7 +1360,331 @@ static void test_CreateIconFromResource(void)
error = GetLastError();
ok(error == 0xdeadbeef, "Last error: %u\n", error);
+ /* Rejection of NULL pointer crashes at least on WNT4WSSP6, W2KPROSP4, WXPPROSP3
+ *
+ * handle = CreateIconFromResource(NULL, ICON_RES_SIZE, TRUE, 0x00030000);
+ * ok(handle == NULL, "Invalid pointer accepted (%p)\n", handle);
+ */
HeapFree(GetProcessHeap(), 0, hotspot);
+
+ /* Test creating an animated cursor. */
+ empty_anicursor.frames[0].data.icon_info.idType = 2; /* type: cursor */
+ empty_anicursor.frames[0].data.icon_info.idEntries[0].xHotspot = 3;
+ empty_anicursor.frames[0].data.icon_info.idEntries[0].yHotspot = 3;
+ handle = CreateIconFromResource((PBYTE) &empty_anicursor, sizeof(empty_anicursor), FALSE, 0x00030000);
+ ok(handle != NULL, "Create cursor failed.\n");
+
+ /* Test the animated cursor's information. */
+ SetLastError(0xdeadbeef);
+ ret = GetIconInfo(handle, &icon_info);
+ ok(ret, "GetIconInfo() failed.\n");
+ error = GetLastError();
+ ok(error == 0xdeadbeef, "Last error: %u\n", error);
+
+ if (ret)
+ {
+ ok(icon_info.fIcon == FALSE, "fIcon != FALSE.\n");
+ ok(icon_info.xHotspot == 3, "xHotspot is %u.\n", icon_info.xHotspot);
+ ok(icon_info.yHotspot == 3, "yHotspot is %u.\n", icon_info.yHotspot);
+ ok(icon_info.hbmColor != NULL || broken(!icon_info.hbmColor) /* no color cursor support */,
+ "No hbmColor!\n");
+ ok(icon_info.hbmMask != NULL, "No hbmMask!\n");
+ }
+
+ /* Clean up. */
+ SetLastError(0xdeadbeef);
+ ret = DestroyCursor(handle);
+ ok(ret, "DestroyCursor() failed.\n");
+ error = GetLastError();
+ ok(error == 0xdeadbeef, "Last error: %u\n", error);
+}
+
+static int check_cursor_data( HDC hdc, HCURSOR hCursor, void *data, int length)
+{
+ char *image = NULL;
+ BITMAPINFO *info;
+ ICONINFO iinfo;
+ DWORD ret;
+
+ ret = GetIconInfo( hCursor, &iinfo );
+ ok(ret, "GetIconInfo() failed\n");
+ if (!ret) return 0;
+ ret = 0;
+ info = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ));
+ ok(info != NULL, "HeapAlloc() failed\n");
+ if (!info) return 0;
+
+ info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ info->bmiHeader.biWidth = 32;
+ info->bmiHeader.biHeight = 32;
+ info->bmiHeader.biPlanes = 1;
+ info->bmiHeader.biBitCount = 32;
+ info->bmiHeader.biCompression = BI_RGB;
+ info->bmiHeader.biSizeImage = 32 * 32 * 4;
+ info->bmiHeader.biXPelsPerMeter = 0;
+ info->bmiHeader.biYPelsPerMeter = 0;
+ info->bmiHeader.biClrUsed = 0;
+ info->bmiHeader.biClrImportant = 0;
+ image = HeapAlloc( GetProcessHeap(), 0, info->bmiHeader.biSizeImage );
+ ok(image != NULL, "HeapAlloc() failed\n");
+ if (!image) goto cleanup;
+ ret = GetDIBits( hdc, iinfo.hbmColor, 0, 32, image, info, DIB_RGB_COLORS );
+ ok(ret, "GetDIBits() failed\n");
+ if (!ret) goto cleanup;
+ ret = (memcmp(image, data, length) == 0);
+ ok(ret, "Expected 0x%x, actually 0x%x (first 4 bytes only)\n", *(DWORD *)data, *(DWORD *)image);
+
+cleanup:
+ HeapFree( GetProcessHeap(), 0, image );
+ HeapFree( GetProcessHeap(), 0, info );
+ return ret;
+}
+
+static HCURSOR (WINAPI *pGetCursorFrameInfo)(HCURSOR hCursor, DWORD unk1, DWORD istep, DWORD *rate, DWORD *steps);
+static void test_GetCursorFrameInfo(void)
+{
+ DWORD frame_identifier[] = { 0x10Ad, 0xc001, 0x1c05 };
+ HBITMAP bmp = NULL, bmpOld = NULL;
+ DWORD rate, steps;
+ BITMAPINFOHEADER *icon_header;
+ BITMAPINFO bitmapInfo;
+ HDC hdc = NULL;
+ void *bits = 0;
+ INT16 *hotspot;
+ HANDLE h1, h2;
+ BOOL ret;
+ int i;
+
+ if (!pGetCursorFrameInfo)
+ {
+ win_skip( "GetCursorFrameInfo not supported, skipping tests.\n" );
+ return;
+ }
+
+ hdc = CreateCompatibleDC(0);
+ ok(hdc != 0, "CreateCompatibleDC(0) failed to return a valid DC\n");
+ if (!hdc)
+ return;
+
+ memset(&bitmapInfo, 0, sizeof(bitmapInfo));
+ bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bitmapInfo.bmiHeader.biWidth = 3;
+ bitmapInfo.bmiHeader.biHeight = 3;
+ bitmapInfo.bmiHeader.biBitCount = 32;
+ bitmapInfo.bmiHeader.biPlanes = 1;
+ bitmapInfo.bmiHeader.biCompression = BI_RGB;
+ bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
+ bmp = CreateDIBSection(hdc, &bitmapInfo, DIB_RGB_COLORS, &bits, NULL, 0);
+ ok (bmp && bits, "CreateDIBSection failed to return a valid bitmap and buffer\n");
+ if (!bmp || !bits)
+ goto cleanup;
+ bmpOld = SelectObject(hdc, bmp);
+
+#define ICON_RES_WIDTH 32
+#define ICON_RES_HEIGHT 32
+#define ICON_RES_AND_SIZE (ICON_WIDTH*ICON_HEIGHT/8)
+#define ICON_RES_BPP 32
+#define ICON_RES_SIZE \
+ (sizeof(BITMAPINFOHEADER) + ICON_AND_SIZE + ICON_AND_SIZE*ICON_BPP)
+#define CRSR_RES_SIZE (2*sizeof(INT16) + ICON_RES_SIZE)
+
+ /* Set icon data. */
+ hotspot = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, CRSR_RES_SIZE);
+
+ /* Cursor resources have an extra hotspot, icon resources not. */
+ hotspot[0] = 3;
+ hotspot[1] = 3;
+
+ icon_header = (BITMAPINFOHEADER *) (hotspot + 2);
+ icon_header->biSize = sizeof(BITMAPINFOHEADER);
+ icon_header->biWidth = ICON_WIDTH;
+ icon_header->biHeight = ICON_HEIGHT*2;
+ icon_header->biPlanes = 1;
+ icon_header->biBitCount = ICON_BPP;
+ icon_header->biSizeImage = 0; /* Uncompressed bitmap. */
+
+ /* Creating a static cursor. */
+ SetLastError(0xdeadbeef);
+ h1 = CreateIconFromResource((PBYTE) hotspot, CRSR_RES_SIZE, FALSE, 0x00030000);
+ ok(h1 != NULL, "Create cursor failed (error = %d).\n", GetLastError());
+
+ /* Check GetCursorFrameInfo behavior on a static cursor */
+ rate = steps = 0xdead;
+ h2 = pGetCursorFrameInfo(h1, 0xdead, 0xdead, &rate, &steps);
+ ok(h1 == h2, "GetCursorFrameInfo() failed: (%p != %p).\n", h1, h2);
+ ok(rate == 0, "GetCursorFrameInfo() unexpected param 4 value (0x%x != 0x0).\n", rate);
+ ok(steps == 1, "GetCursorFrameInfo() unexpected param 5 value (%d != 1).\n", steps);
+
+ /* Clean up static cursor. */
+ SetLastError(0xdeadbeef);
+ ret = DestroyCursor(h1);
+ ok(ret, "DestroyCursor() failed (error = %d).\n", GetLastError());
+
+ /* Creating a single-frame animated cursor. */
+ empty_anicursor.frames[0].data.icon_info.idType = 2; /* type: cursor */
+ empty_anicursor.frames[0].data.icon_info.idEntries[0].xHotspot = 3;
+ empty_anicursor.frames[0].data.icon_info.idEntries[0].yHotspot = 3;
+ memcpy( &empty_anicursor.frames[0].data.bmi_data.data[0], &frame_identifier[0], sizeof(DWORD) );
+ SetLastError(0xdeadbeef);
+ h1 = CreateIconFromResource((PBYTE) &empty_anicursor, sizeof(empty_anicursor), FALSE, 0x00030000);
+ ok(h1 != NULL, "Create cursor failed (error = %d).\n", GetLastError());
+
+ /* Check GetCursorFrameInfo behavior on a single-frame animated cursor */
+ rate = steps = 0xdead;
+ h2 = pGetCursorFrameInfo(h1, 0xdead, 0, &rate, &steps);
+ ok(h1 == h2, "GetCursorFrameInfo() failed: (%p != %p).\n", h1, h2);
+ ret = check_cursor_data( hdc, h2, &frame_identifier[0], sizeof(DWORD) );
+ ok(ret, "GetCursorFrameInfo() returned wrong cursor data for frame 0.\n");
+ ok(rate == 0x0, "GetCursorFrameInfo() unexpected param 4 value (0x%x != 0x0).\n", rate);
+ ok(steps == empty_anicursor.header.header.num_steps,
+ "GetCursorFrameInfo() unexpected param 5 value (%d != 1).\n", steps);
+
+ /* Clean up single-frame animated cursor. */
+ SetLastError(0xdeadbeef);
+ ret = DestroyCursor(h1);
+ ok(ret, "DestroyCursor() failed (error = %d).\n", GetLastError());
+
+ /* Creating a multi-frame animated cursor. */
+ for (i=0; i= 3)
@@ -1741,6 +2484,7 @@ START_TEST(cursoricon)
test_CreateIcon();
test_LoadImage();
test_CreateIconFromResource();
+ test_GetCursorFrameInfo();
test_DrawIcon();
test_DrawIconEx();
test_DrawState();
diff --git a/winetests/user32/dce.c b/winetests/user32/dce.c
index cfa07e51408..4aacd64a593 100755
--- a/winetests/user32/dce.c
+++ b/winetests/user32/dce.c
@@ -66,10 +66,7 @@ static void test_dc_attributes(void)
hdc = hdcs[i] = GetDCEx( hwnd_cache, 0, DCX_USESTYLE | DCX_NORESETATTRS );
if (!hdc) break;
rop = GetROP2( hdc );
- if (hdc == old_hdc)
- todo_wine ok( rop == def_rop, "wrong ROP2 %d after release %p/%p\n", rop, old_hdc, hdc );
- else
- ok( rop == def_rop, "wrong ROP2 %d after release %p/%p\n", rop, old_hdc, hdc );
+ ok( rop == def_rop, "wrong ROP2 %d after release %p/%p\n", rop, old_hdc, hdc );
if (hdc == old_hdc)
{
found_dc = 1;
@@ -104,8 +101,8 @@ static void test_dc_attributes(void)
rop = GetROP2( hdc );
if (hdc == old_hdc)
{
- todo_wine ok( rop == R2_WHITE || broken( rop == def_rop),
- "wrong ROP2 %d after release %p/%p\n", rop, old_hdc, hdc );
+ ok( rop == R2_WHITE || broken( rop == def_rop),
+ "wrong ROP2 %d after release %p/%p\n", rop, old_hdc, hdc );
SetROP2( old_hdc, def_rop );
}
else
@@ -226,7 +223,7 @@ static void test_dc_visrgn(void)
SetRectEmpty( &rect );
GetClipBox( hdc, &rect );
ok( !(rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20),
- "clip box sould have been reset %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
+ "clip box should have been reset %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
ReleaseDC( hwnd_cache, hdc );
/* window DC */
@@ -427,6 +424,87 @@ static void test_invisible_create(void)
DestroyWindow(hwnd_owndc);
}
+static void test_dc_layout(void)
+{
+ DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
+ DWORD (WINAPI *pGetLayout)(HDC hdc);
+ HWND hwnd_cache_rtl, hwnd_owndc_rtl, hwnd_classdc_rtl, hwnd_classdc2_rtl;
+ HDC hdc;
+ DWORD layout;
+ HMODULE mod = GetModuleHandleA("gdi32.dll");
+
+ pGetLayout = (void *)GetProcAddress( mod, "GetLayout" );
+ pSetLayout = (void *)GetProcAddress( mod, "SetLayout" );
+ if (!pGetLayout || !pSetLayout)
+ {
+ win_skip( "Don't have SetLayout\n" );
+ return;
+ }
+
+ hdc = GetDC( hwnd_cache );
+ pSetLayout( hdc, LAYOUT_RTL );
+ layout = pGetLayout( hdc );
+ ReleaseDC( hwnd_cache, hdc );
+ if (!layout)
+ {
+ win_skip( "SetLayout not supported\n" );
+ return;
+ }
+
+ hwnd_cache_rtl = CreateWindowExA(WS_EX_LAYOUTRTL, "cache_class", NULL, WS_OVERLAPPED | WS_VISIBLE,
+ 0, 0, 100, 100, 0, 0, GetModuleHandleA(0), NULL );
+ hwnd_owndc_rtl = CreateWindowExA(WS_EX_LAYOUTRTL, "owndc_class", NULL, WS_OVERLAPPED | WS_VISIBLE,
+ 0, 200, 100, 100, 0, 0, GetModuleHandleA(0), NULL );
+ hwnd_classdc_rtl = CreateWindowExA(WS_EX_LAYOUTRTL, "classdc_class", NULL, WS_OVERLAPPED | WS_VISIBLE,
+ 200, 0, 100, 100, 0, 0, GetModuleHandleA(0), NULL );
+ hwnd_classdc2_rtl = CreateWindowExA(WS_EX_LAYOUTRTL, "classdc_class", NULL, WS_OVERLAPPED | WS_VISIBLE,
+ 200, 200, 100, 100, 0, 0, GetModuleHandleA(0), NULL );
+ hdc = GetDC( hwnd_cache_rtl );
+ layout = pGetLayout( hdc );
+
+ ok( layout == LAYOUT_RTL, "wrong layout %x\n", layout );
+ pSetLayout( hdc, 0 );
+ ReleaseDC( hwnd_cache_rtl, hdc );
+ hdc = GetDC( hwnd_owndc_rtl );
+ layout = pGetLayout( hdc );
+ ok( layout == LAYOUT_RTL, "wrong layout %x\n", layout );
+ ReleaseDC( hwnd_cache_rtl, hdc );
+
+ hdc = GetDC( hwnd_cache );
+ layout = pGetLayout( hdc );
+ ok( layout == 0, "wrong layout %x\n", layout );
+ ReleaseDC( hwnd_cache, hdc );
+
+ hdc = GetDC( hwnd_owndc_rtl );
+ layout = pGetLayout( hdc );
+ ok( layout == LAYOUT_RTL, "wrong layout %x\n", layout );
+ pSetLayout( hdc, 0 );
+ ReleaseDC( hwnd_owndc_rtl, hdc );
+ hdc = GetDC( hwnd_owndc_rtl );
+ layout = pGetLayout( hdc );
+ ok( layout == LAYOUT_RTL, "wrong layout %x\n", layout );
+ ReleaseDC( hwnd_owndc_rtl, hdc );
+
+ hdc = GetDC( hwnd_classdc_rtl );
+ layout = pGetLayout( hdc );
+ ok( layout == LAYOUT_RTL, "wrong layout %x\n", layout );
+ pSetLayout( hdc, 0 );
+ ReleaseDC( hwnd_classdc_rtl, hdc );
+ hdc = GetDC( hwnd_classdc2_rtl );
+ layout = pGetLayout( hdc );
+ ok( layout == LAYOUT_RTL, "wrong layout %x\n", layout );
+ ReleaseDC( hwnd_classdc2_rtl, hdc );
+ hdc = GetDC( hwnd_classdc );
+ layout = pGetLayout( hdc );
+ ok( layout == LAYOUT_RTL, "wrong layout %x\n", layout );
+ ReleaseDC( hwnd_classdc_rtl, hdc );
+
+ DestroyWindow(hwnd_classdc2_rtl);
+ DestroyWindow(hwnd_classdc_rtl);
+ DestroyWindow(hwnd_owndc_rtl);
+ DestroyWindow(hwnd_cache_rtl);
+}
+
static void test_destroyed_window(void)
{
HDC dc;
@@ -483,6 +561,7 @@ START_TEST(dce)
test_dc_visrgn();
test_begin_paint();
test_invisible_create();
+ test_dc_layout();
DestroyWindow(hwnd_classdc2);
DestroyWindow(hwnd_classdc);
diff --git a/winetests/user32/dde.c b/winetests/user32/dde.c
index 529c527f2e2..e273de21379 100755
--- a/winetests/user32/dde.c
+++ b/winetests/user32/dde.c
@@ -19,7 +19,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include
#include
#include
@@ -63,17 +62,19 @@ static void flush_events(void)
static void create_dde_window(HWND *hwnd, LPCSTR name, WNDPROC wndproc)
{
WNDCLASSA wcA;
+ ATOM aclass;
memset(&wcA, 0, sizeof(wcA));
wcA.lpfnWndProc = wndproc;
wcA.lpszClassName = name;
wcA.hInstance = GetModuleHandleA(0);
- assert(RegisterClassA(&wcA));
+ aclass = RegisterClassA(&wcA);
+ ok (aclass, "RegisterClass failed\n");
*hwnd = CreateWindowExA(0, name, NULL, WS_POPUP,
500, 500, CW_USEDEFAULT, CW_USEDEFAULT,
GetDesktopWindow(), 0, GetModuleHandleA(0), NULL);
- assert(*hwnd);
+ ok(*hwnd != NULL, "CreateWindowExA failed\n");
}
static void destroy_dde_window(HWND *hwnd, LPCSTR name)
@@ -1000,7 +1001,7 @@ static LRESULT WINAPI dde_msg_client_wndproc(HWND hwnd, UINT msg, WPARAM wparam,
ok(data->fAckReq == 0, "Expected 0, got %d\n", data->fAckReq);
ok(data->cfFormat == CF_TEXT, "Expected CF_TEXT, got %d\n", data->cfFormat);
ok(!lstrcmpA((LPSTR)data->Value, "requested data\r\n"),
- "Expeted 'requested data\\r\\n', got %s\n", data->Value);
+ "Expected 'requested data\\r\\n', got %s\n", data->Value);
GlobalUnlock((HGLOBAL)lo);
size = GlobalGetAtomNameA(hi, str, MAX_PATH);
@@ -1295,7 +1296,7 @@ static LRESULT WINAPI dde_server_wndprocA(HWND hwnd, UINT msg, WPARAM wparam, LP
if (!conv_unicode)
ok( !lstrcmpA(cmd, exec_cmdA), "server A got wrong command '%s'\n", cmd );
else /* we get garbage as the A command was mapped W->A */
- ok( cmd[0] == '?', "server A got wrong command '%s'\n", cmd );
+ ok( cmd[0] != exec_cmdA[0], "server A got wrong command '%s'\n", cmd );
break;
case 2: /* ANSI command in Unicode format */
@@ -1316,7 +1317,7 @@ static LRESULT WINAPI dde_server_wndprocA(HWND hwnd, UINT msg, WPARAM wparam, LP
if (!conv_unicode)
ok( !lstrcmpA(cmd, exec_cmdWA), "server A got wrong command '%s'\n", cmd );
else /* we get garbage as the A command was mapped W->A */
- ok( cmd[0] == '?', "server A got wrong command '%s'\n", cmd );
+ ok( cmd[0] != exec_cmdWA[0], "server A got wrong command '%s'\n", cmd );
break;
}
GlobalUnlock((HGLOBAL)hi);
@@ -1430,7 +1431,7 @@ static LRESULT WINAPI dde_server_wndprocW(HWND hwnd, UINT msg, WPARAM wparam, LP
case 1: /* ANSI command */
if (conv_unicode && !client_unicode) /* W->A mapping -> garbage */
- ok( cmd[0] == '?', "server W got wrong command '%s'\n", cmd );
+ ok( cmd[0] != exec_cmdA[0], "server W got wrong command '%s'\n", cmd );
else if (!conv_unicode && client_unicode) /* A->W mapping */
ok( !lstrcmpW((LPCWSTR)cmd, exec_cmdAW), "server W got wrong command '%s'\n", cmd );
else
@@ -1457,7 +1458,7 @@ static LRESULT WINAPI dde_server_wndprocW(HWND hwnd, UINT msg, WPARAM wparam, LP
case 4: /* Unicode command in ANSI format */
if (conv_unicode && !client_unicode) /* W->A mapping -> garbage */
- ok( cmd[0] == '?', "server W got wrong command '%s'\n", cmd );
+ ok( cmd[0] != exec_cmdWA[0], "server W got wrong command '%s'\n", cmd );
else if (!conv_unicode && client_unicode) /* A->W mapping */
ok( !lstrcmpW((LPCWSTR)cmd, exec_cmdW), "server W got wrong command '%s'\n", cmd );
else
@@ -1571,6 +1572,7 @@ static void test_dde_aw_transaction( BOOL client_unicode, BOOL server_unicode )
CONVINFO info;
HDDEDATA hdata;
BOOL conv_unicode = client_unicode;
+ BOOL got;
static char test_cmd[] = "test dde command";
if (!(hwnd_server = create_dde_server( server_unicode ))) return;
@@ -1709,7 +1711,8 @@ todo_wine {
ok(err == DMLERR_NOTPROCESSED, "DdeClientTransaction returned error %x\n", err);
}
- ok(DdeDisconnect(hconv), "DdeDisconnect error %x\n", DdeGetLastError(dde_inst));
+ got = DdeDisconnect(hconv);
+ ok(got, "DdeDisconnect error %x\n", DdeGetLastError(dde_inst));
info.cb = sizeof(info);
ret = DdeQueryConvInfo(hconv, QID_SYNC, &info);
@@ -1719,7 +1722,8 @@ todo_wine {
ok(err == DMLERR_INVALIDPARAMETER, "wrong dde error %x\n", err);
}
- ok(DdeFreeStringHandle(dde_inst, hsz_server), "DdeFreeStringHandle error %x\n", DdeGetLastError(dde_inst));
+ got = DdeFreeStringHandle(dde_inst, hsz_server);
+ ok(got, "DdeFreeStringHandle error %x\n", DdeGetLastError(dde_inst));
/* This call hangs on win2k SP4 and XP SP1.
DdeUninitialize(dde_inst);*/
@@ -1757,7 +1761,7 @@ static void test_initialisation(void)
item = DdeCreateStringHandleA(client_pid, "request", CP_WINANSI);
- /* There is no converstation so an invalild parameter results */
+ /* There is no conversation so an invalid parameter results */
res = 0xdeadbeef;
DdeGetLastError(client_pid);
hdata = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_REQUEST, default_timeout, &res);
@@ -2043,12 +2047,6 @@ static void test_DdeCreateStringHandle(void)
dde_inst = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = DdeInitializeW(&dde_inst, client_ddeml_callback, APPCMD_CLIENTONLY, 0);
- if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
- {
- win_skip("DdeInitializeW is unimplemented\n");
- return;
- }
-
ok(ret == DMLERR_INVALIDPARAMETER, "DdeInitializeW should fail, but got %04x instead\n", ret);
ok(DdeGetLastError(dde_inst) == DMLERR_INVALIDPARAMETER, "expected DMLERR_INVALIDPARAMETER\n");
@@ -2493,8 +2491,6 @@ static HDDEDATA CALLBACK server_end_to_end_callback(UINT uType, UINT uFmt, HCONV
else if (unicode_client)
{
/* ASCII string mapped W->A -> garbage */
- ok(size == size_a / sizeof(WCHAR) || size == size_a / sizeof(WCHAR) + 1,
- "Wrong size %d, msg_index=%d\n", size, msg_index);
}
else
{
@@ -2536,7 +2532,8 @@ static HDDEDATA CALLBACK server_end_to_end_callback(UINT uType, UINT uFmt, HCONV
DWORD nt_size = MultiByteToWideChar( CP_ACP, 0, (char *)cmd_w, size_w, test_cmd_a_to_w,
sizeof(test_cmd_a_to_w)/sizeof(WCHAR) ) * sizeof(WCHAR);
DWORD xp_size = MultiByteToWideChar( CP_ACP, 0, (char *)cmd_w, -1, NULL, 0 ) * sizeof(WCHAR);
- ok(size == xp_size || broken(size == nt_size),
+ ok(size == xp_size || broken(size == nt_size) ||
+ broken(str_index == 4 && IsDBCSLeadByte(cmd_w[0])) /* East Asian */,
"Wrong size %d/%d, msg_index=%d\n", size, size_a_to_w, msg_index);
ok(!lstrcmpW((WCHAR*)buffer, test_cmd_a_to_w),
"Expected %s, msg_index=%d\n", wine_dbgstr_w(test_cmd_a_to_w), msg_index);
@@ -2696,6 +2693,7 @@ START_TEST(dde)
char buffer[MAX_PATH];
STARTUPINFO startup;
PROCESS_INFORMATION proc;
+ DWORD dde_inst = 0xdeadbeef;
argc = winetest_get_mainargs(&argv);
if (argc == 3)
@@ -2714,6 +2712,14 @@ START_TEST(dde)
test_initialisation();
+ SetLastError(0xdeadbeef);
+ DdeInitializeW(&dde_inst, client_ddeml_callback, APPCMD_CLIENTONLY, 0);
+ if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
+ {
+ win_skip("Skipping tests on win9x because of brokenness\n");
+ return;
+ }
+
ZeroMemory(&startup, sizeof(STARTUPINFO));
sprintf(buffer, "%s dde ddeml", argv[0]);
startup.cb = sizeof(startup);
diff --git a/winetests/user32/dialog.c b/winetests/user32/dialog.c
index 736c99d784e..8e4ffb577de 100755
--- a/winetests/user32/dialog.c
+++ b/winetests/user32/dialog.c
@@ -50,7 +50,7 @@ static HWND g_hwndTestDlg, g_hwndTestDlgBut1, g_hwndTestDlgBut2, g_hwndTestDlgEd
static HWND g_hwndInitialFocusT1, g_hwndInitialFocusT2, g_hwndInitialFocusGroupBox;
static LONG g_styleInitialFocusT1, g_styleInitialFocusT2;
-static BOOL g_bInitialFocusInitDlgResult;
+static BOOL g_bInitialFocusInitDlgResult, g_bReceivedCommand;
static int g_terminated;
@@ -209,7 +209,7 @@ static BOOL CreateWindows (HINSTANCE hinst)
/* Form the lParam of a WM_KEYDOWN message */
static DWORD KeyDownData (int repeat, int scancode, int extended, int wasdown)
{
- return ((repeat & 0x0000FFFF) | ((scancode & 0x00FF) >> 16) |
+ return ((repeat & 0x0000FFFF) | ((scancode & 0x00FF) << 16) |
(extended ? 0x01000000 : 0) | (wasdown ? 0x40000000 : 0));
}
@@ -539,6 +539,8 @@ static LRESULT CALLBACK testDlgWinProc (HWND hwnd, UINT uiMsg, WPARAM wParam,
case WM_CREATE:
return (OnTestDlgCreate (hwnd,
(LPCREATESTRUCTA) lParam) ? 0 : (LRESULT) -1);
+ case WM_COMMAND:
+ if(LOWORD(wParam) == 300) g_bReceivedCommand = TRUE;
}
return DefDlgProcA (hwnd, uiMsg, wParam, lParam);
@@ -576,6 +578,8 @@ static BOOL RegisterWindowClasses (void)
static void test_WM_NEXTDLGCTL(void)
{
+ HWND child1, child2, child3;
+ MSG msg;
DWORD dwVal;
g_hwndTestDlg = CreateWindowEx( WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR
@@ -638,7 +642,7 @@ static void test_WM_NEXTDLGCTL(void)
"Button1 style not set to BS_DEFPUSHBUTTON\n" );
ok ( !((GetWindowLong( g_hwndTestDlgBut2, GWL_STYLE)) & BS_DEFPUSHBUTTON),
- "Button2's style not chaged to BS_PUSHBUTTON\n" );
+ "Button2's style not changed to BS_PUSHBUTTON\n" );
}
/*
@@ -663,7 +667,7 @@ static void test_WM_NEXTDLGCTL(void)
"Button2 style not set to BS_DEFPUSHBUTTON\n" );
ok ( !((GetWindowLong( g_hwndTestDlgBut1, GWL_STYLE)) & BS_DEFPUSHBUTTON),
- "Button1's style not chaged to BS_PUSHBUTTON\n" );
+ "Button1's style not changed to BS_PUSHBUTTON\n" );
}
/*
@@ -678,6 +682,38 @@ static void test_WM_NEXTDLGCTL(void)
dwVal = DefDlgProcA(g_hwndTestDlg, DM_GETDEFID, 0, 0);
ok ( IDCANCEL == (LOWORD(dwVal)), "WM_NEXTDLGCTL changed default button\n");
}
+
+ /* test nested default buttons */
+
+ child1 = CreateWindowA("button", "child1", WS_VISIBLE|WS_CHILD, 0, 0, 50, 50,
+ g_hwndTestDlg, (HMENU)100, g_hinst, NULL);
+ ok(child1 != NULL, "failed to create first child\n");
+ child2 = CreateWindowA("button", "child2", WS_VISIBLE|WS_CHILD, 60, 60, 30, 30,
+ g_hwndTestDlg, (HMENU)200, g_hinst, NULL);
+ ok(child2 != NULL, "failed to create second child\n");
+ /* create nested child */
+ child3 = CreateWindowA("button", "child3", WS_VISIBLE|WS_CHILD, 10, 10, 10, 10,
+ child1, (HMENU)300, g_hinst, NULL);
+ ok(child3 != NULL, "failed to create subchild\n");
+
+ DefDlgProcA( g_hwndTestDlg, DM_SETDEFID, 200, 0);
+ dwVal = DefDlgProcA( g_hwndTestDlg, DM_GETDEFID, 0, 0);
+ ok(LOWORD(dwVal) == 200, "expected 200, got %x\n", dwVal);
+
+ DefDlgProcA( g_hwndTestDlg, DM_SETDEFID, 300, 0);
+ dwVal = DefDlgProcA( g_hwndTestDlg, DM_GETDEFID, 0, 0);
+ ok(LOWORD(dwVal) == 300, "expected 300, got %x\n", dwVal);
+ ok(SendMessageW( child3, WM_GETDLGCODE, 0, 0) != DLGC_DEFPUSHBUTTON,
+ "expected child3 not to be marked as DLGC_DEFPUSHBUTTON\n");
+
+ g_bReceivedCommand = FALSE;
+ FormEnterMsg (&msg, child3);
+ ok(IsDialogMessage (g_hwndTestDlg, &msg), "Did not handle the ENTER\n");
+ ok(g_bReceivedCommand, "Did not trigger the default Button action\n");
+
+ DestroyWindow(child3);
+ DestroyWindow(child2);
+ DestroyWindow(child1);
DestroyWindow(g_hwndTestDlg);
}
diff --git a/winetests/user32/edit.c b/winetests/user32/edit.c
index fb74143ecd2..c6c815a369c 100755
--- a/winetests/user32/edit.c
+++ b/winetests/user32/edit.c
@@ -559,6 +559,7 @@ static HWND create_editcontrol (DWORD style, DWORD exstyle)
style,
10, 10, 300, 300,
NULL, NULL, hinst, NULL);
+ ok (handle != NULL, "CreateWindow EDIT Control failed\n");
assert (handle);
if (winetest_interactive)
ShowWindow (handle, SW_SHOW);
@@ -570,12 +571,14 @@ static HWND create_child_editcontrol (DWORD style, DWORD exstyle)
HWND parentWnd;
HWND editWnd;
RECT rect;
+ BOOL b;
rect.left = 0;
rect.top = 0;
rect.right = 300;
rect.bottom = 300;
- assert(AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE));
+ b = AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
+ ok(b, "AdjustWindowRect failed\n");
parentWnd = CreateWindowEx(0,
szEditTextPositionClass,
@@ -584,6 +587,7 @@ static HWND create_child_editcontrol (DWORD style, DWORD exstyle)
CW_USEDEFAULT, CW_USEDEFAULT,
rect.right - rect.left, rect.bottom - rect.top,
NULL, NULL, hinst, NULL);
+ ok (parentWnd != NULL, "CreateWindow EDIT Test failed\n");
assert(parentWnd);
editWnd = CreateWindowEx(exstyle,
@@ -592,6 +596,7 @@ static HWND create_child_editcontrol (DWORD style, DWORD exstyle)
WS_CHILD | style,
0, 0, 300, 300,
parentWnd, NULL, hinst, NULL);
+ ok (editWnd != NULL, "CreateWindow EDIT Test Text failed\n");
assert(editWnd);
if (winetest_interactive)
ShowWindow (parentWnd, SW_SHOW);
@@ -837,10 +842,15 @@ static void test_edit_control_3(void)
{
HWND hWnd;
HWND hParent;
- int len;
+ HDC hDC;
+ int len, dpi;
static const char *str = "this is a long string.";
static const char *str2 = "this is a long string.\r\nthis is a long string.\r\nthis is a long string.\r\nthis is a long string.";
+ hDC = GetDC(NULL);
+ dpi = GetDeviceCaps(hDC, LOGPIXELSY);
+ ReleaseDC(NULL, hDC);
+
trace("EDIT: Test notifications\n");
hParent = CreateWindowExA(0,
@@ -947,7 +957,7 @@ static void test_edit_control_3(void)
"EDIT",
NULL,
ES_MULTILINE,
- 10, 10, 50, 50,
+ 10, 10, (50 * dpi) / 96, (50 * dpi) / 96,
hParent, NULL, NULL, NULL);
assert(hWnd);
@@ -992,7 +1002,7 @@ static void test_edit_control_3(void)
"EDIT",
NULL,
ES_MULTILINE | ES_AUTOHSCROLL,
- 10, 10, 50, 50,
+ 10, 10, (50 * dpi) / 96, (50 * dpi) / 96,
hParent, NULL, NULL, NULL);
assert(hWnd);
@@ -1308,9 +1318,7 @@ static void test_edit_control_limittext(void)
ok(r == 30000, "Incorrect default text limit, expected 30000 got %u\n", r);
SendMessage(hwEdit, EM_SETLIMITTEXT, 0, 0);
r = SendMessage(hwEdit, EM_GETLIMITTEXT, 0, 0);
- /* Win9x+ME: 32766; WinNT: 2147483646UL */
- ok( (r == 32766) || (r == 2147483646UL),
- "got limit %u (expected 32766 or 2147483646)\n", r);
+ ok( r == 2147483646, "got limit %u (expected 2147483646)\n", r);
DestroyWindow(hwEdit);
/* Test default limit for multi-line control */
@@ -1320,9 +1328,7 @@ static void test_edit_control_limittext(void)
ok(r == 30000, "Incorrect default text limit, expected 30000 got %u\n", r);
SendMessage(hwEdit, EM_SETLIMITTEXT, 0, 0);
r = SendMessage(hwEdit, EM_GETLIMITTEXT, 0, 0);
- /* Win9x+ME: 65535; WinNT: 4294967295UL */
- ok( (r == 65535) || (r == 4294967295UL),
- "got limit %u (expected 65535 or 4294967295)\n", r);
+ ok( r == 4294967295U, "got limit %u (expected 4294967295)\n", r);
DestroyWindow(hwEdit);
}
@@ -1527,6 +1533,7 @@ static void test_margins_font_change(void)
ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins));
SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(EC_USEFONTINFO,EC_USEFONTINFO));
+ SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins));
ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins));
@@ -1566,7 +1573,7 @@ static void test_text_position_style(DWORD style)
HDC dc;
TEXTMETRIC metrics;
INT b, bm, b2, b3;
- BOOL single_line = !(style & ES_MULTILINE);
+ BOOL xb, single_line = !(style & ES_MULTILINE);
b = GetSystemMetrics(SM_CYBORDER) + 1;
b2 = 2 * b;
@@ -1574,10 +1581,13 @@ static void test_text_position_style(DWORD style)
bm = b2 - 1;
/* Get a stock font for which we can determine the metrics */
- assert(font = GetStockObject(SYSTEM_FONT));
- assert(dc = GetDC(NULL));
+ font = GetStockObject(SYSTEM_FONT);
+ ok (font != NULL, "GetStockObjcet SYSTEM_FONT failed\n");
+ dc = GetDC(NULL);
+ ok (dc != NULL, "GetDC() failed\n");
oldFont = SelectObject(dc, font);
- assert(GetTextMetrics(dc, &metrics));
+ xb = GetTextMetrics(dc, &metrics);
+ ok (xb, "GetTextMetrics failed\n");
SelectObject(dc, oldFont);
ReleaseDC(NULL, dc);
@@ -2212,9 +2222,15 @@ static void test_fontsize(void)
{
HWND hwEdit;
HFONT hfont;
+ HDC hDC;
LOGFONT lf;
LONG r;
char szLocalString[MAXLEN];
+ int dpi;
+
+ hDC = GetDC(NULL);
+ dpi = GetDeviceCaps(hDC, LOGPIXELSY);
+ ReleaseDC(NULL, hDC);
memset(&lf,0,sizeof(LOGFONTA));
strcpy(lf.lfFaceName,"Arial");
@@ -2224,7 +2240,8 @@ static void test_fontsize(void)
trace("EDIT: Oversized font (Multi line)\n");
hwEdit= CreateWindow("EDIT", NULL, ES_MULTILINE|ES_AUTOHSCROLL,
- 0, 0, 150, 50, NULL, NULL, hinst, NULL);
+ 0, 0, (150 * dpi) / 96, (50 * dpi) / 96, NULL, NULL,
+ hinst, NULL);
SendMessage(hwEdit,WM_SETFONT,(WPARAM)hfont,0);
@@ -2435,10 +2452,14 @@ static void test_dialogmode(void)
START_TEST(edit)
{
+ BOOL b;
+
init_function_pointers();
hinst = GetModuleHandleA(NULL);
- assert(RegisterWindowClasses());
+ b = RegisterWindowClasses();
+ ok (b, "RegisterWindowClasses failed\n");
+ if (!b) return;
test_edit_control_1();
test_edit_control_2();
diff --git a/winetests/user32/generated.c b/winetests/user32/generated.c
index e7c08cf9143..c8e8b5542be 100644
--- a/winetests/user32/generated.c
+++ b/winetests/user32/generated.c
@@ -5,9 +5,9 @@
* Unit tests for data structure packing
*/
-#define WINVER 0x0501
-#define _WIN32_IE 0x0501
-#define _WIN32_WINNT 0x0501
+//#define WINVER 0x0501
+//#define _WIN32_IE 0x0501
+//#define _WIN32_WINNT 0x0501
#define WINE_NOWINSOCK
diff --git a/winetests/user32/input.c b/winetests/user32/input.c
index d81240cb384..60904afa24d 100755
--- a/winetests/user32/input.c
+++ b/winetests/user32/input.c
@@ -43,10 +43,9 @@
* if it is a problem.
*
*/
-#undef _WIN32_WINNT
-#undef _WIN32_IE
-#define _WIN32_IE 0x0500
-#define _WIN32_WINNT 0x500
+
+//#define _WIN32_WINNT 0x401
+//#define _WIN32_IE 0x0500
#include
#include
@@ -234,14 +233,15 @@ static BOOL do_test( HWND hwnd, int seqnr, const KEV td[] )
ADDTOINPUTS(td[i])
strcat(buf, getdesc[td[i]]);
if(td[i])
- expmsg[i].message = KbdMessage(td[i], &(expmsg[i].wParam), &(expmsg[i].lParam)); /* see queue_kbd_event() */
+ expmsg[i].message = KbdMessage(td[i], &(expmsg[i].wParam), &(expmsg[i].lParam));
else
expmsg[i].message = 0;
}
for( kmctr = 0; kmctr < MAXKEYEVENTS && expmsg[kmctr].message; kmctr++)
;
- assert( evtctr <= MAXKEYEVENTS );
- assert( evtctr == pSendInput(evtctr, &inputs[0], sizeof(INPUT)));
+ ok( evtctr <= MAXKEYEVENTS, "evtctr is above MAXKEYEVENTS\n" );
+ if( evtctr != pSendInput(evtctr, &inputs[0], sizeof(INPUT)))
+ ok (FALSE, "SendInput failed to send some events\n");
i = 0;
if (winetest_debug > 1)
trace("======== key stroke sequence #%d: %s =============\n",
@@ -369,6 +369,16 @@ static void test_Input_whitebox(void)
DestroyWindow(hWndTest);
}
+static inline BOOL is_keyboard_message( UINT message )
+{
+ return (message >= WM_KEYFIRST && message <= WM_KEYLAST);
+}
+
+static inline BOOL is_mouse_message( UINT message )
+{
+ return (message >= WM_MOUSEFIRST && message <= WM_MOUSELAST);
+}
+
/* try to make sure pending X events have been processed before continuing */
static void empty_message_queue(void)
{
@@ -382,6 +392,9 @@ static void empty_message_queue(void)
if (MsgWaitForMultipleObjects(0, NULL, FALSE, min_timeout, QS_ALLINPUT) == WAIT_TIMEOUT) break;
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
+ if (is_keyboard_message(msg.message) || is_mouse_message(msg.message))
+ ok(msg.time != 0, "message %#x has time set to 0\n", msg.message);
+
TranslateMessage(&msg);
DispatchMessage(&msg);
}
@@ -415,7 +428,7 @@ struct message {
LPARAM lParam; /* expected value of lParam */
};
-struct sendinput_test_s {
+static const struct sendinput_test_s {
WORD wVk;
DWORD dwFlags;
BOOL _todo_wine;
@@ -675,10 +688,10 @@ static struct message sent_messages[MAXKEYMESSAGES];
static UINT sent_messages_cnt;
/* Verify that only specified key state transitions occur */
-static void compare_and_check(int id, BYTE *ks1, BYTE *ks2, struct sendinput_test_s *test)
+static void compare_and_check(int id, BYTE *ks1, BYTE *ks2, const struct sendinput_test_s *test)
{
int i, failcount = 0;
- struct transition_s *t = test->expected_transitions;
+ const struct transition_s *t = test->expected_transitions;
UINT actual_cnt = 0;
const struct message *expected = test->expected_messages;
@@ -1140,6 +1153,8 @@ static void test_Input_unicode(void)
WNDCLASSW wclass;
HANDLE hInstance = GetModuleHandleW(NULL);
HHOOK hook;
+ HMODULE hModuleImm32;
+ BOOL (WINAPI *pImmDisableIME)(DWORD);
wclass.lpszClassName = classNameW;
wclass.style = CS_HREDRAW | CS_VREDRAW;
@@ -1155,6 +1170,16 @@ static void test_Input_unicode(void)
win_skip("Unicode functions not supported\n");
return;
}
+
+ hModuleImm32 = LoadLibrary("imm32.dll");
+ if (hModuleImm32) {
+ pImmDisableIME = (void *)GetProcAddress(hModuleImm32, "ImmDisableIME");
+ if (pImmDisableIME)
+ pImmDisableIME(0);
+ }
+ pImmDisableIME = NULL;
+ FreeLibrary(hModuleImm32);
+
/* create the test window that will receive the keystrokes */
hWndTest = CreateWindowW(wclass.lpszClassName, windowNameW,
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 100, 100,
diff --git a/winetests/user32/listbox.c b/winetests/user32/listbox.c
index 06c41d41531..1d6e8a34ed8 100644
--- a/winetests/user32/listbox.c
+++ b/winetests/user32/listbox.c
@@ -291,7 +291,7 @@ static void test_ownerdraw(void)
cls.hbrBackground = GetStockObject(WHITE_BRUSH);
cls.lpszMenuName = NULL;
cls.lpszClassName = "main_window_class";
- assert(RegisterClass(&cls));
+ ok (RegisterClass(&cls), "RegisterClass failed\n");
parent = CreateWindowEx(0, "main_window_class", NULL,
WS_POPUP | WS_VISIBLE,
@@ -840,7 +840,6 @@ static void test_listbox_LB_DIR(void)
memset(pathBuffer, 0, MAX_PATH);
driveletter = '\0';
SendMessage(hList, LB_GETTEXT, i, (LPARAM)pathBuffer);
- p = pathBuffer + strlen(pathBuffer);
if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1) {
ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
}
@@ -951,7 +950,6 @@ static void test_listbox_LB_DIR(void)
memset(pathBuffer, 0, MAX_PATH);
driveletter = '\0';
SendMessage(hList, LB_GETTEXT, i, (LPARAM)pathBuffer);
- p = pathBuffer + strlen(pathBuffer);
if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1) {
ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
} else {
@@ -987,7 +985,6 @@ static void test_listbox_LB_DIR(void)
memset(pathBuffer, 0, MAX_PATH);
driveletter = '\0';
SendMessage(hList, LB_GETTEXT, i, (LPARAM)pathBuffer);
- p = pathBuffer + strlen(pathBuffer);
ok (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1, "Element %d (%s) does not fit [-X-]\n", i, pathBuffer);
ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
}
@@ -996,8 +993,8 @@ static void test_listbox_LB_DIR(void)
DeleteFileA( "wtest1.tmp.c" );
}
-HWND g_listBox;
-HWND g_label;
+static HWND g_listBox;
+static HWND g_label;
#define ID_TEST_LABEL 1001
#define ID_TEST_LISTBOX 1002
@@ -1181,7 +1178,6 @@ static void test_listbox_dlgdir(void)
for (i = 0; i < itemCount; i++) {
memset(pathBuffer, 0, MAX_PATH);
SendMessage(g_listBox, LB_GETTEXT, i, (LPARAM)pathBuffer);
- p = pathBuffer + strlen(pathBuffer);
ok( pathBuffer[0] == '[' && pathBuffer[strlen(pathBuffer)-1] == ']',
"Element %d (%s) does not fit requested [...]\n", i, pathBuffer);
}
@@ -1321,7 +1317,6 @@ static void test_listbox_dlgdir(void)
memset(pathBuffer, 0, MAX_PATH);
driveletter = '\0';
SendMessage(g_listBox, LB_GETTEXT, i, (LPARAM)pathBuffer);
- p = pathBuffer + strlen(pathBuffer);
if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1) {
ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
} else {
diff --git a/winetests/user32/menu.c b/winetests/user32/menu.c
index deecbe8dd03..2d308c48178 100755
--- a/winetests/user32/menu.c
+++ b/winetests/user32/menu.c
@@ -19,7 +19,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#define _WIN32_WINNT 0x0501
+//#define _WIN32_WINNT 0x0501
#include
#include
@@ -169,6 +169,8 @@ static LRESULT WINAPI menu_ownerdraw_wnd_proc(HWND hwnd, UINT msg,
if( winetest_debug)
trace("WM_MEASUREITEM received data %lx size %dx%d\n",
pmis->itemData, pmis->itemWidth, pmis->itemHeight);
+ ok( !wparam, "wrong wparam %lx\n", wparam );
+ ok( pmis->CtlType == ODT_MENU, "wrong type %x\n", pmis->CtlType );
MOD_odheight = pmis->itemHeight;
pmis->itemWidth = MODsizes[pmis->itemData].cx;
pmis->itemHeight = MODsizes[pmis->itemData].cy;
@@ -197,6 +199,8 @@ static LRESULT WINAPI menu_ownerdraw_wnd_proc(HWND hwnd, UINT msg,
pdis->rcItem.right,pdis->rcItem.bottom );
SelectObject( pdis->hDC, oldpen);
}
+ ok( !wparam, "wrong wparam %lx\n", wparam );
+ ok( pdis->CtlType == ODT_MENU, "wrong type %x\n", pdis->CtlType );
/* calculate widths of some menu texts */
if( ! MOD_txtsizes[0].size.cx)
for(i = 0; MOD_txtsizes[i].text; i++) {
@@ -217,7 +221,7 @@ static LRESULT WINAPI menu_ownerdraw_wnd_proc(HWND hwnd, UINT msg,
}
if( pdis->itemData > MOD_maxid) return TRUE;
- /* store the rectangl */
+ /* store the rectangle */
MOD_rc[pdis->itemData] = pdis->rcItem;
/* calculate average character width */
GetTextExtentPoint( pdis->hDC, chrs, 52, &sz );
@@ -404,6 +408,7 @@ static void test_menu_ownerdraw(void)
int i,j,k;
BOOL ret;
HMENU hmenu;
+ MENUITEMINFO mii;
LONG leftcol;
HWND hwnd = CreateWindowEx(0, MAKEINTATOM(atomMenuCheckClass), NULL,
WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 200, 200,
@@ -425,7 +430,7 @@ static void test_menu_ownerdraw(void)
MOD_maxid = k-1;
assert( k <= sizeof(MOD_rc)/sizeof(RECT));
/* display the menu */
- ret = TrackPopupMenu( hmenu, TPM_RETURNCMD, 100,100, 0, hwnd, NULL);
+ TrackPopupMenu( hmenu, TPM_RETURNCMD, 100,100, 0, hwnd, NULL);
/* columns have a 4 pixel gap between them */
ok( MOD_rc[0].right + 4 == MOD_rc[2].left,
@@ -449,7 +454,7 @@ static void test_menu_ownerdraw(void)
leftcol= MOD_rc[0].left;
ModifyMenu( hmenu, 0, MF_BYCOMMAND| MF_OWNERDRAW| MF_SEPARATOR, 0, 0);
/* display the menu */
- ret = TrackPopupMenu( hmenu, TPM_RETURNCMD, 100,100, 0, hwnd, NULL);
+ TrackPopupMenu( hmenu, TPM_RETURNCMD, 100,100, 0, hwnd, NULL);
/* left should be 4 pixels less now */
ok( leftcol == MOD_rc[0].left + 4,
"columns should be 4 pixels to the left (actual %d).\n",
@@ -463,6 +468,18 @@ static void test_menu_ownerdraw(void)
"Height is incorrect. Got %d expected %d\n",
MOD_rc[0].bottom - MOD_rc[0].top, MOD_SIZE);
+ /* test owner-drawn callback bitmap */
+ ModifyMenu( hmenu, 1, MF_BYPOSITION | MFT_BITMAP, 1, (LPCSTR)HBMMENU_CALLBACK );
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_BITMAP | MIIM_FTYPE | MIIM_ID;
+ if (GetMenuItemInfoA( hmenu, 1, TRUE, &mii ))
+ {
+ ok( mii.fType == MFT_BITMAP, "wrong type %x\n", mii.fType );
+ ok( mii.wID == 1, "wrong id %x\n", mii.wID );
+ ok( mii.hbmpItem == HBMMENU_CALLBACK, "wrong data %p\n", mii.hbmpItem );
+ }
+ TrackPopupMenu( hmenu, TPM_RETURNCMD, 100,100, 0, hwnd, NULL);
+
/* test width/height of an ownerdraw menu bar as well */
ret = DestroyMenu(hmenu);
ok(ret, "DestroyMenu failed with error %d\n", GetLastError());
@@ -562,13 +579,15 @@ static void test_mbs_help( int ispop, int hassub, int mnuopt,
ReleaseDC( hwnd, hdc);
}
if(ispop)
- ret = TrackPopupMenu( hmenu, TPM_RETURNCMD, 100,100, 0, hwnd, NULL);
+ TrackPopupMenu( hmenu, TPM_RETURNCMD, 100,100, 0, hwnd, NULL);
else {
ret = SetMenu( hwnd, hmenu);
ok(ret, "SetMenu failed with error %d\n", GetLastError());
DrawMenuBar( hwnd);
}
ret = GetMenuItemRect( hwnd, hmenu, 0, &rc);
+ ok(ret, "GetMenuItemRect failed with error %d\n", GetLastError());
+
if (0) /* comment out menu size checks, behavior is different in almost every Windows version */
/* the tests should however succeed on win2000, XP and Wine (at least up to 1.1.15) */
/* with a variety of dpis and desktop font sizes */
@@ -660,6 +679,7 @@ static void test_menu_bmp_and_string(void)
MENUINFO mi= {sizeof(MENUINFO)};
MENUITEMINFOA mii= {sizeof(MENUITEMINFOA)};
int count, szidx, txtidx, bmpidx, hassub, mnuopt, ispop;
+ BOOL got;
if( !pGetMenuInfo)
{
@@ -681,12 +701,14 @@ static void test_menu_bmp_and_string(void)
ok( hsysmenu != NULL, "GetSystemMenu failed with error %d\n", GetLastError());
mi.fMask = MIM_STYLE;
mi.dwStyle = 0;
- ok( pGetMenuInfo( hsysmenu, &mi), "GetMenuInfo failed gle=%d\n", GetLastError());
+ got = pGetMenuInfo( hsysmenu, &mi);
+ ok( got, "GetMenuInfo failed gle=%d\n", GetLastError());
ok( MNS_CHECKORBMP == mi.dwStyle, "System Menu Style is %08x, without the bit %08x\n",
mi.dwStyle, MNS_CHECKORBMP);
mii.fMask = MIIM_BITMAP;
mii.hbmpItem = NULL;
- ok( GetMenuItemInfoA( hsysmenu, SC_CLOSE, FALSE, &mii), "GetMenuItemInfoA failed gle=%d\n", GetLastError());
+ got = GetMenuItemInfoA( hsysmenu, SC_CLOSE, FALSE, &mii);
+ ok( got, "GetMenuItemInfoA failed gle=%d\n", GetLastError());
ok( HBMMENU_POPUP_CLOSE == mii.hbmpItem, "Item info did not get the right hbitmap: got %p expected %p\n",
mii.hbmpItem, HBMMENU_POPUP_CLOSE);
@@ -954,7 +976,9 @@ static void check_menu_item_info( int line, HMENU hmenu, BOOL ansi, UINT mask, U
"wrong bmpitem %p/%p\n", info.hbmpItem, item );
ok_(__FILE__, line)( info.dwTypeData == type_data || (ULONG_PTR)info.dwTypeData == LOWORD(type_data),
"wrong type data %p/%p\n", info.dwTypeData, type_data );
- ok_(__FILE__, line)( info.cch == out_len, "wrong len %x/%x\n", info.cch, out_len );
+ ok_(__FILE__, line)( info.cch == out_len ||
+ broken(! ansi && info.cch == 2 * out_len) /* East-Asian */,
+ "wrong len %x/%x\n", info.cch, out_len );
if (expname)
{
if(ansi)
@@ -1058,7 +1082,7 @@ static void test_menu_iteminfo( void )
void *txt, *init, *empty, *string;
HBITMAP hbm = CreateBitmap(1,1,1,1,NULL);
char stringA[0x80];
- HMENU hmenu, submenu=CreateMenu();
+ HMENU hmenu, submenu;
HBITMAP dummy_hbm = (HBITMAP)(ULONG_PTR)0xdeadbeef;
do {
@@ -2031,6 +2055,7 @@ static void test_menu_input(void) {
HINSTANCE hInstance = GetModuleHandleA( NULL );
HANDLE hThread, hWnd;
DWORD tid;
+ ATOM aclass;
if (!pSendInput)
{
@@ -2048,11 +2073,14 @@ static void test_menu_input(void) {
wclass.lpszMenuName = 0;
wclass.cbClsExtra = 0;
wclass.cbWndExtra = 0;
- assert (RegisterClassA( &wclass ));
- assert (hWnd = CreateWindowA( wclass.lpszClassName, "MenuTest",
- WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0,
- 400, 200, NULL, NULL, hInstance, NULL) );
-
+ aclass = RegisterClassA( &wclass );
+ ok (aclass, "MenuTest class not created\n");
+ if (!aclass) return;
+ hWnd = CreateWindowA( wclass.lpszClassName, "MenuTest",
+ WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0,
+ 400, 200, NULL, NULL, hInstance, NULL);
+ ok (hWnd != NULL, "MenuTest window not created\n");
+ if (!hWnd) return;
/* fixed menus */
hMenus[3] = CreatePopupMenu();
AppendMenu(hMenus[3], MF_STRING, 0, "&Enabled");
@@ -2118,6 +2146,7 @@ static void test_menu_hilitemenuitem( void )
HMENU hMenu, hPopupMenu;
WNDCLASSA wclass;
HWND hWnd;
+ ATOM aclass;
wclass.lpszClassName = "HiliteMenuTestClass";
wclass.style = CS_HREDRAW | CS_VREDRAW;
@@ -2129,10 +2158,14 @@ static void test_menu_hilitemenuitem( void )
wclass.lpszMenuName = 0;
wclass.cbClsExtra = 0;
wclass.cbWndExtra = 0;
- assert (RegisterClassA( &wclass ));
- assert (hWnd = CreateWindowA( wclass.lpszClassName, "HiliteMenuTest",
- WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0,
- 400, 200, NULL, NULL, wclass.hInstance, NULL) );
+ aclass = RegisterClassA( &wclass );
+ ok (aclass, "HiliteMenuTest class could not be created\n");
+ if (!aclass) return;
+ hWnd = CreateWindowA( wclass.lpszClassName, "HiliteMenuTest",
+ WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0,
+ 400, 200, NULL, NULL, wclass.hInstance, NULL);
+ ok (hWnd != NULL, "HiliteMenuTest window could not be created\n");
+ if (!hWnd) return;
hMenu = CreateMenu();
hPopupMenu = CreatePopupMenu();
@@ -2884,7 +2917,8 @@ static void test_menu_trackpopupmenu(void)
}
/* display the menu */
/* start with an invalid menu handle */
- gle = 0xdeadbeef;
+ SetLastError(0xdeadbeef);
+
gflag_initmenupopup = gflag_entermenuloop = gflag_initmenu = 0;
ret = MyTrackPopupMenu( Ex, NULL, TPM_RETURNCMD, 100,100, hwnd, NULL);
gle = GetLastError();
@@ -2900,7 +2934,7 @@ static void test_menu_trackpopupmenu(void)
gflag_entermenuloop ? "WM_INITMENULOOP ": "",
gflag_initmenu ? "WM_INITMENU": "");
/* another one but not NULL */
- gle = 0xdeadbeef;
+ SetLastError(0xdeadbeef);
gflag_initmenupopup = gflag_entermenuloop = gflag_initmenu = 0;
ret = MyTrackPopupMenu( Ex, (HMENU)hwnd, TPM_RETURNCMD, 100,100, hwnd, NULL);
gle = GetLastError();
@@ -2915,8 +2949,22 @@ static void test_menu_trackpopupmenu(void)
gflag_initmenupopup ? " WM_INITMENUPOPUP ": " ",
gflag_entermenuloop ? "WM_INITMENULOOP ": "",
gflag_initmenu ? "WM_INITMENU": "");
+
+ /* invalid window */
+ SetLastError(0xdeadbeef);
+ gflag_initmenupopup = gflag_entermenuloop = gflag_initmenu = 0;
+ ret = MyTrackPopupMenu( Ex, hmenu, TPM_RETURNCMD, 100,100, 0, NULL);
+ gle = GetLastError();
+ ok( !ret, "TrackPopupMenu%s should have failed\n", Ex ? "Ex" : "");
+ ok( gle == ERROR_INVALID_WINDOW_HANDLE, "TrackPopupMenu%s error got %u\n", Ex ? "Ex" : "", gle );
+ ok( !(gflag_initmenupopup || gflag_entermenuloop || gflag_initmenu),
+ "got unexpected message(s)%s%s%s\n",
+ gflag_initmenupopup ? " WM_INITMENUPOPUP ": " ",
+ gflag_entermenuloop ? "WM_INITMENULOOP ": "",
+ gflag_initmenu ? "WM_INITMENU": "");
+
/* now a somewhat successful call */
- gle = 0xdeadbeef;
+ SetLastError(0xdeadbeef);
gflag_initmenupopup = gflag_entermenuloop = gflag_initmenu = 0;
ret = MyTrackPopupMenu( Ex, hmenu, TPM_RETURNCMD, 100,100, hwnd, NULL);
gle = GetLastError();
@@ -2934,7 +2982,7 @@ static void test_menu_trackpopupmenu(void)
/* and another */
ret = AppendMenuA( hmenu, MF_STRING, 1, "winetest");
ok( ret, "AppendMenA has failed!\n");
- gle = 0xdeadbeef;
+ SetLastError(0xdeadbeef);
gflag_initmenupopup = gflag_entermenuloop = gflag_initmenu = 0;
ret = MyTrackPopupMenu( Ex, hmenu, TPM_RETURNCMD, 100,100, hwnd, NULL);
gle = GetLastError();
@@ -3055,21 +3103,21 @@ static void test_menu_cancelmode(void)
{MSG msg; while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);}
/* test the effect of sending a WM_CANCELMODE message in the WM_INITMENULOOP
* handler of the menu owner */
- /* test results is exctracted from variable g_got_enteridle. Possible values:
+ /* test results is extracted from variable g_got_enteridle. Possible values:
* 0 : complete conformance. Sending WM_CANCELMODE cancels a menu initializing tracking
* 1 : Sending WM_CANCELMODE cancels a menu that is in tracking state
* 2 : Sending WM_CANCELMODE does not work
*/
/* menu owner is top level window */
g_hwndtosend = hwnd;
- ret = TrackPopupMenu( menu, TPM_RETURNCMD, 100,100, 0, hwnd, NULL);
+ TrackPopupMenu( menu, TPM_RETURNCMD, 100,100, 0, hwnd, NULL);
todo_wine {
ok( g_got_enteridle == 0, "received %d WM_ENTERIDLE messages, none expected\n", g_got_enteridle);
}
ok( g_got_enteridle < 2, "received %d WM_ENTERIDLE messages, should be less than 2\n", g_got_enteridle);
/* menu owner is child window */
g_hwndtosend = hwndchild;
- ret = TrackPopupMenu( menu, TPM_RETURNCMD, 100,100, 0, hwndchild, NULL);
+ TrackPopupMenu( menu, TPM_RETURNCMD, 100,100, 0, hwndchild, NULL);
todo_wine {
ok(g_got_enteridle == 0, "received %d WM_ENTERIDLE messages, none expected\n", g_got_enteridle);
}
@@ -3077,7 +3125,7 @@ static void test_menu_cancelmode(void)
/* now send the WM_CANCELMODE messages to the WRONG window */
/* those should fail ( to have any effect) */
g_hwndtosend = hwnd;
- ret = TrackPopupMenu( menu, TPM_RETURNCMD, 100,100, 0, hwndchild, NULL);
+ TrackPopupMenu( menu, TPM_RETURNCMD, 100,100, 0, hwndchild, NULL);
ok( g_got_enteridle == 2, "received %d WM_ENTERIDLE messages, should be 2\n", g_got_enteridle);
/* cleanup */
DestroyMenu( menu);
@@ -3177,6 +3225,7 @@ static void test_menualign(void)
if( pGetMenuInfo) {
mi.fMask = MIM_STYLE;
ret = pGetMenuInfo( menu, &mi);
+ ok( ret, "GetMenuInfo failed: %d\n", GetLastError());
ok( menu != NULL, "GetMenuInfo() failed\n");
ok( 0 == mi.dwStyle, "menuinfo style is %x\n", mi.dwStyle);
}
diff --git a/winetests/user32/monitor.c b/winetests/user32/monitor.c
index daa303585bd..e31019f6708 100644
--- a/winetests/user32/monitor.c
+++ b/winetests/user32/monitor.c
@@ -267,6 +267,14 @@ static void test_ChangeDisplaySettingsEx(void)
ok(ClipCursor(&r1), "ClipCursor() failed\n");
ok(GetClipCursor(&r), "GetClipCursor() failed\n");
ok(EqualRect(&r, &r1), "Invalid clip rect: (%d %d) x (%d %d)\n", r.left, r.top, r.right, r.bottom);
+ SetRect(&r1, 10, 10, 10, 10);
+ ok(ClipCursor(&r1), "ClipCursor() failed\n");
+ ok(GetClipCursor(&r), "GetClipCursor() failed\n");
+ ok(EqualRect(&r, &r1), "Invalid clip rect: (%d %d) x (%d %d)\n", r.left, r.top, r.right, r.bottom);
+ SetRect(&r1, 10, 10, 10, 9);
+ ok(!ClipCursor(&r1), "ClipCursor() succeeded\n");
+ /* Windows bug: further clipping fails once an empty rect is set, so we have to reset it */
+ ClipCursor(NULL);
SetRect(&r1, virt.left - 10, virt.top - 10, virt.right + 20, virt.bottom + 20);
ok(ClipCursor(&r1), "ClipCursor() failed\n");
diff --git a/winetests/user32/msg.c b/winetests/user32/msg.c
index e0494ef2a06..cdb8206e0f7 100755
--- a/winetests/user32/msg.c
+++ b/winetests/user32/msg.c
@@ -20,8 +20,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#define _WIN32_WINNT 0x0600 /* For WM_CHANGEUISTATE,QS_RAWINPUT,WM_DWMxxxx */
-#define WINVER 0x0600 /* for WM_GETTITLEBARINFOEX */
+//#define _WIN32_WINNT 0x0600 /* For WM_CHANGEUISTATE,QS_RAWINPUT,WM_DWMxxxx */
+//#define WINVER 0x0600 /* for WM_GETTITLEBARINFOEX */
#include
#include
@@ -79,6 +79,7 @@ typedef struct
static BOOL test_DestroyWindow_flag;
static HWINEVENTHOOK hEvent_hook;
+static HHOOK hKBD_hook;
static HHOOK hCBT_hook;
static DWORD cbt_hook_thread_id;
@@ -105,7 +106,8 @@ typedef enum {
beginpaint=0x40,
optional=0x80,
hook=0x100,
- winevent_hook=0x200
+ winevent_hook=0x200,
+ kbd_hook=0x400
} msg_flags_t;
struct message {
@@ -293,7 +295,7 @@ static const struct message WmSwitchChild[] = {
{ WM_NCACTIVATE, sent|wparam|defwinproc, 0 }, /* in the 2nd MDI child */
{ WM_MDIACTIVATE, sent|defwinproc }, /* in the 2nd MDI child */
{ HCBT_MINMAX, hook|lparam, 0, SW_MAXIMIZE },
- /* Preparing for maximize and maximaze the 1st MDI child */
+ /* Preparing for maximize and maximize the 1st MDI child */
{ WM_GETMINMAXINFO, sent|defwinproc }, /* in the 1st MDI child */
{ WM_WINDOWPOSCHANGING, sent|wparam|defwinproc, SWP_FRAMECHANGED|SWP_STATECHANGED }, /* in the 1st MDI child */
{ WM_NCCALCSIZE, sent|wparam|defwinproc, 1 }, /* in the 1st MDI child */
@@ -1717,6 +1719,8 @@ static BOOL (WINAPI *pSetMenuInfo)(HMENU,LPCMENUINFO);
static HWINEVENTHOOK (WINAPI *pSetWinEventHook)(DWORD, DWORD, HMODULE, WINEVENTPROC, DWORD, DWORD, DWORD);
static BOOL (WINAPI *pTrackMouseEvent)(TRACKMOUSEEVENT*);
static BOOL (WINAPI *pUnhookWinEvent)(HWINEVENTHOOK);
+static BOOL (WINAPI *pGetMonitorInfoA)(HMONITOR,LPMONITORINFO);
+static HMONITOR (WINAPI *pMonitorFromPoint)(POINT,DWORD);
/* kernel32 functions */
static BOOL (WINAPI *pGetCPInfoExA)(UINT, DWORD, LPCPINFOEXA);
@@ -1738,6 +1742,8 @@ static void init_procs(void)
GET_PROC(user32, SetWinEventHook)
GET_PROC(user32, TrackMouseEvent)
GET_PROC(user32, UnhookWinEvent)
+ GET_PROC(user32, GetMonitorInfoA)
+ GET_PROC(user32, MonitorFromPoint)
GET_PROC(kernel32, GetCPInfoExA)
@@ -1940,6 +1946,11 @@ static void dump_sequence(const struct message *expected, const char *context, c
trace_(file, line)( " %u: expected: winevent %04x - actual: %s\n",
count, expected->message, actual->output );
}
+ else if (expected->flags & kbd_hook)
+ {
+ trace_(file, line)( " %u: expected: kbd %04x - actual: %s\n",
+ count, expected->message, actual->output );
+ }
else
{
trace_(file, line)( " %u: expected: msg %04x - actual: %s\n",
@@ -2014,7 +2025,8 @@ static void ok_sequence_(const struct message *expected_list, const char *contex
while (expected->message && actual->message)
{
- if (expected->message == actual->message)
+ if (expected->message == actual->message &&
+ !((expected->flags ^ actual->flags) & (hook|winevent_hook|kbd_hook)))
{
if (expected->flags & wparam)
{
@@ -2108,13 +2120,19 @@ static void ok_sequence_(const struct message *expected_list, const char *contex
context, count, expected->message);
if ((expected->flags & winevent_hook) != (actual->flags & winevent_hook)) dump++;
+ ok_( file, line) ((expected->flags & kbd_hook) == (actual->flags & kbd_hook),
+ "%s: %u: the msg 0x%04x should have been sent by a keyboard hook\n",
+ context, count, expected->message);
+ if ((expected->flags & kbd_hook) != (actual->flags & kbd_hook)) dump++;
+
expected++;
actual++;
}
/* silently drop hook messages if there is no support for them */
else if ((expected->flags & optional) ||
((expected->flags & hook) && !hCBT_hook) ||
- ((expected->flags & winevent_hook) && !hEvent_hook))
+ ((expected->flags & winevent_hook) && !hEvent_hook) ||
+ ((expected->flags & kbd_hook) && !hKBD_hook))
expected++;
else if (todo)
{
@@ -3363,7 +3381,7 @@ static void test_mdi_messages(void)
RECT rc;
HMENU hMenu = CreateMenu();
- assert(mdi_RegisterWindowClasses());
+ if (!mdi_RegisterWindowClasses()) assert(0);
flush_sequence();
@@ -6157,6 +6175,16 @@ static void test_paint_messages(void)
flush_events();
ok_sequence( WmEmptySeq, "WmEmptySeq", FALSE );
+ trace("testing UpdateWindow(NULL)\n");
+ SetLastError(0xdeadbeef);
+ ok(!UpdateWindow(NULL), "UpdateWindow(NULL) should fail\n");
+ ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE ||
+ broken( GetLastError() == 0xdeadbeef ) /* win9x */,
+ "wrong error code %d\n", GetLastError());
+ check_update_rgn( hwnd, 0 );
+ flush_events();
+ ok_sequence( WmEmptySeq, "WmEmptySeq", FALSE );
+
/* now with frame */
SetRectRgn( hrgn, -5, -5, 20, 20 );
@@ -6701,7 +6729,7 @@ static void test_interthread_messages(void)
CloseHandle(wnd_event.start_event);
SetLastError(0xdeadbeef);
- ok(!DestroyWindow(wnd_event.hwnd), "DestroyWindow succeded\n");
+ ok(!DestroyWindow(wnd_event.hwnd), "DestroyWindow succeeded\n");
ok(GetLastError() == ERROR_ACCESS_DENIED || GetLastError() == 0xdeadbeef,
"wrong error code %d\n", GetLastError());
@@ -6723,7 +6751,7 @@ static void test_interthread_messages(void)
SetLastError(0xdeadbeef);
len = DispatchMessageA(&msg);
ok((!len && GetLastError() == ERROR_MESSAGE_SYNC_ONLY) || broken(len), /* nt4 */
- "DispatchMessageA(WM_GETTEXT) succeded on another thread window: ret %d, error %d\n", len, GetLastError());
+ "DispatchMessageA(WM_GETTEXT) succeeded on another thread window: ret %d, error %d\n", len, GetLastError());
/* the following test causes an exception in user.exe under win9x */
msg.hwnd = wnd_event.hwnd;
@@ -7686,6 +7714,49 @@ static LRESULT WINAPI PaintLoopProcA(HWND hWnd, UINT msg, WPARAM wParam, LPARAM
return DefWindowProcA(hWnd,msg,wParam,lParam);
}
+static LRESULT WINAPI HotkeyMsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ static LONG defwndproc_counter = 0;
+ LRESULT ret;
+ struct recvd_message msg;
+ DWORD queue_status;
+
+ if (ignore_message( message )) return 0;
+
+ if ((message >= WM_KEYFIRST && message <= WM_KEYLAST) ||
+ message == WM_HOTKEY || message >= WM_APP)
+ {
+ 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 = "HotkeyMsgCheckProcA";
+ add_message(&msg);
+ }
+
+ defwndproc_counter++;
+ ret = DefWindowProcA(hwnd, message, wParam, lParam);
+ defwndproc_counter--;
+
+ if (message == WM_APP)
+ {
+ queue_status = GetQueueStatus(QS_HOTKEY);
+ ok((queue_status & (QS_HOTKEY << 16)) == QS_HOTKEY << 16, "expected QS_HOTKEY << 16 set, got %x\n", queue_status);
+ queue_status = GetQueueStatus(QS_POSTMESSAGE);
+ ok((queue_status & (QS_POSTMESSAGE << 16)) == QS_POSTMESSAGE << 16, "expected QS_POSTMESSAGE << 16 set, got %x\n", queue_status);
+ PostMessageA(hwnd, WM_APP+1, 0, 0);
+ }
+ else if (message == WM_APP+1)
+ {
+ queue_status = GetQueueStatus(QS_HOTKEY);
+ ok((queue_status & (QS_HOTKEY << 16)) == 0, "expected QS_HOTKEY << 16 cleared, got %x\n", queue_status);
+ }
+
+ return ret;
+}
+
static BOOL RegisterWindowClasses(void)
{
WNDCLASSA cls;
@@ -7703,6 +7774,10 @@ static BOOL RegisterWindowClasses(void)
cls.lpszClassName = "TestWindowClass";
if(!RegisterClassA(&cls)) return FALSE;
+ cls.lpfnWndProc = HotkeyMsgCheckProcA;
+ cls.lpszClassName = "HotkeyWindowClass";
+ if(!RegisterClassA(&cls)) return FALSE;
+
cls.lpfnWndProc = ShowWindowProcA;
cls.lpszClassName = "ShowWindowClass";
if(!RegisterClassA(&cls)) return FALSE;
@@ -10012,6 +10087,50 @@ done:
flush_events();
}
+static INT_PTR CALLBACK wm_quit_dlg_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
+{
+ struct recvd_message msg;
+
+ if (ignore_message( message )) return 0;
+
+ msg.hwnd = hwnd;
+ msg.message = message;
+ msg.flags = sent|wparam|lparam;
+ msg.wParam = wp;
+ msg.lParam = lp;
+ msg.descr = "dialog";
+ add_message(&msg);
+
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ PostMessage(hwnd, WM_QUIT, 0x1234, 0x5678);
+ PostMessage(hwnd, WM_USER, 0xdead, 0xbeef);
+ return 0;
+
+ case WM_GETDLGCODE:
+ return 0;
+
+ case WM_USER:
+ EndDialog(hwnd, 0);
+ break;
+ }
+
+ return 1;
+}
+
+static const struct message WmQuitDialogSeq[] = {
+ { HCBT_CREATEWND, hook },
+ { WM_SETFONT, sent },
+ { WM_INITDIALOG, sent },
+ { WM_CHANGEUISTATE, sent|optional },
+ { HCBT_DESTROYWND, hook },
+ { 0x0090, sent|optional }, /* Vista */
+ { WM_DESTROY, sent },
+ { WM_NCDESTROY, sent },
+ { 0 }
+};
+
static void test_quit_message(void)
{
MSG msg;
@@ -10062,6 +10181,18 @@ static void test_quit_message(void)
ret = GetMessage(&msg, NULL, 0, 0);
ok(ret > 0, "GetMessage failed with error %d\n", GetLastError());
ok(msg.message == WM_USER, "Received message 0x%04x instead of WM_USER\n", msg.message);
+
+ flush_events();
+ flush_sequence();
+ ret = DialogBoxParam(GetModuleHandle(0), "TEST_EMPTY_DIALOG", 0, wm_quit_dlg_proc, 0);
+ ok(ret == 1, "expected 1, got %d\n", ret);
+ ok_sequence(WmQuitDialogSeq, "WmQuitDialogSeq", FALSE);
+ memset(&msg, 0xab, sizeof(msg));
+ ret = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
+ ok(ret, "PeekMessage failed\n");
+ ok(msg.message == WM_QUIT, "Received message 0x%04x instead of WM_QUIT\n", msg.message);
+ ok(msg.wParam == 0x1234, "wParam was 0x%lx instead of 0x1234\n", msg.wParam);
+ ok(msg.lParam == 0, "lParam was 0x%lx instead of 0\n", msg.lParam);
}
static const struct message WmMouseHoverSeq[] = {
@@ -10631,71 +10762,132 @@ static void test_ShowWindow(void)
LPARAM ret; /* ShowWindow return value */
DWORD style; /* window style after the command */
const struct message *msg; /* message sequence the command produces */
+ INT wp_cmd, wp_flags; /* window placement after the command */
+ POINT wp_min, wp_max; /* window placement after the command */
BOOL todo_msg; /* message sequence doesn't match what Wine does */
} sw[] =
{
-/* 1 */ { SW_SHOWNORMAL, FALSE, WS_VISIBLE, WmShowNormal, FALSE },
-/* 2 */ { SW_SHOWNORMAL, TRUE, WS_VISIBLE, WmEmptySeq, FALSE },
-/* 3 */ { SW_HIDE, TRUE, 0, WmHide_1, FALSE },
-/* 4 */ { SW_HIDE, FALSE, 0, WmEmptySeq, FALSE },
-/* 5 */ { SW_SHOWMINIMIZED, FALSE, WS_VISIBLE|WS_MINIMIZE, WmShowMinimized_1, FALSE },
-/* 6 */ { SW_SHOWMINIMIZED, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinMax_1, FALSE },
-/* 7 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_1, FALSE },
-/* 8 */ { SW_HIDE, FALSE, WS_MINIMIZE, WmEmptySeq, FALSE },
-/* 9 */ { SW_SHOWMAXIMIZED, FALSE, WS_VISIBLE|WS_MAXIMIZE, WmShowMaximized_1, FALSE },
-/* 10 */ { SW_SHOWMAXIMIZED, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmMinMax_2, FALSE },
-/* 11 */ { SW_HIDE, TRUE, WS_MAXIMIZE, WmHide_1, FALSE },
-/* 12 */ { SW_HIDE, FALSE, WS_MAXIMIZE, WmEmptySeq, FALSE },
-/* 13 */ { SW_SHOWNOACTIVATE, FALSE, WS_VISIBLE, WmShowNoActivate_1, FALSE },
-/* 14 */ { SW_SHOWNOACTIVATE, TRUE, WS_VISIBLE, WmEmptySeq, FALSE },
-/* 15 */ { SW_HIDE, TRUE, 0, WmHide_2, FALSE },
-/* 16 */ { SW_HIDE, FALSE, 0, WmEmptySeq, FALSE },
-/* 17 */ { SW_SHOW, FALSE, WS_VISIBLE, WmShow, FALSE },
-/* 18 */ { SW_SHOW, TRUE, WS_VISIBLE, WmEmptySeq, FALSE },
-/* 19 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinimize_1, FALSE },
-/* 20 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinMax_3, FALSE },
-/* 21 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_2, FALSE },
-/* 22 */ { SW_SHOWMINNOACTIVE, FALSE, WS_VISIBLE|WS_MINIMIZE, WmShowMinNoActivate, TRUE },
-/* 23 */ { SW_SHOWMINNOACTIVE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinMax_4, FALSE },
-/* 24 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_2, FALSE },
-/* 25 */ { SW_HIDE, FALSE, WS_MINIMIZE, WmEmptySeq, FALSE },
-/* 26 */ { SW_SHOWNA, FALSE, WS_VISIBLE|WS_MINIMIZE, WmShowNA_1, FALSE },
-/* 27 */ { SW_SHOWNA, TRUE, WS_VISIBLE|WS_MINIMIZE, WmShowNA_2, FALSE },
-/* 28 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_2, FALSE },
-/* 29 */ { SW_HIDE, FALSE, WS_MINIMIZE, WmEmptySeq, FALSE },
-/* 30 */ { SW_RESTORE, FALSE, WS_VISIBLE, WmRestore_1, FALSE },
-/* 31 */ { SW_RESTORE, TRUE, WS_VISIBLE, WmEmptySeq, FALSE },
-/* 32 */ { SW_HIDE, TRUE, 0, WmHide_3, FALSE },
-/* 33 */ { SW_HIDE, FALSE, 0, WmEmptySeq, FALSE },
-/* 34 */ { SW_NORMALNA, FALSE, 0, WmEmptySeq, FALSE }, /* what does this mean?! */
-/* 35 */ { SW_NORMALNA, FALSE, 0, WmEmptySeq, FALSE },
-/* 36 */ { SW_HIDE, FALSE, 0, WmEmptySeq, FALSE },
-/* 37 */ { SW_RESTORE, FALSE, WS_VISIBLE, WmRestore_2, FALSE },
-/* 38 */ { SW_RESTORE, TRUE, WS_VISIBLE, WmEmptySeq, FALSE },
-/* 39 */ { SW_SHOWNOACTIVATE, TRUE, WS_VISIBLE, WmEmptySeq, FALSE },
-/* 40 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinimize_2, FALSE },
-/* 41 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinMax_3, FALSE },
-/* 42 */ { SW_SHOWMAXIMIZED, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmShowMaximized_2, FALSE },
-/* 43 */ { SW_SHOWMAXIMIZED, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmMinMax_2, FALSE },
-/* 44 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinimize_1, FALSE },
-/* 45 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinMax_3, FALSE },
-/* 46 */ { SW_RESTORE, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmRestore_3, FALSE },
-/* 47 */ { SW_RESTORE, TRUE, WS_VISIBLE, WmRestore_4, FALSE },
-/* 48 */ { SW_SHOWMAXIMIZED, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmShowMaximized_3, FALSE },
-/* 49 */ { SW_SHOW, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmEmptySeq, FALSE },
-/* 50 */ { SW_SHOWNORMAL, TRUE, WS_VISIBLE, WmRestore_5, FALSE },
-/* 51 */ { SW_SHOWNORMAL, TRUE, WS_VISIBLE, WmRestore_5, FALSE },
-/* 52 */ { SW_HIDE, TRUE, 0, WmHide_1, FALSE },
-/* 53 */ { SW_HIDE, FALSE, 0, WmEmptySeq, FALSE },
-/* 54 */ { SW_MINIMIZE, FALSE, WS_VISIBLE|WS_MINIMIZE, WmMinimize_3, FALSE },
-/* 55 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_2, FALSE },
-/* 56 */ { SW_SHOWNOACTIVATE, FALSE, WS_VISIBLE, WmShowNoActivate_2, FALSE },
-/* 57 */ { SW_SHOW, TRUE, WS_VISIBLE, WmEmptySeq, FALSE }
+/* 1 */ { SW_SHOWNORMAL, FALSE, WS_VISIBLE, WmShowNormal,
+ SW_SHOWNORMAL, 0, {-1,-1}, {-1,-1}, FALSE },
+/* 2 */ { SW_SHOWNORMAL, TRUE, WS_VISIBLE, WmEmptySeq,
+ SW_SHOWNORMAL, 0, {-1,-1}, {-1,-1}, FALSE },
+/* 3 */ { SW_HIDE, TRUE, 0, WmHide_1,
+ SW_SHOWNORMAL, 0, {-1,-1}, {-1,-1}, FALSE },
+/* 4 */ { SW_HIDE, FALSE, 0, WmEmptySeq,
+ SW_SHOWNORMAL, 0, {-1,-1}, {-1,-1}, FALSE },
+/* 5 */ { SW_SHOWMINIMIZED, FALSE, WS_VISIBLE|WS_MINIMIZE, WmShowMinimized_1,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 6 */ { SW_SHOWMINIMIZED, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinMax_1,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 7 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_1,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 8 */ { SW_HIDE, FALSE, WS_MINIMIZE, WmEmptySeq,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 9 */ { SW_SHOWMAXIMIZED, FALSE, WS_VISIBLE|WS_MAXIMIZE, WmShowMaximized_1,
+ SW_SHOWMAXIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 10 */ { SW_SHOWMAXIMIZED, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmMinMax_2,
+ SW_SHOWMAXIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 11 */ { SW_HIDE, TRUE, WS_MAXIMIZE, WmHide_1,
+ SW_SHOWMAXIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 12 */ { SW_HIDE, FALSE, WS_MAXIMIZE, WmEmptySeq,
+ SW_SHOWMAXIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 13 */ { SW_SHOWNOACTIVATE, FALSE, WS_VISIBLE, WmShowNoActivate_1,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 14 */ { SW_SHOWNOACTIVATE, TRUE, WS_VISIBLE, WmEmptySeq,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 15 */ { SW_HIDE, TRUE, 0, WmHide_2,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 16 */ { SW_HIDE, FALSE, 0, WmEmptySeq,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 17 */ { SW_SHOW, FALSE, WS_VISIBLE, WmShow,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 18 */ { SW_SHOW, TRUE, WS_VISIBLE, WmEmptySeq,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 19 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinimize_1,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 20 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinMax_3,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 21 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_2,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 22 */ { SW_SHOWMINNOACTIVE, FALSE, WS_VISIBLE|WS_MINIMIZE, WmShowMinNoActivate,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, TRUE },
+/* 23 */ { SW_SHOWMINNOACTIVE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinMax_4,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 24 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_2,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 25 */ { SW_HIDE, FALSE, WS_MINIMIZE, WmEmptySeq,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 26 */ { SW_SHOWNA, FALSE, WS_VISIBLE|WS_MINIMIZE, WmShowNA_1,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 27 */ { SW_SHOWNA, TRUE, WS_VISIBLE|WS_MINIMIZE, WmShowNA_2,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 28 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_2,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 29 */ { SW_HIDE, FALSE, WS_MINIMIZE, WmEmptySeq,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 30 */ { SW_RESTORE, FALSE, WS_VISIBLE, WmRestore_1,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 31 */ { SW_RESTORE, TRUE, WS_VISIBLE, WmEmptySeq,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 32 */ { SW_HIDE, TRUE, 0, WmHide_3,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 33 */ { SW_HIDE, FALSE, 0, WmEmptySeq,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 34 */ { SW_NORMALNA, FALSE, 0, WmEmptySeq, /* what does this mean?! */
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 35 */ { SW_NORMALNA, FALSE, 0, WmEmptySeq,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 36 */ { SW_HIDE, FALSE, 0, WmEmptySeq,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 37 */ { SW_RESTORE, FALSE, WS_VISIBLE, WmRestore_2,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 38 */ { SW_RESTORE, TRUE, WS_VISIBLE, WmEmptySeq,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 39 */ { SW_SHOWNOACTIVATE, TRUE, WS_VISIBLE, WmEmptySeq,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 40 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinimize_2,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 41 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinMax_3,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 42 */ { SW_SHOWMAXIMIZED, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmShowMaximized_2,
+ SW_SHOWMAXIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 43 */ { SW_SHOWMAXIMIZED, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmMinMax_2,
+ SW_SHOWMAXIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 44 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinimize_1,
+ SW_SHOWMINIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 45 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinMax_3,
+ SW_SHOWMINIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 46 */ { SW_RESTORE, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmRestore_3,
+ SW_SHOWMAXIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 47 */ { SW_RESTORE, TRUE, WS_VISIBLE, WmRestore_4,
+ SW_SHOWNORMAL, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 48 */ { SW_SHOWMAXIMIZED, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmShowMaximized_3,
+ SW_SHOWMAXIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 49 */ { SW_SHOW, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmEmptySeq,
+ SW_SHOWMAXIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 50 */ { SW_SHOWNORMAL, TRUE, WS_VISIBLE, WmRestore_5,
+ SW_SHOWNORMAL, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 51 */ { SW_SHOWNORMAL, TRUE, WS_VISIBLE, WmRestore_5,
+ SW_SHOWNORMAL, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 52 */ { SW_HIDE, TRUE, 0, WmHide_1,
+ SW_SHOWNORMAL, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 53 */ { SW_HIDE, FALSE, 0, WmEmptySeq,
+ SW_SHOWNORMAL, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 54 */ { SW_MINIMIZE, FALSE, WS_VISIBLE|WS_MINIMIZE, WmMinimize_3,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 55 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_2,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 56 */ { SW_SHOWNOACTIVATE, FALSE, WS_VISIBLE, WmShowNoActivate_2,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 57 */ { SW_SHOW, TRUE, WS_VISIBLE, WmEmptySeq,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE }
};
HWND hwnd;
DWORD style;
LPARAM ret;
INT i;
+ WINDOWPLACEMENT wp;
+ RECT win_rc, work_rc = {0, 0, 0, 0};
#define WS_BASE (WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_POPUP|WS_CLIPSIBLINGS)
hwnd = CreateWindowEx(0, "ShowWindowClass", NULL, WS_BASE,
@@ -10709,6 +10901,52 @@ static void test_ShowWindow(void)
flush_events();
flush_sequence();
+ if (pGetMonitorInfoA && pMonitorFromPoint)
+ {
+ HMONITOR hmon;
+ MONITORINFO mi;
+ POINT pt = {0, 0};
+
+ SetLastError(0xdeadbeef);
+ hmon = pMonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
+ ok(hmon != 0, "MonitorFromPoint error %u\n", GetLastError());
+
+ mi.cbSize = sizeof(mi);
+ SetLastError(0xdeadbeef);
+ ret = pGetMonitorInfoA(hmon, &mi);
+ ok(ret, "GetMonitorInfo error %u\n", GetLastError());
+ trace("monitor (%d,%d-%d,%d), work (%d,%d-%d,%d)\n",
+ mi.rcMonitor.left, mi.rcMonitor.top, mi.rcMonitor.right, mi.rcMonitor.bottom,
+ mi.rcWork.left, mi.rcWork.top, mi.rcWork.right, mi.rcWork.bottom);
+ work_rc = mi.rcWork;
+ }
+
+ GetWindowRect(hwnd, &win_rc);
+ OffsetRect(&win_rc, -work_rc.left, -work_rc.top);
+
+ wp.length = sizeof(wp);
+ SetLastError(0xdeadbeaf);
+ ret = GetWindowPlacement(hwnd, &wp);
+ ok(ret, "GetWindowPlacement error %u\n", GetLastError());
+ ok(wp.flags == 0, "expected 0, got %#x\n", wp.flags);
+ ok(wp.showCmd == SW_SHOWNORMAL, "expected SW_SHOWNORMAL, got %d\n", wp.showCmd);
+ ok(wp.ptMinPosition.x == -1 && wp.ptMinPosition.y == -1,
+ "expected -1,-1 got %d,%d\n", wp.ptMinPosition.x, wp.ptMinPosition.y);
+ ok(wp.ptMaxPosition.x == -1 && wp.ptMaxPosition.y == -1,
+ "expected -1,-1 got %d,%d\n", wp.ptMaxPosition.x, wp.ptMaxPosition.y);
+ if (work_rc.left || work_rc.top) todo_wine /* FIXME: remove once Wine is fixed */
+ ok(EqualRect(&win_rc, &wp.rcNormalPosition),
+ "expected %d,%d-%d,%d got %d,%d-%d,%d\n",
+ win_rc.left, win_rc.top, win_rc.right, win_rc.bottom,
+ wp.rcNormalPosition.left, wp.rcNormalPosition.top,
+ wp.rcNormalPosition.right, wp.rcNormalPosition.bottom);
+ else
+ ok(EqualRect(&win_rc, &wp.rcNormalPosition),
+ "expected %d,%d-%d,%d got %d,%d-%d,%d\n",
+ win_rc.left, win_rc.top, win_rc.right, win_rc.bottom,
+ wp.rcNormalPosition.left, wp.rcNormalPosition.top,
+ wp.rcNormalPosition.right, wp.rcNormalPosition.bottom);
+
for (i = 0; i < sizeof(sw)/sizeof(sw[0]); i++)
{
static const char * const sw_cmd_name[13] =
@@ -10733,6 +10971,47 @@ static void test_ShowWindow(void)
sprintf(comment, "%d: ShowWindow(%s)", i+1, sw_cmd_name[idx]);
ok_sequence(sw[i].msg, comment, sw[i].todo_msg);
+ wp.length = sizeof(wp);
+ SetLastError(0xdeadbeaf);
+ ret = GetWindowPlacement(hwnd, &wp);
+ ok(ret, "GetWindowPlacement error %u\n", GetLastError());
+ ok(wp.flags == sw[i].wp_flags, "expected %#x, got %#x\n", sw[i].wp_flags, wp.flags);
+ ok(wp.showCmd == sw[i].wp_cmd, "expected %d, got %d\n", sw[i].wp_cmd, wp.showCmd);
+
+ /* NT moves the minimized window to -32000,-32000, win9x to 3000,3000 */
+ if ((wp.ptMinPosition.x + work_rc.left == -32000 && wp.ptMinPosition.y + work_rc.top == -32000) ||
+ (wp.ptMinPosition.x + work_rc.left == 3000 && wp.ptMinPosition.y + work_rc.top == 3000))
+ {
+ ok((wp.ptMinPosition.x + work_rc.left == sw[i].wp_min.x && wp.ptMinPosition.y + work_rc.top == sw[i].wp_min.y) ||
+ (wp.ptMinPosition.x + work_rc.left == 3000 && wp.ptMinPosition.y + work_rc.top == 3000),
+ "expected %d,%d got %d,%d\n", sw[i].wp_min.x, sw[i].wp_min.y, wp.ptMinPosition.x, wp.ptMinPosition.y);
+ }
+ else
+ {
+ if (wp.ptMinPosition.x != sw[i].wp_min.x || wp.ptMinPosition.y != sw[i].wp_min.y)
+ todo_wine
+ ok(wp.ptMinPosition.x == sw[i].wp_min.x && wp.ptMinPosition.y == sw[i].wp_min.y,
+ "expected %d,%d got %d,%d\n", sw[i].wp_min.x, sw[i].wp_min.y, wp.ptMinPosition.x, wp.ptMinPosition.y);
+ else
+ ok(wp.ptMinPosition.x == sw[i].wp_min.x && wp.ptMinPosition.y == sw[i].wp_min.y,
+ "expected %d,%d got %d,%d\n", sw[i].wp_min.x, sw[i].wp_min.y, wp.ptMinPosition.x, wp.ptMinPosition.y);
+ }
+
+ if (wp.ptMaxPosition.x != sw[i].wp_max.x || wp.ptMaxPosition.y != sw[i].wp_max.y)
+ todo_wine
+ ok(wp.ptMaxPosition.x == sw[i].wp_max.x && wp.ptMaxPosition.y == sw[i].wp_max.y,
+ "expected %d,%d got %d,%d\n", sw[i].wp_max.x, sw[i].wp_max.y, wp.ptMaxPosition.x, wp.ptMaxPosition.y);
+ else
+ ok(wp.ptMaxPosition.x == sw[i].wp_max.x && wp.ptMaxPosition.y == sw[i].wp_max.y,
+ "expected %d,%d got %d,%d\n", sw[i].wp_max.x, sw[i].wp_max.y, wp.ptMaxPosition.x, wp.ptMaxPosition.y);
+
+if (0) /* FIXME: Wine behaves completely different here */
+ ok(EqualRect(&win_rc, &wp.rcNormalPosition),
+ "expected %d,%d-%d,%d got %d,%d-%d,%d\n",
+ win_rc.left, win_rc.top, win_rc.right, win_rc.bottom,
+ wp.rcNormalPosition.left, wp.rcNormalPosition.top,
+ wp.rcNormalPosition.right, wp.rcNormalPosition.bottom);
+
flush_events();
flush_sequence();
}
@@ -11419,6 +11698,7 @@ static void test_dbcs_wm_char(void)
ok( !PeekMessageA( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
DestroyWindow(hwnd);
+ DestroyWindow(hwnd2);
}
#define ID_LISTBOX 0x000f
@@ -11746,6 +12026,33 @@ static const struct message wm_popup_menu_3[] =
{ 0 }
};
+static const struct message wm_single_menu_item[] =
+{
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_MENU, 0x20000001 },
+ { WM_SYSKEYDOWN, sent|wparam|lparam, VK_MENU, 0x20000001 },
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'Q', 0x20000001 },
+ { WM_SYSKEYDOWN, sent|wparam|lparam, 'Q', 0x20000001 },
+ { WM_SYSCHAR, sent|wparam|lparam, 'q', 0x20000001 },
+ { HCBT_SYSCOMMAND, hook|wparam|lparam, SC_KEYMENU, 'q' },
+ { WM_ENTERMENULOOP, sent|wparam|lparam, 0, 0 },
+ { WM_INITMENU, sent|lparam, 0, 0 },
+ { WM_MENUSELECT, sent|wparam|optional, MAKEWPARAM(300,MF_HILITE) },
+ { WM_MENUSELECT, sent|wparam|lparam, MAKEWPARAM(0,0xffff), 0 },
+ { WM_EXITMENULOOP, sent|wparam|lparam, 0, 0 },
+ { WM_MENUCOMMAND, sent },
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'Q', 0xe0000001 },
+ { WM_SYSKEYUP, sent|wparam|lparam, 'Q', 0xe0000001 },
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_MENU, 0xc0000001 },
+ { WM_KEYUP, sent|wparam|lparam, VK_MENU, 0xc0000001 },
+
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_ESCAPE, 1 },
+ { WM_KEYDOWN, sent|wparam|lparam, VK_ESCAPE, 1 },
+ { WM_CHAR, sent|wparam|lparam, VK_ESCAPE, 0x00000001 },
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_ESCAPE, 0xc0000001 },
+ { WM_KEYUP, sent|wparam|lparam, VK_ESCAPE, 0xc0000001 },
+ { 0 }
+};
+
static LRESULT WINAPI parent_menu_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
{
if (message == WM_ENTERIDLE ||
@@ -11904,6 +12211,21 @@ static void test_menu_messages(void)
}
ok_sequence(wm_popup_menu_2, "submenu of a popup menu command", FALSE);
+ trace("testing single menu item command\n");
+ flush_sequence();
+ keybd_event(VK_MENU, 0, 0, 0);
+ keybd_event('Q', 0, 0, 0);
+ keybd_event('Q', 0, KEYEVENTF_KEYUP, 0);
+ keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP, 0);
+ keybd_event(VK_ESCAPE, 0, 0, 0);
+ keybd_event(VK_ESCAPE, 0, KEYEVENTF_KEYUP, 0);
+ while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ ok_sequence(wm_single_menu_item, "single menu item command", FALSE);
+
set_menu_style(hmenu, 0);
style = get_menu_style(hmenu);
ok(style == 0, "expected 0, got %u\n", style);
@@ -12501,11 +12823,611 @@ static void test_WaitForInputIdle( char *argv0 )
CloseHandle( thread );
}
+static const struct message WmSetParentSeq_1[] = {
+ { WM_SHOWWINDOW, sent|wparam, 0 },
+ { EVENT_OBJECT_PARENTCHANGE, winevent_hook|wparam|lparam, 0, 0 },
+ { WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOSIZE },
+ { WM_CHILDACTIVATE, sent },
+ { WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOSIZE|SWP_NOREDRAW|SWP_NOCLIENTSIZE },
+ { WM_MOVE, sent|defwinproc|wparam, 0 },
+ { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
+ { WM_SHOWWINDOW, sent|wparam, 1 },
+ { 0 }
+};
+
+static const struct message WmSetParentSeq_2[] = {
+ { WM_SHOWWINDOW, sent|wparam, 0 },
+ { WM_WINDOWPOSCHANGING, sent|wparam, SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE },
+ { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
+ { WM_WINDOWPOSCHANGED, sent|wparam, SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE },
+ { HCBT_SETFOCUS, hook|optional },
+ { WM_NCACTIVATE, sent|wparam|optional, 0 },
+ { WM_ACTIVATE, sent|wparam|optional, 0 },
+ { WM_ACTIVATEAPP, sent|wparam|optional, 0 },
+ { WM_KILLFOCUS, sent|wparam, 0 },
+ { EVENT_OBJECT_PARENTCHANGE, winevent_hook|wparam|lparam, 0, 0 },
+ { WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOSIZE },
+ { HCBT_ACTIVATE, hook|optional },
+ { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
+ { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE },
+ { WM_NCACTIVATE, sent|wparam|optional, 1 },
+ { WM_ACTIVATE, sent|wparam|optional, 1 },
+ { HCBT_SETFOCUS, hook|optional },
+ { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
+ { WM_SETFOCUS, sent|optional|defwinproc },
+ { WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOREDRAW|SWP_NOSIZE|SWP_NOCLIENTSIZE },
+ { WM_MOVE, sent|defwinproc|wparam, 0 },
+ { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
+ { WM_SHOWWINDOW, sent|wparam, 1 },
+ { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE },
+ { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
+ { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE },
+ { 0 }
+};
+
+
+static void test_SetParent(void)
+{
+ HWND parent1, parent2, child, popup;
+ RECT rc, rc_old;
+
+ parent1 = CreateWindowEx(0, "TestParentClass", NULL, WS_OVERLAPPEDWINDOW,
+ 100, 100, 200, 200, 0, 0, 0, NULL);
+ ok(parent1 != 0, "Failed to create parent1 window\n");
+
+ parent2 = CreateWindowEx(0, "TestParentClass", NULL, WS_OVERLAPPEDWINDOW,
+ 400, 100, 200, 200, 0, 0, 0, NULL);
+ ok(parent2 != 0, "Failed to create parent2 window\n");
+
+ /* WS_CHILD window */
+ child = CreateWindowEx(0, "TestWindowClass", NULL, WS_CHILD | WS_VISIBLE,
+ 10, 10, 150, 150, parent1, 0, 0, NULL);
+ ok(child != 0, "Failed to create child window\n");
+
+ GetWindowRect(parent1, &rc);
+ trace("parent1 (%d,%d)-(%d,%d)\n", rc.left, rc.top, rc.right, rc.bottom);
+ GetWindowRect(child, &rc_old);
+ MapWindowPoints(0, parent1, (POINT *)&rc_old, 2);
+ trace("child (%d,%d)-(%d,%d)\n", rc_old.left, rc_old.top, rc_old.right, rc_old.bottom);
+
+ flush_sequence();
+
+ SetParent(child, parent2);
+ flush_events();
+ ok_sequence(WmSetParentSeq_1, "SetParent() visible WS_CHILD", TRUE);
+
+ ok(GetWindowLongA(child, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
+ ok(!IsWindowVisible(child), "IsWindowVisible() should return FALSE\n");
+
+ GetWindowRect(parent2, &rc);
+ trace("parent2 (%d,%d)-(%d,%d)\n", rc.left, rc.top, rc.right, rc.bottom);
+ GetWindowRect(child, &rc);
+ MapWindowPoints(0, parent2, (POINT *)&rc, 2);
+ trace("child (%d,%d)-(%d,%d)\n", rc.left, rc.top, rc.right, rc.bottom);
+
+ ok(EqualRect(&rc_old, &rc), "rects do not match (%d,%d-%d,%d) / (%d,%d-%d,%d)\n",
+ rc_old.left, rc_old.top, rc_old.right, rc_old.bottom,
+ rc.left, rc.top, rc.right, rc.bottom );
+
+ /* WS_POPUP window */
+ popup = CreateWindowEx(0, "TestWindowClass", NULL, WS_POPUP | WS_VISIBLE,
+ 20, 20, 100, 100, 0, 0, 0, NULL);
+ ok(popup != 0, "Failed to create popup window\n");
+
+ GetWindowRect(popup, &rc_old);
+ trace("popup (%d,%d)-(%d,%d)\n", rc_old.left, rc_old.top, rc_old.right, rc_old.bottom);
+
+ flush_sequence();
+
+ SetParent(popup, child);
+ flush_events();
+ ok_sequence(WmSetParentSeq_2, "SetParent() visible WS_POPUP", TRUE);
+
+ ok(GetWindowLongA(popup, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
+ ok(!IsWindowVisible(popup), "IsWindowVisible() should return FALSE\n");
+
+ GetWindowRect(child, &rc);
+ trace("parent2 (%d,%d)-(%d,%d)\n", rc.left, rc.top, rc.right, rc.bottom);
+ GetWindowRect(popup, &rc);
+ MapWindowPoints(0, child, (POINT *)&rc, 2);
+ trace("popup (%d,%d)-(%d,%d)\n", rc.left, rc.top, rc.right, rc.bottom);
+
+ ok(EqualRect(&rc_old, &rc), "rects do not match (%d,%d-%d,%d) / (%d,%d-%d,%d)\n",
+ rc_old.left, rc_old.top, rc_old.right, rc_old.bottom,
+ rc.left, rc.top, rc.right, rc.bottom );
+
+ DestroyWindow(popup);
+ DestroyWindow(child);
+ DestroyWindow(parent1);
+ DestroyWindow(parent2);
+
+ flush_sequence();
+}
+
+static const struct message WmKeyReleaseOnly[] = {
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 0x41, 0x80000001 },
+ { WM_KEYUP, sent|wparam|lparam, 0x41, 0x80000001 },
+ { 0 }
+};
+static const struct message WmKeyPressNormal[] = {
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 0x41, 0x1 },
+ { WM_KEYDOWN, sent|wparam|lparam, 0x41, 0x1 },
+ { 0 }
+};
+static const struct message WmKeyPressRepeat[] = {
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 0x41, 0x40000001 },
+ { WM_KEYDOWN, sent|wparam|lparam, 0x41, 0x40000001 },
+ { 0 }
+};
+static const struct message WmKeyReleaseNormal[] = {
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 0x41, 0xc0000001 },
+ { WM_KEYUP, sent|wparam|lparam, 0x41, 0xc0000001 },
+ { 0 }
+};
+
+static void test_keyflags(void)
+{
+ HWND test_window;
+ SHORT key_state;
+ BYTE keyboard_state[256];
+ MSG msg;
+
+ test_window = CreateWindowEx(0, "TestWindowClass", NULL, WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+ 100, 100, 200, 200, 0, 0, 0, NULL);
+
+ flush_sequence();
+
+ /* keyup without a keydown */
+ keybd_event(0x41, 0, KEYEVENTF_KEYUP, 0);
+ while (PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE))
+ DispatchMessage(&msg);
+ ok_sequence(WmKeyReleaseOnly, "key release only", TRUE);
+
+ key_state = GetAsyncKeyState(0x41);
+ ok((key_state & 0x8000) == 0, "unexpected key state %x\n", key_state);
+
+ key_state = GetKeyState(0x41);
+ ok((key_state & 0x8000) == 0, "unexpected key state %x\n", key_state);
+
+ /* keydown */
+ keybd_event(0x41, 0, 0, 0);
+ while (PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE))
+ DispatchMessage(&msg);
+ ok_sequence(WmKeyPressNormal, "key press only", FALSE);
+
+ key_state = GetAsyncKeyState(0x41);
+ ok((key_state & 0x8000) == 0x8000, "unexpected key state %x\n", key_state);
+
+ key_state = GetKeyState(0x41);
+ ok((key_state & 0x8000) == 0x8000, "unexpected key state %x\n", key_state);
+
+ /* keydown repeat */
+ keybd_event(0x41, 0, 0, 0);
+ while (PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE))
+ DispatchMessage(&msg);
+ ok_sequence(WmKeyPressRepeat, "key press repeat", FALSE);
+
+ key_state = GetAsyncKeyState(0x41);
+ ok((key_state & 0x8000) == 0x8000, "unexpected key state %x\n", key_state);
+
+ key_state = GetKeyState(0x41);
+ ok((key_state & 0x8000) == 0x8000, "unexpected key state %x\n", key_state);
+
+ /* keyup */
+ keybd_event(0x41, 0, KEYEVENTF_KEYUP, 0);
+ while (PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE))
+ DispatchMessage(&msg);
+ ok_sequence(WmKeyReleaseNormal, "key release repeat", FALSE);
+
+ key_state = GetAsyncKeyState(0x41);
+ ok((key_state & 0x8000) == 0, "unexpected key state %x\n", key_state);
+
+ key_state = GetKeyState(0x41);
+ ok((key_state & 0x8000) == 0, "unexpected key state %x\n", key_state);
+
+ /* set the key state in this thread */
+ GetKeyboardState(keyboard_state);
+ keyboard_state[0x41] = 0x80;
+ SetKeyboardState(keyboard_state);
+
+ key_state = GetAsyncKeyState(0x41);
+ ok((key_state & 0x8000) == 0, "unexpected key state %x\n", key_state);
+
+ /* keydown */
+ keybd_event(0x41, 0, 0, 0);
+ while (PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE))
+ DispatchMessage(&msg);
+ ok_sequence(WmKeyPressRepeat, "key press after setkeyboardstate", TRUE);
+
+ key_state = GetAsyncKeyState(0x41);
+ ok((key_state & 0x8000) == 0x8000, "unexpected key state %x\n", key_state);
+
+ key_state = GetKeyState(0x41);
+ ok((key_state & 0x8000) == 0x8000, "unexpected key state %x\n", key_state);
+
+ /* clear the key state in this thread */
+ GetKeyboardState(keyboard_state);
+ keyboard_state[0x41] = 0;
+ SetKeyboardState(keyboard_state);
+
+ key_state = GetAsyncKeyState(0x41);
+ ok((key_state & 0x8000) == 0x8000, "unexpected key state %x\n", key_state);
+
+ /* keyup */
+ keybd_event(0x41, 0, KEYEVENTF_KEYUP, 0);
+ while (PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE))
+ DispatchMessage(&msg);
+ ok_sequence(WmKeyReleaseOnly, "key release after setkeyboardstate", TRUE);
+
+ key_state = GetAsyncKeyState(0x41);
+ ok((key_state & 0x8000) == 0, "unexpected key state %x\n", key_state);
+
+ key_state = GetKeyState(0x41);
+ ok((key_state & 0x8000) == 0, "unexpected key state %x\n", key_state);
+
+ DestroyWindow(test_window);
+ flush_sequence();
+}
+
+static const struct message WmHotkeyPressLWIN[] = {
+ { WM_KEYDOWN, kbd_hook|wparam|lparam, VK_LWIN, LLKHF_INJECTED },
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_LWIN, 1 },
+ { WM_KEYDOWN, sent|wparam|lparam, VK_LWIN, 1 },
+ { 0 }
+};
+static const struct message WmHotkeyPress[] = {
+ { WM_KEYDOWN, kbd_hook|lparam, 0, LLKHF_INJECTED },
+ { WM_HOTKEY, sent|wparam, 5 },
+ { 0 }
+};
+static const struct message WmHotkeyRelease[] = {
+ { WM_KEYUP, kbd_hook|lparam, 0, LLKHF_INJECTED|LLKHF_UP },
+ { HCBT_KEYSKIPPED, hook|lparam|optional, 0, 0x80000001 },
+ { WM_KEYUP, sent|lparam, 0, 0x80000001 },
+ { 0 }
+};
+static const struct message WmHotkeyReleaseLWIN[] = {
+ { WM_KEYUP, kbd_hook|wparam|lparam, VK_LWIN, LLKHF_INJECTED|LLKHF_UP },
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_LWIN, 0xc0000001 },
+ { WM_KEYUP, sent|wparam|lparam, VK_LWIN, 0xc0000001 },
+ { 0 }
+};
+static const struct message WmHotkeyCombined[] = {
+ { WM_KEYDOWN, kbd_hook|wparam|lparam, VK_LWIN, LLKHF_INJECTED },
+ { WM_KEYDOWN, kbd_hook|lparam, 0, LLKHF_INJECTED },
+ { WM_KEYUP, kbd_hook|lparam, 0, LLKHF_INJECTED|LLKHF_UP },
+ { WM_KEYUP, kbd_hook|wparam|lparam, VK_LWIN, LLKHF_INJECTED|LLKHF_UP },
+ { WM_APP, sent, 0, 0 },
+ { WM_HOTKEY, sent|wparam, 5 },
+ { WM_APP+1, sent, 0, 0 },
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_LWIN, 1 },
+ { WM_KEYDOWN, sent|wparam|lparam, VK_LWIN, 1 },
+ { HCBT_KEYSKIPPED, hook|optional, 0, 0x80000001 },
+ { WM_KEYUP, sent, 0, 0x80000001 }, /* lparam not checked so the sequence isn't a todo */
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_LWIN, 0xc0000001 },
+ { WM_KEYUP, sent|wparam|lparam, VK_LWIN, 0xc0000001 },
+ { 0 }
+};
+static const struct message WmHotkeyPrevious[] = {
+ { WM_KEYDOWN, kbd_hook|wparam|lparam, VK_LWIN, LLKHF_INJECTED },
+ { WM_KEYDOWN, kbd_hook|lparam, 0, LLKHF_INJECTED },
+ { WM_KEYUP, kbd_hook|lparam, 0, LLKHF_INJECTED|LLKHF_UP },
+ { WM_KEYUP, kbd_hook|wparam|lparam, VK_LWIN, LLKHF_INJECTED|LLKHF_UP },
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_LWIN, 1 },
+ { WM_KEYDOWN, sent|wparam|lparam, VK_LWIN, 1 },
+ { HCBT_KEYSKIPPED, hook|lparam|optional, 0, 1 },
+ { WM_KEYDOWN, sent|lparam, 0, 1 },
+ { HCBT_KEYSKIPPED, hook|optional|lparam, 0, 0xc0000001 },
+ { WM_KEYUP, sent|lparam, 0, 0xc0000001 },
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_LWIN, 0xc0000001 },
+ { WM_KEYUP, sent|wparam|lparam, VK_LWIN, 0xc0000001 },
+ { 0 }
+};
+static const struct message WmHotkeyNew[] = {
+ { WM_KEYDOWN, kbd_hook|lparam, 0, LLKHF_INJECTED },
+ { WM_KEYUP, kbd_hook|lparam, 0, LLKHF_INJECTED|LLKHF_UP },
+ { WM_HOTKEY, sent|wparam, 5 },
+ { HCBT_KEYSKIPPED, hook|optional, 0, 0x80000001 },
+ { WM_KEYUP, sent, 0, 0x80000001 }, /* lparam not checked so the sequence isn't a todo */
+ { 0 }
+};
+
+static int hotkey_letter;
+
+static LRESULT CALLBACK KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
+{
+ struct recvd_message msg;
+
+ if (nCode == HC_ACTION)
+ {
+ KBDLLHOOKSTRUCT *kdbhookstruct = (KBDLLHOOKSTRUCT*)lParam;
+
+ msg.hwnd = 0;
+ msg.message = wParam;
+ msg.flags = kbd_hook|wparam|lparam;
+ msg.wParam = kdbhookstruct->vkCode;
+ msg.lParam = kdbhookstruct->flags;
+ msg.descr = "KeyboardHookProc";
+ add_message(&msg);
+
+ if (wParam == WM_KEYUP || wParam == WM_KEYDOWN)
+ {
+ ok(kdbhookstruct->vkCode == VK_LWIN || kdbhookstruct->vkCode == hotkey_letter,
+ "unexpected keycode %x\n", kdbhookstruct->vkCode);
+ }
+ }
+
+ return CallNextHookEx(hKBD_hook, nCode, wParam, lParam);
+}
+
+static void test_hotkey(void)
+{
+ HWND test_window, taskbar_window;
+ BOOL ret;
+ MSG msg;
+ DWORD queue_status;
+ SHORT key_state;
+
+ SetLastError(0xdeadbeef);
+ ret = UnregisterHotKey(NULL, 0);
+ ok(ret == FALSE, "expected FALSE, got %i\n", ret);
+ ok(GetLastError() == ERROR_HOTKEY_NOT_REGISTERED || broken(GetLastError() == 0xdeadbeef),
+ "unexpected error %d\n", GetLastError());
+
+ if (ret == TRUE)
+ {
+ skip("hotkeys not supported\n");
+ return;
+ }
+
+ test_window = CreateWindowEx(0, "HotkeyWindowClass", NULL, WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+ 100, 100, 200, 200, 0, 0, 0, NULL);
+
+ flush_sequence();
+
+ SetLastError(0xdeadbeef);
+ ret = UnregisterHotKey(test_window, 0);
+ ok(ret == FALSE, "expected FALSE, got %i\n", ret);
+ ok(GetLastError() == ERROR_HOTKEY_NOT_REGISTERED || broken(GetLastError() == 0xdeadbeef),
+ "unexpected error %d\n", GetLastError());
+
+ /* Search for a Windows Key + letter combination that hasn't been registered */
+ for (hotkey_letter = 0x41; hotkey_letter <= 0x51; hotkey_letter ++)
+ {
+ SetLastError(0xdeadbeef);
+ ret = RegisterHotKey(test_window, 5, MOD_WIN, hotkey_letter);
+
+ if (ret == TRUE)
+ {
+ break;
+ }
+ else
+ {
+ ok(GetLastError() == ERROR_HOTKEY_ALREADY_REGISTERED || broken(GetLastError() == 0xdeadbeef),
+ "unexpected error %d\n", GetLastError());
+ }
+ }
+
+ if (hotkey_letter == 0x52)
+ {
+ ok(0, "Couldn't find any free Windows Key + letter combination\n");
+ goto end;
+ }
+
+ hKBD_hook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProc, GetModuleHandle(NULL), 0);
+ if (!hKBD_hook) win_skip("WH_KEYBOARD_LL is not supported\n");
+
+ /* Same key combination, different id */
+ SetLastError(0xdeadbeef);
+ ret = RegisterHotKey(test_window, 4, MOD_WIN, hotkey_letter);
+ ok(ret == FALSE, "expected FALSE, got %i\n", ret);
+ ok(GetLastError() == ERROR_HOTKEY_ALREADY_REGISTERED || broken(GetLastError() == 0xdeadbeef),
+ "unexpected error %d\n", GetLastError());
+
+ /* Same key combination, different window */
+ SetLastError(0xdeadbeef);
+ ret = RegisterHotKey(NULL, 5, MOD_WIN, hotkey_letter);
+ ok(ret == FALSE, "expected FALSE, got %i\n", ret);
+ ok(GetLastError() == ERROR_HOTKEY_ALREADY_REGISTERED || broken(GetLastError() == 0xdeadbeef),
+ "unexpected error %d\n", GetLastError());
+
+ /* Register the same hotkey twice */
+ SetLastError(0xdeadbeef);
+ ret = RegisterHotKey(test_window, 5, MOD_WIN, hotkey_letter);
+ ok(ret == FALSE, "expected FALSE, got %i\n", ret);
+ ok(GetLastError() == ERROR_HOTKEY_ALREADY_REGISTERED || broken(GetLastError() == 0xdeadbeef),
+ "unexpected error %d\n", GetLastError());
+
+ /* Window on another thread */
+ taskbar_window = FindWindowA("Shell_TrayWnd", NULL);
+ if (!taskbar_window)
+ {
+ skip("no taskbar?\n");
+ }
+ else
+ {
+ SetLastError(0xdeadbeef);
+ ret = RegisterHotKey(taskbar_window, 5, 0, hotkey_letter);
+ ok(ret == FALSE, "expected FALSE, got %i\n", ret);
+ ok(GetLastError() == ERROR_WINDOW_OF_OTHER_THREAD || broken(GetLastError() == 0xdeadbeef),
+ "unexpected error %d\n", GetLastError());
+ }
+
+ /* Inject the appropriate key sequence */
+ keybd_event(VK_LWIN, 0, 0, 0);
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ DispatchMessage(&msg);
+ ok_sequence(WmHotkeyPressLWIN, "window hotkey press LWIN", FALSE);
+
+ keybd_event(hotkey_letter, 0, 0, 0);
+ queue_status = GetQueueStatus(QS_HOTKEY);
+ ok((queue_status & (QS_HOTKEY << 16)) == QS_HOTKEY << 16, "expected QS_HOTKEY << 16 set, got %x\n", queue_status);
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ if (msg.message == WM_HOTKEY)
+ {
+ ok(msg.hwnd == test_window, "unexpected hwnd %p\n", msg.hwnd);
+ ok(msg.lParam == MAKELPARAM(MOD_WIN, hotkey_letter), "unexpected WM_HOTKEY lparam %lx\n", msg.lParam);
+ }
+ DispatchMessage(&msg);
+ }
+ ok_sequence(WmHotkeyPress, "window hotkey press", FALSE);
+
+ queue_status = GetQueueStatus(QS_HOTKEY);
+ ok((queue_status & (QS_HOTKEY << 16)) == 0, "expected QS_HOTKEY << 16 cleared, got %x\n", queue_status);
+
+ key_state = GetAsyncKeyState(hotkey_letter);
+ ok((key_state & 0x8000) == 0x8000, "unexpected key state %x\n", key_state);
+
+ keybd_event(hotkey_letter, 0, KEYEVENTF_KEYUP, 0);
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ DispatchMessage(&msg);
+ ok_sequence(WmHotkeyRelease, "window hotkey release", TRUE);
+
+ keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP, 0);
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ DispatchMessage(&msg);
+ ok_sequence(WmHotkeyReleaseLWIN, "window hotkey release LWIN", FALSE);
+
+ /* normal posted WM_HOTKEY messages set QS_HOTKEY */
+ PostMessage(test_window, WM_HOTKEY, 0, 0);
+ queue_status = GetQueueStatus(QS_HOTKEY);
+ ok((queue_status & (QS_HOTKEY << 16)) == QS_HOTKEY << 16, "expected QS_HOTKEY << 16 set, got %x\n", queue_status);
+ queue_status = GetQueueStatus(QS_POSTMESSAGE);
+ ok((queue_status & (QS_POSTMESSAGE << 16)) == QS_POSTMESSAGE << 16, "expected QS_POSTMESSAGE << 16 set, got %x\n", queue_status);
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ DispatchMessage(&msg);
+ flush_sequence();
+
+ /* Send and process all messages at once */
+ PostMessage(test_window, WM_APP, 0, 0);
+ keybd_event(VK_LWIN, 0, 0, 0);
+ keybd_event(hotkey_letter, 0, 0, 0);
+ keybd_event(hotkey_letter, 0, KEYEVENTF_KEYUP, 0);
+ keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP, 0);
+
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ if (msg.message == WM_HOTKEY)
+ {
+ ok(msg.hwnd == test_window, "unexpected hwnd %p\n", msg.hwnd);
+ ok(msg.lParam == MAKELPARAM(MOD_WIN, hotkey_letter), "unexpected WM_HOTKEY lparam %lx\n", msg.lParam);
+ }
+ DispatchMessage(&msg);
+ }
+ ok_sequence(WmHotkeyCombined, "window hotkey combined", FALSE);
+
+ /* Register same hwnd/id with different key combination */
+ ret = RegisterHotKey(test_window, 5, 0, hotkey_letter);
+ ok(ret == TRUE, "expected TRUE, got %i, err=%d\n", ret, GetLastError());
+
+ /* Previous key combination does not work */
+ keybd_event(VK_LWIN, 0, 0, 0);
+ keybd_event(hotkey_letter, 0, 0, 0);
+ keybd_event(hotkey_letter, 0, KEYEVENTF_KEYUP, 0);
+ keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP, 0);
+
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ DispatchMessage(&msg);
+ ok_sequence(WmHotkeyPrevious, "window hotkey previous", FALSE);
+
+ /* New key combination works */
+ keybd_event(hotkey_letter, 0, 0, 0);
+ keybd_event(hotkey_letter, 0, KEYEVENTF_KEYUP, 0);
+
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ if (msg.message == WM_HOTKEY)
+ {
+ ok(msg.hwnd == test_window, "unexpected hwnd %p\n", msg.hwnd);
+ ok(msg.lParam == MAKELPARAM(0, hotkey_letter), "unexpected WM_HOTKEY lparam %lx\n", msg.lParam);
+ }
+ DispatchMessage(&msg);
+ }
+ ok_sequence(WmHotkeyNew, "window hotkey new", FALSE);
+
+ /* Unregister hotkey properly */
+ ret = UnregisterHotKey(test_window, 5);
+ ok(ret == TRUE, "expected TRUE, got %i, err=%d\n", ret, GetLastError());
+
+ /* Unregister hotkey again */
+ SetLastError(0xdeadbeef);
+ ret = UnregisterHotKey(test_window, 5);
+ ok(ret == FALSE, "expected FALSE, got %i\n", ret);
+ ok(GetLastError() == ERROR_HOTKEY_NOT_REGISTERED || broken(GetLastError() == 0xdeadbeef),
+ "unexpected error %d\n", GetLastError());
+
+ /* Register thread hotkey */
+ ret = RegisterHotKey(NULL, 5, MOD_WIN, hotkey_letter);
+ ok(ret == TRUE, "expected TRUE, got %i, err=%d\n", ret, GetLastError());
+
+ /* Inject the appropriate key sequence */
+ keybd_event(VK_LWIN, 0, 0, 0);
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ ok(msg.hwnd != NULL, "unexpected thread message %x\n", msg.message);
+ DispatchMessage(&msg);
+ }
+ ok_sequence(WmHotkeyPressLWIN, "thread hotkey press LWIN", FALSE);
+
+ keybd_event(hotkey_letter, 0, 0, 0);
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ if (msg.message == WM_HOTKEY)
+ {
+ struct recvd_message message;
+ ok(msg.hwnd == NULL, "unexpected hwnd %p\n", msg.hwnd);
+ ok(msg.lParam == MAKELPARAM(MOD_WIN, hotkey_letter), "unexpected WM_HOTKEY lparam %lx\n", msg.lParam);
+ message.message = msg.message;
+ message.flags = sent|wparam|lparam;
+ message.wParam = msg.wParam;
+ message.lParam = msg.lParam;
+ message.descr = "test_hotkey thread message";
+ add_message(&message);
+ }
+ else
+ ok(msg.hwnd != NULL, "unexpected thread message %x\n", msg.message);
+ DispatchMessage(&msg);
+ }
+ ok_sequence(WmHotkeyPress, "thread hotkey press", FALSE);
+
+ keybd_event(hotkey_letter, 0, KEYEVENTF_KEYUP, 0);
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ ok(msg.hwnd != NULL, "unexpected thread message %x\n", msg.message);
+ DispatchMessage(&msg);
+ }
+ ok_sequence(WmHotkeyRelease, "thread hotkey release", TRUE);
+
+ keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP, 0);
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ ok(msg.hwnd != NULL, "unexpected thread message %x\n", msg.message);
+ DispatchMessage(&msg);
+ }
+ ok_sequence(WmHotkeyReleaseLWIN, "thread hotkey release LWIN", FALSE);
+
+ /* Unregister thread hotkey */
+ ret = UnregisterHotKey(NULL, 5);
+ ok(ret == TRUE, "expected TRUE, got %i, err=%d\n", ret, GetLastError());
+
+ if (hKBD_hook) UnhookWindowsHookEx(hKBD_hook);
+ hKBD_hook = NULL;
+
+end:
+ UnregisterHotKey(NULL, 5);
+ UnregisterHotKey(test_window, 5);
+ DestroyWindow(test_window);
+ flush_sequence();
+}
+
START_TEST(msg)
{
char **test_argv;
BOOL ret;
BOOL (WINAPI *pIsWinEventHookInstalled)(DWORD)= 0;/*GetProcAddress(user32, "IsWinEventHookInstalled");*/
+ HMODULE hModuleImm32;
+ BOOL (WINAPI *pImmDisableIME)(DWORD);
int argc = winetest_get_mainargs( &test_argv );
if (argc >= 3)
@@ -12519,6 +13441,15 @@ START_TEST(msg)
init_procs();
+ hModuleImm32 = LoadLibrary("imm32.dll");
+ if (hModuleImm32) {
+ pImmDisableIME = (void *)GetProcAddress(hModuleImm32, "ImmDisableIME");
+ if (pImmDisableIME)
+ pImmDisableIME(0);
+ }
+ pImmDisableIME = NULL;
+ FreeLibrary(hModuleImm32);
+
if (!RegisterWindowClasses()) assert(0);
if (pSetWinEventHook)
@@ -12553,6 +13484,7 @@ START_TEST(msg)
hEvent_hook = 0;
#endif
+ test_SetParent();
test_PostMessage();
test_ShowWindow();
test_PeekMessage();
@@ -12597,6 +13529,8 @@ START_TEST(msg)
test_paintingloop();
test_defwinproc();
test_clipboard_viewers();
+ test_keyflags();
+ test_hotkey();
/* keep it the last test, under Windows it tends to break the tests
* which rely on active/foreground windows being correct.
*/
diff --git a/winetests/user32/resource.c b/winetests/user32/resource.c
index c64aff0a60e..5bc2d7a34d0 100755
--- a/winetests/user32/resource.c
+++ b/winetests/user32/resource.c
@@ -180,12 +180,10 @@ static void test_accel1(void)
ok( hAccel != NULL, "create accelerator table\n");
r = CopyAcceleratorTable( hAccel, NULL, 0 );
- ok( r == n || broken(r == 2), /* win9x */
- "two entries in table %u/%u\n", r, n);
+ ok( r == n, "two entries in table %u/%u\n", r, n);
r = CopyAcceleratorTable( hAccel, &ac[0], n );
- ok( r == n || broken(r == 2), /* win9x */
- "still should be two entries in table %u/%u\n", r, n);
+ ok( r == n, "still should be two entries in table %u/%u\n", r, n);
n=0;
ok( ac[n].cmd == 1000, "cmd 0 not preserved got %x\n", ac[n].cmd);
@@ -262,11 +260,11 @@ static void test_accel2(void)
hac = CreateAcceleratorTable( &ac[0], 2);
ok( hac != NULL , "fail\n");
res = CopyAcceleratorTable( hac, NULL, 100 );
- ok( res == 2 || broken(res == 0), /* win9x */ "copy null failed %d\n", res);
+ ok( res == 2, "copy null failed %d\n", res);
res = CopyAcceleratorTable( hac, NULL, 0 );
ok( res == 2, "copy null failed %d\n", res);
res = CopyAcceleratorTable( hac, NULL, 1 );
- ok( res == 2 || broken(res == 0), /* win9x */ "copy null failed %d\n", res);
+ ok( res == 2, "copy null failed %d\n", res);
ok( 1 == CopyAcceleratorTable( hac, out, 1 ), "copy 1 failed\n");
ok( 2 == CopyAcceleratorTable( hac, out, 2 ), "copy 2 failed\n");
ok( DestroyAcceleratorTable( hac ), "destroy failed\n");
@@ -318,7 +316,7 @@ static void test_accel2(void)
hac = CreateAcceleratorTable( &ac[0], 2);
ok( hac != NULL , "fail\n");
res = CopyAcceleratorTable( hac, out, 2 );
- ok( res == 2 || broken(res == 1), /* win9x */ "copy 2 failed %d\n", res);
+ ok( res == 2, "copy 2 failed %d\n", res);
/* ok( memcmp( ac, out, sizeof ac ), "tables not different\n"); */
ok( out[0].cmd == ac[0].cmd, "cmd modified\n");
ok( out[0].fVirt == (ac[0].fVirt&0x7f), "fVirt not modified\n");
diff --git a/winetests/user32/scroll.c b/winetests/user32/scroll.c
index e3f6938129c..e4bfdb15de5 100644
--- a/winetests/user32/scroll.c
+++ b/winetests/user32/scroll.c
@@ -259,7 +259,7 @@ todo_wine
"Scroll bar range is %d,%d. Expected 0,100. Style %08x\n", min, max, style);
/* test GetScrollInfo, vist for vertical SB */
ret = GetScrollInfo( hwnd, SB_VERT, &si);
- /* should fail if no H orV scroll bar styles are present. Succeed otherwise */
+ /* should fail if no H or V scroll bar styles are present. Succeed otherwise */
if( !( style & ( WS_VSCROLL | WS_HSCROLL)))
ok( !ret, "GetScrollInfo succeeded unexpectedly. Style is %08x\n", style);
else
@@ -269,7 +269,7 @@ todo_wine
"GetScrollInfo failed unexpectedly. Style is %08x\n", style);
/* Same for Horizontal SB */
ret = GetScrollInfo( hwnd, SB_HORZ, &si);
- /* should fail if no H orV scroll bar styles are present. Succeed otherwise */
+ /* should fail if no H or V scroll bar styles are present. Succeed otherwise */
if( !( style & ( WS_VSCROLL | WS_HSCROLL)))
ok( !ret, "GetScrollInfo succeeded unexpectedly. Style is %08x\n", style);
else
@@ -316,7 +316,7 @@ todo_wine
hwnd = CreateWindowExA( 0, "static", "", WS_POPUP | style,
0, 0, 10, 10, 0, 0, 0, NULL);
assert( hwnd != 0);
- /* Set Horizonta Scroll range to something that could be the default value it
+ /* Set Horizontal Scroll range to something that could be the default value it
* already has */;
ret = SetScrollRange( hwnd, SB_HORZ, 0, 100, FALSE);
ok( ret, "SetScrollRange failed.\n");
diff --git a/winetests/user32/static.c b/winetests/user32/static.c
index d04f725138a..b7613563104 100644
--- a/winetests/user32/static.c
+++ b/winetests/user32/static.c
@@ -95,9 +95,7 @@ static void test_updates(int style, int flags)
if (flags & TODO_COUNT)
todo_wine { expect_eq(g_nReceivedColorStatic, exp, int, "%d"); }
else if ((style & SS_TYPEMASK) == SS_ICON || (style & SS_TYPEMASK) == SS_BITMAP)
- ok( g_nReceivedColorStatic == exp ||
- broken(g_nReceivedColorStatic == 0), /* win9x */
- "expected %u got %u\n", exp, g_nReceivedColorStatic );
+ ok( g_nReceivedColorStatic == exp, "expected %u got %u\n", exp, g_nReceivedColorStatic );
else
expect_eq(g_nReceivedColorStatic, exp, int, "%d");
DestroyWindow(hStatic);
diff --git a/winetests/user32/sysparams.c b/winetests/user32/sysparams.c
index ba1c8026a89..1de3da0300f 100755
--- a/winetests/user32/sysparams.c
+++ b/winetests/user32/sysparams.c
@@ -24,7 +24,7 @@
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0600 /* For SPI_GETMOUSEHOVERWIDTH and more */
-#define _WIN32_IE 0x0700
+//#define _WIN32_IE 0x0700
#include "wine/test.h"
#include "windef.h"
@@ -2463,7 +2463,7 @@ static DWORD WINAPI SysParamsThreadFunc( LPVOID lpParam )
* not all metrics are properly restored. Problems are
* SM_CXMAXTRACK, SM_CYMAXTRACK
* Fortunately setting the Non-Client metrics like in
- * test_SPI_SETNONCLIENTMETRICS will corect this. That is why
+ * test_SPI_SETNONCLIENTMETRICS will correct this. That is why
* we do the DISPLAY change now... */
test_WM_DISPLAYCHANGE();
test_SPI_SETNONCLIENTMETRICS(); /* 42 */
diff --git a/winetests/user32/text.c b/winetests/user32/text.c
index 88ea6b566c0..1874b1572e0 100755
--- a/winetests/user32/text.c
+++ b/winetests/user32/text.c
@@ -114,13 +114,7 @@ static void test_DrawTextCalcRect(void)
heightcheck = textheight = DrawTextExA(hdc, text, 0, &rect, DT_CALCRECT, NULL );
ok( !EMPTY(rect) && !MODIFIED(rect),
"rectangle should NOT be empty got %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
- if (textheight != 0) /* Windows 98 */
- {
- win_skip("XP conformity failed, skipping XP tests. Probably win9x\n");
- conform_xp = FALSE;
- }
- else
- ok(textheight==0,"Got textheight from DrawTextExA\n");
+ ok(textheight==0,"Got textheight from DrawTextExA\n");
SetRect( &rect, 10,10, 100, 100);
textheight = DrawTextA(hdc, text, 0, &rect, DT_CALCRECT);
@@ -617,6 +611,9 @@ static void test_TabbedText(void)
ret = GetTextMetricsA( hdc, &tm);
ok( ret, "GetTextMetrics error %u\n", GetLastError());
+ extent = GetTabbedTextExtentA( hdc, "x", 0, 1, tabs);
+ ok( extent == 0, "GetTabbedTextExtentA returned non-zero on nCount == 0\n");
+
extent = GetTabbedTextExtentA( hdc, "x", 1, 1, tabs);
cx = LOWORD( extent);
cy = HIWORD( extent);
diff --git a/winetests/user32/win.c b/winetests/user32/win.c
index 33c837bed0e..94f7c638612 100644
--- a/winetests/user32/win.c
+++ b/winetests/user32/win.c
@@ -21,7 +21,7 @@
*/
/* To get ICON_SMALL2 with the MSVC headers */
-#define _WIN32_WINNT 0x0501
+//#define _WIN32_WINNT 0x0501
#include
#include
@@ -49,10 +49,17 @@ static BOOL (WINAPI *pGetWindowInfo)(HWND,WINDOWINFO*);
static UINT (WINAPI *pGetWindowModuleFileNameA)(HWND,LPSTR,UINT);
static BOOL (WINAPI *pGetLayeredWindowAttributes)(HWND,COLORREF*,BYTE*,DWORD*);
static BOOL (WINAPI *pSetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD);
+static BOOL (WINAPI *pUpdateLayeredWindow)(HWND,HDC,POINT*,SIZE*,HDC,POINT*,COLORREF,BLENDFUNCTION*,DWORD);
static BOOL (WINAPI *pGetMonitorInfoA)(HMONITOR,LPMONITORINFO);
static HMONITOR (WINAPI *pMonitorFromPoint)(POINT,DWORD);
static int (WINAPI *pGetWindowRgnBox)(HWND,LPRECT);
static BOOL (WINAPI *pGetGUIThreadInfo)(DWORD, GUITHREADINFO*);
+static BOOL (WINAPI *pGetProcessDefaultLayout)( DWORD *layout );
+static BOOL (WINAPI *pSetProcessDefaultLayout)( DWORD layout );
+static BOOL (WINAPI *pFlashWindowEx)( PFLASHWINFO pfwi );
+static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
+static DWORD (WINAPI *pGetLayout)(HDC hdc);
+static BOOL (WINAPI *pMirrorRgn)(HWND hwnd, HRGN hrgn);
static BOOL test_lbuttondown_flag;
static HWND hwndMessage;
@@ -121,6 +128,34 @@ static void check_parents( HWND hwnd, HWND ga_parent, HWND gwl_parent, HWND get_
}
}
+#define check_wnd_state(a,b,c,d) check_wnd_state_(__FILE__,__LINE__,a,b,c,d)
+static void check_wnd_state_(const char *file, int line,
+ HWND active, HWND foreground, HWND focus, HWND capture)
+{
+ ok_(file, line)(active == GetActiveWindow(), "GetActiveWindow() = %p\n", GetActiveWindow());
+ /* only check foreground if it belongs to the current thread */
+ /* foreground can be moved to a different app pretty much at any time */
+ if (foreground && GetForegroundWindow() &&
+ GetWindowThreadProcessId(GetForegroundWindow(), NULL) == GetCurrentThreadId())
+ ok_(file, line)(foreground == GetForegroundWindow(), "GetForegroundWindow() = %p\n", GetForegroundWindow());
+ ok_(file, line)(focus == GetFocus(), "GetFocus() = %p\n", GetFocus());
+ ok_(file, line)(capture == GetCapture(), "GetCapture() = %p\n", GetCapture());
+}
+
+/* same as above but without capture test */
+#define check_active_state(a,b,c) check_active_state_(__FILE__,__LINE__,a,b,c)
+static void check_active_state_(const char *file, int line,
+ HWND active, HWND foreground, HWND focus)
+{
+ ok_(file, line)(active == GetActiveWindow(), "GetActiveWindow() = %p\n", GetActiveWindow());
+ /* only check foreground if it belongs to the current thread */
+ /* foreground can be moved to a different app pretty much at any time */
+ if (foreground && GetForegroundWindow() &&
+ GetWindowThreadProcessId(GetForegroundWindow(), NULL) == GetCurrentThreadId())
+ ok_(file, line)(foreground == GetForegroundWindow(), "GetForegroundWindow() = %p\n", GetForegroundWindow());
+ ok_(file, line)(focus == GetFocus(), "GetFocus() = %p\n", GetFocus());
+}
+
static BOOL ignore_message( UINT message )
{
/* these are always ignored */
@@ -380,6 +415,15 @@ static void test_parent_owner(void)
check_parents( test, desktop, 0, desktop, 0, test, desktop );
/* window is now child of desktop so GWLP_HWNDPARENT changes owner from now on */
+ if (!is_win9x)
+ {
+ ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, (LONG_PTR)test );
+ ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0\n", ret );
+ check_parents( test, desktop, 0, desktop, 0, test, desktop );
+ }
+ else
+ win_skip("Test creates circular window tree under Win9x/WinMe\n" );
+
ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, (LONG_PTR)child );
ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0\n", ret );
check_parents( test, desktop, child, desktop, child, test, desktop );
@@ -596,6 +640,22 @@ static DWORD CALLBACK enum_thread( void *arg )
BOOL ret;
MSG msg;
+ if (pGetGUIThreadInfo)
+ {
+ GUITHREADINFO info;
+ info.cbSize = sizeof(info);
+ ret = pGetGUIThreadInfo( GetCurrentThreadId(), &info );
+ ok( ret || broken(!ret), /* win9x */
+ "GetGUIThreadInfo failed without message queue\n" );
+ SetLastError( 0xdeadbeef );
+ info.cbSize = sizeof(info) + 1;
+ ret = pGetGUIThreadInfo( GetCurrentThreadId(), &info );
+ ok( !ret, "GetGUIThreadInfo succeeded with wrong size\n" );
+ ok( GetLastError() == ERROR_INVALID_PARAMETER ||
+ broken(GetLastError() == 0xdeadbeef), /* win9x */
+ "wrong error %u\n", GetLastError() );
+ }
+
PeekMessage( &msg, 0, 0, 0, PM_NOREMOVE ); /* make sure we have a message queue */
count = 0;
@@ -665,8 +725,12 @@ static LRESULT WINAPI main_window_procA(HWND hwnd, UINT msg, WPARAM wparam, LPAR
/* Win9x does not fixup cx/xy for WM_WINDOWPOSCHANGING */
if (!(winpos->flags & SWP_NOSIZE) && !is_win9x)
{
- ok(winpos->cx >= 0 && winpos->cx <= 32767, "bad winpos->cx %d\n", winpos->cx);
- ok(winpos->cy >= 0 && winpos->cy <= 32767, "bad winpos->cy %d\n", winpos->cy);
+ ok((winpos->cx >= 0 && winpos->cx <= 32767) ||
+ winpos->cx == 32768, /* win7 doesn't truncate */
+ "bad winpos->cx %d\n", winpos->cx);
+ ok((winpos->cy >= 0 && winpos->cy <= 32767) ||
+ winpos->cy == 40000, /* win7 doesn't truncate */
+ "bad winpos->cy %d\n", winpos->cy);
}
break;
}
@@ -680,8 +744,12 @@ static LRESULT WINAPI main_window_procA(HWND hwnd, UINT msg, WPARAM wparam, LPAR
ok(winpos->x >= -32768 && winpos->x <= 32767, "bad winpos->x %d\n", winpos->x);
ok(winpos->y >= -32768 && winpos->y <= 32767, "bad winpos->y %d\n", winpos->y);
- ok(winpos->cx >= 0 && winpos->cx <= 32767, "bad winpos->cx %d\n", winpos->cx);
- ok(winpos->cy >= 0 && winpos->cy <= 32767, "bad winpos->cy %d\n", winpos->cy);
+ ok((winpos->cx >= 0 && winpos->cx <= 32767) ||
+ winpos->cx == 32768, /* win7 doesn't truncate */
+ "bad winpos->cx %d\n", winpos->cx);
+ ok((winpos->cy >= 0 && winpos->cy <= 32767) ||
+ winpos->cy == 40000, /* win7 doesn't truncate */
+ "bad winpos->cy %d\n", winpos->cy);
GetWindowRect(hwnd, &rc1);
SetRect(&rc2, winpos->x, winpos->y, winpos->x + winpos->cx, winpos->y + winpos->cy);
@@ -939,8 +1007,6 @@ static LRESULT CALLBACK cbt_hook_proc(int nCode, WPARAM wParam, LPARAM lParam)
RECT rc;
LONG style;
CBT_CREATEWNDA *createwnd = (CBT_CREATEWNDA *)lParam;
- trace("HCBT_CREATEWND: hwnd %p, parent %p, style %08x\n",
- hwnd, createwnd->lpcs->hwndParent, createwnd->lpcs->style);
ok(createwnd->hwndInsertAfter == HWND_TOP, "hwndInsertAfter should be always HWND_TOP\n");
if (pGetWindowInfo)
@@ -1009,7 +1075,6 @@ static LRESULT CALLBACK cbt_hook_proc(int nCode, WPARAM wParam, LPARAM lParam)
case HCBT_MOVESIZE:
case HCBT_MINMAX:
case HCBT_ACTIVATE:
- case HCBT_SETFOCUS:
if (pGetWindowInfo && IsWindow(hwnd))
{
WINDOWINFO info;
@@ -1023,9 +1088,9 @@ static LRESULT CALLBACK cbt_hook_proc(int nCode, WPARAM wParam, LPARAM lParam)
verify_window_info(code_name, hwnd, &info);
}
break;
- /* on HCBT_DESTROYWND window state is undefined */
+ /* window state is undefined */
+ case HCBT_SETFOCUS:
case HCBT_DESTROYWND:
- trace( "HCBT_DESTROYWND: hwnd %p\n", hwnd );
break;
default:
break;
@@ -1905,10 +1970,14 @@ static LRESULT WINAPI nccalcsize_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM
return DefWindowProc( hwnd, msg, wparam, lparam );
}
-static void test_SetWindowPos(HWND hwnd)
+static void test_SetWindowPos(HWND hwnd, HWND hwnd2)
{
RECT orig_win_rc, rect;
LONG_PTR old_proc;
+ HWND hwnd_grandchild, hwnd_child, hwnd_child2;
+ HWND hwnd_desktop;
+ RECT rc1, rc2;
+ BOOL ret;
SetRect(&rect, 111, 222, 333, 444);
ok(!GetWindowRect(0, &rect), "GetWindowRect succeeded\n");
@@ -1923,7 +1992,8 @@ static void test_SetWindowPos(HWND hwnd)
GetWindowRect(hwnd, &orig_win_rc);
old_proc = SetWindowLongPtr( hwnd, GWLP_WNDPROC, (ULONG_PTR)nccalcsize_proc );
- SetWindowPos(hwnd, 0, 100, 100, 0, 0, SWP_NOZORDER|SWP_FRAMECHANGED);
+ ret = SetWindowPos(hwnd, 0, 100, 100, 0, 0, SWP_NOZORDER|SWP_FRAMECHANGED);
+ ok(ret, "Got %d\n", ret);
GetWindowRect( hwnd, &rect );
ok( rect.left == 100 && rect.top == 100 && rect.right == 100 && rect.bottom == 100,
"invalid window rect %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
@@ -1932,7 +2002,8 @@ static void test_SetWindowPos(HWND hwnd)
ok( rect.left == 90 && rect.top == 90 && rect.right == 110 && rect.bottom == 110,
"invalid client rect %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
- SetWindowPos(hwnd, 0, 200, 200, 0, 0, SWP_NOZORDER|SWP_FRAMECHANGED);
+ ret = SetWindowPos(hwnd, 0, 200, 200, 0, 0, SWP_NOZORDER|SWP_FRAMECHANGED);
+ ok(ret, "Got %d\n", ret);
GetWindowRect( hwnd, &rect );
ok( rect.left == 200 && rect.top == 200 && rect.right == 200 && rect.bottom == 200,
"invalid window rect %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
@@ -1941,30 +2012,151 @@ static void test_SetWindowPos(HWND hwnd)
ok( rect.left == 210 && rect.top == 210 && rect.right == 190 && rect.bottom == 190,
"invalid client rect %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
- SetWindowPos(hwnd, 0, orig_win_rc.left, orig_win_rc.top,
- orig_win_rc.right, orig_win_rc.bottom, 0);
+ ret = SetWindowPos(hwnd, 0, orig_win_rc.left, orig_win_rc.top,
+ orig_win_rc.right, orig_win_rc.bottom, 0);
+ ok(ret, "Got %d\n", ret);
SetWindowLongPtr( hwnd, GWLP_WNDPROC, old_proc );
/* Win9x truncates coordinates to 16-bit irrespectively */
if (!is_win9x)
{
- SetWindowPos(hwnd, 0, -32769, -40000, -32769, -90000, SWP_NOMOVE);
- SetWindowPos(hwnd, 0, 32768, 40000, 32768, 40000, SWP_NOMOVE);
+ ret = SetWindowPos(hwnd, 0, -32769, -40000, -32769, -90000, SWP_NOMOVE);
+ ok(ret, "Got %d\n", ret);
+ ret = SetWindowPos(hwnd, 0, 32768, 40000, 32768, 40000, SWP_NOMOVE);
+ ok(ret, "Got %d\n", ret);
- SetWindowPos(hwnd, 0, -32769, -40000, -32769, -90000, SWP_NOSIZE);
- SetWindowPos(hwnd, 0, 32768, 40000, 32768, 40000, SWP_NOSIZE);
+ ret = SetWindowPos(hwnd, 0, -32769, -40000, -32769, -90000, SWP_NOSIZE);
+ ok(ret, "Got %d\n", ret);
+ ret = SetWindowPos(hwnd, 0, 32768, 40000, 32768, 40000, SWP_NOSIZE);
+ ok(ret, "Got %d\n", ret);
}
- SetWindowPos(hwnd, 0, orig_win_rc.left, orig_win_rc.top,
- orig_win_rc.right, orig_win_rc.bottom, 0);
+ ret = SetWindowPos(hwnd, 0, orig_win_rc.left, orig_win_rc.top,
+ orig_win_rc.right, orig_win_rc.bottom, 0);
+ ok(ret, "Got %d\n", ret);
ok(!(GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST), "WS_EX_TOPMOST should not be set\n");
- SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
+ ret = SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
+ ok(ret, "Got %d\n", ret);
ok(GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST, "WS_EX_TOPMOST should be set\n");
- SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
+ ret = SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
+ ok(ret, "Got %d\n", ret);
ok(GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST, "WS_EX_TOPMOST should be set\n");
- SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
+ ret = SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
+ ok(ret, "Got %d\n", ret);
ok(!(GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST), "WS_EX_TOPMOST should not be set\n");
+
+ hwnd_desktop = GetDesktopWindow();
+ ok(!!hwnd_desktop, "Failed to get hwnd_desktop window (%d).\n", GetLastError());
+ hwnd_child = create_tool_window(WS_VISIBLE|WS_CHILD, hwnd);
+ ok(!!hwnd_child, "Failed to create child window (%d)\n", GetLastError());
+ hwnd_grandchild = create_tool_window(WS_VISIBLE|WS_CHILD, hwnd_child);
+ ok(!!hwnd_child, "Failed to create child window (%d)\n", GetLastError());
+ hwnd_child2 = create_tool_window(WS_VISIBLE|WS_CHILD, hwnd);
+ ok(!!hwnd_child2, "Failed to create second child window (%d)\n", GetLastError());
+
+ ret = SetWindowPos(hwnd, hwnd2, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
+ ok(ret, "Got %d\n", ret);
+ check_active_state(hwnd, hwnd, hwnd);
+
+ ret = SetWindowPos(hwnd2, hwnd, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
+ ok(ret, "Got %d\n", ret);
+ check_active_state(hwnd2, hwnd2, hwnd2);
+
+ /* Returns TRUE also for windows that are not siblings */
+ ret = SetWindowPos(hwnd_child, hwnd2, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
+ ok(ret, "Got %d\n", ret);
+ check_active_state(hwnd2, hwnd2, hwnd2);
+
+ ret = SetWindowPos(hwnd2, hwnd_child, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
+ ok(ret, "Got %d\n", ret);
+ check_active_state(hwnd2, hwnd2, hwnd2);
+
+ /* Does not seem to do anything even without passing flags, still returns TRUE */
+ GetWindowRect(hwnd_child, &rc1);
+ ret = SetWindowPos(hwnd_child, hwnd2 , 1, 2, 3, 4, 0);
+ ok(ret, "Got %d\n", ret);
+ GetWindowRect(hwnd_child, &rc2);
+ ok(rc1.left == rc2.left && rc1.top == rc2.top &&
+ rc1.right == rc2.right && rc1.bottom == rc2.bottom,
+ "(%d, %d, %d, %d) != (%d, %d, %d, %d)\n",
+ rc1.left, rc1.top, rc1.right, rc1.bottom, rc2.left, rc2.top, rc2.right, rc2.bottom);
+ check_active_state(hwnd2, hwnd2, hwnd2);
+
+ /* Same thing the other way around. */
+ GetWindowRect(hwnd2, &rc1);
+ ret = SetWindowPos(hwnd2, hwnd_child, 1, 2, 3, 4, 0);
+ ok(ret, "Got %d\n", ret);
+ GetWindowRect(hwnd2, &rc2);
+ ok(rc1.left == rc2.left && rc1.top == rc2.top &&
+ rc1.right == rc2.right && rc1.bottom == rc2.bottom,
+ "(%d, %d, %d, %d) != (%d, %d, %d, %d)\n",
+ rc1.left, rc1.top, rc1.right, rc1.bottom, rc2.left, rc2.top, rc2.right, rc2.bottom);
+ check_active_state(hwnd2, hwnd2, hwnd2);
+
+ /* .. and with these windows. */
+ GetWindowRect(hwnd_grandchild, &rc1);
+ ret = SetWindowPos(hwnd_grandchild, hwnd_child2, 1, 2, 3, 4, 0);
+ ok(ret, "Got %d\n", ret);
+ GetWindowRect(hwnd_grandchild, &rc2);
+ ok(rc1.left == rc2.left && rc1.top == rc2.top &&
+ rc1.right == rc2.right && rc1.bottom == rc2.bottom,
+ "(%d, %d, %d, %d) != (%d, %d, %d, %d)\n",
+ rc1.left, rc1.top, rc1.right, rc1.bottom, rc2.left, rc2.top, rc2.right, rc2.bottom);
+ check_active_state(hwnd2, hwnd2, hwnd2);
+
+ /* Add SWP_NOZORDER and it will be properly resized. */
+ GetWindowRect(hwnd_grandchild, &rc1);
+ ret = SetWindowPos(hwnd_grandchild, hwnd_child2, 1, 2, 3, 4, SWP_NOZORDER);
+ ok(ret, "Got %d\n", ret);
+ GetWindowRect(hwnd_grandchild, &rc2);
+ ok((rc1.left+1) == rc2.left && (rc1.top+2) == rc2.top &&
+ (rc1.left+4) == rc2.right && (rc1.top+6) == rc2.bottom,
+ "(%d, %d, %d, %d) != (%d, %d, %d, %d)\n",
+ rc1.left+1, rc1.top+2, rc1.left+4, rc1.top+6, rc2.left, rc2.top, rc2.right, rc2.bottom);
+ check_active_state(hwnd2, hwnd2, hwnd2);
+
+ /* Given a sibling window, the window is properly resized. */
+ GetWindowRect(hwnd_child, &rc1);
+ ret = SetWindowPos(hwnd_child, hwnd_child2, 1, 2, 3, 4, 0);
+ ok(ret, "Got %d\n", ret);
+ GetWindowRect(hwnd_child, &rc2);
+ ok((rc1.left+1) == rc2.left && (rc1.top+2) == rc2.top &&
+ (rc1.left+4) == rc2.right && (rc1.top+6) == rc2.bottom,
+ "(%d, %d, %d, %d) != (%d, %d, %d, %d)\n",
+ rc1.left+1, rc1.top+2, rc1.left+4, rc1.top+6, rc2.left, rc2.top, rc2.right, rc2.bottom);
+ check_active_state(hwnd2, hwnd2, hwnd2);
+
+ /* Involving the desktop window changes things. */
+ ret = SetWindowPos(hwnd_child, hwnd_desktop, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
+ ok(!ret, "Got %d\n", ret);
+ check_active_state(hwnd2, hwnd2, hwnd2);
+
+ GetWindowRect(hwnd_child, &rc1);
+ ret = SetWindowPos(hwnd_child, hwnd_desktop, 0, 0, 0, 0, 0);
+ ok(!ret, "Got %d\n", ret);
+ GetWindowRect(hwnd_child, &rc2);
+ ok(rc1.top == rc2.top && rc1.left == rc2.left &&
+ rc1.bottom == rc2.bottom && rc1.right == rc2.right,
+ "(%d, %d, %d, %d) != (%d, %d, %d, %d)\n",
+ rc1.top, rc1.left, rc1.bottom, rc1.right, rc2.top, rc2.left, rc2.bottom, rc2.right);
+ check_active_state(hwnd2, hwnd2, hwnd2);
+
+ ret = SetWindowPos(hwnd_desktop, hwnd_child, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
+ ok(!ret, "Got %d\n", ret);
+ check_active_state(hwnd2, hwnd2, hwnd2);
+
+ ret = SetWindowPos(hwnd_desktop, hwnd, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
+ ok(!ret, "Got %d\n", ret);
+ check_active_state(hwnd2, hwnd2, hwnd2);
+
+ ret = SetWindowPos(hwnd, hwnd_desktop, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
+ ok(!ret, "Got %d\n", ret);
+ check_active_state(hwnd2, hwnd2, hwnd2);
+
+ DestroyWindow(hwnd_grandchild);
+ DestroyWindow(hwnd_child);
+ DestroyWindow(hwnd_child2);
}
static void test_SetMenu(HWND parent)
@@ -2403,20 +2595,6 @@ todo_wine
DestroyWindow( child );
}
-#define check_wnd_state(a,b,c,d) check_wnd_state_(__FILE__,__LINE__,a,b,c,d)
-static void check_wnd_state_(const char *file, int line,
- HWND active, HWND foreground, HWND focus, HWND capture)
-{
- ok_(file, line)(active == GetActiveWindow(), "GetActiveWindow() = %p\n", GetActiveWindow());
- /* only check foreground if it belongs to the current thread */
- /* foreground can be moved to a different app pretty much at any time */
- if (foreground && GetForegroundWindow() &&
- GetWindowThreadProcessId(GetForegroundWindow(), NULL) == GetCurrentThreadId())
- ok_(file, line)(foreground == GetForegroundWindow(), "GetForegroundWindow() = %p\n", GetForegroundWindow());
- ok_(file, line)(focus == GetFocus(), "GetFocus() = %p\n", GetFocus());
- ok_(file, line)(capture == GetCapture(), "GetCapture() = %p\n", GetCapture());
-}
-
static void test_SetActiveWindow(HWND hwnd)
{
HWND hwnd2;
@@ -2550,7 +2728,8 @@ static void test_SetForegroundWindow(HWND hwnd)
hwnd2 = GetForegroundWindow();
ok(hwnd2 == hwnd, "Wrong foreground window %p\n", hwnd2);
- ok(SetForegroundWindow( GetDesktopWindow() ), "SetForegroundWindow(desktop) error: %d\n", GetLastError());
+ ret = SetForegroundWindow( GetDesktopWindow() );
+ ok(ret, "SetForegroundWindow(desktop) error: %d\n", GetLastError());
hwnd2 = GetForegroundWindow();
ok(hwnd2 != hwnd, "Wrong foreground window %p\n", hwnd2);
@@ -2669,10 +2848,7 @@ static LRESULT WINAPI button_hook_proc(HWND button, UINT msg, WPARAM wparam, LPA
static void test_capture_1(void)
{
- HWND button, capture, oldFocus, oldActive;
-
- oldFocus = GetFocus();
- oldActive = GetActiveWindow();
+ HWND button, capture;
capture = GetCapture();
ok(capture == 0, "GetCapture() = %p\n", capture);
@@ -2690,7 +2866,9 @@ static void test_capture_1(void)
check_wnd_state(button, 0, button, button);
DestroyWindow(button);
- check_wnd_state(oldActive, 0, oldFocus, 0);
+ /* old active window test depends on previously executed window
+ * activation tests, and fails under NT4.
+ check_wnd_state(oldActive, 0, oldFocus, 0);*/
}
static void test_capture_2(void)
@@ -2847,6 +3025,7 @@ static void test_capture_4(void)
HWND hwnd;
WNDCLASSA wclass;
HINSTANCE hInstance = GetModuleHandleA( NULL );
+ ATOM aclass;
if (!pGetGUIThreadInfo)
{
@@ -2863,10 +3042,11 @@ static void test_capture_4(void)
wclass.lpszMenuName = 0;
wclass.cbClsExtra = 0;
wclass.cbWndExtra = 0;
- assert (RegisterClassA( &wclass ));
- assert (hwnd = CreateWindowA( wclass.lpszClassName, "MenuTest",
- WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0,
- 400, 200, NULL, NULL, hInstance, NULL) );
+ aclass = RegisterClassA( &wclass );
+ ok( aclass, "RegisterClassA failed with error %d\n", GetLastError());
+ hwnd = CreateWindowA( wclass.lpszClassName, "MenuTest",
+ WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0,
+ 400, 200, NULL, NULL, hInstance, NULL);
ok(hwnd != NULL, "CreateWindowEx failed with error %d\n", GetLastError());
if (!hwnd) return;
hmenu = CreatePopupMenu();
@@ -3293,10 +3473,10 @@ static void test_nccalcscroll(HWND parent)
static void test_SetParent(void)
{
- BOOL ret;
HWND desktop = GetDesktopWindow();
HMENU hMenu;
- HWND parent, child1, child2, child3, child4, sibling;
+ HWND ret, parent, child1, child2, child3, child4, sibling, popup;
+ BOOL bret;
parent = CreateWindowExA(0, "static", NULL, WS_OVERLAPPEDWINDOW,
100, 100, 200, 200, 0, 0, 0, NULL);
@@ -3341,8 +3521,6 @@ static void test_SetParent(void)
if (!is_win9x) /* Win9x doesn't survive this test */
{
- HWND ret;
-
ok(!SetParent(parent, child1), "SetParent should fail\n");
ok(!SetParent(child2, child3), "SetParent should fail\n");
ok(SetParent(child1, parent) != 0, "SetParent should not fail\n");
@@ -3388,8 +3566,7 @@ static void test_SetParent(void)
ok(SetParent(sibling, parent) != 0, "SetParent should not fail\n");
ok(GetMenu(sibling) == hMenu, "SetParent should not remove menu\n");
- ret = DestroyWindow(parent);
- ok( ret, "DestroyWindow() error %d\n", GetLastError());
+ ok(DestroyWindow(parent), "DestroyWindow() failed\n");
ok(!IsWindow(parent), "parent still exists\n");
ok(!IsWindow(sibling), "sibling still exists\n");
@@ -3397,6 +3574,51 @@ static void test_SetParent(void)
ok(!IsWindow(child2), "child2 still exists\n");
ok(!IsWindow(child3), "child3 still exists\n");
ok(!IsWindow(child4), "child4 still exists\n");
+
+ parent = CreateWindowExA(0, "static", NULL, WS_OVERLAPPEDWINDOW,
+ 100, 100, 200, 200, 0, 0, 0, NULL);
+ assert(parent != 0);
+ child1 = CreateWindowExA(0, "static", NULL, WS_CHILD,
+ 0, 0, 50, 50, parent, 0, 0, NULL);
+ assert(child1 != 0);
+ popup = CreateWindowExA(0, "static", NULL, WS_POPUP,
+ 0, 0, 50, 50, 0, 0, 0, NULL);
+ assert(popup != 0);
+
+ trace("parent %p, child %p, popup %p\n", parent, child1, popup);
+
+ check_parents(parent, desktop, 0, 0, 0, parent, parent);
+ check_parents(child1, parent, parent, parent, 0, parent, parent);
+ check_parents(popup, desktop, 0, 0, 0, popup, popup);
+
+ SetActiveWindow(parent);
+ SetFocus(parent);
+ check_active_state(parent, 0, parent);
+
+ ret = SetParent(popup, child1);
+ ok(ret == desktop, "expected %p, got %p\n", desktop, ret);
+ check_parents(popup, child1, child1, 0, 0, parent, popup);
+todo_wine
+ check_active_state(popup, 0, popup);
+
+ SetActiveWindow(parent);
+ SetFocus(parent);
+ check_active_state(parent, 0, parent);
+
+ bret = SetForegroundWindow(popup);
+todo_wine {
+ ok(bret || broken(!bret), "SetForegroundWindow() failed\n");
+ if (!bret)
+ check_active_state(popup, 0, popup);
+ else
+ check_active_state(popup, popup, popup);
+ }
+
+ ok(DestroyWindow(parent), "DestroyWindow() failed\n");
+
+ ok(!IsWindow(parent), "parent still exists\n");
+ ok(!IsWindow(child1), "child1 still exists\n");
+ ok(!IsWindow(popup), "popup still exists\n");
}
static LRESULT WINAPI StyleCheckProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
@@ -3482,6 +3704,25 @@ static void check_window_style(DWORD dwStyleIn, DWORD dwExStyleIn, DWORD dwStyle
"Style (0x%08x) should really be 0x%08x and/or Ex style (0x%08x) should really be 0x%08x\n",
dwActualStyle, dwStyleOut, dwActualExStyle, dwExStyleOut);
+ /* try setting the styles explicitly */
+ SetWindowLong( hwnd, GWL_EXSTYLE, dwExStyleIn );
+ SetWindowLong( hwnd, GWL_STYLE, dwStyleIn );
+ dwActualStyle = GetWindowLong(hwnd, GWL_STYLE);
+ dwActualExStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
+ /* WS_CLIPSIBLINGS can't be reset on top-level windows */
+ if (dwStyleIn & WS_CHILD) dwStyleOut = dwStyleIn;
+ else dwStyleOut = dwStyleIn | WS_CLIPSIBLINGS;
+ /* WS_EX_WINDOWEDGE can't always be changed */
+ if ((dwExStyleIn & WS_EX_DLGMODALFRAME) || (dwStyleIn & WS_THICKFRAME))
+ dwExStyleOut = dwExStyleIn | WS_EX_WINDOWEDGE;
+ else if (dwStyleIn & (WS_CHILD | WS_POPUP))
+ dwExStyleOut = dwExStyleIn & ~WS_EX_WINDOWEDGE;
+ else
+ dwExStyleOut = dwExStyleIn;
+ ok((dwActualStyle == dwStyleOut) && (dwActualExStyle == dwExStyleOut),
+ "%08x/%08x: Style (0x%08x) should really be 0x%08x and/or Ex style (0x%08x) should really be 0x%08x\n",
+ dwStyleIn, dwExStyleIn, dwActualStyle, dwStyleOut, dwActualExStyle, dwExStyleOut);
+
DestroyWindow(hwnd);
if (hwndParent) DestroyWindow(hwndParent);
}
@@ -3823,6 +4064,10 @@ static void test_params(void)
HWND hwnd;
INT rc;
+ ok(!IsWindow(0), "IsWindow(0)\n");
+ ok(!IsWindow(HWND_BROADCAST), "IsWindow(HWND_BROADCAST)\n");
+ ok(!IsWindow(HWND_TOPMOST), "IsWindow(HWND_TOPMOST)\n");
+
/* Just a param check */
if (pGetMonitorInfoA)
{
@@ -4442,6 +4687,8 @@ static LRESULT CALLBACK winsizes_wnd_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM
"wrong y size %d/%d\n", cs->cy, expected_cy );
ok( (rect.right - rect.left == expected_rect.right - expected_rect.left &&
rect.bottom - rect.top == expected_rect.bottom - expected_rect.top) ||
+ (rect.right - rect.left == min( 65535, expected_rect.right - expected_rect.left ) &&
+ rect.bottom - rect.top == min( 65535, expected_rect.bottom - expected_rect.top )) ||
broken( rect.right - rect.left == broken_rect.right - broken_rect.left &&
rect.bottom - rect.top == broken_rect.bottom - broken_rect.top) ||
broken( rect.right - rect.left == (short)broken_rect.right - (short)broken_rect.left &&
@@ -4472,10 +4719,12 @@ static void test_CreateWindow(void)
HMENU hmenu;
RECT rc, rc_minmax;
MINMAXINFO minmax;
+ BOOL res;
#define expect_menu(window, menu) \
SetLastError(0xdeadbeef); \
- ok(GetMenu(window) == (HMENU)menu, "GetMenu error %d\n", GetLastError())
+ res = (GetMenu(window) == (HMENU)menu); \
+ ok(res, "GetMenu error %d\n", GetLastError())
#define expect_style(window, style)\
ok((ULONG)GetWindowLong(window, GWL_STYLE) == (style), "expected style %x != %x\n", (LONG)(style), GetWindowLong(window, GWL_STYLE))
@@ -4494,7 +4743,8 @@ static void test_CreateWindow(void)
assert(parent != 0);
SetLastError(0xdeadbeef);
- ok(IsMenu(hmenu), "IsMenu error %d\n", GetLastError());
+ res = IsMenu(hmenu);
+ ok(res, "IsMenu error %d\n", GetLastError());
/* WS_CHILD */
SetLastError(0xdeadbeef);
@@ -4743,8 +4993,10 @@ static void test_CreateWindow(void)
hwnd = CreateWindowExA(0, "Sizes_WndClass", NULL, WS_CHILD, 300000, 300000, 200000, 200000, parent, 0, 0, NULL);
ok( hwnd != 0, "creation failed err %u\n", GetLastError());
GetClientRect( hwnd, &rc );
- ok( rc.right == 200000 || broken(rc.right == (short)200000), "invalid rect right %u\n", rc.right );
- ok( rc.bottom == 200000 || broken(rc.bottom == (short)200000), "invalid rect bottom %u\n", rc.bottom );
+ ok( rc.right == 200000 || rc.right == 65535 || broken(rc.right == (short)200000),
+ "invalid rect right %u\n", rc.right );
+ ok( rc.bottom == 200000 || rc.bottom == 65535 || broken(rc.bottom == (short)200000),
+ "invalid rect bottom %u\n", rc.bottom );
DestroyWindow(hwnd);
expected_cx = expected_cy = -10;
@@ -4780,7 +5032,8 @@ static void test_CreateWindow(void)
ok( hwnd != 0, "creation failed err %u\n", GetLastError());
GetClientRect( hwnd, &rc );
ok( rc.right == 100, "invalid rect right %u\n", rc.right );
- ok( rc.bottom == 0x7fffffff - 10 || broken(rc.bottom == 0), "invalid rect bottom %u\n", rc.bottom );
+ ok( rc.bottom == 0x7fffffff - 10 || rc.bottom ==65535 || broken(rc.bottom == 0),
+ "invalid rect bottom %u\n", rc.bottom );
DestroyWindow(hwnd);
expected_cx = 0x7fffffff;
@@ -4790,8 +5043,10 @@ static void test_CreateWindow(void)
hwnd = CreateWindowExA(0, "Sizes_WndClass", NULL, WS_CHILD, 20, 10, 0x7fffffff, 0x7fffffff, parent, 0, 0, NULL);
ok( hwnd != 0, "creation failed err %u\n", GetLastError());
GetClientRect( hwnd, &rc );
- ok( rc.right == 0x7fffffff - 20 || broken(rc.right == 0), "invalid rect right %u\n", rc.right );
- ok( rc.bottom == 0x7fffffff - 10 || broken(rc.bottom == 0), "invalid rect bottom %u\n", rc.bottom );
+ ok( rc.right == 0x7fffffff - 20 || rc.right == 65535 || broken(rc.right == 0),
+ "invalid rect right %u\n", rc.right );
+ ok( rc.bottom == 0x7fffffff - 10 || rc.right == 65535 || broken(rc.bottom == 0),
+ "invalid rect bottom %u\n", rc.bottom );
DestroyWindow(hwnd);
/* top level window */
@@ -4804,6 +5059,74 @@ static void test_CreateWindow(void)
ok( rc.bottom <= expected_cy, "invalid rect bottom %u\n", rc.bottom );
DestroyWindow(hwnd);
+ if (pGetLayout && pSetLayout)
+ {
+ HDC hdc = GetDC( parent );
+ pSetLayout( hdc, LAYOUT_RTL );
+ if (pGetLayout( hdc ))
+ {
+ ReleaseDC( parent, hdc );
+ DestroyWindow( parent );
+ SetLastError( 0xdeadbeef );
+ parent = CreateWindowEx(WS_EX_APPWINDOW | WS_EX_LAYOUTRTL, "static", NULL, WS_POPUP,
+ 0, 0, 100, 100, 0, 0, 0, NULL);
+ ok( parent != 0, "creation failed err %u\n", GetLastError());
+ expect_ex_style( parent, WS_EX_APPWINDOW | WS_EX_LAYOUTRTL );
+ hwnd = CreateWindowExA(0, "static", NULL, WS_CHILD, 0, 0, 20, 20, parent, 0, 0, NULL);
+ ok( hwnd != 0, "creation failed err %u\n", GetLastError());
+ expect_ex_style( hwnd, WS_EX_LAYOUTRTL );
+ DestroyWindow( hwnd );
+ hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP, 0, 0, 20, 20, parent, 0, 0, NULL);
+ ok( hwnd != 0, "creation failed err %u\n", GetLastError());
+ expect_ex_style( hwnd, 0 );
+ DestroyWindow( hwnd );
+ SetWindowLongW( parent, GWL_EXSTYLE, WS_EX_APPWINDOW | WS_EX_LAYOUTRTL | WS_EX_NOINHERITLAYOUT );
+ hwnd = CreateWindowExA(0, "static", NULL, WS_CHILD, 0, 0, 20, 20, parent, 0, 0, NULL);
+ ok( hwnd != 0, "creation failed err %u\n", GetLastError());
+ expect_ex_style( hwnd, 0 );
+ DestroyWindow( hwnd );
+
+ if (pGetProcessDefaultLayout && pSetProcessDefaultLayout)
+ {
+ DWORD layout;
+
+ SetLastError( 0xdeadbeef );
+ ok( !pGetProcessDefaultLayout( NULL ), "GetProcessDefaultLayout succeeded\n" );
+ ok( GetLastError() == ERROR_NOACCESS, "wrong error %u\n", GetLastError() );
+ SetLastError( 0xdeadbeef );
+ ok( pGetProcessDefaultLayout( &layout ),
+ "GetProcessDefaultLayout failed err %u\n", GetLastError ());
+ ok( layout == 0, "GetProcessDefaultLayout wrong layout %x\n", layout );
+ SetLastError( 0xdeadbeef );
+ ok( pSetProcessDefaultLayout( 7 ),
+ "SetProcessDefaultLayout failed err %u\n", GetLastError ());
+ ok( pGetProcessDefaultLayout( &layout ),
+ "GetProcessDefaultLayout failed err %u\n", GetLastError ());
+ ok( layout == 7, "GetProcessDefaultLayout wrong layout %x\n", layout );
+ SetLastError( 0xdeadbeef );
+ ok( pSetProcessDefaultLayout( LAYOUT_RTL ),
+ "SetProcessDefaultLayout failed err %u\n", GetLastError ());
+ ok( pGetProcessDefaultLayout( &layout ),
+ "GetProcessDefaultLayout failed err %u\n", GetLastError ());
+ ok( layout == LAYOUT_RTL, "GetProcessDefaultLayout wrong layout %x\n", layout );
+ hwnd = CreateWindowEx(WS_EX_APPWINDOW, "static", NULL, WS_POPUP,
+ 0, 0, 100, 100, 0, 0, 0, NULL);
+ ok( hwnd != 0, "creation failed err %u\n", GetLastError());
+ expect_ex_style( hwnd, WS_EX_APPWINDOW | WS_EX_LAYOUTRTL );
+ DestroyWindow( hwnd );
+ hwnd = CreateWindowEx(WS_EX_APPWINDOW, "static", NULL, WS_POPUP,
+ 0, 0, 100, 100, parent, 0, 0, NULL);
+ ok( hwnd != 0, "creation failed err %u\n", GetLastError());
+ expect_ex_style( hwnd, WS_EX_APPWINDOW );
+ DestroyWindow( hwnd );
+ pSetProcessDefaultLayout( 0 );
+ }
+ else win_skip( "SetProcessDefaultLayout not supported\n" );
+ }
+ else win_skip( "SetLayout not supported\n" );
+ }
+ else win_skip( "SetLayout not available\n" );
+
DestroyWindow(parent);
UnregisterClass("MinMax_WndClass", GetModuleHandle(0));
@@ -4834,13 +5157,13 @@ static void test_SetWindowLong(void)
retval = SetWindowLongPtr(NULL, GWLP_WNDPROC, 0);
ok(!retval, "SetWindowLongPtr on invalid window handle should have returned 0 instead of 0x%lx\n", retval);
ok(check_error(GetLastError(), ERROR_INVALID_WINDOW_HANDLE),
- "SetWindowLongPtr should have set error to ERROR_INVALID_WINDOW_HANDLE instad of %d\n", GetLastError());
+ "SetWindowLongPtr should have set error to ERROR_INVALID_WINDOW_HANDLE instead of %d\n", GetLastError());
SetLastError(0xdeadbeef);
retval = SetWindowLongPtr(hwndMain, 0xdeadbeef, 0);
ok(!retval, "SetWindowLongPtr on invalid index should have returned 0 instead of 0x%lx\n", retval);
ok(check_error(GetLastError(), ERROR_INVALID_INDEX),
- "SetWindowLongPtr should have set error to ERROR_INVALID_INDEX instad of %d\n", GetLastError());
+ "SetWindowLongPtr should have set error to ERROR_INVALID_INDEX instead of %d\n", GetLastError());
SetLastError(0xdeadbeef);
retval = SetWindowLongPtr(hwndMain, GWLP_WNDPROC, 0);
@@ -4872,7 +5195,7 @@ static void test_ShowWindow(void)
{
HWND hwnd;
DWORD style;
- RECT rcMain, rc;
+ RECT rcMain, rc, rcMinimized;
LPARAM ret;
SetRect(&rcMain, 120, 120, 210, 210);
@@ -4914,8 +5237,16 @@ static void test_ShowWindow(void)
ok(style & WS_VISIBLE, "window should be visible\n");
ok(style & WS_MINIMIZE, "window should be minimized\n");
ok(!(style & WS_MAXIMIZE), "window should not be maximized\n");
+ GetWindowRect(hwnd, &rcMinimized);
+ ok(!EqualRect(&rcMain, &rcMinimized), "rects shouldn't match\n");
+ /* shouldn't be able to resize minimized windows */
+ ret = SetWindowPos(hwnd, 0, 0, 0,
+ (rcMinimized.right - rcMinimized.left) * 2,
+ (rcMinimized.bottom - rcMinimized.top) * 2,
+ SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
+ ok(ret, "not expected ret: %lu\n", ret);
GetWindowRect(hwnd, &rc);
- ok(!EqualRect(&rcMain, &rc), "rects shouldn't match\n");
+ ok(EqualRect(&rc, &rcMinimized), "rects should match\n");
ShowWindow(hwnd, SW_RESTORE);
ok(ret, "not expected ret: %lu\n", ret);
@@ -5448,16 +5779,29 @@ static void test_layered_window(void)
COLORREF key = 0;
BYTE alpha = 0;
DWORD flags = 0;
+ POINT pt = { 0, 0 };
+ SIZE sz = { 200, 200 };
+ HDC hdc;
+ HBITMAP hbm;
BOOL ret;
- if (!pGetLayeredWindowAttributes || !pSetLayeredWindowAttributes)
+ if (!pGetLayeredWindowAttributes || !pSetLayeredWindowAttributes || !pUpdateLayeredWindow)
{
win_skip( "layered windows not supported\n" );
return;
}
+
+ hdc = CreateCompatibleDC( 0 );
+ hbm = CreateCompatibleBitmap( hdc, 200, 200 );
+ SelectObject( hdc, hbm );
+
hwnd = CreateWindowExA(0, "MainWindowClass", "message window", WS_CAPTION,
100, 100, 200, 200, 0, 0, 0, NULL);
assert( hwnd );
+ SetLastError( 0xdeadbeef );
+ ret = pUpdateLayeredWindow( hwnd, 0, NULL, &sz, hdc, &pt, 0, NULL, ULW_OPAQUE );
+ ok( !ret, "UpdateLayeredWindow should fail on non-layered window\n" );
+ ok( GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError() );
ret = pGetLayeredWindowAttributes( hwnd, &key, &alpha, &flags );
ok( !ret, "GetLayeredWindowAttributes should fail on non-layered window\n" );
ret = pSetLayeredWindowAttributes( hwnd, 0, 0, LWA_ALPHA );
@@ -5465,6 +5809,10 @@ static void test_layered_window(void)
SetWindowLong( hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED );
ret = pGetLayeredWindowAttributes( hwnd, &key, &alpha, &flags );
ok( !ret, "GetLayeredWindowAttributes should fail on layered but not initialized window\n" );
+ ret = pUpdateLayeredWindow( hwnd, 0, NULL, &sz, hdc, &pt, 0, NULL, ULW_OPAQUE );
+ ok( ret, "UpdateLayeredWindow should succeed on layered window\n" );
+ ret = pGetLayeredWindowAttributes( hwnd, &key, &alpha, &flags );
+ ok( !ret, "GetLayeredWindowAttributes should fail on layered but not initialized window\n" );
ret = pSetLayeredWindowAttributes( hwnd, 0x123456, 44, LWA_ALPHA );
ok( ret, "SetLayeredWindowAttributes should succeed on layered window\n" );
ret = pGetLayeredWindowAttributes( hwnd, &key, &alpha, &flags );
@@ -5472,14 +5820,23 @@ static void test_layered_window(void)
ok( key == 0x123456 || key == 0, "wrong color key %x\n", key );
ok( alpha == 44, "wrong alpha %u\n", alpha );
ok( flags == LWA_ALPHA, "wrong flags %x\n", flags );
+ SetLastError( 0xdeadbeef );
+ ret = pUpdateLayeredWindow( hwnd, 0, NULL, &sz, hdc, &pt, 0, NULL, ULW_OPAQUE );
+ ok( !ret, "UpdateLayeredWindow should fail on layered but initialized window\n" );
+ ok( GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError() );
/* clearing WS_EX_LAYERED resets attributes */
SetWindowLong( hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) & ~WS_EX_LAYERED );
+ SetLastError( 0xdeadbeef );
+ ret = pUpdateLayeredWindow( hwnd, 0, NULL, &sz, hdc, &pt, 0, NULL, ULW_OPAQUE );
+ ok( !ret, "UpdateLayeredWindow should fail on non-layered window\n" );
ret = pGetLayeredWindowAttributes( hwnd, &key, &alpha, &flags );
ok( !ret, "GetLayeredWindowAttributes should fail on no longer layered window\n" );
SetWindowLong( hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED );
ret = pGetLayeredWindowAttributes( hwnd, &key, &alpha, &flags );
ok( !ret, "GetLayeredWindowAttributes should fail on layered but not initialized window\n" );
+ ret = pUpdateLayeredWindow( hwnd, 0, NULL, &sz, hdc, &pt, 0, NULL, ULW_OPAQUE );
+ ok( ret, "UpdateLayeredWindow should succeed on layered window\n" );
ret = pSetLayeredWindowAttributes( hwnd, 0x654321, 22, LWA_COLORKEY | LWA_ALPHA );
ok( ret, "SetLayeredWindowAttributes should succeed on layered window\n" );
ret = pGetLayeredWindowAttributes( hwnd, &key, &alpha, &flags );
@@ -5487,6 +5844,10 @@ static void test_layered_window(void)
ok( key == 0x654321, "wrong color key %x\n", key );
ok( alpha == 22, "wrong alpha %u\n", alpha );
ok( flags == (LWA_COLORKEY | LWA_ALPHA), "wrong flags %x\n", flags );
+ SetLastError( 0xdeadbeef );
+ ret = pUpdateLayeredWindow( hwnd, 0, NULL, &sz, hdc, &pt, 0, NULL, ULW_OPAQUE );
+ ok( !ret, "UpdateLayeredWindow should fail on layered but initialized window\n" );
+ ok( GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError() );
ret = pSetLayeredWindowAttributes( hwnd, 0x888888, 33, LWA_COLORKEY );
ok( ret, "SetLayeredWindowAttributes should succeed on layered window\n" );
@@ -5520,6 +5881,8 @@ static void test_layered_window(void)
ok( flags == 0, "wrong flags %x\n", flags );
DestroyWindow( hwnd );
+ DeleteDC( hdc );
+ DeleteObject( hbm );
}
static MONITORINFO mi;
@@ -5881,7 +6244,8 @@ static void test_thick_child_size(HWND parentWindow)
cls.lpszMenuName = NULL;
cls.lpszClassName = className;
SetLastError(0xdeadbeef);
- ok(RegisterClassA(&cls),"RegisterClassA failed, error: %u\n", GetLastError());
+ success = RegisterClassA(&cls);
+ ok(success,"RegisterClassA failed, error: %u\n", GetLastError());
for(i = 0; i < NUMBER_OF_THICK_CHILD_TESTS; i++)
{
@@ -5973,7 +6337,7 @@ static void test_winregion(void)
{
HWND hwnd;
RECT r;
- int ret;
+ int ret, width;
HRGN hrgn;
if (!pGetWindowRgnBox)
@@ -6006,23 +6370,249 @@ static void test_winregion(void)
ok( r.left == 2 && r.top == 3 && r.right == 10 && r.bottom == 15,
"Expected (2,3,10,15), got (%d,%d,%d,%d)\n", r.left, r.top,
r.right, r.bottom);
- DeleteObject(hrgn);
+ if (pMirrorRgn)
+ {
+ hrgn = CreateRectRgn(2, 3, 10, 15);
+ ret = pMirrorRgn( hwnd, hrgn );
+ ok( ret == TRUE, "MirrorRgn failed %u\n", ret );
+ r.left = r.top = r.right = r.bottom = 0;
+ GetWindowRect( hwnd, &r );
+ width = r.right - r.left;
+ r.left = r.top = r.right = r.bottom = 0;
+ ret = GetRgnBox( hrgn, &r );
+ ok( ret == SIMPLEREGION, "GetRgnBox failed %u\n", ret );
+ ok( r.left == width - 10 && r.top == 3 && r.right == width - 2 && r.bottom == 15,
+ "Wrong rectangle (%d,%d,%d,%d) for width %d\n", r.left, r.top, r.right, r.bottom, width );
+ }
+ else win_skip( "MirrorRgn not supported\n" );
}
DestroyWindow(hwnd);
}
+static void test_rtl_layout(void)
+{
+ HWND parent, child;
+ RECT r;
+ POINT pt;
+
+ if (!pSetProcessDefaultLayout)
+ {
+ win_skip( "SetProcessDefaultLayout not supported\n" );
+ return;
+ }
+
+ parent = CreateWindowExA(WS_EX_LAYOUTRTL, "static", NULL, WS_POPUP, 100, 100, 300, 300, NULL, 0, 0, NULL);
+ child = CreateWindowExA(0, "static", NULL, WS_CHILD, 10, 10, 20, 20, parent, 0, 0, NULL);
+
+ GetWindowRect( parent, &r );
+ ok( r.left == 100 && r.right == 400, "wrong rect %d,%d - %d,%d\n", r.left, r.top, r.right, r.bottom );
+ GetClientRect( parent, &r );
+ ok( r.left == 0 && r.right == 300, "wrong rect %d,%d - %d,%d\n", r.left, r.top, r.right, r.bottom );
+ GetClientRect( child, &r );
+ ok( r.left == 0 && r.right == 20, "wrong rect %d,%d - %d,%d\n", r.left, r.top, r.right, r.bottom );
+ MapWindowPoints( child, parent, (POINT *)&r, 2 );
+ ok( r.left == 10 && r.right == 30, "wrong rect %d,%d - %d,%d\n", r.left, r.top, r.right, r.bottom );
+ GetWindowRect( child, &r );
+ ok( r.left == 370 && r.right == 390, "wrong rect %d,%d - %d,%d\n", r.left, r.top, r.right, r.bottom );
+ MapWindowPoints( NULL, parent, (POINT *)&r, 2 );
+ ok( r.left == 10 && r.right == 30, "wrong rect %d,%d - %d,%d\n", r.left, r.top, r.right, r.bottom );
+ GetWindowRect( child, &r );
+ MapWindowPoints( NULL, parent, (POINT *)&r, 1 );
+ MapWindowPoints( NULL, parent, (POINT *)&r + 1, 1 );
+ ok( r.left == 30 && r.right == 10, "wrong rect %d,%d - %d,%d\n", r.left, r.top, r.right, r.bottom );
+ pt.x = pt.y = 12;
+ MapWindowPoints( child, parent, &pt, 1 );
+ ok( pt.x == 22 && pt.y == 22, "wrong point %d,%d\n", pt.x, pt.y );
+ SetWindowPos( parent, 0, 0, 0, 250, 250, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE );
+ GetWindowRect( parent, &r );
+ ok( r.left == 100 && r.right == 350, "wrong rect %d,%d - %d,%d\n", r.left, r.top, r.right, r.bottom );
+ GetWindowRect( child, &r );
+ ok( r.left == 320 && r.right == 340, "wrong rect %d,%d - %d,%d\n", r.left, r.top, r.right, r.bottom );
+ SetWindowLongW( parent, GWL_EXSTYLE, 0 );
+ GetWindowRect( child, &r );
+ ok( r.left == 320 && r.right == 340, "wrong rect %d,%d - %d,%d\n", r.left, r.top, r.right, r.bottom );
+ MapWindowPoints( NULL, parent, (POINT *)&r, 2 );
+ ok( r.left == 220 && r.right == 240, "wrong rect %d,%d - %d,%d\n", r.left, r.top, r.right, r.bottom );
+ SetWindowLongW( parent, GWL_EXSTYLE, WS_EX_LAYOUTRTL );
+ GetWindowRect( child, &r );
+ ok( r.left == 320 && r.right == 340, "wrong rect %d,%d - %d,%d\n", r.left, r.top, r.right, r.bottom );
+ MapWindowPoints( NULL, parent, (POINT *)&r, 2 );
+ ok( r.left == 10 && r.right == 30, "wrong rect %d,%d - %d,%d\n", r.left, r.top, r.right, r.bottom );
+ SetWindowPos( child, 0, 0, 0, 30, 30, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE );
+ GetWindowRect( child, &r );
+ ok( r.left == 310 && r.right == 340, "wrong rect %d,%d - %d,%d\n", r.left, r.top, r.right, r.bottom );
+ MapWindowPoints( NULL, parent, (POINT *)&r, 2 );
+ ok( r.left == 10 && r.right == 40, "wrong rect %d,%d - %d,%d\n", r.left, r.top, r.right, r.bottom );
+ DestroyWindow( child );
+ DestroyWindow( parent );
+}
+
+static void test_FlashWindowEx(void)
+{
+ HWND hwnd;
+ FLASHWINFO finfo;
+ BOOL ret;
+
+ if (!pFlashWindowEx)
+ {
+ win_skip( "FlashWindowEx not supported\n" );
+ return;
+ }
+
+ hwnd = CreateWindowExA( 0, "MainWindowClass", "FlashWindow", WS_POPUP,
+ 0, 0, 0, 0, 0, 0, 0, NULL );
+ ok( hwnd != 0, "CreateWindowExA error %d\n", GetLastError() );
+
+ finfo.cbSize = sizeof(FLASHWINFO);
+ finfo.dwFlags = FLASHW_TIMER;
+ finfo.uCount = 3;
+ finfo.dwTimeout = 200;
+ finfo.hwnd = NULL;
+ SetLastError(0xdeadbeef);
+ ret = pFlashWindowEx(&finfo);
+ todo_wine ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
+ "FlashWindowEx returned with %d\n", GetLastError());
+
+ finfo.hwnd = hwnd;
+ SetLastError(0xdeadbeef);
+ ret = pFlashWindowEx(NULL);
+ todo_wine ok(!ret && GetLastError() == ERROR_NOACCESS,
+ "FlashWindowEx returned with %d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = pFlashWindowEx(&finfo);
+ todo_wine ok(!ret, "FlashWindowEx succeeded\n");
+
+ finfo.cbSize = sizeof(FLASHWINFO) - 1;
+ SetLastError(0xdeadbeef);
+ ret = pFlashWindowEx(&finfo);
+ todo_wine ok(!ret && GetLastError()==ERROR_INVALID_PARAMETER,
+ "FlashWindowEx succeeded\n");
+
+ finfo.cbSize = sizeof(FLASHWINFO) + 1;
+ SetLastError(0xdeadbeef);
+ ret = pFlashWindowEx(&finfo);
+ todo_wine ok(!ret && GetLastError()==ERROR_INVALID_PARAMETER,
+ "FlashWindowEx succeeded\n");
+ finfo.cbSize = sizeof(FLASHWINFO);
+
+ DestroyWindow( hwnd );
+
+ SetLastError(0xdeadbeef);
+ ret = pFlashWindowEx(&finfo);
+ todo_wine ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
+ "FlashWindowEx returned with %d\n", GetLastError());
+
+ ok(finfo.cbSize == sizeof(FLASHWINFO), "FlashWindowEx modified cdSize to %x\n", finfo.cbSize);
+ ok(finfo.hwnd == hwnd, "FlashWindowEx modified hwnd to %p\n", finfo.hwnd);
+ ok(finfo.dwFlags == FLASHW_TIMER, "FlashWindowEx modified dwFlags to %x\n", finfo.dwFlags);
+ ok(finfo.uCount == 3, "FlashWindowEx modified uCount to %x\n", finfo.uCount);
+ ok(finfo.dwTimeout == 200, "FlashWindowEx modified dwTimeout to %x\n", finfo.dwTimeout);
+
+ hwnd = CreateWindowExA( 0, "MainWindowClass", "FlashWindow", WS_VISIBLE | WS_POPUPWINDOW,
+ 0, 0, 0, 0, 0, 0, 0, NULL );
+ ok( hwnd != 0, "CreateWindowExA error %d\n", GetLastError() );
+ finfo.hwnd = hwnd;
+
+ SetLastError(0xdeadbeef);
+ ret = pFlashWindowEx(NULL);
+ todo_wine ok(!ret && GetLastError() == ERROR_NOACCESS,
+ "FlashWindowEx returned with %d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = pFlashWindowEx(&finfo);
+ todo_wine ok(!ret, "FlashWindowEx succeeded\n");
+
+ ok(finfo.cbSize == sizeof(FLASHWINFO), "FlashWindowEx modified cdSize to %x\n", finfo.cbSize);
+ ok(finfo.hwnd == hwnd, "FlashWindowEx modified hwnd to %p\n", finfo.hwnd);
+ ok(finfo.dwFlags == FLASHW_TIMER, "FlashWindowEx modified dwFlags to %x\n", finfo.dwFlags);
+ ok(finfo.uCount == 3, "FlashWindowEx modified uCount to %x\n", finfo.uCount);
+ ok(finfo.dwTimeout == 200, "FlashWindowEx modified dwTimeout to %x\n", finfo.dwTimeout);
+
+ finfo.dwFlags = FLASHW_STOP;
+ SetLastError(0xdeadbeef);
+ ret = pFlashWindowEx(&finfo);
+ ok(ret, "FlashWindowEx failed with %d\n", GetLastError());
+
+ DestroyWindow( hwnd );
+}
+
+static void test_FindWindowEx(void)
+{
+ HWND hwnd, found;
+ CHAR title[1];
+
+ hwnd = CreateWindowExA( 0, "MainWindowClass", "caption", WS_POPUP, 0,0,0,0, 0, 0, 0, NULL );
+ ok( hwnd != 0, "CreateWindowExA error %d\n", GetLastError() );
+
+ title[0] = 0;
+
+ found = FindWindowExA( 0, 0, "MainWindowClass", title );
+ ok( found == NULL, "expected a NULL hwnd\n" );
+ found = FindWindowExA( 0, 0, "MainWindowClass", NULL );
+ ok( found == hwnd, "found is %p, expected a valid hwnd\n", found );
+
+ DestroyWindow( hwnd );
+
+ hwnd = CreateWindowExA( 0, "MainWindowClass", NULL, WS_POPUP, 0,0,0,0, 0, 0, 0, NULL );
+ ok( hwnd != 0, "CreateWindowExA error %d\n", GetLastError() );
+
+ found = FindWindowExA( 0, 0, "MainWindowClass", title );
+ ok( found == hwnd, "found is %p, expected a valid hwnd\n", found );
+ found = FindWindowExA( 0, 0, "MainWindowClass", NULL );
+ ok( found == hwnd, "found is %p, expected a valid hwnd\n", found );
+
+ DestroyWindow( hwnd );
+
+ /* test behaviour with a window title that is an empty character */
+ found = FindWindowExA( 0, 0, "Shell_TrayWnd", title );
+ ok( found != NULL, "found is NULL, expected a valid hwnd\n" );
+ found = FindWindowExA( 0, 0, "Shell_TrayWnd", NULL );
+ ok( found != NULL, "found is NULL, expected a valid hwnd\n" );
+}
+
+static void test_GetLastActivePopup(void)
+{
+ HWND hwndOwner, hwndPopup1, hwndPopup2;
+
+ hwndOwner = CreateWindowExA(0, "MainWindowClass", NULL,
+ WS_VISIBLE | WS_POPUPWINDOW,
+ 100, 100, 200, 200,
+ NULL, 0, GetModuleHandle(0), NULL);
+ hwndPopup1 = CreateWindowExA(0, "MainWindowClass", NULL,
+ WS_VISIBLE | WS_POPUPWINDOW,
+ 100, 100, 200, 200,
+ hwndOwner, 0, GetModuleHandle(0), NULL);
+ hwndPopup2 = CreateWindowExA(0, "MainWindowClass", NULL,
+ WS_VISIBLE | WS_POPUPWINDOW,
+ 100, 100, 200, 200,
+ hwndPopup1, 0, GetModuleHandle(0), NULL);
+ ok( GetLastActivePopup(hwndOwner) == hwndPopup2, "wrong last active popup\n" );
+ DestroyWindow( hwndPopup2 );
+ DestroyWindow( hwndPopup1 );
+ DestroyWindow( hwndOwner );
+}
+
START_TEST(win)
{
HMODULE user32 = GetModuleHandleA( "user32.dll" );
+ HMODULE gdi32 = GetModuleHandleA("gdi32.dll");
pGetAncestor = (void *)GetProcAddress( user32, "GetAncestor" );
pGetWindowInfo = (void *)GetProcAddress( user32, "GetWindowInfo" );
pGetWindowModuleFileNameA = (void *)GetProcAddress( user32, "GetWindowModuleFileNameA" );
pGetLayeredWindowAttributes = (void *)GetProcAddress( user32, "GetLayeredWindowAttributes" );
pSetLayeredWindowAttributes = (void *)GetProcAddress( user32, "SetLayeredWindowAttributes" );
+ pUpdateLayeredWindow = (void *)GetProcAddress( user32, "UpdateLayeredWindow" );
pGetMonitorInfoA = (void *)GetProcAddress( user32, "GetMonitorInfoA" );
pMonitorFromPoint = (void *)GetProcAddress( user32, "MonitorFromPoint" );
pGetWindowRgnBox = (void *)GetProcAddress( user32, "GetWindowRgnBox" );
pGetGUIThreadInfo = (void *)GetProcAddress( user32, "GetGUIThreadInfo" );
+ pGetProcessDefaultLayout = (void *)GetProcAddress( user32, "GetProcessDefaultLayout" );
+ pSetProcessDefaultLayout = (void *)GetProcAddress( user32, "SetProcessDefaultLayout" );
+ pFlashWindowEx = (void *)GetProcAddress( user32, "FlashWindowEx" );
+ pGetLayout = (void *)GetProcAddress( gdi32, "GetLayout" );
+ pSetLayout = (void *)GetProcAddress( gdi32, "SetLayout" );
+ pMirrorRgn = (void *)GetProcAddress( gdi32, "MirrorRgn" );
if (!RegisterWindowClasses()) assert(0);
@@ -6033,6 +6623,10 @@ START_TEST(win)
hhook = SetWindowsHookExA(WH_CBT, cbt_hook_proc, 0, GetCurrentThreadId());
if (!hhook) win_skip( "Cannot set CBT hook, skipping some tests\n" );
+ /* make sure that these tests are executed first */
+ test_FindWindowEx();
+ test_SetParent();
+
hwndMain = CreateWindowExA(/*WS_EX_TOOLWINDOW*/ 0, "MainWindowClass", "Main window",
WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX |
WS_MAXIMIZEBOX | WS_POPUP,
@@ -6059,15 +6653,16 @@ START_TEST(win)
test_capture_2();
test_capture_3(hwndMain, hwndMain2);
test_capture_4();
+ test_rtl_layout();
+ test_FlashWindowEx();
test_CreateWindow();
test_parent_owner();
- test_SetParent();
test_enum_thread_windows();
test_mdi();
test_icons();
- test_SetWindowPos(hwndMain);
+ test_SetWindowPos(hwndMain, hwndMain2);
test_SetMenu(hwndMain);
test_SetFocus(hwndMain);
test_SetActiveWindow(hwndMain);
@@ -6076,6 +6671,7 @@ START_TEST(win)
test_children_zorder(hwndMain);
test_popup_zorder(hwndMain2, hwndMain, WS_POPUP);
test_popup_zorder(hwndMain2, hwndMain, 0);
+ test_GetLastActivePopup();
test_keyboard_input(hwndMain);
test_mouse_input(hwndMain);
test_validatergn(hwndMain);
@@ -6098,11 +6694,14 @@ START_TEST(win)
test_Expose();
test_layered_window();
- test_SetForegroundWindow(hwndMain);
- if(!winetest_interactive)
- skip("bug 5957: skipping test_shell_window, it crashes ros/win7 explorer\n");
+ if(!winetest_interactive)
+ skip("skipping test_SetForegroundWindow, Hangs on WaitForSingleObject line 2771\n");
else
- test_shell_window();
+ test_SetForegroundWindow(hwndMain);
+ if(!winetest_interactive)
+ skip("bug 5957: skipping test_shell_window, it crashes ros/win7 explorer\n");
+ else
+ test_shell_window();
test_handles( hwndMain );
test_winregion();
diff --git a/winetests/user32/wsprintf.c b/winetests/user32/wsprintf.c
index bca16bd9f86..5370df4636a 100755
--- a/winetests/user32/wsprintf.c
+++ b/winetests/user32/wsprintf.c
@@ -23,39 +23,93 @@
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
+#include "winnls.h"
+
+static const struct
+{
+ const char *fmt;
+ ULONGLONG value;
+ const char *res;
+} i64_formats[] =
+{
+ { "%I64X", ((ULONGLONG)0x12345 << 32) | 0x67890a, "123450067890A" },
+ { "%I32X", ((ULONGLONG)0x12345 << 32) | 0x67890a, "67890A" },
+ { "%I64d", (ULONGLONG)543210 * 1000000, "543210000000" },
+ { "%I64X", (LONGLONG)-0x12345, "FFFFFFFFFFFEDCBB" },
+ { "%I32x", (LONGLONG)-0x12345, "fffedcbb" },
+ { "%I64u", (LONGLONG)-123, "18446744073709551493" },
+ { "%Id", (LONGLONG)-12345, "-12345" },
+#ifdef _WIN64
+ { "%Ix", ((ULONGLONG)0x12345 << 32) | 0x67890a, "123450067890a" },
+ { "%Ix", (LONGLONG)-0x12345, "fffffffffffedcbb" },
+ { "%p", (LONGLONG)-0x12345, "FFFFFFFFFFFEDCBB" },
+#else
+ { "%Ix", ((ULONGLONG)0x12345 << 32) | 0x67890a, "67890a" },
+ { "%Ix", (LONGLONG)-0x12345, "fffedcbb" },
+ { "%p", (LONGLONG)-0x12345, "FFFEDCBB" },
+#endif
+};
static void wsprintfATest(void)
{
char buf[25];
+ unsigned int i;
int rc;
rc=wsprintfA(buf, "%010ld", -1);
- ok(rc == 10, "wsPrintfA length failure: rc=%d error=%d\n",rc,GetLastError());
+ ok(rc == 10, "wsprintfA length failure: rc=%d error=%d\n",rc,GetLastError());
ok((lstrcmpA(buf, "-000000001") == 0),
"wsprintfA zero padded negative value failure: buf=[%s]\n",buf);
+ rc = wsprintfA(buf, "%I64X", (ULONGLONG)0);
+ if (rc == 4 && !lstrcmpA(buf, "I64X"))
+ {
+ win_skip( "I64 formats not supported\n" );
+ return;
+ }
+ for (i = 0; i < sizeof(i64_formats)/sizeof(i64_formats[0]); i++)
+ {
+ rc = wsprintfA(buf, i64_formats[i].fmt, i64_formats[i].value);
+ ok(rc == strlen(i64_formats[i].res), "%u: wsprintfA length failure: rc=%d\n", i, rc);
+ ok(!strcmp(buf, i64_formats[i].res), "%u: wrong result [%s]\n", i, buf);
+ }
}
static void wsprintfWTest(void)
{
- static const WCHAR fmt[] = {'%','0','1','0','l','d','\0'};
- static const WCHAR target[] = {'-','0','0','0','0','0','0','0','0','1', '\0'};
- WCHAR buf[25];
+ static const WCHAR fmt_010ld[] = {'%','0','1','0','l','d','\0'};
+ static const WCHAR res_010ld[] = {'-','0','0','0','0','0','0','0','0','1', '\0'};
+ static const WCHAR fmt_I64x[] = {'%','I','6','4','x',0};
+ WCHAR buf[25], fmt[25], res[25];
+ unsigned int i;
int rc;
- rc=wsprintfW(buf, fmt, -1);
+ rc=wsprintfW(buf, fmt_010ld, -1);
if (rc==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
{
win_skip("wsprintfW is not implemented\n");
return;
}
ok(rc == 10, "wsPrintfW length failure: rc=%d error=%d\n",rc,GetLastError());
- ok((lstrcmpW(buf, target) == 0),
+ ok((lstrcmpW(buf, res_010ld) == 0),
"wsprintfW zero padded negative value failure\n");
+ rc = wsprintfW(buf, fmt_I64x, (ULONGLONG)0 );
+ if (rc == 4 && !lstrcmpW(buf, fmt_I64x + 1))
+ {
+ win_skip( "I64 formats not supported\n" );
+ return;
+ }
+ for (i = 0; i < sizeof(i64_formats)/sizeof(i64_formats[0]); i++)
+ {
+ MultiByteToWideChar( CP_ACP, 0, i64_formats[i].fmt, -1, fmt, sizeof(fmt)/sizeof(WCHAR) );
+ MultiByteToWideChar( CP_ACP, 0, i64_formats[i].res, -1, res, sizeof(res)/sizeof(WCHAR) );
+ rc = wsprintfW(buf, fmt, i64_formats[i].value);
+ ok(rc == lstrlenW(res), "%u: wsprintfW length failure: rc=%d\n", i, rc);
+ ok(!lstrcmpW(buf, res), "%u: wrong result [%s]\n", i, wine_dbgstr_w(buf));
+ }
}
/* Test if the CharUpper / CharLower functions return true 16 bit results,
- if the input is a 16 bit input value. Up to Wine 11-2003 the input value
- 0xff returns 0xffffffff. */
+ if the input is a 16 bit input value. */
static void CharUpperTest(void)
{