[MSCTFIME][CICERO] Half-implement CIMEUIWindowHandler (#6521)

Supporting TIPs...
JIRA issue: CORE-19360
- Add implementation to
  CIMEUIWindowHandler class.
This commit is contained in:
Katayama Hirofumi MZ 2024-02-23 13:45:00 +09:00 committed by GitHub
parent 353edbd3f4
commit 69b08be0e0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 407 additions and 20 deletions

View file

@ -231,7 +231,7 @@ CicBridge::SelectEx(
if (fSelect)
{
if (pCicIC)
pCicIC->m_dwUnknown6[1] &= ~1;
pCicIC->m_bCandidateOpen = FALSE;
if (imcLock.get().fOpen)
OnSetOpenStatus(pTLS, pThreadMgr, imcLock, pCicIC);
}

View file

@ -16,7 +16,6 @@ CicInputContext::CicInputContext(
_In_ HIMC hIMC)
{
m_hIMC = hIMC;
m_guid = GUID_NULL;
m_dwQueryPos = 0;
m_cRefs = 1;
}
@ -266,18 +265,44 @@ HRESULT CicInputContext::EscbCompComplete(CicIMCLock& imcLock)
return E_NOTIMPL;
}
/// @unimplemented
HRESULT CicInputContext::DelayedReconvertFuncCall(CicIMCLock& imcLock)
{
return E_NOTIMPL;
}
/// @unimplemented
HRESULT
CicInputContext::MsImeMouseHandler(
DWORD dwUnknown58,
DWORD dwUnknown59,
UINT keys,
CicIMCLock& imcLock)
{
return E_NOTIMPL;
}
/// @unimplemented
HRESULT
CicInputContext::SetupReconvertString(
CicIMCLock& imcLock,
ITfThreadMgr_P *pThreadMgr,
UINT uCodePage,
DWORD dwUnknown61,
UINT uMsg,
BOOL bUndo)
{
return E_NOTIMPL;
}
void CicInputContext::ClearPrevCandidatePos()
{
m_dwUnknown8 = 0;
ZeroMemory(&m_rcCandidate1, sizeof(m_rcCandidate1));
ZeroMemory(&m_CandForm, sizeof(m_CandForm));
ZeroMemory(&m_rcCandidate2, sizeof(m_rcCandidate2));
m_dwQueryPos = 0;
}
/// @unimplemented
HRESULT CicInputContext::EndReconvertString(CicIMCLock& imcLock)
{

View file

@ -8,6 +8,7 @@
#pragma once
#include "sinks.h"
#include "misc.h"
class CInputContextOwnerCallBack;
class CInputContextOwner;
@ -44,8 +45,10 @@ public:
DWORD m_dwUnknown4[2];
DWORD m_dwQueryPos;
DWORD m_dwUnknown5;
GUID m_guid;
DWORD m_dwUnknown6[11];
CModeBias m_ModeBias;
DWORD m_dwUnknown6;
BOOL m_bCandidateOpen;
DWORD m_dwUnknown6_5[9];
BOOL m_bSelecting;
BOOL m_bReconverting;
LONG m_cCompLocks;
@ -53,7 +56,10 @@ public:
WORD m_cGuidAtoms;
WORD m_padding;
DWORD m_adwGuidAtoms[256];
DWORD m_dwUnknown8[17];
DWORD m_dwUnknown8;
RECT m_rcCandidate1;
CANDIDATEFORM m_CandForm;
RECT m_rcCandidate2;
TfClientId m_clientId;
DWORD m_dwUnknown9;
@ -96,7 +102,15 @@ public:
CicIMCLock& imcLock,
ITfThreadMgr_P *pThreadMgr,
UINT uCodePage,
DWORD dwUnknown61,
UINT uMsg,
BOOL bUndo);
HRESULT MsImeMouseHandler(
DWORD dwUnknown58,
DWORD dwUnknown59,
UINT keys,
CicIMCLock& imcLock);
HRESULT EndReconvertString(CicIMCLock& imcLock);
HRESULT DelayedReconvertFuncCall(CicIMCLock& imcLock);
void ClearPrevCandidatePos();
};

View file

@ -50,6 +50,8 @@ class CModeBias
public:
GUID m_guid;
CModeBias() : m_guid(GUID_NULL) { }
GUID ConvertModeBias(LONG bias);
LONG ConvertModeBias(REFGUID guid);
void SetModeBias(REFGUID rguid);

View file

@ -54,6 +54,8 @@ DEFINE_GUID(GUID_MODEBIAS_FILENAME, 0xD7F707FE, 0x44C6, 0x4FCA,
DEFINE_GUID(GUID_MODEBIAS_NUMERIC, 0x4021766C, 0xE872, 0x48FD, 0x9C, 0xEE, 0x4E, 0xC5, 0xC7, 0x5E, 0x16, 0xC3);
DEFINE_GUID(GUID_MODEBIAS_URLHISTORY, 0x8B0E54D9, 0x63F2, 0x4C68, 0x84, 0xD4, 0x79, 0xAE, 0xE7, 0xA5, 0x9F, 0x09);
DEFINE_GUID(GUID_MODEBIAS_DEFAULT, 0xF3DA8BD4, 0x0786, 0x49C2, 0x8C, 0x09, 0x68, 0x39, 0xD8, 0xB8, 0x4F, 0x58);
DEFINE_GUID(GUID_PROP_MODEBIAS, 0x372E0716, 0x974F, 0x40AC, 0xA0, 0x88, 0x08, 0xCD, 0xC9, 0x2E, 0xBF, 0xBC);
#define GUID_MODEBIAS_NONE GUID_NULL
#include "resource.h"

View file

@ -784,6 +784,88 @@ UIComposition::CompWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
return 0;
}
/// @implemented
HRESULT UIComposition::OnImeNotifySetCompositionWindow(CicIMCLock& imcLock)
{
return UpdateCompositionRect(imcLock);
}
/// @unimplemented
HRESULT UIComposition::UpdateCompositionRect(CicIMCLock& imcLock)
{
return E_NOTIMPL;
}
/// @implemented
INT UIComposition::GetLevelFromIMC(CicIMCLock& imcLock)
{
DWORD dwStyle = imcLock.get().cfCompForm.dwStyle;
if (dwStyle == CFS_DEFAULT)
return 1;
if (!(dwStyle & (CFS_FORCE_POSITION | CFS_POINT | CFS_RECT)))
return 0;
RECT rc;
::GetClientRect(imcLock.get().hWnd, &rc);
if (!::PtInRect(&rc, imcLock.get().cfCompForm.ptCurrentPos))
return 1;
INPUTCONTEXT *pIC = &imcLock.get();
if ((pIC->cfCompForm.dwStyle & CFS_RECT) &&
(pIC->cfCompForm.rcArea.top == pIC->cfCompForm.rcArea.bottom) &&
(pIC->cfCompForm.rcArea.left == pIC->cfCompForm.rcArea.right))
{
return 1;
}
return 2;
}
/// @implemented
HRESULT UIComposition::OnImeSetContextAfter(CicIMCLock& imcLock)
{
if ((!m_pDefCompFrameWindow || !::IsWindow(*m_pDefCompFrameWindow)) && !::IsWindow(m_CompStrs[0].m_hWnd))
{
m_dwUnknown56[0] &= ~0x8000;
return S_OK;
}
if (FAILED(imcLock.m_hr))
return imcLock.m_hr;
INT Level = GetLevelFromIMC(imcLock);
if ((Level == 1 || Level == 2) && (m_dwUnknown56[0] & 0x80000000) && m_dwUnknown56[1])
{
DWORD dwCompStrLen = 0;
UpdateShowCompWndFlag(imcLock, &dwCompStrLen);
if (Level == 1)
{
::ShowWindow(*m_pDefCompFrameWindow, (m_bHasCompStr ? SW_SHOWNOACTIVATE : SW_HIDE));
}
else if (Level == 2 && !m_bHasCompStr && dwCompStrLen)
{
for (INT iCompStr = 0; iCompStr < 3; ++iCompStr)
{
m_CompStrs[iCompStr].m_Caret.HideCaret();
::ShowWindow(m_CompStrs[iCompStr].m_Caret, SW_HIDE);
}
}
}
else
{
::ShowWindow(*m_pDefCompFrameWindow, SW_HIDE);
for (INT iCompStr = 0; iCompStr < 3; ++iCompStr)
{
m_CompStrs[iCompStr].m_Caret.HideCaret();
::ShowWindow(m_CompStrs[iCompStr].m_Caret, SW_HIDE);
}
}
return S_OK;
}
/***********************************************************************/
// For GetWindowLongPtr/SetWindowLongPtr
@ -853,31 +935,166 @@ void UI::OnImeSetContext(CicIMCLock& imcLock, WPARAM wParam, LPARAM lParam)
struct CIMEUIWindowHandler
{
static LRESULT CALLBACK ImeUIMsImeHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK ImeUIMsImeMouseHandler(HWND hWnd, WPARAM wParam, LPARAM lParam);
static HRESULT CALLBACK ImeUIMsImeMouseHandler(HWND hWnd, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK ImeUIMsImeModeBiasHandler(HWND hWnd, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK ImeUIMsImeReconvertRequest(HWND hWnd, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK ImeUIWndProcWorker(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
static HRESULT CALLBACK ImeUIDelayedReconvertFuncCall(HWND hWnd);
static HRESULT CALLBACK ImeUIOnLayoutChange(LPARAM lParam);
static HRESULT CALLBACK ImeUIPrivateHandler(UINT uMsg, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK ImeUINotifyHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
};
/// @unimplemented
LRESULT CALLBACK
/// @implemented
HRESULT CALLBACK
CIMEUIWindowHandler::ImeUIMsImeMouseHandler(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
return 0; //FIXME
if ((BYTE)wParam == 0xFF)
return TRUE;
CicIMCLock imcLock((HIMC)lParam);
if (FAILED(imcLock.m_hr))
return imcLock.m_hr;
CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
if (FAILED(imeContext.m_hr))
return FALSE;
HRESULT hr = E_FAIL;
CicInputContext *pCicIC = imeContext.get().m_pCicIC;
if (pCicIC)
{
UINT keys = 0;
if (wParam & MK_LBUTTON)
keys |= 0x1;
if (wParam & MK_SHIFT)
keys |= 0x10;
if (wParam & MK_RBUTTON)
keys |= 0x2;
if (wParam & MK_MBUTTON)
keys |= 0x780000;
else if (wParam & MK_ALT)
keys |= 0xFF880000;
hr = pCicIC->MsImeMouseHandler(HIWORD(wParam), HIBYTE(LOWORD(wParam)), keys, imcLock);
}
return hr;
}
/// @unimplemented
/// @implemented
HRESULT CALLBACK CIMEUIWindowHandler::ImeUIOnLayoutChange(LPARAM lParam)
{
CicIMCLock imcLock((HIMC)lParam);
if (FAILED(imcLock.m_hr))
return S_OK;
CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
if (FAILED(imeContext.m_hr))
return S_OK;
CicInputContext *pCicIC = imeContext.get().m_pCicIC;
if (pCicIC)
{
auto pContextOwnerServices = pCicIC->m_pContextOwnerServices;
pContextOwnerServices->AddRef();
pContextOwnerServices->OnLayoutChange();
pContextOwnerServices->Release();
}
return S_OK;
}
/// @implemented
HRESULT CALLBACK
CIMEUIWindowHandler::ImeUIPrivateHandler(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CicIMCLock imcLock((HIMC)lParam);
if (FAILED(imcLock.m_hr))
return imcLock.m_hr;
CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
if (FAILED(imeContext.m_hr))
return imeContext.m_hr;
CicInputContext *pCicIC = imeContext.get().m_pCicIC;
if (pCicIC && wParam == 0x10)
pCicIC->EscbClearDocFeedBuffer(imcLock, TRUE);
return S_OK;
}
/// @implemented
LRESULT CALLBACK
CIMEUIWindowHandler::ImeUIMsImeModeBiasHandler(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
return 0; //FIXME
if (!wParam)
return TRUE;
CicIMCLock imcLock((HIMC)lParam);
if (FAILED(imcLock.m_hr))
return imcLock.m_hr;
CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
if (FAILED(imeContext.m_hr))
return FALSE;
CicInputContext *pCicIC = imeContext.get().m_pCicIC;
if (!pCicIC)
return FALSE;
if (wParam == 1)
{
if (lParam == 0 || lParam == 1 || lParam == 4 || lParam == 0x10000)
{
GUID guid = pCicIC->m_ModeBias.ConvertModeBias((DWORD)lParam);
pCicIC->m_ModeBias.SetModeBias(guid);
pCicIC->m_dwUnknown7[2] |= 1;
pCicIC->m_pContextOwnerServices->AddRef();
pCicIC->m_pContextOwnerServices->OnAttributeChange(GUID_PROP_MODEBIAS);
pCicIC->m_pContextOwnerServices->Release();
return TRUE;
}
}
else if (wParam == 2)
{
return pCicIC->m_ModeBias.ConvertModeBias(pCicIC->m_ModeBias.m_guid);
}
return FALSE;
}
/// @unimplemented
/// @implemented
LRESULT CALLBACK
CIMEUIWindowHandler::ImeUIMsImeReconvertRequest(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
return 0; //FIXME
if (wParam == 0x10000000)
return TRUE;
HIMC hIMC = (HIMC)::GetWindowLongPtrW(hWnd, UI_GWLP_HIMC);
CicIMCLock imcLock(hIMC);
if (FAILED(imcLock.m_hr))
return FALSE;
CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
if (FAILED(imeContext.m_hr))
return FALSE;
CicInputContext *pCicIC = imeContext.get().m_pCicIC;
TLS *pTLS = TLS::GetTLS();
if (!pCicIC || !pTLS)
return FALSE;
auto pThreadMgr = pTLS->m_pThreadMgr;
auto pProfile = pTLS->m_pProfile;
if (!pThreadMgr || !pProfile)
return FALSE;
UINT uCodePage = 0;
pProfile->GetCodePageA(&uCodePage);
pCicIC->SetupReconvertString(imcLock, pThreadMgr, uCodePage, WM_MSIME_RECONVERT, FALSE);
pCicIC->EndReconvertString(imcLock);
return TRUE;
}
/// @implemented
@ -905,8 +1122,114 @@ CIMEUIWindowHandler::ImeUIMsImeHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
return 0;
}
/// @implemented
HRESULT CALLBACK
CIMEUIWindowHandler::ImeUIDelayedReconvertFuncCall(HWND hWnd)
{
HIMC hIMC = (HIMC)::GetWindowLongPtrW(hWnd, UI_GWLP_HIMC);
CicIMCLock imcLock(hIMC);
if (FAILED(imcLock.m_hr))
return imcLock.m_hr;
CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
if (FAILED(imeContext.m_hr))
return imeContext.m_hr;
CicInputContext *pCicIC = imeContext.get().m_pCicIC;
if (pCicIC)
pCicIC->DelayedReconvertFuncCall(imcLock);
return S_OK;
}
/// @unimplemented
LRESULT CALLBACK
CIMEUIWindowHandler::ImeUINotifyHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HIMC hIMC = (HIMC)::GetWindowLongPtrW(hWnd, UI_GWLP_HIMC);
CicIMCLock imcLock(hIMC);
if (FAILED(imcLock.m_hr))
return imcLock.m_hr;
CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
if (FAILED(imeContext.m_hr))
return imeContext.m_hr;
CicInputContext *pCicIC = imeContext.get().m_pCicIC;
if (pCicIC)
{
switch (wParam)
{
case IMN_CLOSECANDIDATE:
{
pCicIC->m_bCandidateOpen = FALSE;
HWND hImeWnd = ::ImmGetDefaultIMEWnd(NULL);
if (::IsWindow(hImeWnd))
::PostMessage(hImeWnd, WM_IME_NOTIFY, 0x10, (LPARAM)hIMC);
break;
}
case IMN_OPENCANDIDATE:
{
pCicIC->m_bCandidateOpen = TRUE;
pCicIC->ClearPrevCandidatePos();
break;
}
case IMN_SETCANDIDATEPOS:
{
//FIXME
break;
}
case IMN_SETCOMPOSITIONFONT:
{
//FIXME
break;
}
case IMN_SETCOMPOSITIONWINDOW:
{
//FIXME
break;
}
case 0xF:
{
CIMEUIWindowHandler::ImeUIOnLayoutChange(lParam);
break;
}
case 0x10:
{
CIMEUIWindowHandler::ImeUIPrivateHandler(uMsg, 0x10, lParam);
break;
}
case 0x13:
{
CIMEUIWindowHandler::ImeUIOnLayoutChange(lParam);
break;
}
case 0x14:
{
//FIXME
break;
}
case 0x16:
{
::SetTimer(hWnd, 2, 100, NULL);
break;
}
case 0x17:
{
return (LRESULT)hWnd;
}
case 0x10D:
{
//FIXME
break;
}
case 0x10E:
pCicIC->m_dwQueryPos = 0;
break;
}
}
return 0;
}
/// @implemented
LRESULT CALLBACK
CIMEUIWindowHandler::ImeUIWndProcWorker(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
TLS *pTLS = TLS::GetTLS();
@ -914,7 +1237,7 @@ CIMEUIWindowHandler::ImeUIWndProcWorker(HWND hWnd, UINT uMsg, WPARAM wParam, LPA
{
if (uMsg == WM_CREATE)
return -1;
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
return ::DefWindowProcW(hWnd, uMsg, wParam, lParam);
}
switch (uMsg)
@ -954,7 +1277,7 @@ CIMEUIWindowHandler::ImeUIWndProcWorker(HWND hWnd, UINT uMsg, WPARAM wParam, LPA
{
pUI->m_pComp->OnImeCompositionUpdate(imcLock);
::SetTimer(hWnd, 0, 10, NULL);
//FIXME
pUI->m_pComp->m_bInComposition = TRUE;
}
break;
}
@ -973,8 +1296,24 @@ CIMEUIWindowHandler::ImeUIWndProcWorker(HWND hWnd, UINT uMsg, WPARAM wParam, LPA
}
case WM_TIMER:
{
//FIXME
::KillTimer(hWnd, wParam);
switch (wParam)
{
case 0:
::KillTimer(hWnd, wParam);
pUI->m_pComp->m_bInComposition = FALSE;
pUI->m_pComp->OnImeNotifySetCompositionWindow(imcLock);
break;
case 1:
::KillTimer(hWnd, wParam);
pUI->m_pComp->OnImeSetContextAfter(imcLock);
break;
case 2:
::KillTimer(hWnd, wParam);
CIMEUIWindowHandler::ImeUIDelayedReconvertFuncCall(hWnd);
break;
default:
break;
}
break;
}
case WM_IME_NOTIFY:
@ -991,7 +1330,7 @@ CIMEUIWindowHandler::ImeUIWndProcWorker(HWND hWnd, UINT uMsg, WPARAM wParam, LPA
{
if (IsMsImeMessage(uMsg))
return CIMEUIWindowHandler::ImeUIMsImeHandler(hWnd, uMsg, wParam, lParam);
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
return ::DefWindowProcW(hWnd, uMsg, wParam, lParam);
}
}

View file

@ -175,11 +175,15 @@ public:
HRESULT UpdateShowCompWndFlag(CicIMCLock& imcLock, DWORD *pdwCompStrLen);
HRESULT UpdateFont(CicIMCLock& imcLock);
HRESULT UpdateCompositionRect(CicIMCLock& imcLock);
LPWSTR GetCompStrBuffer(INT cchStr);
INT GetLevelFromIMC(CicIMCLock& imcLock);
void OnImeStartComposition(CicIMCLock& imcLock, HWND hUIWnd);
HRESULT OnImeCompositionUpdate(CicIMCLock& imcLock);
HRESULT OnImeEndComposition();
HRESULT OnImeNotifySetCompositionWindow(CicIMCLock& imcLock);
HRESULT OnImeSetContextAfter(CicIMCLock& imcLock);
void OnImeSetContext(CicIMCLock& imcLock, HWND hUIWnd, WPARAM wParam, LPARAM lParam);
void OnPaintTheme(WPARAM wParam);
void OnTimer(HWND hWnd);

View file

@ -21,6 +21,7 @@ public:
enum { TIMER_ID = 0x4F83AF91 };
CicCaret();
virtual ~CicCaret();
operator HWND() const { return m_hWnd; }
void CreateCaret(HWND hWnd, SIZE size);
void DestroyCaret();