https://git.reactos.org/?p=reactos.git;a=commitdiff;h=006bdfa234a834e5b0a2464bdd79f9eeed878156

commit 006bdfa234a834e5b0a2464bdd79f9eeed878156
Author:     Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com>
AuthorDate: Tue Jan 2 19:45:03 2024 +0900
Commit:     GitHub <nore...@github.com>
CommitDate: Tue Jan 2 19:45:03 2024 +0900

    [MSCTFIME][SDK] Half-implement CTextEventSink (#6274)
    
    Supporting TIPs...
    JIRA issue: CORE-19360
    - Add CTextEventSink class.
    - Add ITfTextLayoutSink interface
      into "msctf.idl".
---
 dll/ime/msctfime/msctfime.cpp | 167 +++++++++++++++++++++++++++++++++++++++++-
 sdk/include/psdk/msctf.idl    |  21 ++++++
 2 files changed, 186 insertions(+), 2 deletions(-)

diff --git a/dll/ime/msctfime/msctfime.cpp b/dll/ime/msctfime/msctfime.cpp
index d0feb2008da..c9f235937bc 100644
--- a/dll/ime/msctfime/msctfime.cpp
+++ b/dll/ime/msctfime/msctfime.cpp
@@ -597,9 +597,166 @@ HRESULT CCompartmentEventSink::_Unadvise()
 }
 
 class CInputContextOwnerCallBack;
-class CTextEventSink;
 class CInputContextOwner;
 
+typedef INT (CALLBACK *FN_ENDEDIT)(INT, LPVOID, LPVOID);
+typedef INT (CALLBACK *FN_LAYOUTCHANGE)(UINT nType, FN_ENDEDIT fnEndEdit, 
ITfContextView *pView);
+
+class CTextEventSink : public ITfTextEditSink, ITfTextLayoutSink
+{
+protected:
+    LONG m_cRefs;
+    IUnknown *m_pUnknown;
+    DWORD m_dwEditSinkCookie;
+    DWORD m_dwLayoutSinkCookie;
+    FN_LAYOUTCHANGE m_fnLayoutChange;
+    FN_ENDEDIT m_fnEndEdit;
+    LPVOID m_pCallbackPV;
+
+public:
+    CTextEventSink(FN_ENDEDIT fnEndEdit, LPVOID pCallbackPV);
+    virtual ~CTextEventSink();
+
+    HRESULT _Advise(IUnknown *pUnknown, UINT uFlags);
+    HRESULT _Unadvise();
+
+    // IUnknown interface
+    STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override;
+    STDMETHODIMP_(ULONG) AddRef() override;
+    STDMETHODIMP_(ULONG) Release() override;
+
+    // ITfTextEditSink interface
+    STDMETHODIMP OnEndEdit(
+        ITfContext *pic,
+        TfEditCookie ecReadOnly,
+        ITfEditRecord *pEditRecord) override;
+
+    // ITfTextLayoutSink interface
+    STDMETHODIMP
+    OnLayoutChange(
+        ITfContext *pContext,
+        TfLayoutCode lcode,
+        ITfContextView *pContextView) override;
+};
+
+/**
+ * @implemented
+ */
+CTextEventSink::CTextEventSink(FN_ENDEDIT fnEndEdit, LPVOID pCallbackPV)
+{
+    m_cRefs = 1;
+    m_pUnknown = NULL;
+    m_dwEditSinkCookie = (DWORD)-1;
+    m_dwLayoutSinkCookie = (DWORD)-1;
+    m_fnLayoutChange = NULL;
+    m_fnEndEdit = fnEndEdit;
+    m_pCallbackPV = pCallbackPV;
+}
+
+/**
+ * @implemented
+ */
+CTextEventSink::~CTextEventSink()
+{
+}
+
+/**
+ * @implemented
+ */
+STDMETHODIMP CTextEventSink::QueryInterface(REFIID riid, LPVOID* ppvObj)
+{
+    if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, 
IID_ITfTextEditSink))
+    {
+        *ppvObj = this;
+        AddRef();
+        return S_OK;
+    }
+    if (IsEqualIID(riid, IID_ITfTextLayoutSink))
+    {
+        *ppvObj = static_cast<ITfTextLayoutSink*>(this);
+        AddRef();
+        return S_OK;
+    }
+    return E_NOINTERFACE;
+}
+
+/**
+ * @implemented
+ */
+STDMETHODIMP_(ULONG) CTextEventSink::AddRef()
+{
+    return ::InterlockedIncrement(&m_cRefs);
+}
+
+/**
+ * @implemented
+ */
+STDMETHODIMP_(ULONG) CTextEventSink::Release()
+{
+    if (::InterlockedDecrement(&m_cRefs) == 0)
+    {
+        delete this;
+        return 0;
+    }
+    return m_cRefs;
+}
+
+struct TEXT_EVENT_SINK_END_EDIT
+{
+    TfEditCookie m_ecReadOnly;
+    ITfEditRecord *m_pEditRecord;
+    ITfContext *m_pContext;
+};
+
+/**
+ * @implemented
+ */
+STDMETHODIMP CTextEventSink::OnEndEdit(
+    ITfContext *pic,
+    TfEditCookie ecReadOnly,
+    ITfEditRecord *pEditRecord)
+{
+    TEXT_EVENT_SINK_END_EDIT Data = { ecReadOnly, pEditRecord, pic };
+    return m_fnEndEdit(1, m_pCallbackPV, (LPVOID)&Data);
+}
+
+/**
+ * @implemented
+ */
+STDMETHODIMP CTextEventSink::OnLayoutChange(
+    ITfContext *pContext,
+    TfLayoutCode lcode,
+    ITfContextView *pContextView)
+{
+    switch (lcode)
+    {
+        case TF_LC_CREATE:
+            return m_fnLayoutChange(3, m_fnEndEdit, pContextView);
+        case TF_LC_CHANGE:
+            return m_fnLayoutChange(2, m_fnEndEdit, pContextView);
+        case TF_LC_DESTROY:
+            return m_fnLayoutChange(4, m_fnEndEdit, pContextView);
+        default:
+            return E_INVALIDARG;
+    }
+}
+
+/**
+ * @unimplemented
+ */
+HRESULT CTextEventSink::_Advise(IUnknown *pUnknown, UINT uFlags)
+{
+    return E_NOTIMPL;
+}
+
+/**
+ * @unimplemented
+ */
+HRESULT CTextEventSink::_Unadvise()
+{
+    return E_NOTIMPL;
+}
+
 /***********************************************************************
  *      CicInputContext
  *
@@ -821,7 +978,13 @@ CicInputContext::DestroyInputContext()
         pSource->UnadviseSingleSink(m_clientId, IID_ITfCleanupContextSink);
 
     //FIXME: m_dwUnknown5
-    //FIXME: m_pTextEventSink
+
+    if (m_pTextEventSink)
+    {
+        m_pTextEventSink->_Unadvise();
+        m_pTextEventSink->Release();
+        m_pTextEventSink = NULL;
+    }
 
     if (m_pCompEventSink2)
     {
diff --git a/sdk/include/psdk/msctf.idl b/sdk/include/psdk/msctf.idl
index e3d642c651c..60219b328e0 100644
--- a/sdk/include/psdk/msctf.idl
+++ b/sdk/include/psdk/msctf.idl
@@ -109,6 +109,7 @@ interface ITfKeyEventSink;
 interface ITfPersistentPropertyLoaderACP;
 interface ITfRangeACP;
 interface ITfCleanupContextSink;
+interface ITfTextLayoutSink;
 
 cpp_quote("#if 0")
 typedef [uuid(4f5d560f-5ab5-4dde-8c4d-404592857ab0)] UINT_PTR HKL;
@@ -1919,3 +1920,23 @@ interface ITfTransitoryExtensionSink : IUnknown
         [in] ITfRange *pCompositionRange,
         [out] BOOL *pfDeleteResultRange);
 }
+
+[
+    object,
+    uuid(2af2d06a-dd5b-4927-a0b4-54f19c91fade),
+    pointer_default(unique)
+]
+interface ITfTextLayoutSink : IUnknown
+{
+    typedef [uuid(603553cf-9edd-4cc1-9ecc-069e4a427734)] enum
+    {
+        TF_LC_CREATE = 0,
+        TF_LC_CHANGE = 1,
+        TF_LC_DESTROY = 2
+    } TfLayoutCode;
+
+    HRESULT OnLayoutChange(
+        [in] ITfContext     *pic,
+        [in] TfLayoutCode   lcode,
+        [in] ITfContextView *pView);
+}

Reply via email to