Based on a patch by Paul Gofman.
v2 - Changed title - Removed CoCreateInstance calls.
Signed-off-by: Alistair Leslie-Hughes leslie_alistair@hotmail.com --- dlls/user32/tests/Makefile.in | 2 +- dlls/user32/tests/win.c | 156 ++++++++++++++++++++++++++++++++++ 2 files changed, 157 insertions(+), 1 deletion(-)
diff --git a/dlls/user32/tests/Makefile.in b/dlls/user32/tests/Makefile.in index dd101d69f3c..73f692b9d4b 100644 --- a/dlls/user32/tests/Makefile.in +++ b/dlls/user32/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = user32.dll -IMPORTS = user32 gdi32 advapi32 hid +IMPORTS = user32 gdi32 advapi32 hid ole32 imm32
C_SRCS = \ broadcast.c \ diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c index 47864340e39..08f413c88e6 100644 --- a/dlls/user32/tests/win.c +++ b/dlls/user32/tests/win.c @@ -31,6 +31,8 @@ #include "wingdi.h" #include "winuser.h" #include "winreg.h" +#include "objbase.h" +#include "imm.h"
#include "wine/test.h"
@@ -11894,6 +11896,158 @@ static void test_cancel_mode(void) DestroyWindow(hwnd2); }
+static LRESULT CALLBACK TestWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + return DefWindowProcA(hwnd, uMsg, wParam, lParam); +} + +static DWORD WINAPI window_create_noime_thread(LPVOID data) +{ + APTTYPEQUALIFIER apttypequal; + APTTYPE apttype; + HWND hwnd; + HRESULT hr; + + /* Show that Disabling IME stops the implicit MTA creation. */ + ImmDisableIME(GetCurrentThreadId()); + + hwnd = CreateWindowExA(0, "Test class", "Test window", WS_VISIBLE, 0, 0, 100, 100, + GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL); + + hr = CoGetApartmentType(&apttype, &apttypequal); + ok(hr == CO_E_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + + DestroyWindow(hwnd); + + return 0; +} + +static DWORD WINAPI window_create_setwindowpos_thread(LPVOID data) +{ + APTTYPEQUALIFIER apttypequal; + APTTYPE apttype; + HWND hwnd; + HRESULT hr; + + hr = CoGetApartmentType(&apttype, &apttypequal); + ok(hr == CO_E_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + + hwnd = CreateWindowExA(0, "Test class", "Test window", WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_SYSMENU | WS_MINIMIZEBOX, 0, 0, 100, 100, + GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL); + + hr = CoGetApartmentType(&apttype, &apttypequal); + ok(hr == CO_E_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + + /* Showing the window actually causes the implicit MTA */ + SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW); + + hr = CoGetApartmentType(&apttype, &apttypequal); + todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + todo_wine ok(apttype == APTTYPE_MAINSTA && apttypequal == APTTYPEQUALIFIER_NONE, "Unexpected %u/%u\n", apttype, apttypequal); + + hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = CoGetApartmentType(&apttype, &apttypequal); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(apttype == APTTYPE_MTA && apttypequal == APTTYPEQUALIFIER_NONE, "Unexpected %u/%u\n", apttype, apttypequal); + CoUninitialize(); + + DestroyWindow(hwnd); + + return 0; +} + +static DWORD WINAPI window_create_show_window_thread(LPVOID data) +{ + APTTYPEQUALIFIER apttypequal; + APTTYPE apttype; + HWND hwnd; + HRESULT hr; + + hr = CoGetApartmentType(&apttype, &apttypequal); + ok(hr == CO_E_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + + hwnd = CreateWindowExA(0, "Test class", "Test window", WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_SYSMENU | WS_MINIMIZEBOX, 0, 0, 100, 100, + GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL); + + hr = CoGetApartmentType(&apttype, &apttypequal); + ok(hr == CO_E_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + + /* Showing the window actually causes the implicit MTA */ + ShowWindow(hwnd, SW_SHOW); + + hr = CoGetApartmentType(&apttype, &apttypequal); + todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + todo_wine ok(apttype == APTTYPE_MAINSTA && apttypequal == APTTYPEQUALIFIER_NONE, "Unexpected %u/%u\n", apttype, apttypequal); + + DestroyWindow(hwnd); + + return 0; +} + +static DWORD WINAPI window_create_visible_thread(LPVOID data) +{ + APTTYPEQUALIFIER apttypequal; + APTTYPE apttype; + HWND hwnd; + HRESULT hr; + + hr = CoGetApartmentType(&apttype, &apttypequal); + ok(hr == CO_E_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + + hwnd = CreateWindowExA(0, "Test class", "Test window", WS_VISIBLE, 0, 0, 100, 100, + GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL); + + hr = CoGetApartmentType(&apttype, &apttypequal); + todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + todo_wine ok(apttype == APTTYPE_MAINSTA && apttypequal == APTTYPEQUALIFIER_NONE, "Unexpected %u/%u\n", apttype, apttypequal); + + DestroyWindow(hwnd); + + return 0; +} + +static void test_implicit_mta(void) +{ + APTTYPEQUALIFIER apttypequal; + APTTYPE apttype; + WNDCLASSA clsA; + HRESULT hr; + HANDLE thread; + + clsA.style = 0; + clsA.lpfnWndProc = TestWindowProc; + clsA.cbClsExtra = 0; + clsA.cbWndExtra = 0; + clsA.hInstance = GetModuleHandleA(NULL); + clsA.hIcon = 0; + clsA.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW); + clsA.hbrBackground = GetStockObject(WHITE_BRUSH); + clsA.lpszMenuName = NULL; + clsA.lpszClassName = "Test class"; + + RegisterClassA(&clsA); + + hr = CoGetApartmentType(&apttype, &apttypequal); + ok(hr == CO_E_NOTINITIALIZED, "Unexpected hr %#x.\n", hr); + + thread = CreateThread(NULL, 0, window_create_noime_thread, NULL, 0, NULL); + WaitForSingleObject(thread, INFINITE); + CloseHandle(thread); + + thread = CreateThread(NULL, 0, window_create_setwindowpos_thread, NULL, 0, NULL); + WaitForSingleObject(thread, INFINITE); + CloseHandle(thread); + + thread = CreateThread(NULL, 0, window_create_show_window_thread, NULL, 0, NULL); + WaitForSingleObject(thread, INFINITE); + CloseHandle(thread); + + thread = CreateThread(NULL, 0, window_create_visible_thread, NULL, 0, NULL); + WaitForSingleObject(thread, INFINITE); + CloseHandle(thread); +} + START_TEST(win) { char **argv; @@ -11941,6 +12095,8 @@ START_TEST(win) return; }
+ test_implicit_mta(); + if (!RegisterWindowClasses()) assert(0);
hwndMain = CreateWindowExA(/*WS_EX_TOOLWINDOW*/ 0, "MainWindowClass", "Main window",