// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved #include "Private.h" #include "globals.h" #include "SampleIME.h" #include "CandidateListUIPresenter.h" #include "CompositionProcessorEngine.h" #include "Compartment.h" //+--------------------------------------------------------------------------- // // CreateInstance // //---------------------------------------------------------------------------- /* static */ HRESULT CSampleIME::CreateInstance(_In_ IUnknown *pUnkOuter, REFIID riid, _Outptr_ void **ppvObj) { CSampleIME* pSampleIME = nullptr; HRESULT hr = S_OK; if (ppvObj == nullptr) { return E_INVALIDARG; } *ppvObj = nullptr; if (nullptr != pUnkOuter) { return CLASS_E_NOAGGREGATION; } pSampleIME = new (std::nothrow) CSampleIME(); if (pSampleIME == nullptr) { return E_OUTOFMEMORY; } hr = pSampleIME->QueryInterface(riid, ppvObj); pSampleIME->Release(); return hr; } //+--------------------------------------------------------------------------- // // ctor // //---------------------------------------------------------------------------- CSampleIME::CSampleIME() { DllAddRef(); _pThreadMgr = nullptr; _threadMgrEventSinkCookie = TF_INVALID_COOKIE; _pTextEditSinkContext = nullptr; _textEditSinkCookie = TF_INVALID_COOKIE; _activeLanguageProfileNotifySinkCookie = TF_INVALID_COOKIE; _dwThreadFocusSinkCookie = TF_INVALID_COOKIE; _pComposition = nullptr; _pCompositionProcessorEngine = nullptr; _candidateMode = CANDIDATE_NONE; _pCandidateListUIPresenter = nullptr; _isCandidateWithWildcard = FALSE; _pDocMgrLastFocused = nullptr; _pSIPIMEOnOffCompartment = nullptr; _dwSIPIMEOnOffCompartmentSinkCookie = 0; _msgWndHandle = nullptr; _pContext = nullptr; _refCount = 1; } //+--------------------------------------------------------------------------- // // dtor // //---------------------------------------------------------------------------- CSampleIME::~CSampleIME() { if (_pCandidateListUIPresenter) { delete _pCandidateListUIPresenter; _pCandidateListUIPresenter = nullptr; } DllRelease(); } //+--------------------------------------------------------------------------- // // QueryInterface // //---------------------------------------------------------------------------- STDAPI CSampleIME::QueryInterface(REFIID riid, _Outptr_ void **ppvObj) { if (ppvObj == nullptr) { return E_INVALIDARG; } *ppvObj = nullptr; if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfTextInputProcessor)) { *ppvObj = (ITfTextInputProcessor *)this; } else if (IsEqualIID(riid, IID_ITfTextInputProcessorEx)) { *ppvObj = (ITfTextInputProcessorEx *)this; } else if (IsEqualIID(riid, IID_ITfThreadMgrEventSink)) { *ppvObj = (ITfThreadMgrEventSink *)this; } else if (IsEqualIID(riid, IID_ITfTextEditSink)) { *ppvObj = (ITfTextEditSink *)this; } else if (IsEqualIID(riid, IID_ITfKeyEventSink)) { *ppvObj = (ITfKeyEventSink *)this; } else if (IsEqualIID(riid, IID_ITfActiveLanguageProfileNotifySink)) { *ppvObj = (ITfActiveLanguageProfileNotifySink *)this; } else if (IsEqualIID(riid, IID_ITfCompositionSink)) { *ppvObj = (ITfKeyEventSink *)this; } else if (IsEqualIID(riid, IID_ITfDisplayAttributeProvider)) { *ppvObj = (ITfDisplayAttributeProvider *)this; } else if (IsEqualIID(riid, IID_ITfThreadFocusSink)) { *ppvObj = (ITfThreadFocusSink *)this; } else if (IsEqualIID(riid, IID_ITfFunctionProvider)) { *ppvObj = (ITfFunctionProvider *)this; } else if (IsEqualIID(riid, IID_ITfFunction)) { *ppvObj = (ITfFunction *)this; } else if (IsEqualIID(riid, IID_ITfFnGetPreferredTouchKeyboardLayout)) { *ppvObj = (ITfFnGetPreferredTouchKeyboardLayout *)this; } if (*ppvObj) { AddRef(); return S_OK; } return E_NOINTERFACE; } //+--------------------------------------------------------------------------- // // AddRef // //---------------------------------------------------------------------------- STDAPI_(ULONG) CSampleIME::AddRef() { return ++_refCount; } //+--------------------------------------------------------------------------- // // Release // //---------------------------------------------------------------------------- STDAPI_(ULONG) CSampleIME::Release() { LONG cr = --_refCount; assert(_refCount >= 0); if (_refCount == 0) { delete this; } return cr; } //+--------------------------------------------------------------------------- // // ITfTextInputProcessorEx::ActivateEx // //---------------------------------------------------------------------------- STDAPI CSampleIME::ActivateEx(ITfThreadMgr *pThreadMgr, TfClientId tfClientId, DWORD dwFlags) { _pThreadMgr = pThreadMgr; _pThreadMgr->AddRef(); _tfClientId = tfClientId; _dwActivateFlags = dwFlags; if (!_InitThreadMgrEventSink()) { goto ExitError; } ITfDocumentMgr* pDocMgrFocus = nullptr; if (SUCCEEDED(_pThreadMgr->GetFocus(&pDocMgrFocus)) && (pDocMgrFocus != nullptr)) { _InitTextEditSink(pDocMgrFocus); pDocMgrFocus->Release(); } if (!_InitKeyEventSink()) { goto ExitError; } if (!_InitActiveLanguageProfileNotifySink()) { goto ExitError; } if (!_InitThreadFocusSink()) { goto ExitError; } if (!_InitDisplayAttributeGuidAtom()) { goto ExitError; } if (!_InitFunctionProviderSink()) { goto ExitError; } if (!_AddTextProcessorEngine()) { goto ExitError; } return S_OK; ExitError: Deactivate(); return E_FAIL; } //+--------------------------------------------------------------------------- // // ITfTextInputProcessorEx::Deactivate // //---------------------------------------------------------------------------- STDAPI CSampleIME::Deactivate() { if (_pCompositionProcessorEngine) { delete _pCompositionProcessorEngine; _pCompositionProcessorEngine = nullptr; } ITfContext* pContext = _pContext; if (_pContext) { pContext->AddRef(); _EndComposition(_pContext); } if (_pCandidateListUIPresenter) { delete _pCandidateListUIPresenter; _pCandidateListUIPresenter = nullptr; if (pContext) { pContext->Release(); } _candidateMode = CANDIDATE_NONE; _isCandidateWithWildcard = FALSE; } _UninitFunctionProviderSink(); _UninitThreadFocusSink(); _UninitActiveLanguageProfileNotifySink(); _UninitKeyEventSink(); _UninitThreadMgrEventSink(); CCompartment CompartmentKeyboardOpen(_pThreadMgr, _tfClientId, GUID_COMPARTMENT_KEYBOARD_OPENCLOSE); CompartmentKeyboardOpen._ClearCompartment(); CCompartment CompartmentDoubleSingleByte(_pThreadMgr, _tfClientId, Global::SampleIMEGuidCompartmentDoubleSingleByte); CompartmentDoubleSingleByte._ClearCompartment(); CCompartment CompartmentPunctuation(_pThreadMgr, _tfClientId, Global::SampleIMEGuidCompartmentPunctuation); CompartmentDoubleSingleByte._ClearCompartment(); if (_pThreadMgr != nullptr) { _pThreadMgr->Release(); } _tfClientId = TF_CLIENTID_NULL; if (_pDocMgrLastFocused) { _pDocMgrLastFocused->Release(); _pDocMgrLastFocused = nullptr; } return S_OK; } //+--------------------------------------------------------------------------- // // ITfFunctionProvider::GetType // //---------------------------------------------------------------------------- HRESULT CSampleIME::GetType(__RPC__out GUID *pguid) { HRESULT hr = E_INVALIDARG; if (pguid) { *pguid = Global::SampleIMECLSID; hr = S_OK; } return hr; } //+--------------------------------------------------------------------------- // // ITfFunctionProvider::::GetDescription // //---------------------------------------------------------------------------- HRESULT CSampleIME::GetDescription(__RPC__deref_out_opt BSTR *pbstrDesc) { HRESULT hr = E_INVALIDARG; if (pbstrDesc != nullptr) { *pbstrDesc = nullptr; hr = E_NOTIMPL; } return hr; } //+--------------------------------------------------------------------------- // // ITfFunctionProvider::::GetFunction // //---------------------------------------------------------------------------- HRESULT CSampleIME::GetFunction(__RPC__in REFGUID rguid, __RPC__in REFIID riid, __RPC__deref_out_opt IUnknown **ppunk) { HRESULT hr = E_NOINTERFACE; if ((IsEqualGUID(rguid, GUID_NULL)) && (IsEqualGUID(riid, __uuidof(ITfFnSearchCandidateProvider)))) { hr = _pITfFnSearchCandidateProvider->QueryInterface(riid, (void**)ppunk); } else if (IsEqualGUID(rguid, GUID_NULL)) { hr = QueryInterface(riid, (void **)ppunk); } return hr; } //+--------------------------------------------------------------------------- // // ITfFunction::GetDisplayName // //---------------------------------------------------------------------------- HRESULT CSampleIME::GetDisplayName(_Out_ BSTR *pbstrDisplayName) { HRESULT hr = E_INVALIDARG; if (pbstrDisplayName != nullptr) { *pbstrDisplayName = nullptr; hr = E_NOTIMPL; } return hr; } //+--------------------------------------------------------------------------- // // ITfFnGetPreferredTouchKeyboardLayout::GetLayout // The tkblayout will be Optimized layout. //---------------------------------------------------------------------------- HRESULT CSampleIME::GetLayout(_Out_ TKBLayoutType *ptkblayoutType, _Out_ WORD *pwPreferredLayoutId) { HRESULT hr = E_INVALIDARG; if ((ptkblayoutType != nullptr) && (pwPreferredLayoutId != nullptr)) { *ptkblayoutType = TKBLT_OPTIMIZED; *pwPreferredLayoutId = TKBL_OPT_SIMPLIFIED_CHINESE_PINYIN; hr = S_OK; } return hr; }