221 lines
4.8 KiB
C++
221 lines
4.8 KiB
C++
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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"
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// 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;
|
|
|
|
_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;
|
|
}
|
|
|
|
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)
|
|
{
|
|
_pThreadMgr = pThreadMgr;
|
|
_pThreadMgr->AddRef();
|
|
|
|
//
|
|
// 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();
|
|
}
|
|
|
|
|
|
return S_OK;
|
|
|
|
ExitError:
|
|
Deactivate(); // cleanup any half-finished init
|
|
return E_FAIL;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Deactivate
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CTextService::Deactivate()
|
|
{
|
|
//
|
|
// Unadvise TextEditSink if it is advised.
|
|
//
|
|
_InitTextEditSink(NULL);
|
|
|
|
//
|
|
// Uninitialize ThreadMgrEventSink.
|
|
//
|
|
_UninitThreadMgrEventSink();
|
|
|
|
// we MUST release all refs to _pThreadMgr in Deactivate
|
|
if (_pThreadMgr != NULL)
|
|
{
|
|
_pThreadMgr->Release();
|
|
_pThreadMgr = NULL;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|