////////////////////////////////////////////////////////////////////// // // 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) 2003 Microsoft Corporation. All rights reserved. // // TextService.cpp // // IUnknown, ITfTextInputProcessor implementation. // ////////////////////////////////////////////////////////////////////// #include "globals.h" #include "TextService.h" #include "CandidateList.h" //+--------------------------------------------------------------------------- // // CreateInstance // //---------------------------------------------------------------------------- /* static */ HRESULT CTextService::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObj) { CTextService *pCase; HRESULT hr; if (ppvObj == NULL) return E_INVALIDARG; *ppvObj = NULL; if (NULL != pUnkOuter) return CLASS_E_NOAGGREGATION; if ((pCase = new CTextService) == NULL) return E_OUTOFMEMORY; hr = pCase->QueryInterface(riid, ppvObj); pCase->Release(); // caller still holds ref if hr == S_OK return hr; } //+--------------------------------------------------------------------------- // // ctor // //---------------------------------------------------------------------------- CTextService::CTextService() { DllAddRef(); // // Initialize the thread manager pointer. // _pThreadMgr = NULL; // // Initialize the numbers for ThreadMgrEventSink. // _dwThreadMgrEventSinkCookie = TF_INVALID_COOKIE; // // Initialize the numbers for TextEditSink. // _pTextEditSinkContext = NULL; _dwTextEditSinkCookie = TF_INVALID_COOKIE; // // Initialize the composition object pointer. // _pComposition = NULL; // // Initialize the candidate list object pointer. // _pCandidateList = NULL; _cRef = 1; } //+--------------------------------------------------------------------------- // // dtor // //---------------------------------------------------------------------------- CTextService::~CTextService() { DllRelease(); } //+--------------------------------------------------------------------------- // // QueryInterface // //---------------------------------------------------------------------------- STDAPI CTextService::QueryInterface(REFIID riid, void **ppvObj) { if (ppvObj == NULL) return E_INVALIDARG; *ppvObj = NULL; if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfTextInputProcessor)) { *ppvObj = (ITfTextInputProcessor *)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_ITfCompositionSink)) { *ppvObj = (ITfKeyEventSink *)this; } else if (IsEqualIID(riid, IID_ITfDisplayAttributeProvider)) { *ppvObj = (ITfDisplayAttributeProvider *)this; } if (*ppvObj) { AddRef(); return S_OK; } return E_NOINTERFACE; } //+--------------------------------------------------------------------------- // // AddRef // //---------------------------------------------------------------------------- STDAPI_(ULONG) CTextService::AddRef() { return ++_cRef; } //+--------------------------------------------------------------------------- // // Release // //---------------------------------------------------------------------------- STDAPI_(ULONG) CTextService::Release() { LONG cr = --_cRef; assert(_cRef >= 0); if (_cRef == 0) { delete this; } return cr; } //+--------------------------------------------------------------------------- // // Activate // //---------------------------------------------------------------------------- STDAPI CTextService::Activate(ITfThreadMgr *pThreadMgr, TfClientId tfClientId) { return ActivateEx(pThreadMgr, tfClientId, 0); } //+--------------------------------------------------------------------------- // // Activate // //---------------------------------------------------------------------------- STDAPI CTextService::ActivateEx(ITfThreadMgr *pThreadMgr, TfClientId tfClientId, DWORD dwFlags) { _pThreadMgr = pThreadMgr; _pThreadMgr->AddRef(); _tfClientId = tfClientId; // // Initialize ThreadMgrEventSink. // if (!_InitThreadMgrEventSink()) goto ExitError; // // If there is the focus document manager already, // we advise the TextEditSink. // ITfDocumentMgr *pDocMgrFocus; if ((_pThreadMgr->GetFocus(&pDocMgrFocus) == S_OK) && (pDocMgrFocus != NULL)) { _InitTextEditSink(pDocMgrFocus); pDocMgrFocus->Release(); } // // Initialize Language Bar. // if (!_InitLanguageBar()) goto ExitError; // // Initialize KeyEventSink // if (!_InitKeyEventSink()) goto ExitError; // // Initialize PreservedKeys // if (!_InitPreservedKey()) goto ExitError; // // Initialize display guid atom // if (!_InitDisplayAttributeGuidAtom()) goto ExitError; return S_OK; ExitError: Deactivate(); // cleanup any half-finished init return E_FAIL; } //+--------------------------------------------------------------------------- // // Deactivate // //---------------------------------------------------------------------------- STDAPI CTextService::Deactivate() { // delete the candidate list object if it exists. if (_pCandidateList != NULL) { delete _pCandidateList; _pCandidateList = NULL; } // // Unadvise TextEditSink if it is advised. // _InitTextEditSink(NULL); // // Uninitialize ThreadMgrEventSink. // _UninitThreadMgrEventSink(); // // Uninitialize Language Bar. // _UninitLanguageBar(); // // Uninitialize KeyEventSink // _UninitKeyEventSink(); // // Uninitialize PreservedKeys // _UninitPreservedKey(); // we MUST release all refs to _pThreadMgr in Deactivate if (_pThreadMgr != NULL) { _pThreadMgr->Release(); _pThreadMgr = NULL; } _tfClientId = TF_CLIENTID_NULL; return S_OK; }