Windows-classic-samples/Samples/IME/cpp/SampleIME/SearchCandidateProvider.cpp
2025-11-28 00:35:46 +09:00

211 lines
5.7 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) Microsoft Corporation. All rights reserved
#include "private.h"
#include "SearchCandidateProvider.h"
#include <new>
#include "SampleIME.h"
#include "CompositionProcessorEngine.h"
#include "TipCandidateList.h"
#include "TipCandidateString.h"
/*------------------------------------------------------------------------------
create instance of CSearchCandidateProvider
------------------------------------------------------------------------------*/
HRESULT CSearchCandidateProvider::CreateInstance(_Outptr_ ITfFnSearchCandidateProvider **ppobj, _In_ ITfTextInputProcessorEx *ptip)
{
if (ppobj == nullptr)
{
return E_INVALIDARG;
}
*ppobj = nullptr;
*ppobj = new (std::nothrow) CSearchCandidateProvider(ptip);
if (nullptr == *ppobj)
{
return E_OUTOFMEMORY;
}
return S_OK;
}
/*------------------------------------------------------------------------------
create instance of CSearchCandidateProvider
------------------------------------------------------------------------------*/
HRESULT CSearchCandidateProvider::CreateInstance(REFIID riid, _Outptr_ void **ppvObj, _In_ ITfTextInputProcessorEx *ptip)
{
if (ppvObj == nullptr)
{
return E_INVALIDARG;
}
*ppvObj = nullptr;
*ppvObj = new (std::nothrow) CSearchCandidateProvider(ptip);
if (nullptr == *ppvObj)
{
return E_OUTOFMEMORY;
}
return ((CSearchCandidateProvider*)(*ppvObj))->QueryInterface(riid, ppvObj);
}
/*------------------------------------------------------------------------------
constructor of CSearchCandidateProvider
------------------------------------------------------------------------------*/
CSearchCandidateProvider::CSearchCandidateProvider(_In_ ITfTextInputProcessorEx *ptip)
{
assert(ptip != nullptr);
_pTip = ptip;
_refCount = 0;
}
/*------------------------------------------------------------------------------
destructor of CSearchCandidateProvider
------------------------------------------------------------------------------*/
CSearchCandidateProvider::~CSearchCandidateProvider(void)
{
}
/*------------------------------------------------------------------------------
query interface
(IUnknown method)
------------------------------------------------------------------------------*/
STDMETHODIMP CSearchCandidateProvider::QueryInterface(REFIID riid, _Outptr_ void **ppvObj)
{
if (ppvObj == nullptr)
{
return E_POINTER;
}
*ppvObj = nullptr;
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, __uuidof(ITfFnSearchCandidateProvider)))
{
*ppvObj = (ITfFnSearchCandidateProvider*)this;
}
else if (IsEqualIID(riid, IID_ITfFunction))
{
*ppvObj = (ITfFunction*)this;
}
if (*ppvObj == nullptr)
{
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
/*------------------------------------------------------------------------------
increment reference count
(IUnknown method)
------------------------------------------------------------------------------*/
STDMETHODIMP_(ULONG) CSearchCandidateProvider::AddRef()
{
return (ULONG)InterlockedIncrement(&_refCount);
}
/*------------------------------------------------------------------------------
decrement reference count and release object
(IUnknown method)
------------------------------------------------------------------------------*/
STDMETHODIMP_(ULONG) CSearchCandidateProvider::Release()
{
ULONG ref = (ULONG)InterlockedDecrement(&_refCount);
if (0 < ref)
{
return ref;
}
delete this;
return 0;
}
STDMETHODIMP CSearchCandidateProvider::GetDisplayName(_Out_ BSTR *pbstrName)
{
if (pbstrName == nullptr)
{
return E_INVALIDARG;
}
*pbstrName = SysAllocString(L"SearchCandidateProvider");
return S_OK;
}
STDMETHODIMP CSearchCandidateProvider::GetSearchCandidates(BSTR bstrQuery, BSTR bstrApplicationID, _Outptr_result_maybenull_ ITfCandidateList **pplist)
{
bstrApplicationID;bstrQuery;
HRESULT hr = E_FAIL;
*pplist = nullptr;
if (nullptr == _pTip)
{
return hr;
}
CCompositionProcessorEngine* pCompositionProcessorEngine = ((CSampleIME*)_pTip)->GetCompositionProcessorEngine();
if (nullptr == pCompositionProcessorEngine)
{
return hr;
}
CSampleImeArray<CCandidateListItem> candidateList;
pCompositionProcessorEngine->GetCandidateList(&candidateList, TRUE, FALSE);
int cCand = min(candidateList.Count(), FAKECANDIDATENUMBER);
if (0 < cCand)
{
hr = CTipCandidateList::CreateInstance(pplist, cCand);
if (FAILED(hr))
{
return hr;
}
for (int iCand = 0; iCand < cCand; iCand++)
{
ITfCandidateString* pCandStr = nullptr;
CTipCandidateString::CreateInstance(IID_ITfCandidateString, (void**)&pCandStr);
((CTipCandidateString*)pCandStr)->SetIndex(iCand);
((CTipCandidateString*)pCandStr)->SetString(candidateList.GetAt(iCand)->_ItemString.Get(), candidateList.GetAt(iCand)->_ItemString.GetLength());
((CTipCandidateList*)(*pplist))->SetCandidate(&pCandStr);
}
}
hr = S_OK;
return hr;
}
/*------------------------------------------------------------------------------
set result
(ITfFnSearchCandidateProvider method)
------------------------------------------------------------------------------*/
STDMETHODIMP CSearchCandidateProvider::SetResult(BSTR bstrQuery, BSTR bstrApplicationID, BSTR bstrResult)
{
bstrQuery;bstrApplicationID;bstrResult;
return E_NOTIMPL;
}