imm32: Properly separate the IME UI window and the thread default IME window.
This commit is contained in:
parent
7eb49ae703
commit
5f5f20d6cf
|
@ -50,6 +50,7 @@ typedef struct _tagImmHkl{
|
|||
IMEINFO imeInfo;
|
||||
WCHAR imeClassName[17]; /* 16 character max */
|
||||
ULONG uSelected;
|
||||
HWND UIWnd;
|
||||
|
||||
/* Function Pointers */
|
||||
MAKE_FUNCPTR(ImeInquire);
|
||||
|
@ -77,7 +78,6 @@ typedef struct tagInputContextData
|
|||
INPUTCONTEXT IMC;
|
||||
|
||||
ImmHkl *immKbd;
|
||||
HWND imeWnd;
|
||||
UINT lastVK;
|
||||
} InputContextData;
|
||||
|
||||
|
@ -110,6 +110,8 @@ static const WCHAR szImeFileW[] = {'I','m','e',' ','F','i','l','e',0};
|
|||
static const WCHAR szLayoutTextW[] = {'L','a','y','o','u','t',' ','T','e','x','t',0};
|
||||
static const WCHAR szImeRegFmt[] = {'S','y','s','t','e','m','\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\','C','o','n','t','r','o','l','\\','K','e','y','b','o','a','r','d',' ','L','a','y','o','u','t','s','\\','%','0','8','l','x',0};
|
||||
|
||||
static LRESULT WINAPI DefIME_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
|
||||
#define is_himc_ime_unicode(p) (p->immKbd->imeInfo.fdwProperty & IME_PROP_UNICODE)
|
||||
#define is_kbd_ime_unicode(p) (p->imeInfo.fdwProperty & IME_PROP_UNICODE)
|
||||
|
@ -357,6 +359,8 @@ static void IMM_FreeAllImmHkl(void)
|
|||
ptr->pImeDestroy(1);
|
||||
FreeLibrary(ptr->hIME);
|
||||
}
|
||||
if (ptr->UIWnd)
|
||||
DestroyWindow(ptr->UIWnd);
|
||||
HeapFree(GetProcessHeap(),0,ptr);
|
||||
}
|
||||
}
|
||||
|
@ -372,6 +376,22 @@ static void IMM_RegisterMessages(void)
|
|||
WM_MSIME_DOCUMENTFEED = RegisterWindowMessageA("MSIMEDocumentFeed");
|
||||
}
|
||||
|
||||
static void IMM_RegisterIMEClass(HINSTANCE hInstDLL)
|
||||
{
|
||||
static const WCHAR szwIME[] = {'I','M','E',0};
|
||||
WNDCLASSW wndClass;
|
||||
|
||||
ZeroMemory(&wndClass, sizeof(WNDCLASSW));
|
||||
|
||||
wndClass.style = CS_GLOBALCLASS;
|
||||
wndClass.lpfnWndProc = (WNDPROC) DefIME_WindowProc;
|
||||
wndClass.cbWndExtra = 2 * sizeof(LONG_PTR);
|
||||
wndClass.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_ARROW);
|
||||
wndClass.lpszClassName = szwIME;
|
||||
|
||||
RegisterClassW(&wndClass);
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
|
||||
{
|
||||
TRACE("%p, %x, %p\n",hInstDLL,fdwReason,lpReserved);
|
||||
|
@ -382,6 +402,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
|
|||
tlsIndex = TlsAlloc();
|
||||
if (tlsIndex == TLS_OUT_OF_INDEXES)
|
||||
return FALSE;
|
||||
IMM_RegisterIMEClass(hInstDLL);
|
||||
break;
|
||||
case DLL_THREAD_ATTACH:
|
||||
break;
|
||||
|
@ -678,10 +699,6 @@ static BOOL IMM_DestroyContext(HIMC hIMC)
|
|||
data->immKbd->pImeSelect(hIMC, FALSE);
|
||||
SendMessageW(data->IMC.hWnd, WM_IME_SELECT, FALSE, (LPARAM)GetKeyboardLayout(0));
|
||||
|
||||
if (IMM_GetThreadData()->hwndDefault == data->imeWnd)
|
||||
IMM_GetThreadData()->hwndDefault = NULL;
|
||||
DestroyWindow(data->imeWnd);
|
||||
|
||||
ImmDestroyIMCC(data->IMC.hCompStr);
|
||||
ImmDestroyIMCC(data->IMC.hCandInfo);
|
||||
ImmDestroyIMCC(data->IMC.hGuideLine);
|
||||
|
@ -1490,6 +1507,10 @@ BOOL WINAPI ImmGetConversionStatus(
|
|||
*/
|
||||
HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
|
||||
{
|
||||
static const WCHAR szwIME[] = {'I','M','E',0};
|
||||
if (IMM_GetThreadData()->hwndDefault == NULL)
|
||||
IMM_GetThreadData()->hwndDefault = CreateWindowExW( WS_EX_TOOLWINDOW,
|
||||
szwIME, NULL, WS_POPUP, 0, 0, 1, 1, 0, 0, 0, 0);
|
||||
TRACE("Default is %p\n",IMM_GetThreadData()->hwndDefault);
|
||||
return IMM_GetThreadData()->hwndDefault;
|
||||
}
|
||||
|
@ -2262,16 +2283,16 @@ BOOL WINAPI ImmSetCompositionWindow(
|
|||
|
||||
data->IMC.cfCompForm = *lpCompForm;
|
||||
|
||||
if (IsWindowVisible(IMM_GetThreadData()->hwndDefault))
|
||||
if (IsWindowVisible(data->immKbd->UIWnd))
|
||||
{
|
||||
reshow = TRUE;
|
||||
ShowWindow(IMM_GetThreadData()->hwndDefault,SW_HIDE);
|
||||
ShowWindow(data->immKbd->UIWnd,SW_HIDE);
|
||||
}
|
||||
|
||||
/* FIXME: this is a partial stub */
|
||||
|
||||
if (reshow)
|
||||
ShowWindow(IMM_GetThreadData()->hwndDefault,SW_SHOWNOACTIVATE);
|
||||
ShowWindow(data->immKbd->UIWnd,SW_SHOWNOACTIVATE);
|
||||
|
||||
ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONWINDOW, 0);
|
||||
return TRUE;
|
||||
|
@ -2321,14 +2342,13 @@ BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
|
|||
if (!data)
|
||||
return FALSE;
|
||||
|
||||
if (data->imeWnd == NULL)
|
||||
if (data->immKbd->UIWnd == NULL)
|
||||
{
|
||||
/* create the ime window */
|
||||
data->imeWnd = CreateWindowExW( WS_EX_TOOLWINDOW,
|
||||
data->immKbd->UIWnd = CreateWindowExW( WS_EX_TOOLWINDOW,
|
||||
data->immKbd->imeClassName, NULL, WS_POPUP, 0, 0, 1, 1, 0,
|
||||
0, data->immKbd->hIME, 0);
|
||||
SetWindowLongPtrW(data->imeWnd, IMMGWL_IMC, (LONG_PTR)data);
|
||||
IMM_GetThreadData()->hwndDefault = data->imeWnd;
|
||||
SetWindowLongPtrW(data->immKbd->UIWnd, IMMGWL_IMC, (LONG_PTR)data);
|
||||
}
|
||||
|
||||
if (!fOpen != !data->IMC.fOpen)
|
||||
|
@ -2855,3 +2875,45 @@ BOOL WINAPI ImmGetHotKey(DWORD hotkey, UINT *modifiers, UINT *key, HKL hkl)
|
|||
FIXME("%x, %p, %p, %p: stub\n", hotkey, modifiers, key, hkl);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Window Proc for the Default IME window class
|
||||
*/
|
||||
static LRESULT WINAPI DefIME_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
|
||||
LPARAM lParam)
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_CREATE:
|
||||
case WM_NCCREATE:
|
||||
return TRUE;
|
||||
case WM_IME_COMPOSITION:
|
||||
case WM_IME_STARTCOMPOSITION:
|
||||
case WM_IME_ENDCOMPOSITION:
|
||||
case WM_IME_SELECT:
|
||||
case WM_IME_CONTROL:
|
||||
case WM_IME_NOTIFY:
|
||||
{
|
||||
ImmHkl *immHkl = IMM_GetImmHkl(GetKeyboardLayout(0));
|
||||
if (immHkl->UIWnd)
|
||||
PostMessageW(immHkl->UIWnd,uMsg,wParam,lParam);
|
||||
return TRUE;
|
||||
}
|
||||
default:
|
||||
if ((uMsg == WM_MSIME_RECONVERTOPTIONS) ||
|
||||
(uMsg ==WM_MSIME_SERVICE) ||
|
||||
(uMsg == WM_MSIME_MOUSE) ||
|
||||
(uMsg == WM_MSIME_RECONVERTREQUEST) ||
|
||||
(uMsg == WM_MSIME_RECONVERT) ||
|
||||
(uMsg == WM_MSIME_QUERYPOSITION) ||
|
||||
(uMsg == WM_MSIME_DOCUMENTFEED))
|
||||
{
|
||||
ImmHkl *immHkl = IMM_GetImmHkl(GetKeyboardLayout(0));
|
||||
if (immHkl->UIWnd)
|
||||
PostMessageW(immHkl->UIWnd,uMsg,wParam,lParam);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -618,6 +618,43 @@ static void test_ImmGetDescription(void)
|
|||
UnloadKeyboardLayout(hkl);
|
||||
}
|
||||
|
||||
static void test_ImmDefaultHwnd(void)
|
||||
{
|
||||
HIMC imc1, imc2, imc3;
|
||||
HWND def1, def3;
|
||||
HWND hwnd;
|
||||
|
||||
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "Wine imm32.dll test",
|
||||
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
240, 120, NULL, NULL, GetModuleHandle(0), NULL);
|
||||
|
||||
ShowWindow(hwnd, SW_SHOWNORMAL);
|
||||
|
||||
imc1 = ImmGetContext(hwnd);
|
||||
if (!imc1)
|
||||
{
|
||||
win_skip("IME support not implemented\n");
|
||||
return;
|
||||
}
|
||||
|
||||
def1 = ImmGetDefaultIMEWnd(hwnd);
|
||||
|
||||
imc2 = ImmCreateContext();
|
||||
ImmSetOpenStatus(imc2, TRUE);
|
||||
|
||||
imc3 = ImmGetContext(hwnd);
|
||||
def3 = ImmGetDefaultIMEWnd(hwnd);
|
||||
|
||||
ok(def3 == def1, "Default IME window should not change\n");
|
||||
ok(imc1 == imc3, "IME context should not change\n");
|
||||
ImmSetOpenStatus(imc2, FALSE);
|
||||
|
||||
ImmReleaseContext(hwnd, imc1);
|
||||
ImmReleaseContext(hwnd, imc3);
|
||||
ImmDestroyContext(imc2);
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
START_TEST(imm32) {
|
||||
if (init())
|
||||
{
|
||||
|
@ -630,6 +667,7 @@ START_TEST(imm32) {
|
|||
test_ImmIsUIMessage();
|
||||
test_ImmGetContext();
|
||||
test_ImmGetDescription();
|
||||
test_ImmDefaultHwnd();
|
||||
}
|
||||
cleanup();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
MODULE = winex11.drv
|
||||
IMPORTS = uuid user32 gdi32 advapi32 imm32
|
||||
DELAYIMPORTS = comctl32 ole32 shell32
|
||||
IMPORTS = uuid user32 gdi32 advapi32
|
||||
DELAYIMPORTS = comctl32 ole32 shell32 imm32
|
||||
EXTRAINCL = @X_CFLAGS@
|
||||
EXTRALIBS = @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@
|
||||
|
||||
|
|
Loading…
Reference in New Issue