terminal/src/tsf/TfDispAttr.cpp
Dustin Howett d4d59fa339 Initial release of the Windows Terminal source code
This commit introduces all of the Windows Terminal and Console Host source,
under the MIT license.
2019-05-02 15:29:04 -07:00

201 lines
5.6 KiB
C++

/*++
Copyright (c) Microsoft Corporation.
Licensed under the MIT license.
Module Name:
TfDispAttr.cpp
Abstract:
This file implements the CicDisplayAttributeMgr Class.
Author:
Revision History:
Notes:
--*/
#include "precomp.h"
#include "TfDispAttr.h"
//+---------------------------------------------------------------------------
//
// CicDisplayAttributeMgr::ctor
// CicDisplayAttributeMgr::dtor
//
//----------------------------------------------------------------------------
CicDisplayAttributeMgr::CicDisplayAttributeMgr()
{
}
CicDisplayAttributeMgr::~CicDisplayAttributeMgr()
{
if (m_pDAM) {
m_pDAM.Release();
}
}
//+---------------------------------------------------------------------------
//
// CicDisplayAttributeMgr::GetDisplayAttributeTrackPropertyRange
//
//----------------------------------------------------------------------------
[[nodiscard]]
HRESULT CicDisplayAttributeMgr::GetDisplayAttributeTrackPropertyRange(TfEditCookie ec, ITfContext *pic, ITfRange *pRange,
ITfReadOnlyProperty **ppProp, IEnumTfRanges **ppEnum, ULONG *pulNumProp)
{
HRESULT hr = E_FAIL;
ULONG ulNumProp;
ulNumProp = (ULONG) m_DispAttrProp.Count();
if (ulNumProp) {
const GUID **ppguidProp;
//
// TrackProperties wants an array of GUID *'s
//
ppguidProp = (const GUID **) new(std::nothrow) GUID* [ulNumProp];
if (ppguidProp == NULL) {
hr = E_OUTOFMEMORY;
}
else {
for (ULONG i=0; i<ulNumProp; i++) {
ppguidProp[i] = m_DispAttrProp.GetAt(i);
}
CComPtr<ITfReadOnlyProperty> pProp;
if (SUCCEEDED(hr = pic->TrackProperties(ppguidProp, ulNumProp, 0, NULL, &pProp))) {
hr = pProp->EnumRanges(ec, ppEnum, pRange);
if (SUCCEEDED(hr)) {
*ppProp = pProp;
(*ppProp)->AddRef();
}
pProp.Release();
}
delete [] ppguidProp;
if (SUCCEEDED(hr)) {
*pulNumProp = ulNumProp;
}
}
}
return hr;
}
//+---------------------------------------------------------------------------
//
// CicDisplayAttributeMgr::GetDisplayAttributeData
//
//----------------------------------------------------------------------------
[[nodiscard]]
HRESULT CicDisplayAttributeMgr::GetDisplayAttributeData(ITfCategoryMgr *pcat, TfEditCookie ec, ITfReadOnlyProperty *pProp, ITfRange *pRange, TF_DISPLAYATTRIBUTE *pda, TfGuidAtom *pguid, ULONG /*ulNumProp*/)
{
VARIANT var;
HRESULT hr = E_FAIL;
if (SUCCEEDED(pProp->GetValue(ec, pRange, &var))) {
FAIL_FAST_IF(!(var.vt == VT_UNKNOWN));
CComQIPtr<IEnumTfPropertyValue> pEnumPropertyVal(var.punkVal);
if (pEnumPropertyVal) {
TF_PROPERTYVAL tfPropVal;
while (pEnumPropertyVal->Next(1, &tfPropVal, NULL) == S_OK) {
if (tfPropVal.varValue.vt == VT_EMPTY) {
continue; // prop has no value over this span
}
FAIL_FAST_IF(!(tfPropVal.varValue.vt == VT_I4)); // expecting GUIDATOMs
TfGuidAtom gaVal = (TfGuidAtom)tfPropVal.varValue.lVal;
GUID guid;
pcat->GetGUID(gaVal, &guid);
CComPtr<ITfDisplayAttributeInfo> pDAI;
if (SUCCEEDED(m_pDAM->GetDisplayAttributeInfo(guid, &pDAI, NULL))) {
//
// Issue: for simple apps.
//
// Small apps can not show multi underline. So
// this helper function returns only one
// DISPLAYATTRIBUTE structure.
//
if (pda) {
pDAI->GetAttributeInfo(pda);
}
if (pguid) {
*pguid = gaVal;
}
pDAI.Release();
hr = S_OK;
break;
}
}
}
VariantClear(&var);
}
return hr;
}
//+---------------------------------------------------------------------------
//
// CicDisplayAttributeMgr::InitCategoryInstance
//
//----------------------------------------------------------------------------
[[nodiscard]]
HRESULT CicDisplayAttributeMgr::InitDisplayAttributeInstance(ITfCategoryMgr* pcat)
{
HRESULT hr;
//
// Create ITfDisplayAttributeMgr instance.
//
if (FAILED(hr = m_pDAM.CoCreateInstance(CLSID_TF_DisplayAttributeMgr))) {
return hr;
}
CComPtr<IEnumGUID> pEnumProp;
pcat->EnumItemsInCategory(GUID_TFCAT_DISPLAYATTRIBUTEPROPERTY, &pEnumProp);
//
// make a database for Display Attribute Properties.
//
if (pEnumProp) {
GUID guidProp;
//
// add System Display Attribute first.
// so no other Display Attribute property overwrite it.
//
GUID *pguid;
pguid = m_DispAttrProp.Append();
if (pguid != NULL) {
*pguid = GUID_PROP_ATTRIBUTE;
}
while(pEnumProp->Next(1, &guidProp, NULL) == S_OK) {
if (!IsEqualGUID(guidProp, GUID_PROP_ATTRIBUTE)) {
pguid = m_DispAttrProp.Append();
if (pguid != NULL) {
*pguid = guidProp;
}
}
}
}
return hr;
}