mirror of
https://github.com/reactos/reactos.git
synced 2024-06-29 01:12:06 +00:00
[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:
parent
2f2795ab4c
commit
8f719cb97e
|
@ -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;
|
||||||
|
|
|
@ -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))
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue