2025-11-28 00:35:46 +09:00

123 lines
3.9 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.
//
// StartComposition.cpp
//
// the rountins to start a new composition object.
//
//////////////////////////////////////////////////////////////////////
#include "Globals.h"
#include "EditSession.h"
#include "TextService.h"
//+---------------------------------------------------------------------------
//
// CStartCompositinoEditSession
//
//----------------------------------------------------------------------------
class CStartCompositionEditSession : public CEditSessionBase
{
public:
CStartCompositionEditSession(CTextService *pTextService, ITfContext *pContext) : CEditSessionBase(pTextService, pContext)
{
}
// ITfEditSession
STDMETHODIMP DoEditSession(TfEditCookie ec);
};
//+---------------------------------------------------------------------------
//
// DoEditSession
//
//----------------------------------------------------------------------------
STDAPI CStartCompositionEditSession::DoEditSession(TfEditCookie ec)
{
ITfInsertAtSelection *pInsertAtSelection = NULL;
ITfRange *pRangeInsert = NULL;
ITfContextComposition *pContextComposition = NULL;
ITfComposition *pComposition = NULL;
HRESULT hr = E_FAIL;
// we need a special interface to insert text at the selection
if (_pContext->QueryInterface(IID_ITfInsertAtSelection, (void **)&pInsertAtSelection) != S_OK)
{
goto Exit;
}
// insert the text
if (pInsertAtSelection->InsertTextAtSelection(ec, TF_IAS_QUERYONLY, NULL, 0, &pRangeInsert) != S_OK)
{
goto Exit;
}
// get an interface on the context we can use to deal with compositions
if (_pContext->QueryInterface(IID_ITfContextComposition, (void **)&pContextComposition) != S_OK)
{
goto Exit;
}
// start the new composition
if ((pContextComposition->StartComposition(ec, pRangeInsert, _pTextService, &pComposition) == S_OK) && (pComposition != NULL))
{
// Store the pointer of this new composition object in the instance
// of the CTextService class. So this instance of the CTextService
// class can know now it is in the composition stage.
_pTextService->_SetComposition(pComposition);
//
// set selection to the adjusted range
//
TF_SELECTION tfSelection;
tfSelection.range = pRangeInsert;
tfSelection.style.ase = TF_AE_NONE;
tfSelection.style.fInterimChar = FALSE;
_pContext->SetSelection(ec, 1, &tfSelection);
}
Exit:
if (pContextComposition != NULL)
pContextComposition->Release();
if (pRangeInsert != NULL)
pRangeInsert->Release();
if (pInsertAtSelection != NULL)
pInsertAtSelection->Release();
return S_OK;
}
//+---------------------------------------------------------------------------
//
// _StartComposition
//
// this starts the new composition at the selection of the current
// focus context.
//----------------------------------------------------------------------------
void CTextService::_StartComposition(ITfContext *pContext)
{
CStartCompositionEditSession *pStartCompositionEditSession;
if (pStartCompositionEditSession = new CStartCompositionEditSession(this, pContext))
{
HRESULT hr;
// we need a synchronus document write lock.
// the CStartCompositionEditSession will do all the work when the
// CStartCompositionEditSession::DoEditSession method is called by the context
pContext->RequestEditSession(_tfClientId, pStartCompositionEditSession, TF_ES_SYNC | TF_ES_READWRITE, &hr);
pStartCompositionEditSession->Release();
}
}