From: Aric Stewart Subject: (try 7)[3/5] imm32: use thread data from target HWND Message-Id: <540E6081.1050906@codeweavers.com> Date: Mon, 08 Sep 2014 21:05:53 -0500 --- dlls/imm32/imm.c | 34 ++++++++++++++++++++++++++-------- dlls/imm32/tests/imm32.c | 21 ++++++++++++++------- 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c index 19a1470..9b70237 100644 --- a/dlls/imm32/imm.c +++ b/dlls/imm32/imm.c @@ -255,6 +255,21 @@ static IMMThreadData* IMM_GetThreadData(DWORD id) return data; } +static IMMThreadData* IMM_GetThreadDataForWindow(HWND hwnd) +{ + DWORD process; + DWORD thread = 0; + + if (hwnd) + { + thread = GetWindowThreadProcessId(hwnd, &process); + if (process != GetCurrentProcessId()) + return NULL; + } + + return IMM_GetThreadData(thread); +} + static BOOL IMM_IsDefaultContext(HIMC imc) { InputContextData *data = get_imc_data(imc); @@ -511,9 +526,9 @@ static InputContextData* get_imc_data(HIMC hIMC) return data; } -static IMMThreadData* IMM_GetInitializedThreadData(void) +static IMMThreadData* IMM_GetInitializedThreadData(HWND hWnd) { - IMMThreadData* thread_data = IMM_GetThreadData(0); + IMMThreadData* thread_data = IMM_GetThreadDataForWindow(hWnd); if (!thread_data) return NULL; @@ -525,7 +540,7 @@ static IMMThreadData* IMM_GetInitializedThreadData(void) defaultContext = ImmCreateContext(); if (defaultContext) ((InputContextData*)defaultContext)->threadDefault = TRUE; - thread_data = IMM_GetThreadData(0); + thread_data = IMM_GetThreadDataForWindow(hWnd); if (!thread_data) { IMM_DestroyContext(defaultContext); @@ -561,7 +576,7 @@ HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC) if (hIMC && data->IMC.hWnd == hWnd) return hIMC; - thread_data = IMM_GetInitializedThreadData(); + thread_data = IMM_GetInitializedThreadData(hWnd); if (!thread_data) return NULL; @@ -636,7 +651,7 @@ BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags) TRACE("(%p, %p, 0x%x):\n", hWnd, hIMC, dwFlags); - thread_data = IMM_GetInitializedThreadData(); + thread_data = IMM_GetInitializedThreadData(hWnd); if (!thread_data) return FALSE; @@ -1503,7 +1518,7 @@ HIMC WINAPI ImmGetContext(HWND hWnd) return NULL; } - thread_data = IMM_GetInitializedThreadData(); + thread_data = IMM_GetInitializedThreadData(hWnd); if (!thread_data) return NULL; @@ -1628,8 +1643,11 @@ BOOL WINAPI ImmGetConversionStatus( HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd) { HWND ret; - IMMThreadData* thread_data = IMM_GetThreadData(0); - if (thread_data->hwndDefault == NULL) + IMMThreadData* thread_data = IMM_GetThreadDataForWindow(hWnd); + DWORD ctid = GetCurrentThreadId(); + if (!thread_data) + return NULL; + if (thread_data->hwndDefault == NULL && ctid == thread_data->threadID) thread_data->hwndDefault = CreateWindowExW( WS_EX_TOOLWINDOW, szwIME, NULL, WS_POPUP, 0, 0, 1, 1, 0, 0, 0, 0); ret = thread_data->hwndDefault; diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c index 4c0a888..2471634 100644 --- a/dlls/imm32/tests/imm32.c +++ b/dlls/imm32/tests/imm32.c @@ -425,15 +425,17 @@ static DWORD WINAPI ImmGetContextThreadFunc( LPVOID lpParam) HWND hwnd2; COMPOSITIONFORM cf; POINT pt; + MSG msg; + igc_threadinfo *info= (igc_threadinfo*)lpParam; info->hwnd = CreateWindowExA(WS_EX_CLIENTEDGE, wndcls, "Wine imm32.dll test", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, GetModuleHandleW(NULL), NULL); h1 = ImmGetContext(hwnd); - todo_wine ok(info->himc == h1, "hwnd context changed in new thread\n"); + ok(info->himc == h1, "hwnd context changed in new thread\n"); h2 = ImmGetContext(info->hwnd); - todo_wine ok(h2 != h1, "new hwnd in new thread should have different context\n"); + ok(h2 != h1, "new hwnd in new thread should have different context\n"); info->himc = h2; ImmReleaseContext(hwnd,h1); @@ -452,7 +454,12 @@ static DWORD WINAPI ImmGetContextThreadFunc( LPVOID lpParam) ImmSetStatusWindowPos(h1, &pt); SetEvent(info->event); - Sleep(INFINITE); + + while(GetMessageW(&msg, 0, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } return 1; } @@ -477,8 +484,8 @@ static void test_ImmThreads(void) otherHimc = ImmGetContext(threadinfo.hwnd); - todo_wine ok(himc != otherHimc, "Windows from other threads should have different himc\n"); - todo_wine ok(otherHimc == threadinfo.himc, "Context from other thread should not change in main thread\n"); + ok(himc != otherHimc, "Windows from other threads should have different himc\n"); + ok(otherHimc == threadinfo.himc, "Context from other thread should not change in main thread\n"); if (0) /* FIXME: Causes wine to hang */ { @@ -566,7 +573,7 @@ static void test_ImmThreads(void) ok (rc == 1, "ImmGetCandidateWindow should succeed\n"); rc = ImmGetCandidateWindow(otherHimc, 0, &cdf); - todo_wine ok (rc == 0, "ImmGetCandidateWindow should fail\n"); + ok (rc == 0, "ImmGetCandidateWindow should fail\n"); rc = ImmSetCandidateWindow(otherHimc, &cdf); todo_wine ok (rc == 0, "ImmSetCandidateWindow should fail\n"); @@ -577,7 +584,7 @@ static void test_ImmThreads(void) TerminateThread(hThread, 1); himc = ImmGetContext(GetDesktopWindow()); - todo_wine ok(himc == NULL, "Should not be able to get himc from other process window\n"); + ok(himc == NULL, "Should not be able to get himc from other process window\n"); } static void test_ImmIsUIMessage(void)