// 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) Microsoft Corporation. All rights reserved #include "private.h" #include "TipCandidateList.h" #include "EnumTfCandidates.h" #include "TipCandidateString.h" HRESULT CTipCandidateList::CreateInstance(_Outptr_ ITfCandidateList **ppobj, size_t candStrReserveSize) { if (ppobj == nullptr) { return E_INVALIDARG; } *ppobj = nullptr; *ppobj = new (std::nothrow) CTipCandidateList(candStrReserveSize); if (*ppobj == nullptr) { return E_OUTOFMEMORY; } return S_OK; } HRESULT CTipCandidateList::CreateInstance(REFIID riid, _Outptr_ void **ppvObj, size_t candStrReserveSize) { if (ppvObj == nullptr) { return E_INVALIDARG; } *ppvObj = nullptr; *ppvObj = new (std::nothrow) CTipCandidateList(candStrReserveSize); if (*ppvObj == nullptr) { return E_OUTOFMEMORY; } return ((CTipCandidateList*)(*ppvObj))->QueryInterface(riid, ppvObj); } CTipCandidateList::CTipCandidateList(size_t candStrReserveSize) { _refCount = 0; if (0 < candStrReserveSize) { _tfCandStrList.reserve(candStrReserveSize); } } CTipCandidateList::~CTipCandidateList() { } STDMETHODIMP CTipCandidateList::QueryInterface(REFIID riid, _Outptr_ void **ppvObj) { if (ppvObj == nullptr) { return E_POINTER; } *ppvObj = nullptr; if (IsEqualIID(riid, IID_IUnknown)) { *ppvObj = (ITfCandidateList*)this; } else if (IsEqualIID(riid, IID_ITfCandidateList)) { *ppvObj = (ITfCandidateList*)this; } if (*ppvObj == nullptr) { return E_NOINTERFACE; } AddRef(); return S_OK; } STDMETHODIMP_(ULONG) CTipCandidateList::AddRef() { return (ULONG)InterlockedIncrement((LONG*)&_refCount); } STDMETHODIMP_(ULONG) CTipCandidateList::Release() { ULONG cRefT = (ULONG)InterlockedDecrement((LONG*)&_refCount); if (0 < cRefT) { return cRefT; } delete this; return 0; } STDMETHODIMP CTipCandidateList::EnumCandidates(_Outptr_ IEnumTfCandidates **ppEnum) { return CEnumTfCandidates::CreateInstance(IID_IEnumTfCandidates, (void**)ppEnum, _tfCandStrList); } STDMETHODIMP CTipCandidateList::GetCandidate(ULONG nIndex, _Outptr_result_maybenull_ ITfCandidateString **ppCandStr) { if (ppCandStr == nullptr) { return E_POINTER; } *ppCandStr = nullptr; ULONG sizeCandStr = (ULONG)_tfCandStrList.Count(); if (sizeCandStr <= nIndex) { return E_FAIL; } for (UINT i = 0; i < _tfCandStrList.Count(); i++) { ITfCandidateString** ppCandStrCur = _tfCandStrList.GetAt(i); ULONG indexCur = 0; if ((nullptr != ppCandStrCur) && (SUCCEEDED((*ppCandStrCur)->GetIndex(&indexCur)))) { if (nIndex == indexCur) { BSTR bstr; CTipCandidateString* pTipCandidateStrCur = (CTipCandidateString*)(*ppCandStrCur); pTipCandidateStrCur->GetString(&bstr); CTipCandidateString::CreateInstance(IID_ITfCandidateString, (void**)ppCandStr); if (nullptr != (*ppCandStr)) { CTipCandidateString* pTipCandidateStr = (CTipCandidateString*)(*ppCandStr); pTipCandidateStr->SetString((LPCWSTR)bstr, SysStringLen(bstr)); } SysFreeString(bstr); break; } } } return S_OK; } STDMETHODIMP CTipCandidateList::GetCandidateNum(_Out_ ULONG *pnCnt) { if (pnCnt == nullptr) { return E_POINTER; } *pnCnt = (ULONG)(_tfCandStrList.Count()); return S_OK; } STDMETHODIMP CTipCandidateList::SetResult(ULONG nIndex, TfCandidateResult imcr) { nIndex;imcr; return E_NOTIMPL; } STDMETHODIMP CTipCandidateList::SetCandidate(_In_ ITfCandidateString **ppCandStr) { if (ppCandStr == nullptr) { return E_POINTER; } ITfCandidateString** ppCandLast = _tfCandStrList.Append(); if (ppCandLast) { *ppCandLast = *ppCandStr; } return S_OK; }