terminal/src/tsf/TfTxtevCb.cpp

170 lines
5.1 KiB
C++

/*++
Copyright (c) Microsoft Corporation.
Licensed under the MIT license.
Module Name:
TfTxtevCb.cpp
Abstract:
This file implements the CTextEventSinkCallBack Class.
Author:
Revision History:
Notes:
--*/
#include "precomp.h"
#include "ConsoleTSF.h"
#include "TfEditses.h"
//+---------------------------------------------------------------------------
//
// CConsoleTSF::HasCompositionChanged
//
//----------------------------------------------------------------------------
BOOL CConsoleTSF::_HasCompositionChanged(ITfContext* pInputContext, TfEditCookie ecReadOnly, ITfEditRecord* pEditRecord)
{
BOOL fChanged;
if (SUCCEEDED(pEditRecord->GetSelectionStatus(&fChanged)))
{
if (fChanged)
{
return TRUE;
}
}
//
// Find GUID_PROP_CONIME_TRACKCOMPOSITION property.
//
wil::com_ptr_nothrow<ITfProperty> Property;
wil::com_ptr_nothrow<ITfRange> FoundRange;
wil::com_ptr_nothrow<ITfProperty> PropertyTrackComposition;
BOOL bFound = FALSE;
if (SUCCEEDED(pInputContext->GetProperty(GUID_PROP_CONIME_TRACKCOMPOSITION, &Property)))
{
wil::com_ptr_nothrow<IEnumTfRanges> EnumFindFirstTrackCompRange;
if (SUCCEEDED(Property->EnumRanges(ecReadOnly, &EnumFindFirstTrackCompRange, NULL)))
{
HRESULT hr;
wil::com_ptr_nothrow<ITfRange> range;
while ((hr = EnumFindFirstTrackCompRange->Next(1, &range, NULL)) == S_OK)
{
VARIANT var;
VariantInit(&var);
hr = Property->GetValue(ecReadOnly, range.get(), &var);
if (SUCCEEDED(hr))
{
if ((V_VT(&var) == VT_I4 && V_I4(&var) != 0))
{
range->Clone(&FoundRange);
bFound = TRUE; // FOUND!!
break;
}
}
VariantClear(&var);
if (bFound)
{
break; // FOUND!!
}
}
}
}
//
// if there is no track composition property,
// the composition has been changed since we put it.
//
if (!bFound)
{
return TRUE;
}
if (FoundRange == NULL)
{
return FALSE;
}
bFound = FALSE; // RESET bFound flag...
wil::com_ptr_nothrow<ITfRange> rangeTrackComposition;
if (SUCCEEDED(FoundRange->Clone(&rangeTrackComposition)))
{
//
// get the text range that does not include read only area for
// reconversion.
//
wil::com_ptr_nothrow<ITfRange> rangeAllText;
LONG cch;
if (SUCCEEDED(CEditSessionObject::GetAllTextRange(ecReadOnly, pInputContext, &rangeAllText, &cch)))
{
LONG lResult;
if (SUCCEEDED(rangeTrackComposition->CompareStart(ecReadOnly, rangeAllText.get(), TF_ANCHOR_START, &lResult)))
{
//
// if the start position of the track composition range is not
// the beggining of IC,
// the composition has been changed since we put it.
//
if (lResult != 0)
{
bFound = TRUE; // FOUND!!
}
else if (SUCCEEDED(rangeTrackComposition->CompareEnd(ecReadOnly, rangeAllText.get(), TF_ANCHOR_END, &lResult)))
{
//
// if the start position of the track composition range is not
// the beggining of IC,
// the composition has been changed since we put it.
//
//
// If we find the changes in these property, we need to update hIMC.
//
const GUID* guids[] = { &GUID_PROP_COMPOSING,
&GUID_PROP_ATTRIBUTE };
const int guid_size = sizeof(guids) / sizeof(GUID*);
wil::com_ptr_nothrow<IEnumTfRanges> EnumPropertyChanged;
if (lResult != 0)
{
bFound = TRUE; // FOUND!!
}
else if (SUCCEEDED(pEditRecord->GetTextAndPropertyUpdates(TF_GTP_INCL_TEXT, guids, guid_size, &EnumPropertyChanged)))
{
HRESULT hr;
wil::com_ptr_nothrow<ITfRange> range;
while ((hr = EnumPropertyChanged->Next(1, &range, NULL)) == S_OK)
{
BOOL empty;
if (range->IsEmpty(ecReadOnly, &empty) == S_OK && empty)
{
continue;
}
bFound = TRUE; // FOUND!!
break;
}
}
}
}
}
}
return bFound;
}