Author: akhaldi
Date: Thu Aug 18 10:08:05 2016
New Revision: 72282
URL:
http://svn.reactos.org/svn/reactos?rev=72282&view=rev
Log:
[IMM32_WINETEST] Sync with Wine Staging 1.9.16. CORE-11866
Modified:
trunk/rostests/winetests/imm32/imm32.c
Modified: trunk/rostests/winetests/imm32/imm32.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/imm32/imm32.c?r…
==============================================================================
--- trunk/rostests/winetests/imm32/imm32.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/imm32/imm32.c [iso-8859-1] Thu Aug 18 10:08:05 2016
@@ -44,7 +44,7 @@
HWND hwnd;
HHOOK get_msg_hook;
HHOOK call_wnd_proc_hook;
- imm_msgs msgs[32];
+ imm_msgs msgs[64];
unsigned int i_msg;
} msg_spy;
@@ -58,6 +58,12 @@
HARDWAREINPUT hi;
} u;
} TEST_INPUT;
+
+typedef struct _tagTRANSMSG {
+ UINT message;
+ WPARAM wParam;
+ LPARAM lParam;
+} TRANSMSG, *LPTRANSMSG;
static UINT (WINAPI *pSendInput) (UINT, INPUT*, size_t);
@@ -166,19 +172,72 @@
* messages being sent to this window in response.
*/
static const char wndcls[] = "winetest_imm32_wndcls";
+static enum { PHASE_UNKNOWN, FIRST_WINDOW, SECOND_WINDOW,
+ CREATE_CANCEL, NCCREATE_CANCEL, IME_DISABLED } test_phase;
static HWND hwnd;
+static HWND get_ime_window(void);
+
static LRESULT WINAPI wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
+ HWND default_ime_wnd;
switch (msg)
{
case WM_IME_SETCONTEXT:
+ return TRUE;
case WM_NCCREATE:
+ default_ime_wnd = get_ime_window();
+ switch(test_phase) {
+ case FIRST_WINDOW:
+ case IME_DISABLED:
+ ok(!default_ime_wnd, "expected no IME windows\n");
+ break;
+ case SECOND_WINDOW:
+ ok(default_ime_wnd != NULL, "expected IME window
existence\n");
+ break;
+ default:
+ break; /* do nothing */
+ }
+ if (test_phase == NCCREATE_CANCEL)
+ return FALSE;
+ return TRUE;
+ case WM_NCCALCSIZE:
+ default_ime_wnd = get_ime_window();
+ switch(test_phase) {
+ case FIRST_WINDOW:
+ case SECOND_WINDOW:
+ case CREATE_CANCEL:
+ todo_wine_if(test_phase == FIRST_WINDOW || test_phase ==
CREATE_CANCEL)
+ ok(default_ime_wnd != NULL, "expected IME window
existence\n");
+ break;
+ case IME_DISABLED:
+ ok(!default_ime_wnd, "expected no IME windows\n");
+ break;
+ default:
+ break; /* do nothing */
+ }
+ break;
case WM_CREATE:
+ default_ime_wnd = get_ime_window();
+ switch(test_phase) {
+ case FIRST_WINDOW:
+ case SECOND_WINDOW:
+ case CREATE_CANCEL:
+ todo_wine_if(test_phase == FIRST_WINDOW || test_phase ==
CREATE_CANCEL)
+ ok(default_ime_wnd != NULL, "expected IME window
existence\n");
+ break;
+ case IME_DISABLED:
+ ok(!default_ime_wnd, "expected no IME windows\n");
+ break;
+ default:
+ break; /* do nothing */
+ }
+ if (test_phase == CREATE_CANCEL)
+ return -1;
return TRUE;
}
- return DefWindowProcA(hwnd,msg,wParam,lParam);
+ return DefWindowProcA(hWnd,msg,wParam,lParam);
}
static BOOL init(void) {
@@ -633,8 +692,11 @@
ImmReleaseContext(threadinfo.hwnd,otherHimc);
ImmReleaseContext(hwnd,himc);
- DestroyWindow(threadinfo.hwnd);
- TerminateThread(hThread, 1);
+ SendMessageA(threadinfo.hwnd, WM_CLOSE, 0, 0);
+ rc = PostThreadMessageA(dwThreadId, WM_QUIT, 1, 0);
+ ok(rc == 1, "PostThreadMessage should succeed\n");
+ WaitForSingleObject(hThread, INFINITE);
+ CloseHandle(hThread);
himc = ImmGetContext(GetDesktopWindow());
ok(himc == NULL, "Should not be able to get himc from other process
window\n");
@@ -836,11 +898,175 @@
WaitForSingleObject(thread, INFINITE);
ok(thread_ime_wnd != def1, "thread_ime_wnd == def1\n");
ok(!IsWindow(thread_ime_wnd), "thread_ime_wnd was not destroyed\n");
+ CloseHandle(thread);
ImmReleaseContext(hwnd, imc1);
ImmReleaseContext(hwnd, imc3);
ImmDestroyContext(imc2);
DestroyWindow(hwnd);
+}
+
+static BOOL CALLBACK is_ime_window_proc(HWND hWnd, LPARAM param)
+{
+ static const WCHAR imeW[] = {'I','M','E',0};
+ WCHAR class_nameW[16];
+ HWND *ime_window = (HWND *)param;
+ if (GetClassNameW(hWnd, class_nameW, sizeof(class_nameW)/sizeof(class_nameW[0]))
&&
+ !lstrcmpW(class_nameW, imeW)) {
+ *ime_window = hWnd;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static HWND get_ime_window(void)
+{
+ HWND ime_window = NULL;
+ EnumThreadWindows(GetCurrentThreadId(), is_ime_window_proc,
(LPARAM)&ime_window);
+ return ime_window;
+}
+
+struct testcase_ime_window {
+ BOOL visible;
+ BOOL top_level_window;
+};
+
+static DWORD WINAPI test_default_ime_window_cb(void *arg)
+{
+ struct testcase_ime_window *testcase = (struct testcase_ime_window *)arg;
+ DWORD visible = testcase->visible ? WS_VISIBLE : 0;
+ HWND hwnd1, hwnd2, default_ime_wnd, ime_wnd;
+
+ ok(!get_ime_window(), "Expected no IME windows\n");
+ if (testcase->top_level_window) {
+ test_phase = FIRST_WINDOW;
+ hwnd1 = CreateWindowExA(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll
test",
+ WS_OVERLAPPEDWINDOW | visible,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
+ }
+ else {
+ hwnd1 = CreateWindowExA(WS_EX_CLIENTEDGE, "EDIT", "Wine imm32.dll
test",
+ WS_CHILD | visible,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ 240, 24, hwnd, NULL, GetModuleHandleW(NULL), NULL);
+ }
+ ime_wnd = get_ime_window();
+ todo_wine ok(ime_wnd != NULL, "Expected IME window existence\n");
+ default_ime_wnd = ImmGetDefaultIMEWnd(hwnd1);
+ todo_wine ok(ime_wnd == default_ime_wnd, "Expected %p, got %p\n", ime_wnd,
default_ime_wnd);
+
+ test_phase = SECOND_WINDOW;
+ hwnd2 = CreateWindowExA(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
+ WS_OVERLAPPEDWINDOW | visible,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
+ DestroyWindow(hwnd2);
+ todo_wine ok(IsWindow(ime_wnd) ||
+ broken(!testcase->visible /* Vista */) ||
+ broken(!testcase->top_level_window /* Vista */) ,
+ "Expected IME window existence\n");
+ DestroyWindow(hwnd1);
+ ok(!IsWindow(ime_wnd), "Expected no IME windows\n");
+ return 1;
+}
+
+static DWORD WINAPI test_default_ime_window_cancel_cb(void *arg)
+{
+ struct testcase_ime_window *testcase = (struct testcase_ime_window *)arg;
+ DWORD visible = testcase->visible ? WS_VISIBLE : 0;
+ HWND hwnd1, hwnd2, default_ime_wnd, ime_wnd;
+
+ ok(!get_ime_window(), "Expected no IME windows\n");
+ test_phase = NCCREATE_CANCEL;
+ hwnd1 = CreateWindowExA(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
+ WS_OVERLAPPEDWINDOW | visible,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
+ ok(hwnd1 == NULL, "creation succeeded, got %p\n", hwnd1);
+ ok(!get_ime_window(), "Expected no IME windows\n");
+
+ test_phase = CREATE_CANCEL;
+ hwnd1 = CreateWindowExA(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
+ WS_OVERLAPPEDWINDOW | visible,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
+ ok(hwnd1 == NULL, "creation succeeded, got %p\n", hwnd1);
+ ok(!get_ime_window(), "Expected no IME windows\n");
+
+ test_phase = FIRST_WINDOW;
+ hwnd2 = CreateWindowExA(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
+ WS_OVERLAPPEDWINDOW | visible,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
+ ime_wnd = get_ime_window();
+ todo_wine ok(ime_wnd != NULL, "Expected IME window existence\n");
+ default_ime_wnd = ImmGetDefaultIMEWnd(hwnd2);
+ todo_wine ok(ime_wnd == default_ime_wnd, "Expected %p, got %p\n", ime_wnd,
default_ime_wnd);
+
+ DestroyWindow(hwnd2);
+ ok(!IsWindow(ime_wnd), "Expected no IME windows\n");
+ return 1;
+}
+
+static DWORD WINAPI test_default_ime_disabled_cb(void *arg)
+{
+ HWND hWnd, default_ime_wnd;
+
+ ok(!get_ime_window(), "Expected no IME windows\n");
+ ImmDisableIME(GetCurrentThreadId());
+ test_phase = IME_DISABLED;
+ hWnd = CreateWindowExA(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test",
+ WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL);
+ default_ime_wnd = ImmGetDefaultIMEWnd(hWnd);
+ ok(!default_ime_wnd, "Expected no IME windows\n");
+ DestroyWindow(hWnd);
+ return 1;
+}
+
+static void test_default_ime_window_creation(void)
+{
+ HANDLE thread;
+ size_t i;
+ struct testcase_ime_window testcases[] = {
+ /* visible, top-level window */
+ { TRUE, TRUE },
+ { FALSE, TRUE },
+ { TRUE, FALSE },
+ { FALSE, FALSE }
+ };
+
+ for (i = 0; i < sizeof(testcases)/sizeof(testcases[0]); i++)
+ {
+ thread = CreateThread(NULL, 0, test_default_ime_window_cb, &testcases[i], 0,
NULL);
+ ok(thread != NULL, "CreateThread failed with error %u\n",
GetLastError());
+ while (MsgWaitForMultipleObjects(1, &thread, FALSE, INFINITE, QS_ALLINPUT) ==
WAIT_OBJECT_0 + 1)
+ {
+ MSG msg;
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ TranslateMessage(&msg);
+ DispatchMessageA(&msg);
+ }
+ }
+ CloseHandle(thread);
+
+ if (testcases[i].top_level_window)
+ {
+ thread = CreateThread(NULL, 0, test_default_ime_window_cancel_cb,
&testcases[i], 0, NULL);
+ ok(thread != NULL, "CreateThread failed with error %u\n",
GetLastError());
+ WaitForSingleObject(thread, INFINITE);
+ CloseHandle(thread);
+ }
+ }
+
+ thread = CreateThread(NULL, 0, test_default_ime_disabled_cb, NULL, 0, NULL);
+ WaitForSingleObject(thread, INFINITE);
+ CloseHandle(thread);
+
+ test_phase = PHASE_UNKNOWN;
}
static void test_ImmGetIMCLockCount(void)
@@ -1015,6 +1241,9 @@
HIMC imc;
UINT idx = 0;
+ LPINPUTCONTEXT lpIMC;
+ LPTRANSMSG lpTransMsg;
+
HWND hwnd = CreateWindowExA(WS_EX_CLIENTEDGE, "EDIT", "Wine imm32.dll
test",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
240, 120, NULL, NULL, GetModuleHandleA(NULL), NULL);
@@ -1032,6 +1261,64 @@
if (msg) ok(!msg->post, "Message should not be posted\n");
} while (msg);
msg_spy_flush_msgs();
+
+ lpIMC = ImmLockIMC(imc);
+ lpIMC->hMsgBuf = ImmReSizeIMCC(lpIMC->hMsgBuf, (lpIMC->dwNumMsgBuf + 1) *
sizeof(TRANSMSG));
+ lpTransMsg = ImmLockIMCC(lpIMC->hMsgBuf);
+ lpTransMsg += lpIMC->dwNumMsgBuf;
+ lpTransMsg->message = WM_IME_STARTCOMPOSITION;
+ lpTransMsg->wParam = 0;
+ lpTransMsg->lParam = 0;
+ ImmUnlockIMCC(lpIMC->hMsgBuf);
+ lpIMC->dwNumMsgBuf++;
+ ImmUnlockIMC(imc);
+ ImmGenerateMessage(imc);
+ idx = 0;
+ do
+ {
+ msg = msg_spy_find_next_msg(WM_IME_STARTCOMPOSITION, &idx);
+ if (msg) ok(!msg->post, "Message should not be posted\n");
+ } while (msg);
+ msg_spy_flush_msgs();
+
+ lpIMC = ImmLockIMC(imc);
+ lpIMC->hMsgBuf = ImmReSizeIMCC(lpIMC->hMsgBuf, (lpIMC->dwNumMsgBuf + 1) *
sizeof(TRANSMSG));
+ lpTransMsg = ImmLockIMCC(lpIMC->hMsgBuf);
+ lpTransMsg += lpIMC->dwNumMsgBuf;
+ lpTransMsg->message = WM_IME_COMPOSITION;
+ lpTransMsg->wParam = 0;
+ lpTransMsg->lParam = 0;
+ ImmUnlockIMCC(lpIMC->hMsgBuf);
+ lpIMC->dwNumMsgBuf++;
+ ImmUnlockIMC(imc);
+ ImmGenerateMessage(imc);
+ idx = 0;
+ do
+ {
+ msg = msg_spy_find_next_msg(WM_IME_COMPOSITION, &idx);
+ if (msg) ok(!msg->post, "Message should not be posted\n");
+ } while (msg);
+ msg_spy_flush_msgs();
+
+ lpIMC = ImmLockIMC(imc);
+ lpIMC->hMsgBuf = ImmReSizeIMCC(lpIMC->hMsgBuf, (lpIMC->dwNumMsgBuf + 1) *
sizeof(TRANSMSG));
+ lpTransMsg = ImmLockIMCC(lpIMC->hMsgBuf);
+ lpTransMsg += lpIMC->dwNumMsgBuf;
+ lpTransMsg->message = WM_IME_ENDCOMPOSITION;
+ lpTransMsg->wParam = 0;
+ lpTransMsg->lParam = 0;
+ ImmUnlockIMCC(lpIMC->hMsgBuf);
+ lpIMC->dwNumMsgBuf++;
+ ImmUnlockIMC(imc);
+ ImmGenerateMessage(imc);
+ idx = 0;
+ do
+ {
+ msg = msg_spy_find_next_msg(WM_IME_ENDCOMPOSITION, &idx);
+ if (msg) ok(!msg->post, "Message should not be posted\n");
+ } while (msg);
+ msg_spy_flush_msgs();
+
ImmSetOpenStatus(imc, FALSE);
ImmReleaseContext(hwnd, imc);
DestroyWindow(hwnd);
@@ -1523,6 +1810,7 @@
test_ImmGetContext();
test_ImmGetDescription();
test_ImmDefaultHwnd();
+ test_default_ime_window_creation();
test_ImmGetIMCLockCount();
test_ImmGetIMCCLockCount();
test_ImmDestroyContext();