From 299abf7c87af209e8f4a92b56ce8febee651f7b2 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Fri, 8 Mar 2024 20:43:32 +0900 Subject: [PATCH] [MSCTFIME][SDK] Add CInputContextOwner (stub) (#6584) Supporting TIPs... JIRA issue: CORE-19360 - Add ITfContextOwner interface to "msctf.idl". - Stub-implement CInputContextOwner class. --- dll/ime/msctfime/inputcontext.cpp | 186 +++++++++++++++++++++++++++++- dll/ime/msctfime/inputcontext.h | 53 +++++++++ sdk/include/psdk/msctf.idl | 32 +++++ 3 files changed, 270 insertions(+), 1 deletion(-) diff --git a/dll/ime/msctfime/inputcontext.cpp b/dll/ime/msctfime/inputcontext.cpp index 86ffb1f5627..f4f1e3c5318 100644 --- a/dll/ime/msctfime/inputcontext.cpp +++ b/dll/ime/msctfime/inputcontext.cpp @@ -9,6 +9,185 @@ WINE_DEFAULT_DEBUG_CHANNEL(msctfime); +/*********************************************************************** + * CInputContextOwner + */ + +/// @unimplemented +CInputContextOwner::CInputContextOwner(FN_IC_OWNER_CALLBACK fnCallback, LPVOID pCallbackPV) +{ + m_dwCookie = -1; + m_fnCallback = fnCallback; + m_cRefs = 1; + m_pCallbackPV = pCallbackPV; +} + +/// @implemented +CInputContextOwner::~CInputContextOwner() +{ +} + +/// @implemented +HRESULT CInputContextOwner::_Advise(IUnknown *pContext) +{ + ITfSource *pSource = NULL; + + m_pContext = NULL; + + HRESULT hr = E_FAIL; + if (SUCCEEDED(m_pContext->QueryInterface(IID_ITfSource, (LPVOID*)&pSource)) && + SUCCEEDED(pSource->AdviseSink(IID_ITfContextOwner, + static_cast(this), &m_dwCookie))) + { + m_pContext = pContext; + m_pContext->AddRef(); + hr = S_OK; + } + + if (pSource) + pSource->Release(); + + return hr; +} + +/// @implemented +HRESULT CInputContextOwner::_Unadvise() +{ + ITfSource *pSource = NULL; + + HRESULT hr = E_FAIL; + if (m_pContext) + { + if (SUCCEEDED(m_pContext->QueryInterface(IID_ITfSource, (LPVOID*)&pSource)) && + SUCCEEDED(pSource->UnadviseSink(m_dwCookie))) + { + hr = S_OK; + } + } + + if (m_pContext) + { + m_pContext->Release(); + m_pContext = NULL; + } + + if (pSource) + pSource->Release(); + + return hr; +} + +/// @implemented +STDMETHODIMP CInputContextOwner::QueryInterface(REFIID riid, LPVOID* ppvObj) +{ + *ppvObj = NULL; + + if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfContextOwner)) + { + *ppvObj = this; + AddRef(); + return S_OK; + } + + if (IsEqualIID(riid, IID_ITfMouseTrackerACP)) + { + *ppvObj = static_cast(this); + AddRef(); + return S_OK; + } + + return E_NOINTERFACE; +} + +/// @implemented +STDMETHODIMP_(ULONG) CInputContextOwner::AddRef() +{ + return ++m_cRefs; +} + +/// @implemented +STDMETHODIMP_(ULONG) CInputContextOwner::Release() +{ + if (--m_cRefs == 0) + { + delete this; + return 0; + } + return m_cRefs; +} + +/// @unimplemented +STDMETHODIMP +CInputContextOwner::GetACPFromPoint( + const POINT *ptScreen, + DWORD dwFlags, + LONG *pacp) +{ + return E_NOTIMPL; +} + +/// @unimplemented +STDMETHODIMP +CInputContextOwner::GetTextExt( + LONG acpStart, + LONG acpEnd, + RECT *prc, + BOOL *pfClipped) +{ + return E_NOTIMPL; +} + +/// @implemented +STDMETHODIMP CInputContextOwner::GetScreenExt(RECT *prc) +{ + return m_fnCallback(2, &prc, m_pCallbackPV); +} + +/// @implemented +STDMETHODIMP CInputContextOwner::GetStatus(TF_STATUS *pdcs) +{ + return m_fnCallback(6, &pdcs, m_pCallbackPV); +} + +/// @unimplemented +STDMETHODIMP CInputContextOwner::GetWnd(HWND *phwnd) +{ + return m_fnCallback(7, &phwnd, m_pCallbackPV); +} + +/// @unimplemented +STDMETHODIMP CInputContextOwner::GetAttribute(REFGUID rguidAttribute, VARIANT *pvarValue) +{ + return E_NOTIMPL; +} + +struct MOUSE_SINK_ARGS +{ + ITfRangeACP *range; + ITfMouseSink *pSink; + DWORD *pdwCookie; +}; + +/// @implemented +STDMETHODIMP CInputContextOwner::AdviseMouseSink( + ITfRangeACP *range, + ITfMouseSink *pSink, + DWORD *pdwCookie) +{ + MOUSE_SINK_ARGS args = { range, pSink, pdwCookie }; + return m_fnCallback(9, &args, m_pCallbackPV); +} + +/// @implemented +STDMETHODIMP CInputContextOwner::UnadviseMouseSink(DWORD dwCookie) +{ + return m_fnCallback(10, &dwCookie, m_pCallbackPV); +} + +/*********************************************************************** + * CicInputContext + */ + /// @unimplemented CicInputContext::CicInputContext( _In_ TfClientId cliendId, @@ -157,7 +336,12 @@ CicInputContext::DestroyInputContext() m_pCompEventSink1 = NULL; } - //FIXME: m_pInputContextOwner + if (m_pInputContextOwner) + { + m_pInputContextOwner->_Unadvise(); + m_pInputContextOwner->Release(); + m_pInputContextOwner = NULL; + } if (m_pDocumentMgr) m_pDocumentMgr->Pop(1); diff --git a/dll/ime/msctfime/inputcontext.h b/dll/ime/msctfime/inputcontext.h index 7ae33906fd5..9065a36b57f 100644 --- a/dll/ime/msctfime/inputcontext.h +++ b/dll/ime/msctfime/inputcontext.h @@ -12,6 +12,59 @@ class CInputContextOwnerCallBack; class CInputContextOwner; +class CicInputContext; + + +typedef HRESULT (CALLBACK *FN_IC_OWNER_CALLBACK)(UINT uType, LPVOID args, LPVOID param); + +/*********************************************************************** + * CInputContextOwner + */ +class CInputContextOwner + : public ITfContextOwner + , public ITfMouseTrackerACP +{ +protected: + LONG m_cRefs; + IUnknown *m_pContext; + DWORD m_dwCookie; + FN_IC_OWNER_CALLBACK m_fnCallback; + LPVOID m_pCallbackPV; + +public: + CInputContextOwner(FN_IC_OWNER_CALLBACK fnCallback, LPVOID pCallbackPV); + virtual ~CInputContextOwner(); + + HRESULT _Advise(IUnknown *pContext); + HRESULT _Unadvise(); + + // IUnknown methods + STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override; + STDMETHODIMP_(ULONG) AddRef() override; + STDMETHODIMP_(ULONG) Release() override; + + // ITfContextOwner methods + STDMETHODIMP GetACPFromPoint( + const POINT *ptScreen, + DWORD dwFlags, + LONG *pacp) override; + STDMETHODIMP GetTextExt( + LONG acpStart, + LONG acpEnd, + RECT *prc, + BOOL *pfClipped) override; + STDMETHODIMP GetScreenExt(RECT *prc) override; + STDMETHODIMP GetStatus(TF_STATUS *pdcs) override; + STDMETHODIMP GetWnd(HWND *phwnd) override; + STDMETHODIMP GetAttribute(REFGUID rguidAttribute, VARIANT *pvarValue) override; + + // ITfMouseTrackerACP methods + STDMETHODIMP AdviseMouseSink( + ITfRangeACP *range, + ITfMouseSink *pSink, + DWORD *pdwCookie) override; + STDMETHODIMP UnadviseMouseSink(DWORD dwCookie) override; +}; /*********************************************************************** * CicInputContext diff --git a/sdk/include/psdk/msctf.idl b/sdk/include/psdk/msctf.idl index f7f3b12327d..0cd5ac1af9c 100644 --- a/sdk/include/psdk/msctf.idl +++ b/sdk/include/psdk/msctf.idl @@ -950,6 +950,38 @@ interface ITfTextEditSink : IUnknown [in] ITfEditRecord *pEditRecord); } +[ + object, + uuid(AA80E80C-2021-11D2-93E0-0060B067B86E), + pointer_default(unique) +] +interface ITfContextOwner : IUnknown +{ + HRESULT GetACPFromPoint( + [in] const POINT *ptScreen, + [in] DWORD dwFlags, + [out] LONG *pacp); + + HRESULT GetTextExt( + [in] LONG acpStart, + [in] LONG acpEnd, + [out] RECT *prc, + [out] BOOL *pfClipped); + + HRESULT GetScreenExt( + [out] RECT *prc); + + HRESULT GetStatus( + [out] TF_STATUS *pdcs); + + HRESULT GetWnd( + [out] HWND *phwnd); + + HRESULT GetAttribute( + [in] REFGUID rguidAttribute, + [out] VARIANT *pvarValue); +} + [ object, uuid(5F20AA40-B57A-4F34-96AB-3576F377CC79),