[NTUSER][IMM32] Create the default IME window! (retry) (#4463)

The default IME window has to be created for each top-level window in specific condition. It is needed for implementing Japanese input.
- Add IntFocusSetInputContext helper function.
- Call IntFocusSetInputContext after sending WM_KILLFOCUS message.
- Add IntWantImeWindow, co_IntCreateDefaultImeWindow, and IntDestroyOwnedWindows helper functions.
- Create the default IME window (spwndDefaultIme) for the specified window at IntCreateWindow.
- Fix Imm32InternalLockIMC function.
CORE-11700
This commit is contained in:
Katayama Hirofumi MZ 2022-04-23 07:11:48 +09:00 committed by GitHub
parent 2f2795ab4c
commit 8f719cb97e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 265 additions and 48 deletions

View file

@ -830,7 +830,13 @@ LPINPUTCONTEXT APIENTRY Imm32InternalLockIMC(HIMC hIMC, BOOL fSelect)
RtlEnterCriticalSection(&pClientImc->cs); RtlEnterCriticalSection(&pClientImc->cs);
if (pClientImc->hInputContext) if (pClientImc->hInputContext)
goto Finish; {
pIC = LocalLock(pClientImc->hInputContext);
if (pIC)
goto Success;
else
goto Failure;
}
dwThreadId = (DWORD)NtUserQueryInputContext(hIMC, QIC_INPUTTHREADID); dwThreadId = (DWORD)NtUserQueryInputContext(hIMC, QIC_INPUTTHREADID);
if (dwThreadId == GetCurrentThreadId() && Imm32IsCiceroMode() && !Imm32Is16BitMode()) if (dwThreadId == GetCurrentThreadId() && Imm32IsCiceroMode() && !Imm32Is16BitMode())
@ -847,14 +853,14 @@ LPINPUTCONTEXT APIENTRY Imm32InternalLockIMC(HIMC hIMC, BOOL fSelect)
} }
if (!NtUserQueryInputContext(hIMC, QIC_DEFAULTWINDOWIME)) if (!NtUserQueryInputContext(hIMC, QIC_DEFAULTWINDOWIME))
goto Quit; goto Failure;
hIC = LocalAlloc(LHND, sizeof(INPUTCONTEXTDX)); hIC = LocalAlloc(LHND, sizeof(INPUTCONTEXTDX));
pIC = LocalLock(hIC); pIC = LocalLock(hIC);
if (!pIC) if (!pIC)
{ {
LocalFree(hIC); LocalFree(hIC);
goto Quit; goto Failure;
} }
pClientImc->hInputContext = hIC; pClientImc->hInputContext = hIC;
@ -862,17 +868,17 @@ LPINPUTCONTEXT APIENTRY Imm32InternalLockIMC(HIMC hIMC, BOOL fSelect)
if (!Imm32CreateInputContext(hIMC, pIC, pClientImc, hNewKL, fSelect)) if (!Imm32CreateInputContext(hIMC, pIC, pClientImc, hNewKL, fSelect))
{ {
pClientImc->hInputContext = LocalFree(pClientImc->hInputContext); pClientImc->hInputContext = LocalFree(pClientImc->hInputContext);
goto Quit; goto Failure;
} }
Finish: Success:
CtfImmTIMCreateInputContext(hIMC); CtfImmTIMCreateInputContext(hIMC);
RtlLeaveCriticalSection(&pClientImc->cs); RtlLeaveCriticalSection(&pClientImc->cs);
InterlockedIncrement(&pClientImc->cLockObj); InterlockedIncrement(&pClientImc->cLockObj);
ImmUnlockClientImc(pClientImc); ImmUnlockClientImc(pClientImc);
return pIC; return pIC;
Quit: Failure:
RtlLeaveCriticalSection(&pClientImc->cs); RtlLeaveCriticalSection(&pClientImc->cs);
ImmUnlockClientImc(pClientImc); ImmUnlockClientImc(pClientImc);
return NULL; return NULL;
@ -1243,6 +1249,7 @@ BOOL WINAPI ImmSetActiveContextConsoleIME(HWND hwnd, BOOL fFlag)
BOOL WINAPI User32InitializeImmEntryTable(DWORD); BOOL WINAPI User32InitializeImmEntryTable(DWORD);
// Win: ImmDllInitialize
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{ {
HKL hKL; HKL hKL;

View file

@ -24,6 +24,11 @@ extern "C" {
#define IMC_GETSOFTKBDPOS 0x0013 #define IMC_GETSOFTKBDPOS 0x0013
#define IMC_SETSOFTKBDPOS 0x0014 #define IMC_SETSOFTKBDPOS 0x0014
/* wParam for WM_IME_SYSTEM */
#define IMS_IMEACTIVATE 0x17
#define IMS_IMEDEACTIVATE 0x18
#define IMS_ACTIVATELAYOUT 0x19
#define IMMGWL_IMC 0 #define IMMGWL_IMC 0
#define IMMGWL_PRIVATE (sizeof(LONG)) #define IMMGWL_PRIVATE (sizeof(LONG))

View file

@ -7,6 +7,7 @@
*/ */
#include <win32k.h> #include <win32k.h>
#include <ddk/immdev.h>
DBG_DEFAULT_CHANNEL(UserFocus); DBG_DEFAULT_CHANNEL(UserFocus);
PUSER_MESSAGE_QUEUE gpqForeground = NULL; PUSER_MESSAGE_QUEUE gpqForeground = NULL;
@ -145,11 +146,47 @@ co_IntSendDeactivateMessages(HWND hWndPrev, HWND hWnd, BOOL Clear)
return Ret; return Ret;
} }
// Win: xxxFocusSetInputContext
VOID IntFocusSetInputContext(PWND pWnd, BOOL bActivate, BOOL bCallback)
{
PTHREADINFO pti;
PWND pImeWnd;
USER_REFERENCE_ENTRY Ref;
HWND hImeWnd;
WPARAM wParam;
LPARAM lParam;
if (!pWnd || !pWnd->pcls || IS_WND_IMELIKE(pWnd))
return;
pti = pWnd->head.pti;
if (!pti || (pti->TIF_flags & TIF_INCLEANUP))
return;
pImeWnd = pti->spwndDefaultIme;
if (!pImeWnd)
return;
UserRefObjectCo(pImeWnd, &Ref);
hImeWnd = UserHMGetHandle(pImeWnd);
wParam = (bActivate ? IMS_IMEACTIVATE : IMS_IMEDEACTIVATE);
lParam = (LPARAM)UserHMGetHandle(pWnd);
if (bCallback)
co_IntSendMessageWithCallBack(hImeWnd, WM_IME_SYSTEM, wParam, lParam, NULL, 0, NULL);
else
co_IntSendMessage(hImeWnd, WM_IME_SYSTEM, wParam, lParam);
UserDerefObjectCo(pImeWnd);
}
// //
// Deactivating the foreground message queue. // Deactivating the foreground message queue.
// //
// Release Active, Capture and Focus Windows associated with this message queue. // Release Active, Capture and Focus Windows associated with this message queue.
// //
// Win: xxxDeactivate
BOOL FASTCALL BOOL FASTCALL
IntDeactivateWindow(PTHREADINFO pti, HANDLE tid) IntDeactivateWindow(PTHREADINFO pti, HANDLE tid)
{ {
@ -297,6 +334,10 @@ IntDeactivateWindow(PTHREADINFO pti, HANDLE tid)
UserRefObjectCo(pwndFocus, &Ref); UserRefObjectCo(pwndFocus, &Ref);
co_IntSendMessage(UserHMGetHandle(pwndFocus), WM_KILLFOCUS, 0, 0); co_IntSendMessage(UserHMGetHandle(pwndFocus), WM_KILLFOCUS, 0, 0);
if (IS_IMM_MODE())
{
IntFocusSetInputContext(pwndFocus, FALSE, FALSE);
}
UserDerefObjectCo(pwndFocus); UserDerefObjectCo(pwndFocus);
} }
@ -569,11 +610,13 @@ co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOO
return InAAPM; return InAAPM;
} }
// Win: xxxSendFocusMessages
VOID FASTCALL VOID FASTCALL
IntSendFocusMessages( PTHREADINFO pti, PWND pWnd) IntSendFocusMessages( PTHREADINFO pti, PWND pWnd)
{ {
PWND pWndPrev; PWND pWndPrev;
PUSER_MESSAGE_QUEUE ThreadQueue = pti->MessageQueue; // Queue can change... PUSER_MESSAGE_QUEUE ThreadQueue = pti->MessageQueue; // Queue can change...
HWND hwndPrev;
ThreadQueue->QF_flags &= ~QF_FOCUSNULLSINCEACTIVE; ThreadQueue->QF_flags &= ~QF_FOCUSNULLSINCEACTIVE;
if (!pWnd && ThreadQueue->spwndActive) if (!pWnd && ThreadQueue->spwndActive)
@ -593,12 +636,22 @@ IntSendFocusMessages( PTHREADINFO pti, PWND pWnd)
if (pWndPrev) if (pWndPrev)
{ {
co_IntSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, (WPARAM)UserHMGetHandle(pWnd), 0); co_IntSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, (WPARAM)UserHMGetHandle(pWnd), 0);
if (IS_IMM_MODE())
{
IntFocusSetInputContext(pWndPrev, FALSE, FALSE);
}
} }
if (ThreadQueue->spwndFocus == pWnd) if (ThreadQueue->spwndFocus == pWnd)
{ {
if (IS_IMM_MODE())
{
IntFocusSetInputContext(pWnd, TRUE, FALSE);
}
IntNotifyWinEvent(EVENT_OBJECT_FOCUS, pWnd, OBJID_CLIENT, CHILDID_SELF, 0); IntNotifyWinEvent(EVENT_OBJECT_FOCUS, pWnd, OBJID_CLIENT, CHILDID_SELF, 0);
co_IntSendMessage(UserHMGetHandle(pWnd), WM_SETFOCUS, (WPARAM)(pWndPrev ? UserHMGetHandle(pWndPrev) : NULL), 0); hwndPrev = (pWndPrev ? UserHMGetHandle(pWndPrev) : NULL);
co_IntSendMessage(UserHMGetHandle(pWnd), WM_SETFOCUS, (WPARAM)hwndPrev, 0);
} }
} }
else else
@ -608,6 +661,10 @@ IntSendFocusMessages( PTHREADINFO pti, PWND pWnd)
IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0); IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
co_IntSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, 0, 0); co_IntSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, 0, 0);
if (IS_IMM_MODE())
{
IntFocusSetInputContext(pWndPrev, FALSE, FALSE);
}
} }
} }
} }
@ -1241,6 +1298,7 @@ UserSetActiveWindow( _In_opt_ PWND Wnd )
return FALSE; return FALSE;
} }
// Win: PWND xxxSetFocus(Window)
HWND FASTCALL HWND FASTCALL
co_UserSetFocus(PWND Window) co_UserSetFocus(PWND Window)
{ {

View file

@ -1889,7 +1889,110 @@ BOOL IntFindNonImeRelatedWndOfSameThread(PWND pwndParent, PWND pwndTarget)
return FALSE; return FALSE;
} }
// Can we destroy the default IME window for the target child window? // Determines whether the target window needs the IME window.
// Win: WantImeWindow(pwndParent, pwndTarget)
BOOL FASTCALL IntWantImeWindow(PWND pwndTarget)
{
PDESKTOP rpdesk;
PWINSTATION_OBJECT rpwinstaParent;
PWND pwndNode, pwndParent = pwndTarget->spwndParent;
if (gptiCurrent->TIF_flags & TIF_DISABLEIME)
return FALSE;
if (IS_WND_IMELIKE(pwndTarget))
return FALSE;
if (pwndTarget->fnid == FNID_DESKTOP || pwndTarget->fnid == FNID_MESSAGEWND)
return FALSE;
if (pwndTarget->state & WNDS_SERVERSIDEWINDOWPROC)
return FALSE;
rpdesk = pwndTarget->head.rpdesk;
if (!rpdesk)
return FALSE;
rpwinstaParent = rpdesk->rpwinstaParent;
if (!rpwinstaParent || (rpwinstaParent->Flags & WSS_NOIO))
return FALSE;
for (pwndNode = pwndParent; pwndNode; pwndNode = pwndNode->spwndParent)
{
if (rpdesk != pwndNode->head.rpdesk)
break;
if (pwndNode == rpdesk->spwndMessage)
return FALSE;
}
return TRUE;
}
// Create the default IME window for the target window.
// Win: xxxCreateDefaultImeWindow(pwndTarget, ATOM, hInst)
PWND FASTCALL co_IntCreateDefaultImeWindow(PWND pwndTarget, HINSTANCE hInst)
{
LARGE_UNICODE_STRING WindowName;
UNICODE_STRING ClassName;
PWND pImeWnd;
PIMEUI pimeui;
CREATESTRUCTW Cs;
USER_REFERENCE_ENTRY Ref;
PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
HANDLE pid = PsGetThreadProcessId(pti->pEThread);
if (!(pti->spDefaultImc) && pid == gpidLogon)
UserCreateInputContext(0);
if (!(pti->spDefaultImc) || IS_WND_IMELIKE(pwndTarget) || !(pti->rpdesk->pheapDesktop))
return NULL;
if (IS_WND_CHILD(pwndTarget) && !(pwndTarget->style & WS_VISIBLE) &&
pwndTarget->spwndParent->head.pti->ppi != pti->ppi)
{
return NULL;
}
RtlInitLargeUnicodeString(&WindowName, L"Default IME", 0);
ClassName.Buffer = (PWCH)(ULONG_PTR)gpsi->atomSysClass[ICLS_IME];
ClassName.Length = 0;
ClassName.MaximumLength = 0;
UserRefObjectCo(pwndTarget, &Ref);
RtlZeroMemory(&Cs, sizeof(Cs));
Cs.style = WS_POPUP | WS_DISABLED;
Cs.hInstance = hInst;
Cs.hwndParent = UserHMGetHandle(pwndTarget);
Cs.lpszName = WindowName.Buffer;
Cs.lpszClass = ClassName.Buffer;
// NOTE: LARGE_UNICODE_STRING is compatible to LARGE_STRING.
pImeWnd = co_UserCreateWindowEx(&Cs, &ClassName, (PLARGE_STRING)&WindowName, NULL, WINVER);
if (pImeWnd)
{
pimeui = ((PIMEWND)pImeWnd)->pimeui;
_SEH2_TRY
{
ProbeForWrite(pimeui, sizeof(IMEUI), 1);
pimeui->fDefault = TRUE;
if (IS_WND_CHILD(pwndTarget) && pwndTarget->spwndParent->head.pti != pti)
pimeui->fChildThreadDef = TRUE;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
NOTHING;
}
_SEH2_END;
}
UserDerefObjectCo(pwndTarget);
return pImeWnd;
}
// Determines whether the system can destroy the default IME window for the target child window.
// Win: ImeCanDestroyDefIMEforChild // Win: ImeCanDestroyDefIMEforChild
BOOL FASTCALL IntImeCanDestroyDefIMEforChild(PWND pImeWnd, PWND pwndTarget) BOOL FASTCALL IntImeCanDestroyDefIMEforChild(PWND pImeWnd, PWND pwndTarget)
{ {
@ -1911,7 +2014,7 @@ BOOL FASTCALL IntImeCanDestroyDefIMEforChild(PWND pImeWnd, PWND pwndTarget)
} }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{ {
; NOTHING;
} }
_SEH2_END; _SEH2_END;
@ -1934,8 +2037,7 @@ BOOL FASTCALL IntImeCanDestroyDefIMEforChild(PWND pImeWnd, PWND pwndTarget)
return TRUE; return TRUE;
} }
// Can we destroy the default IME window for the non-child target window? // Determines whether the system can destroy the default IME window for the non-child target window.
// If so, this function sets spwndOwner to NULL.
// Win: ImeCanDestroyDefIME // Win: ImeCanDestroyDefIME
BOOL FASTCALL IntImeCanDestroyDefIME(PWND pImeWnd, PWND pwndTarget) BOOL FASTCALL IntImeCanDestroyDefIME(PWND pImeWnd, PWND pwndTarget)
{ {
@ -1957,7 +2059,7 @@ BOOL FASTCALL IntImeCanDestroyDefIME(PWND pImeWnd, PWND pwndTarget)
} }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{ {
; NOTHING;
} }
_SEH2_END; _SEH2_END;

View file

@ -8,6 +8,7 @@
*/ */
#include <win32k.h> #include <win32k.h>
#include <ddk/immdev.h>
DBG_DEFAULT_CHANNEL(UserWnd); DBG_DEFAULT_CHANNEL(UserWnd);
INT gNestedWindowLimit = 50; INT gNestedWindowLimit = 50;
@ -658,8 +659,16 @@ LRESULT co_UserFreeWindow(PWND Window,
ThreadData->rpdesk->rpwinstaParent->ShellListView = NULL; ThreadData->rpdesk->rpwinstaParent->ShellListView = NULL;
} }
if (ThreadData->spwndDefaultIme &&
ThreadData->spwndDefaultIme->spwndOwner == Window)
{
ThreadData->spwndDefaultIme->spwndOwner = NULL;
}
if (IS_IMM_MODE() && Window == ThreadData->spwndDefaultIme) if (IS_IMM_MODE() && Window == ThreadData->spwndDefaultIme)
{
UserAssignmentUnlock((PVOID*)&(ThreadData->spwndDefaultIme)); UserAssignmentUnlock((PVOID*)&(ThreadData->spwndDefaultIme));
}
/* Fixes dialog test_focus breakage due to r66237. */ /* Fixes dialog test_focus breakage due to r66237. */
if (ThreadData->MessageQueue->spwndFocus == Window) if (ThreadData->MessageQueue->spwndFocus == Window)
@ -1775,7 +1784,7 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
{ {
PWND pWnd = NULL; PWND pWnd = NULL;
HWND hWnd; HWND hWnd;
PTHREADINFO pti = NULL; PTHREADINFO pti;
BOOL MenuChanged; BOOL MenuChanged;
BOOL bUnicodeWindow; BOOL bUnicodeWindow;
PCALLPROCDATA pcpd; PCALLPROCDATA pcpd;
@ -2027,6 +2036,28 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
pWnd->strName.MaximumLength = WindowName->Length + sizeof(UNICODE_NULL); pWnd->strName.MaximumLength = WindowName->Length + sizeof(UNICODE_NULL);
} }
/* Create the IME window for pWnd */
if (IS_IMM_MODE() && !(pti->spwndDefaultIme) && IntWantImeWindow(pWnd))
{
PWND pwndDefaultIme = co_IntCreateDefaultImeWindow(pWnd, pWnd->hModule);
UserAssignmentLock((PVOID*)&(pti->spwndDefaultIme), pwndDefaultIme);
if (pwndDefaultIme && (pti->pClientInfo->CI_flags & CI_IMMACTIVATE))
{
USER_REFERENCE_ENTRY Ref;
HKL hKL;
UserRefObjectCo(pwndDefaultIme, &Ref);
hKL = pti->KeyboardLayout->hkl;
co_IntSendMessage(UserHMGetHandle(pwndDefaultIme), WM_IME_SYSTEM,
IMS_ACTIVATELAYOUT, (LPARAM)hKL);
pti->pClientInfo->CI_flags &= ~CI_IMMACTIVATE;
UserDerefObjectCo(pwndDefaultIme);
}
}
/* Correct the window style. */ /* Correct the window style. */
if ((pWnd->style & (WS_CHILD | WS_POPUP)) != WS_CHILD) if ((pWnd->style & (WS_CHILD | WS_POPUP)) != WS_CHILD)
{ {
@ -2133,7 +2164,6 @@ Error:
/* /*
* @implemented * @implemented
* Win: xxxCreateWindowEx
*/ */
PWND FASTCALL PWND FASTCALL
co_UserCreateWindowEx(CREATESTRUCTW* Cs, co_UserCreateWindowEx(CREATESTRUCTW* Cs,
@ -2748,6 +2778,49 @@ cleanup:
return hwnd; return hwnd;
} }
// Win: xxxDW_DestroyOwnedWindows
VOID FASTCALL IntDestroyOwnedWindows(PWND Window)
{
HWND* List;
HWND* phWnd;
PWND pWnd;
PTHREADINFO pti = Window->head.pti;
USER_REFERENCE_ENTRY Ref;
List = IntWinListOwnedPopups(Window);
if (!List)
return;
for (phWnd = List; *phWnd; ++phWnd)
{
pWnd = ValidateHwndNoErr(*phWnd);
if (pWnd == NULL)
continue;
ASSERT(pWnd->spwndOwner == Window);
ASSERT(pWnd != Window);
if (IS_IMM_MODE() && !(pti->TIF_flags & TIF_INCLEANUP) &&
pWnd == pti->spwndDefaultIme)
{
continue;
}
pWnd->spwndOwner = NULL;
if (IntWndBelongsToThread(pWnd, PsGetCurrentThreadWin32Thread()))
{
UserRefObjectCo(pWnd, &Ref); // Temp HACK?
co_UserDestroyWindow(pWnd);
UserDerefObjectCo(pWnd); // Temp HACK?
}
else
{
ERR("IntWndBelongsToThread(0x%p) is FALSE, ignoring.\n", pWnd);
}
}
ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
}
// Win: xxxDestroyWindow // Win: xxxDestroyWindow
BOOLEAN co_UserDestroyWindow(PVOID Object) BOOLEAN co_UserDestroyWindow(PVOID Object)
{ {
@ -2876,37 +2949,7 @@ BOOLEAN co_UserDestroyWindow(PVOID Object)
/* Recursively destroy owned windows */ /* Recursively destroy owned windows */
if (!(Window->style & WS_CHILD)) if (!(Window->style & WS_CHILD))
{ {
HWND* List; IntDestroyOwnedWindows(Window);
HWND* phWnd;
PWND pWnd;
List = IntWinListOwnedPopups(Window);
if (List)
{
for (phWnd = List; *phWnd; ++phWnd)
{
pWnd = ValidateHwndNoErr(*phWnd);
if (pWnd == NULL)
continue;
ASSERT(pWnd->spwndOwner == Window);
ASSERT(pWnd != Window);
pWnd->spwndOwner = NULL;
if (IntWndBelongsToThread(pWnd, PsGetCurrentThreadWin32Thread()))
{
USER_REFERENCE_ENTRY Ref;
UserRefObjectCo(pWnd, &Ref); // Temp HACK?
co_UserDestroyWindow(pWnd);
UserDerefObjectCo(pWnd); // Temp HACK?
}
else
{
ERR("IntWndBelongsToThread(0x%p) is FALSE, ignoring.\n", pWnd);
}
}
ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
}
} }
/* Generate mouse move message for the next window */ /* Generate mouse move message for the next window */

View file

@ -112,6 +112,8 @@ VOID FASTCALL IntFreeHwndList(PWINDOWLIST pwlTarget);
(((pWnd)->pcls->style & CS_IME) || \ (((pWnd)->pcls->style & CS_IME) || \
((pWnd)->pcls->atomClassName == gpsi->atomSysClass[ICLS_IME])) ((pWnd)->pcls->atomClassName == gpsi->atomSysClass[ICLS_IME]))
BOOL FASTCALL IntWantImeWindow(PWND pwndTarget);
PWND FASTCALL co_IntCreateDefaultImeWindow(PWND pwndTarget, HINSTANCE hInst);
BOOL FASTCALL IntImeCanDestroyDefIMEforChild(PWND pImeWnd, PWND pwndTarget); BOOL FASTCALL IntImeCanDestroyDefIMEforChild(PWND pImeWnd, PWND pwndTarget);
BOOL FASTCALL IntImeCanDestroyDefIME(PWND pImeWnd, PWND pwndTarget); BOOL FASTCALL IntImeCanDestroyDefIME(PWND pImeWnd, PWND pwndTarget);

View file

@ -664,15 +664,15 @@ static LRESULT ImeWnd_OnImeSystem(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
// TODO: // TODO:
break; break;
case 0x17: case IMS_IMEACTIVATE:
User32SetImeActivenessOfWindow((HWND)lParam, TRUE); User32SetImeActivenessOfWindow((HWND)lParam, TRUE);
break; break;
case 0x18: case IMS_IMEDEACTIVATE:
User32SetImeActivenessOfWindow((HWND)lParam, FALSE); User32SetImeActivenessOfWindow((HWND)lParam, FALSE);
break; break;
case 0x19: case IMS_ACTIVATELAYOUT:
ret = IMM_FN(ImmActivateLayout)((HKL)lParam); ret = IMM_FN(ImmActivateLayout)((HKL)lParam);
break; break;