https://git.reactos.org/?p=reactos.git;a=commitdiff;h=353edbd3f4aaefe56ecbe0b8c0de7cf811186d31

commit 353edbd3f4aaefe56ecbe0b8c0de7cf811186d31
Author:     Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com>
AuthorDate: Fri Feb 23 11:18:52 2024 +0900
Commit:     GitHub <nore...@github.com>
CommitDate: Fri Feb 23 11:18:52 2024 +0900

    [MSCTFIME] Add UIComposition Part 2 (#6520)
    
    Supporting TIPs...
    JIRA issue: CORE-19360
    - Add implementation to
      UIComposition class.
---
 dll/ime/msctfime/misc.cpp |  25 +++
 dll/ime/msctfime/misc.h   |   4 +
 dll/ime/msctfime/tls.cpp  |  22 +++
 dll/ime/msctfime/tls.h    |   2 +
 dll/ime/msctfime/ui.cpp   | 412 +++++++++++++++++++++++++++++++++++++++++++---
 dll/ime/msctfime/ui.h     |  71 +++++++-
 6 files changed, 504 insertions(+), 32 deletions(-)

diff --git a/dll/ime/msctfime/misc.cpp b/dll/ime/msctfime/misc.cpp
index 18e01939ada..7cf38ad15b2 100644
--- a/dll/ime/msctfime/misc.cpp
+++ b/dll/ime/msctfime/misc.cpp
@@ -208,3 +208,28 @@ LONG CModeBias::ConvertModeBias(REFGUID guid)
     }
     return 0;
 }
+
+/***********************************************************************/
+
+/// East-Asian language?
+/// @implemented
+BOOL IsEALang(VOID)
+{
+    TLS *pTLS = TLS::GetTLS();
+    if (!pTLS || !pTLS->m_pProfile)
+        return FALSE;
+
+    LANGID LangID;
+    pTLS->m_pProfile->GetLangId(&LangID);
+
+    switch (PRIMARYLANGID(LangID))
+    {
+        case LANG_CHINESE:
+        case LANG_JAPANESE:
+        case LANG_KOREAN:
+            return TRUE;
+
+        default:
+            return FALSE;
+    }
+}
diff --git a/dll/ime/msctfime/misc.h b/dll/ime/msctfime/misc.h
index ca96a227f54..f1f600b4671 100644
--- a/dll/ime/msctfime/misc.h
+++ b/dll/ime/msctfime/misc.h
@@ -54,3 +54,7 @@ public:
     LONG ConvertModeBias(REFGUID guid);
     void SetModeBias(REFGUID rguid);
 };
+
+/***********************************************************************/
+
+BOOL IsEALang(VOID);
diff --git a/dll/ime/msctfime/tls.cpp b/dll/ime/msctfime/tls.cpp
index efb6f9726f5..c6db21cc61e 100644
--- a/dll/ime/msctfime/tls.cpp
+++ b/dll/ime/msctfime/tls.cpp
@@ -54,3 +54,25 @@ BOOL TLS::InternalDestroyTLS()
     ::TlsSetValue(s_dwTlsIndex, NULL);
     return TRUE;
 }
+
+/// @implemented
+BOOL TLS::NonEACompositionEnabled()
+{
+    if (!m_NonEAComposition)
+    {
+        DWORD dwValue = 1;
+
+        CicRegKey regKey;
+        LSTATUS error = regKey.Open(HKEY_CURRENT_USER, 
TEXT("SOFTWARE\\Microsoft\\CTF\\CUAS"));
+        if (error == ERROR_SUCCESS)
+        {
+            error = regKey.QueryDword(TEXT("NonEAComposition"), &dwValue);
+            if (error != ERROR_SUCCESS)
+                dwValue = 1;
+        }
+
+        m_NonEAComposition = dwValue;
+    }
+
+    return (m_NonEAComposition == 2);
+}
diff --git a/dll/ime/msctfime/tls.h b/dll/ime/msctfime/tls.h
index ae1a6000e9c..2d2c882a67e 100644
--- a/dll/ime/msctfime/tls.h
+++ b/dll/ime/msctfime/tls.h
@@ -71,4 +71,6 @@ public:
 
     static TLS* InternalAllocateTLS();
     static BOOL InternalDestroyTLS();
+
+    BOOL NonEACompositionEnabled();
 };
diff --git a/dll/ime/msctfime/ui.cpp b/dll/ime/msctfime/ui.cpp
index fb8ae4105a9..ed8455782c2 100644
--- a/dll/ime/msctfime/ui.cpp
+++ b/dll/ime/msctfime/ui.cpp
@@ -287,8 +287,8 @@ void CDefCompFrameWindow::SetCompStrRect(INT nWidth, INT 
nHeight, BOOL bShow)
 
     Show(bShow);
 
-    ::MoveWindow(m_hwndDefCompFrame, GripperWidth + 2, 7, nWidth, nHeight, 
TRUE);
-    ::ShowWindow(m_hwndDefCompFrame, (bShow ? SW_SHOWNOACTIVATE : SW_HIDE));
+    ::MoveWindow(m_hwndCompStr, GripperWidth + 2, 7, nWidth, nHeight, TRUE);
+    ::ShowWindow(m_hwndCompStr, (bShow ? SW_SHOWNOACTIVATE : SW_HIDE));
 }
 
 /// @implemented
@@ -342,11 +342,11 @@ STDMETHODIMP_(void) CDefCompFrameWindow::OnCreate(HWND 
hWnd)
 /// @implemented
 STDMETHODIMP_(BOOL) CDefCompFrameWindow::OnSetCursor(UINT uMsg, LONG x, LONG y)
 {
-    if (!::IsWindow(m_hwndDefCompFrame))
+    if (!::IsWindow(m_hwndCompStr))
         return FALSE;
 
     RECT rc;
-    ::GetWindowRect(m_hwndDefCompFrame, &rc);
+    ::GetWindowRect(m_hwndCompStr, &rc);
     MyScreenToClient(NULL, &rc);
     POINT pt = { x, y };
     return ::PtInRect(&rc, pt);
@@ -365,15 +365,15 @@ CDefCompFrameWindow::OnWindowPosChanged(HWND hWnd, UINT 
uMsg, WPARAM wParam, LPA
 /// @implemented
 STDMETHODIMP_(void) CDefCompFrameWindow::HandleMouseMsg(UINT uMsg, LONG x, 
LONG y)
 {
-    if (::IsWindow(m_hwndDefCompFrame))
+    if (::IsWindow(m_hwndCompStr))
     {
         RECT rc;
-        ::GetWindowRect(m_hwndDefCompFrame, &rc);
+        ::GetWindowRect(m_hwndCompStr, &rc);
         MyScreenToClient(NULL, &rc);
 
         POINT pt = { x, y };
         if (::PtInRect(&rc, pt))
-            ::SendMessage(m_hwndDefCompFrame, 0x7E8, 0, 0);
+            ::SendMessage(m_hwndCompStr, 0x7E8, 0, 0);
     }
 
     CUIFWindow::HandleMouseMsg(uMsg, x, y);
@@ -381,27 +381,380 @@ STDMETHODIMP_(void) 
CDefCompFrameWindow::HandleMouseMsg(UINT uMsg, LONG x, LONG
 
 /***********************************************************************/
 
+/// @implemented
+POLYTEXTW *CPolyText::GetPolyAt(INT iItem)
+{
+    return &m_PolyTextArray[iItem];
+}
+
+/// @implemented
+HRESULT CPolyText::ShiftPolyText(INT xDelta, INT yDelta)
+{
+    for (size_t iItem = 0; iItem < m_PolyTextArray.size(); ++iItem)
+    {
+        POLYTEXTW *pPolyText = &m_PolyTextArray[iItem];
+        pPolyText->x += xDelta;
+        pPolyText->y += yDelta;
+        ::OffsetRect((LPRECT)&pPolyText->rcl, xDelta, yDelta);
+    }
+    return S_OK;
+}
+
+/// @implemented
+HRESULT CPolyText::RemoveLastLine(BOOL bHorizontal)
+{
+    size_t iItem, cItems = m_PolyTextArray.size();
+    if (!cItems)
+        return E_FAIL;
+
+    POLYTEXTW *pData1 = &m_PolyTextArray[cItems - 1];
+
+    for (iItem = 0; iItem < cItems; ++iItem)
+    {
+        POLYTEXTW *pData2 = &m_PolyTextArray[iItem];
+        if (bHorizontal)
+        {
+            if (pData1->x == pData2->x)
+                break;
+        }
+        else
+        {
+            if (pData1->y == pData2->y)
+                break;
+        }
+    }
+
+    if (iItem >= cItems)
+        return E_FAIL;
+
+    m_PolyTextArray.Remove(iItem, cItems - iItem);
+    m_ValueArray.Remove(iItem, cItems - iItem);
+    return S_OK;
+}
+
+/// @implemented
+void CPolyText::RemoveAll()
+{
+    m_PolyTextArray.clear();
+    m_ValueArray.clear();
+}
+
+/***********************************************************************/
+
+/// @implemented
+void COMPWND::_ClientToScreen(LPRECT prc)
+{
+    ::ClientToScreen(m_hWnd, (LPPOINT)prc);
+    ::ClientToScreen(m_hWnd, (LPPOINT)&prc->right);
+}
+
+/***********************************************************************/
+
 // For GetWindowLongPtr/SetWindowLongPtr
-#define UIGWLP_HIMC 0
-#define UIGWLP_UI   sizeof(HIMC)
-#define UIGWLP_SIZE (UIGWLP_UI + sizeof(UI*))
+#define UICOMP_GWLP_INDEX 0
+#define UICOMP_GWLP_SIZE  (UICOMP_GWLP_INDEX + sizeof(INT))
 
 /// @unimplemented
-void UIComposition::OnImeStartComposition(CicIMCLock& imcLock, HWND hUIWnd)
+UIComposition::UIComposition(HWND hwndParent)
 {
-    //FIXME
+}
+
+/// @implemented
+UIComposition::~UIComposition()
+{
+    DestroyCompositionWindow();
+
+    if (m_hFont1)
+    {
+        ::DeleteObject(m_hFont1);
+        m_hFont1 = NULL;
+    }
+
+    if (m_hFont2)
+    {
+        ::DeleteObject(m_hFont2);
+        m_hFont2 = NULL;
+    }
+
+    if (m_strCompStr)
+    {
+        cicMemFree(m_strCompStr);
+        m_strCompStr = NULL;
+    }
+
+    m_cchCompStr = 0;
+}
+
+// @implemented
+BOOL UIComposition::SendMessageToUI(CicIMCLock& imcLock, WPARAM wParam, LPARAM 
lParam)
+{
+    HWND hImeWnd = ImmGetDefaultIMEWnd(0);
+    if (!::IsWindow(hImeWnd))
+        return TRUE;
+    TLS *pTLS = TLS::GetTLS();
+    LRESULT ret;
+    if (pTLS && pTLS->m_cWnds > 1)
+        ret = ::SendMessage(imcLock.get().hWnd, WM_IME_NOTIFY, wParam, lParam);
+    else
+        ret = ::SendMessage(hImeWnd, WM_IME_NOTIFY, wParam, lParam);
+    return !ret;
+}
+
+/// @implemented
+HRESULT UIComposition::CreateDefFrameWnd(HWND hwndParent, HIMC hIMC)
+{
+    if (!m_pDefCompFrameWindow)
+    {
+        m_pDefCompFrameWindow = new(cicNoThrow) CDefCompFrameWindow(hIMC, 
0x800000A4);
+        if (!m_pDefCompFrameWindow)
+            return E_OUTOFMEMORY;
+        if (!m_pDefCompFrameWindow->Initialize())
+        {
+            delete m_pDefCompFrameWindow;
+            m_pDefCompFrameWindow = NULL;
+            return E_FAIL;
+        }
+
+        m_pDefCompFrameWindow->Init();
+    }
+
+    m_pDefCompFrameWindow->CreateWnd(hwndParent);
+    return S_OK;
+}
+
+/// @implemented
+HRESULT UIComposition::CreateCompButtonWnd(HWND hwndParent, HIMC hIMC)
+{
+    TLS *pTLS = TLS::GetTLS();
+    if (!pTLS || !pTLS->NonEACompositionEnabled())
+        return S_OK;
+
+    if (IsEALang())
+    {
+        if (m_pCompButtonFrameWindow)
+        {
+            delete m_pCompButtonFrameWindow;
+            m_pCompButtonFrameWindow = NULL;
+        }
+        return S_OK;
+    }
+
+    if (!m_pCompButtonFrameWindow)
+    {
+        m_pCompButtonFrameWindow = new(cicNoThrow) 
CCompButtonFrameWindow(hIMC, 0x800000B4);
+        if (!m_pCompButtonFrameWindow)
+            return E_OUTOFMEMORY;
+
+        if (!m_pCompButtonFrameWindow->Initialize())
+        {
+            if (m_pCompButtonFrameWindow)
+            {
+                delete m_pCompButtonFrameWindow;
+                m_pCompButtonFrameWindow = NULL;
+            }
+            return E_FAIL;
+        }
+
+        m_pCompButtonFrameWindow->Init();
+    }
+
+    m_pCompButtonFrameWindow->CreateWnd(hwndParent);
+    return S_OK;
+}
+
+/// @implemented
+HRESULT UIComposition::CreateCompositionWindow(CicIMCLock& imcLock, HWND 
hwndParent)
+{
+    if (FAILED(imcLock.m_hr))
+        return imcLock.m_hr;
+
+    if (!::IsWindow(hwndParent) || m_bHasCompWnd)
+        return E_FAIL;
+
+    for (INT iCompStr = 0; iCompStr < 3; ++iCompStr)
+    {
+        DWORD style = WS_POPUP | WS_DISABLED;
+        HWND hwndCompStr = ::CreateWindowExW(0, L"MSCTFIME Composition", NULL, 
style,
+                                             0, 0, 0, 0, hwndParent, NULL, 
g_hInst, NULL);
+        m_CompStrs[iCompStr].m_hWnd = hwndCompStr;
+        ::SetWindowLongPtrW(hwndCompStr, GWLP_USERDATA, (LONG_PTR)this);
+        ::SetWindowLongPtrW(hwndCompStr, UICOMP_GWLP_INDEX, iCompStr);
+        m_CompStrs[iCompStr].m_Caret.CreateCaret(hwndCompStr, m_CaretSize);
+    }
+
+    HRESULT hr = CreateCompButtonWnd(hwndParent, imcLock.m_hIMC);
+    if (FAILED(hr))
+    {
+        DestroyCompositionWindow();
+        return E_OUTOFMEMORY;
+    }
+
+    hr = CreateDefFrameWnd(hwndParent, imcLock.m_hIMC);
+    if (FAILED(hr))
+    {
+        DestroyCompositionWindow();
+        return E_OUTOFMEMORY;
+    }
+
+    DWORD style = WS_CHILD | WS_DISABLED;
+    HWND hwndCompStr = ::CreateWindowExW(WS_EX_CLIENTEDGE, L"MSCTFIME 
Composition", NULL, style,
+                                         0, 0, 0, 0, *m_pDefCompFrameWindow, 
NULL, g_hInst, NULL);
+    if (!hwndCompStr)
+    {
+        DestroyCompositionWindow();
+        return E_OUTOFMEMORY;
+    }
+
+    m_CompStrs[3].m_hWnd = hwndCompStr;
+    m_pDefCompFrameWindow->m_hwndCompStr = hwndCompStr;
+    ::SetWindowLongPtrW(hwndCompStr, GWLP_USERDATA, (LONG_PTR)this);
+    ::SetWindowLongPtrW(hwndCompStr, UICOMP_GWLP_INDEX, -1);
+    m_CompStrs[3].m_Caret.CreateCaret(hwndCompStr, m_CaretSize);
+    m_bHasCompWnd = TRUE;
+
+    return S_OK;
+}
+
+/// @implemented
+HRESULT UIComposition::DestroyCompositionWindow()
+{
+    for (INT i = 0; i < 4; ++i)
+    {
+        COMPWND *pCompStr = &m_CompStrs[i];
+        pCompStr->m_Caret.DestroyCaret();
+        if (::IsWindow(pCompStr->m_hWnd))
+        {
+            DestroyWindow(pCompStr->m_hWnd);
+            pCompStr->m_PolyText.RemoveAll();
+        }
+        pCompStr->m_hWnd = NULL;
+    }
+
+    if (m_pCompButtonFrameWindow)
+    {
+        ::DestroyWindow(*m_pCompButtonFrameWindow);
+        delete m_pCompButtonFrameWindow;
+        m_pCompButtonFrameWindow = NULL;
+    }
+
+    if (m_pDefCompFrameWindow)
+    {
+        ::DestroyWindow(*m_pDefCompFrameWindow);
+        delete m_pDefCompFrameWindow;
+        m_pDefCompFrameWindow = NULL;
+    }
+
+    return 0;
+}
+
+// @implemented
+BOOL UIComposition::InquireImeUIWndState(CicIMCLock& imcLock)
+{
+    BOOL bValue = FALSE;
+    UIComposition::SendMessageToUI(imcLock, 0x11u, (LPARAM)&bValue);
+    return bValue;
+}
+
+/// @implemented
+HRESULT UIComposition::UpdateShowCompWndFlag(CicIMCLock& imcLock, DWORD 
*pdwCompStrLen)
+{
+    if (FAILED(imcLock.m_hr))
+        return imcLock.m_hr;
+    if (!::IsWindow(imcLock.get().hWnd))
+        return E_FAIL;
+
+    CicIMCCLock<COMPOSITIONSTRING> compStr(imcLock.get().hCompStr);
+    if (FAILED(compStr.m_hr))
+        return compStr.m_hr;
+
+    if ((m_dwUnknown56[0] & 0x80000000) && compStr.get().dwCompStrLen)
+        m_bHasCompStr = TRUE;
+    else
+        m_bHasCompStr = FALSE;
+
+    if (pdwCompStrLen)
+        *pdwCompStrLen = compStr.get().dwCompStrLen;
+
+    return S_OK;
+}
+
+/// @implemented
+HRESULT UIComposition::UpdateFont(CicIMCLock& imcLock)
+{
+    if (FAILED(imcLock.m_hr))
+        return imcLock.m_hr;
+
+    if (m_hFont1)
+        ::DeleteObject(m_hFont1);
+    if (m_hFont2)
+        ::DeleteObject(m_hFont2);
+
+    LOGFONTW lf = imcLock.get().lfFont.W;
+    m_hFont2 = ::CreateFontIndirectW(&lf);
+
+    lf.lfEscapement = 0;
+    lf.lfOrientation = 0;
+    BOOL bVertical = (lf.lfFaceName[0] == L'@');
+    if (bVertical)
+    {
+        MoveMemory(lf.lfFaceName, &lf.lfFaceName[1], sizeof(lf.lfFaceName) - 
sizeof(WCHAR));
+        lf.lfFaceName[_countof(lf.lfFaceName) - 1] = UNICODE_NULL;
+    }
+    m_hFont1 = ::CreateFontIndirectW(&lf);
+
+    return S_OK;
+}
+
+// @implemented
+void UIComposition::OnTimer(HWND hWnd)
+{
+    INT iCompStr = (INT)::GetWindowLongPtrW(hWnd, UICOMP_GWLP_INDEX);
+    if (iCompStr == -1)
+        m_CompStrs[3].m_Caret.OnTimer();
+    else
+        m_CompStrs[iCompStr].m_Caret.OnTimer();
+}
+
+/// @implemented
+BOOL UIComposition::GetImeUIWndTextExtent(CicIMCLock& imcLock, LPARAM lParam)
+{
+    return !UIComposition::SendMessageToUI(imcLock, 0x14, lParam);
+}
+
+/// @implemented
+LPWSTR UIComposition::GetCompStrBuffer(INT cchStr)
+{
+    if (!m_strCompStr)
+    {
+        m_strCompStr = (LPWSTR)cicMemAllocClear((cchStr + 1) * sizeof(WCHAR));
+        m_cchCompStr = cchStr;
+    }
+    if (m_cchCompStr < cchStr)
+    {
+        m_strCompStr = (LPWSTR)cicMemReAlloc(m_strCompStr, (cchStr + 1) * 
sizeof(WCHAR));
+        m_cchCompStr = cchStr;
+    }
+    return m_strCompStr;
 }
 
 /// @unimplemented
-void UIComposition::OnImeCompositionUpdate(CicIMCLock& imcLock)
+void UIComposition::OnImeStartComposition(CicIMCLock& imcLock, HWND hUIWnd)
 {
     //FIXME
 }
 
+/// @implemented
+HRESULT UIComposition::OnImeCompositionUpdate(CicIMCLock& imcLock)
+{
+    m_dwUnknown56[0] |= 0x8000;
+    return UIComposition::UpdateShowCompWndFlag(imcLock, NULL);
+}
+
 /// @unimplemented
-void UIComposition::OnImeEndComposition()
+HRESULT UIComposition::OnImeEndComposition()
 {
-    //FIXME
+    m_dwUnknown56[0] = 0;
+    return DestroyCompositionWindow();
 }
 
 /// @unimplemented
@@ -416,10 +769,10 @@ void UIComposition::OnPaintTheme(WPARAM wParam)
     //FIXME
 }
 
-/// @unimplemented
-void UIComposition::OnDestroy()
+/// @implemented
+HRESULT UIComposition::OnDestroy()
 {
-    //FIXME
+    return DestroyCompositionWindow();
 }
 
 /// @unimplemented
@@ -433,6 +786,11 @@ UIComposition::CompWndProc(HWND hWnd, UINT uMsg, WPARAM 
wParam, LPARAM lParam)
 
 /***********************************************************************/
 
+// For GetWindowLongPtr/SetWindowLongPtr
+#define UI_GWLP_HIMC 0
+#define UI_GWLP_UI   sizeof(HIMC)
+#define UI_GWLP_SIZE (UI_GWLP_UI + sizeof(UI*))
+
 /// @implemented
 UI::UI(HWND hWnd) : m_hWnd(hWnd)
 {
@@ -447,11 +805,11 @@ UI::~UI()
 /// @implemented
 HRESULT UI::_Create()
 {
-    m_pComp = new(cicNoThrow) UIComposition();
+    m_pComp = new(cicNoThrow) UIComposition(m_hWnd);
     if (!m_pComp)
         return E_OUTOFMEMORY;
 
-    ::SetWindowLongPtrW(m_hWnd, UIGWLP_UI, (LONG_PTR)this);
+    ::SetWindowLongPtrW(m_hWnd, UI_GWLP_UI, (LONG_PTR)this);
     return S_OK;
 }
 
@@ -459,13 +817,13 @@ HRESULT UI::_Create()
 void UI::_Destroy()
 {
     m_pComp->OnDestroy();
-    ::SetWindowLongPtrW(m_hWnd, UIGWLP_UI, 0);
+    ::SetWindowLongPtrW(m_hWnd, UI_GWLP_UI, 0);
 }
 
 /// @implemented
 void UI::OnCreate(HWND hWnd)
 {
-    UI *pUI = (UI*)::GetWindowLongPtrW(hWnd, UIGWLP_UI);
+    UI *pUI = (UI*)::GetWindowLongPtrW(hWnd, UI_GWLP_UI);
     if (pUI)
         return;
     pUI = new(cicNoThrow) UI(hWnd);
@@ -476,7 +834,7 @@ void UI::OnCreate(HWND hWnd)
 /// @implemented
 void UI::OnDestroy(HWND hWnd)
 {
-    UI *pUI = (UI*)::GetWindowLongPtrW(hWnd, UIGWLP_UI);
+    UI *pUI = (UI*)::GetWindowLongPtrW(hWnd, UI_GWLP_UI);
     if (!pUI)
         return;
 
@@ -580,8 +938,8 @@ CIMEUIWindowHandler::ImeUIWndProcWorker(HWND hWnd, UINT 
uMsg, WPARAM wParam, LPA
         case WM_IME_SELECT:
         case WM_TIMER:
         {
-            HIMC hIMC = (HIMC)GetWindowLongPtrW(hWnd, UIGWLP_HIMC);
-            UI* pUI = (UI*)GetWindowLongPtrW(hWnd, UIGWLP_UI);
+            HIMC hIMC = (HIMC)GetWindowLongPtrW(hWnd, UI_GWLP_HIMC);
+            UI* pUI = (UI*)GetWindowLongPtrW(hWnd, UI_GWLP_UI);
             CicIMCLock imcLock(hIMC);
             switch (uMsg)
             {
@@ -664,7 +1022,7 @@ BOOL RegisterImeClass(VOID)
     {
         ZeroMemory(&wcx, sizeof(wcx));
         wcx.cbSize          = sizeof(WNDCLASSEXW);
-        wcx.cbWndExtra      = UIGWLP_SIZE;
+        wcx.cbWndExtra      = UI_GWLP_SIZE;
         wcx.hIcon           = LoadIconW(0, (LPCWSTR)IDC_ARROW);
         wcx.hInstance       = g_hInst;
         wcx.hCursor         = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW);
@@ -680,7 +1038,7 @@ BOOL RegisterImeClass(VOID)
     {
         ZeroMemory(&wcx, sizeof(wcx));
         wcx.cbSize          = sizeof(WNDCLASSEXW);
-        wcx.cbWndExtra      = sizeof(DWORD);
+        wcx.cbWndExtra      = UICOMP_GWLP_SIZE;
         wcx.hIcon           = NULL;
         wcx.hInstance       = g_hInst;
         wcx.hCursor         = LoadCursorW(NULL, (LPCWSTR)IDC_IBEAM);
diff --git a/dll/ime/msctfime/ui.h b/dll/ime/msctfime/ui.h
index 71b32ebb40d..8d416312a72 100644
--- a/dll/ime/msctfime/ui.h
+++ b/dll/ime/msctfime/ui.h
@@ -94,7 +94,7 @@ public:
 class CDefCompFrameWindow : public CCompFrameWindow
 {
 public:
-    HWND m_hwndDefCompFrame;
+    HWND m_hwndCompStr;
     CDefCompFrameGripper *m_pGripper;
     CCompFinalizeButton *m_pFinalizeButton;
     MARGINS m_Margins;
@@ -120,14 +120,74 @@ public:
 
 /***********************************************************************/
 
-struct UIComposition
+struct CPolyText
 {
+    CicArray<POLYTEXTW> m_PolyTextArray;
+    CicArray<DWORD> m_ValueArray;
+
+    HRESULT ShiftPolyText(INT xDelta, INT yDelta);
+    POLYTEXTW *GetPolyAt(INT iItem);
+    HRESULT RemoveLastLine(BOOL bHorizontal);
+    void RemoveAll();
+};
+
+/***********************************************************************/
+
+struct COMPWND
+{
+    HWND m_hWnd;
+    CPolyText m_PolyText;
+    CicCaret m_Caret;
+    DWORD m_dwUnknown57[3];
+
+    void _ClientToScreen(LPRECT prc);
+};
+
+/***********************************************************************/
+
+class UIComposition
+{
+public:
+    HWND m_hwndParent;
+    BOOL m_bHasCompWnd;
+    COMPWND m_CompStrs[4];
+    HFONT m_hFont1;
+    DWORD m_dwUnknown54;
+    HFONT m_hFont2;
+    DWORD m_dwUnknown55;
+    SIZE m_CaretSize;
+    DWORD m_dwUnknown56[2];
+    LPWSTR m_strCompStr;
+    INT m_cchCompStr;
+    BOOL m_bInComposition;
+    BOOL m_bHasCompStr;
+    CDefCompFrameWindow *m_pDefCompFrameWindow;
+    CCompButtonFrameWindow *m_pCompButtonFrameWindow;
+
+public:
+    UIComposition(HWND hwndParent);
+    virtual ~UIComposition();
+
+    HRESULT CreateDefFrameWnd(HWND hwndParent, HIMC hIMC);
+    HRESULT CreateCompButtonWnd(HWND hwndParent, HIMC hIMC);
+    HRESULT CreateCompositionWindow(CicIMCLock& imcLock, HWND hwndParent);
+    HRESULT DestroyCompositionWindow();
+
+    HRESULT UpdateShowCompWndFlag(CicIMCLock& imcLock, DWORD *pdwCompStrLen);
+    HRESULT UpdateFont(CicIMCLock& imcLock);
+    LPWSTR GetCompStrBuffer(INT cchStr);
+
     void OnImeStartComposition(CicIMCLock& imcLock, HWND hUIWnd);
-    void OnImeCompositionUpdate(CicIMCLock& imcLock);
-    void OnImeEndComposition();
+    HRESULT OnImeCompositionUpdate(CicIMCLock& imcLock);
+    HRESULT OnImeEndComposition();
     void OnImeSetContext(CicIMCLock& imcLock, HWND hUIWnd, WPARAM wParam, 
LPARAM lParam);
     void OnPaintTheme(WPARAM wParam);
-    void OnDestroy();
+    void OnTimer(HWND hWnd);
+    HRESULT OnDestroy();
+
+    static BOOL SendMessageToUI(CicIMCLock& imcLock, WPARAM wParam, LPARAM 
lParam);
+    static BOOL InquireImeUIWndState(CicIMCLock& imcLock);
+    static BOOL GetImeUIWndTextExtent(CicIMCLock& imcLock, LPARAM lParam);
 
     static LRESULT CALLBACK CompWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, 
LPARAM lParam);
 };
@@ -147,6 +207,7 @@ struct UI
 
     static void OnCreate(HWND hWnd);
     static void OnDestroy(HWND hWnd);
+
     void OnImeSetContext(CicIMCLock& imcLock, WPARAM wParam, LPARAM lParam);
 };
 

Reply via email to