void CTextService::InsertHello() { ITfDocumentMgr *pDocMgrFocus; ITfContext *pContext; CInsertHelloEditSession *pInsertHelloEditSession; HRESULT hr; // get the focus document if (_pThreadMgr->GetFocus(&pDocMgrFocus) != S_OK) return; // we want the topmost context, since the main doc context could be // superceded by a modal tip context if (pDocMgrFocus->GetTop(&pContext) != S_OK) { pContext = NULL; goto Exit; } if (pInsertHelloEditSession = new CInsertHelloEditSession(pContext)) { // we need a document write lock to insert text // the CInsertHelloEditSession will do all the work when the // CInsertHelloEditSession::DoEditSession method is called by the context pContext->RequestEditSession(_tfClientId, pInsertHelloEditSession, TF_ES_READWRITE | TF_ES_ASYNCDONTCARE, &hr); pInsertHelloEditSession->Release(); } Exit: if (pContext) pContext->Release(); pDocMgrFocus->Release(); }
HRESULT CDIME::_CreateAndStartCandidate(_In_ CCompositionProcessorEngine *pCompositionProcessorEngine, TfEditCookie ec, _In_ ITfContext *pContext) { debugPrint(L"CDIME::_CreateAndStartCandidate(), _candidateMode = %d", _candidateMode); HRESULT hr = S_OK; if ((_candidateMode == CANDIDATE_NONE) && (_pUIPresenter)) { // we don't cache the document manager object. So get it from pContext. ITfDocumentMgr* pDocumentMgr = nullptr; if (SUCCEEDED(pContext->GetDocumentMgr(&pDocumentMgr))) { // get the composition range. ITfRange* pRange = nullptr; if (SUCCEEDED(_pComposition->GetRange(&pRange))) { hr = _pUIPresenter->_StartCandidateList(_tfClientId, pDocumentMgr, pContext, ec, pRange, pCompositionProcessorEngine->GetCandidateWindowWidth()); pRange->Release(); } pDocumentMgr->Release(); } } return hr; }
STDAPI CTextService::Activate(ITfThreadMgr *pThreadMgr, TfClientId tfClientId) { _pThreadMgr = pThreadMgr; _pThreadMgr->AddRef(); // // Initialize ThreadMgrEventSink. // if (!_InitThreadMgrEventSink()) goto ExitError; // // If there is the focus document manager already, // we advise the TextEditSink. // ITfDocumentMgr *pDocMgrFocus; if ((_pThreadMgr->GetFocus(&pDocMgrFocus) == S_OK) && (pDocMgrFocus != NULL)) { _InitTextEditSink(pDocMgrFocus); pDocMgrFocus->Release(); } // // Initialize Language Bar. // if (!_InitLanguageBar()) goto ExitError; return S_OK; ExitError: Deactivate(); // cleanup any half-finished init return E_FAIL; }
HRESULT CTextService::_HandleCharacterKey(TfEditCookie ec, ITfContext *pContext, WPARAM wParam) { if (!_IsComposing()) _StartComposition(pContext); // // create an instance of the candidate list class. // if (_pCandidateList == NULL) _pCandidateList = new CCandidateList(this); // // The document manager object is not cached. Get it from pContext. // ITfDocumentMgr *pDocumentMgr; if (pContext->GetDocumentMgr(&pDocumentMgr) == S_OK) { // // get the composition range. // ITfRange *pRange; if (_pComposition->GetRange(&pRange) == S_OK) { _pCandidateList->_StartCandidateList(_tfClientId, pDocumentMgr, pContext, ec, pRange); pRange->Release(); } pDocumentMgr->Release(); } if (_IsComposing()) _TerminateComposition(ec, pContext); return S_OK; }
/* static */ void CMarkTextService::_Menu_OnComposition(CMarkTextService *_this) { ITfDocumentMgr *pFocusDoc; ITfContext *pContext; CCompositionEditSession *pCompositionEditSession; HRESULT hr; // get the focus document if (_this->_pThreadMgr->GetFocus(&pFocusDoc) != S_OK) return; // we want the topmost context, since the main doc context could be // superceded by a modal tip context if (pFocusDoc->GetTop(&pContext) != S_OK) { pContext = NULL; goto Exit; } if (pCompositionEditSession = new CCompositionEditSession(pContext, _this)) { // we need a document write lock // the CCompositionEditSession will do all the work when the // CCompositionEditSession::DoEditSession method is called by the context pContext->RequestEditSession(_this->_tfClientId, pCompositionEditSession, TF_ES_READWRITE | TF_ES_ASYNCDONTCARE, &hr); pCompositionEditSession->Release(); } Exit: SafeRelease(pContext); pFocusDoc->Release(); }
STDAPI CExtentMonitorTextService::OnSetFocus(ITfDocumentMgr *pDocMgrFocus, ITfDocumentMgr *pDocMgrPrevFocus) { // // Whenever focus is changed, we initialize the TextEditSink. // ITfDocumentMgr *pDocMgrTarget = NULL; if (GetNonTransitoryDim(pDocMgrFocus, &pDocMgrTarget) != S_OK) { if (pDocMgrFocus) { pDocMgrTarget = pDocMgrFocus; pDocMgrTarget->AddRef(); } } _InitTextEditSink(pDocMgrTarget); if (pDocMgrTarget) { ITfContext *pContext; if (SUCCEEDED(pDocMgrTarget->GetBase(&pContext))) { DumpExtent(pContext, DE_EVENTID_ONSETFOCUS); pContext->Release(); } pDocMgrTarget->Release(); } return S_OK; }
void CTextService::_StartInputModeWindow() { switch(inputmode) { case im_default: case im_hiragana: case im_katakana: case im_katakana_ank: case im_jlatin: case im_ascii: _EndInputModeWindow(); ITfDocumentMgr *pDocumentMgr; if((_pThreadMgr->GetFocus(&pDocumentMgr) == S_OK) && (pDocumentMgr != nullptr)) { ITfContext *pContext; if((pDocumentMgr->GetTop(&pContext) == S_OK) && (pContext != nullptr)) { try { _pInputModeWindow = new CInputModeWindow(); if(_pInputModeWindow->_Create(this, pContext, FALSE, nullptr)) { HRESULT hr = E_FAIL; HRESULT hrSession = E_FAIL; try { CInputModeWindowEditSession *pEditSession = new CInputModeWindowEditSession(this, pContext, _pInputModeWindow); // Asynchronous, read-only hr = pContext->RequestEditSession(_ClientId, pEditSession, TF_ES_ASYNC | TF_ES_READ, &hrSession); SafeRelease(&pEditSession); // It is possible that asynchronous requests are treated as synchronous requests. if(hr != S_OK || (hrSession != TF_S_ASYNC && hrSession != S_OK)) { _EndInputModeWindow(); } } catch(...) { } } } catch(...) { } SafeRelease(&pContext); } SafeRelease(&pDocumentMgr); } break; default: break; } }
ITfContext* TextService::currentContext() { ITfContext* context = NULL; ITfDocumentMgr *docMgr; if(threadMgr_->GetFocus(&docMgr) == S_OK) { docMgr->GetTop(&context); docMgr->Release(); } return context; }
HRESULT CCandidateListUIPresenter::_CandidateChangeNotification(_In_ enum CANDWND_ACTION action) { HRESULT hr = E_FAIL; TfClientId tfClientId = _pTextService->_GetClientId(); ITfThreadMgr* pThreadMgr = nullptr; ITfDocumentMgr* pDocumentMgr = nullptr; ITfContext* pContext = nullptr; _KEYSTROKE_STATE KeyState; KeyState.Category = _Category; KeyState.Function = FUNCTION_FINALIZE_CANDIDATELIST; if (CAND_ITEM_SELECT != action) { goto Exit; } pThreadMgr = _pTextService->_GetThreadMgr(); if (nullptr == pThreadMgr) { goto Exit; } hr = pThreadMgr->GetFocus(&pDocumentMgr); if (FAILED(hr)) { goto Exit; } hr = pDocumentMgr->GetTop(&pContext); if (FAILED(hr)) { pDocumentMgr->Release(); goto Exit; } CKeyHandlerEditSession *pEditSession = new (std::nothrow) CKeyHandlerEditSession(_pTextService, pContext, 0, 0, KeyState); if (nullptr != pEditSession) { HRESULT hrSession = S_OK; hr = pContext->RequestEditSession(tfClientId, pEditSession, TF_ES_SYNC | TF_ES_READWRITE, &hrSession); if (hrSession == TF_E_SYNCHRONOUS || hrSession == TS_E_READONLY) { hr = pContext->RequestEditSession(tfClientId, pEditSession, TF_ES_ASYNC | TF_ES_READWRITE, &hrSession); } pEditSession->Release(); } pContext->Release(); pDocumentMgr->Release(); Exit: return hr; }
HRESULT CDIME::_ProbeCompositionRangeNotification(_In_ TfEditCookie ec, _In_ ITfContext *pContext) { debugPrint(L"CDIME::_ProbeCompositionRangeNotification(), \n"); HRESULT hr = S_OK; if(!_IsComposing()) _StartComposition(pContext); hr = E_FAIL; ULONG fetched = 0; TF_SELECTION tfSelection; if ( pContext == nullptr || (hr = pContext->GetSelection(ec, TF_DEFAULT_SELECTION, 1, &tfSelection, &fetched)) != S_OK || fetched != 1 ||tfSelection.range==nullptr) { _TerminateComposition(ec,pContext); return hr; } tfSelection.range->Release(); ITfRange *pRange; ITfContextView* pContextView; ITfDocumentMgr* pDocumgr; if (_pComposition&&SUCCEEDED(_pComposition->GetRange(&pRange)) && pRange) { if(pContext && SUCCEEDED(pContext->GetActiveView(&pContextView)) && pContextView) { if(pContext && SUCCEEDED( pContext->GetDocumentMgr(&pDocumgr)) && pDocumgr && _pThreadMgr &&_pUIPresenter) { ITfDocumentMgr* pFocusDocuMgr; _pThreadMgr->GetFocus(&pFocusDocuMgr); if(pFocusDocuMgr == pDocumgr) { _pUIPresenter->_StartLayout(pContext, ec, pRange); _pUIPresenter->_MoveUIWindowsToTextExt(); } else _pUIPresenter->ClearNotify(); pDocumgr->Release(); } pContextView->Release(); } pRange->Release(); } _TerminateComposition(ec,pContext); return hr; }
void CExtentMonitorTextService::DumpExtentFocusContext(UINT nEventId) { ITfDocumentMgr *pDocMgrFocus; if ((_pThreadMgr->GetFocus(&pDocMgrFocus) == S_OK) && (pDocMgrFocus != NULL)) { ITfContext *pContext; if (SUCCEEDED(pDocMgrFocus->GetBase(&pContext))) { DumpExtent(pContext, nEventId); pContext->Release(); } pDocMgrFocus->Release(); } }
HRESULT COVTSF::_CreateAndStartCandidate(_In_ CCompositionProcessorEngine *pCompositionProcessorEngine, TfEditCookie ec, _In_ ITfContext *pContext) { HRESULT hr = S_OK; if (((_candidateMode == CANDIDATE_PHRASE) && (_pCandidateListUIPresenter)) || ((_candidateMode == CANDIDATE_NONE) && (_pCandidateListUIPresenter))) { // Recreate candidate list _pCandidateListUIPresenter->_EndCandidateList(); delete _pCandidateListUIPresenter; _pCandidateListUIPresenter = nullptr; _candidateMode = CANDIDATE_NONE; _isCandidateWithWildcard = FALSE; } if (_pCandidateListUIPresenter == nullptr) { _pCandidateListUIPresenter = new (std::nothrow) CCandidateListUIPresenter(this, Global::AtomCandidateWindow, CATEGORY_CANDIDATE, pCompositionProcessorEngine->GetCandidateListIndexRange(), FALSE); if (!_pCandidateListUIPresenter) { return E_OUTOFMEMORY; } _candidateMode = CANDIDATE_INCREMENTAL; _isCandidateWithWildcard = FALSE; // we don't cache the document manager object. So get it from pContext. ITfDocumentMgr* pDocumentMgr = nullptr; if (SUCCEEDED(pContext->GetDocumentMgr(&pDocumentMgr))) { // get the composition range. ITfRange* pRange = nullptr; if (SUCCEEDED(_pComposition->GetRange(&pRange))) { hr = _pCandidateListUIPresenter->_StartCandidateList(_tfClientId, pDocumentMgr, pContext, ec, pRange, pCompositionProcessorEngine->GetCandidateWindowWidth()); pRange->Release(); } pDocumentMgr->Release(); } } return hr; }
STDAPI CSampleIME::OnSetFocus(_In_ ITfDocumentMgr *pDocMgrFocus, _In_ ITfDocumentMgr *pDocMgrPrevFocus) { pDocMgrPrevFocus; _InitTextEditSink(pDocMgrFocus); _UpdateLanguageBarOnSetFocus(pDocMgrFocus); // // We have to hide/unhide candidate list depending on whether they are // associated with pDocMgrFocus. // if (_pCandidateListUIPresenter) { ITfDocumentMgr* pCandidateListDocumentMgr = nullptr; ITfContext* pTfContext = _pCandidateListUIPresenter->_GetContextDocument(); if ((nullptr != pTfContext) && SUCCEEDED(pTfContext->GetDocumentMgr(&pCandidateListDocumentMgr))) { if (pCandidateListDocumentMgr != pDocMgrFocus) { _pCandidateListUIPresenter->OnKillThreadFocus(); } else { _pCandidateListUIPresenter->OnSetThreadFocus(); } pCandidateListDocumentMgr->Release(); } } if (_pDocMgrLastFocused) { _pDocMgrLastFocused->Release(); _pDocMgrLastFocused = nullptr; } _pDocMgrLastFocused = pDocMgrFocus; if (_pDocMgrLastFocused) { _pDocMgrLastFocused->AddRef(); } return S_OK; }
STDAPI CIME::OnSetThreadFocus() { if (_pCandidateListUIPresenter) { ITfDocumentMgr* pCandidateListDocumentMgr = nullptr; ITfContext* pTfContext = _pCandidateListUIPresenter->_GetContextDocument(); if ((nullptr != pTfContext) && SUCCEEDED(pTfContext->GetDocumentMgr(&pCandidateListDocumentMgr))) { if (pCandidateListDocumentMgr == _pDocMgrLastFocused) { _pCandidateListUIPresenter->OnSetThreadFocus(); } pCandidateListDocumentMgr->Release(); } } return S_OK; }
BOOL CTextEditor::InitTSF() { _pTextStore = new CTextStore(this); if (!_pTextStore) { return FALSE; } if (FAILED(g_pThreadMgr->CreateDocumentMgr(&_pDocumentMgr))) { return FALSE; } if (FAILED(_pDocumentMgr->CreateContext(g_TfClientId, 0, (ITextStoreACP *)_pTextStore, &_pInputContext, &_ecTextStore))) { return FALSE; } if (FAILED(_pDocumentMgr->Push(_pInputContext))) { return FALSE; } ITfDocumentMgr *pDocumentMgrPrev; g_pThreadMgr->AssociateFocus(_hwnd, _pDocumentMgr, &pDocumentMgrPrev); if (pDocumentMgrPrev) pDocumentMgrPrev->Release(); _pTextEditSink = new CTextEditSink(this); if (!_pTextEditSink) { return FALSE; } _pTextEditSink->_Advise(_pInputContext); return TRUE; }
void CTextService::_AttachStaticProperty(WCHAR *psz) { ITfDocumentMgr *pDocMgrFocus; ITfContext *pContext; if ((_pThreadMgr->GetFocus(&pDocMgrFocus) == S_OK) && (pDocMgrFocus != NULL)) { if (pDocMgrFocus->GetTop(&pContext) == S_OK) { CStaticPropertyEditSession *pEditSession; if (pEditSession = new CStaticPropertyEditSession(this, pContext, psz)) { HRESULT hr; pContext->RequestEditSession(_tfClientId, pEditSession, TF_ES_ASYNCDONTCARE | TF_ES_READWRITE, &hr); pEditSession->Release(); } pContext->Release(); } pDocMgrFocus->Release(); } return; }
HRESULT CSampleIME::_HandleCandidateWorker(TfEditCookie ec, _In_ ITfContext *pContext) { HRESULT hrReturn = E_FAIL; DWORD_PTR candidateLen = 0; const WCHAR* pCandidateString = nullptr; BSTR pbstr = nullptr; CStringRange candidateString; CSampleImeArray<CCandidateListItem> candidatePhraseList; if (nullptr == _pCandidateListUIPresenter) { hrReturn = S_OK; goto Exit; } candidateLen = _pCandidateListUIPresenter->_GetSelectedCandidateString(&pCandidateString); if (0 == candidateLen) { hrReturn = S_FALSE; goto Exit; } candidateString.Set(pCandidateString, candidateLen); BOOL fMakePhraseFromText = _pCompositionProcessorEngine->IsMakePhraseFromText(); if (fMakePhraseFromText) { _pCompositionProcessorEngine->GetCandidateStringInConverted(candidateString, &candidatePhraseList); LCID locale = _pCompositionProcessorEngine->GetLocale(); _pCandidateListUIPresenter->RemoveSpecificCandidateFromList(locale, candidatePhraseList, candidateString); } // We have a candidate list if candidatePhraseList.Cnt is not 0 // If we are showing reverse conversion, use CCandidateListUIPresenter CANDIDATE_MODE tempCandMode = CANDIDATE_NONE; CCandidateListUIPresenter* pTempCandListUIPresenter = nullptr; if (candidatePhraseList.Count()) { tempCandMode = CANDIDATE_WITH_NEXT_COMPOSITION; pTempCandListUIPresenter = new (std::nothrow) CCandidateListUIPresenter(this, Global::AtomCandidateWindow, CATEGORY_CANDIDATE, _pCompositionProcessorEngine->GetCandidateListIndexRange(), FALSE); if (nullptr == pTempCandListUIPresenter) { hrReturn = E_OUTOFMEMORY; goto Exit; } } // call _Start*Line for CCandidateListUIPresenter or CReadingLine // we don't cache the document manager object so get it from pContext. ITfDocumentMgr* pDocumentMgr = nullptr; HRESULT hrStartCandidateList = E_FAIL; if (pContext->GetDocumentMgr(&pDocumentMgr) == S_OK) { ITfRange* pRange = nullptr; if (_pComposition->GetRange(&pRange) == S_OK) { if (pTempCandListUIPresenter) { hrStartCandidateList = pTempCandListUIPresenter->_StartCandidateList(_tfClientId, pDocumentMgr, pContext, ec, pRange, _pCompositionProcessorEngine->GetCandidateWindowWidth()); } pRange->Release(); } pDocumentMgr->Release(); } // set up candidate list if it is being shown if (SUCCEEDED(hrStartCandidateList)) { pTempCandListUIPresenter->_SetTextColor(RGB(0, 0x80, 0), GetSysColor(COLOR_WINDOW)); // Text color is green pTempCandListUIPresenter->_SetFillColor((HBRUSH)(COLOR_WINDOW+1)); // Background color is window pTempCandListUIPresenter->_SetText(&candidatePhraseList, FALSE); // Add composing character hrReturn = _AddComposingAndChar(ec, pContext, &candidateString); // close candidate list if (_pCandidateListUIPresenter) { _pCandidateListUIPresenter->_EndCandidateList(); delete _pCandidateListUIPresenter; _pCandidateListUIPresenter = nullptr; _candidateMode = CANDIDATE_NONE; _isCandidateWithWildcard = FALSE; } if (hrReturn == S_OK) { // copy temp candidate _pCandidateListUIPresenter = pTempCandListUIPresenter; _candidateMode = tempCandMode; _isCandidateWithWildcard = FALSE; } } else { hrReturn = _HandleCandidateFinalize(ec, pContext); } if (pbstr) { SysFreeString(pbstr); } Exit: return hrReturn; }
STDAPI CPropertyMonitorTextService::Activate(ITfThreadMgr *pThreadMgr, TfClientId tfClientId) { _pThreadMgr = pThreadMgr; _pThreadMgr->AddRef(); _tfClientId = tfClientId; // // Initialize ThreadMgrEventSink. // if (!_InitThreadMgrEventSink()) goto ExitError; // // If there is the focus document manager already, // we advise the TextEditSink. // ITfDocumentMgr *pDocMgrFocus; if ((_pThreadMgr->GetFocus(&pDocMgrFocus) == S_OK) && (pDocMgrFocus != NULL)) { _InitTextEditSink(pDocMgrFocus); pDocMgrFocus->Release(); } // // Initialize Language Bar. // if (!_InitLanguageBar()) goto ExitError; // // Initialize Thread focus sink. // if (!_InitThreadFocusSink()) goto ExitError; if (CoCreateInstance(CLSID_TF_DisplayAttributeMgr, NULL, CLSCTX_INPROC_SERVER, IID_ITfDisplayAttributeMgr, (void**)&_pDisplayAttributeMgr) != S_OK) { goto ExitError; } if (CoCreateInstance(CLSID_TF_CategoryMgr, NULL, CLSCTX_INPROC_SERVER, IID_ITfCategoryMgr, (void**)&_pCategoryMgr) != S_OK) { goto ExitError; } _pMemStream = CreateMemoryStream(); if (_pMemStream == NULL) { goto ExitError; } return S_OK; ExitError: Deactivate(); // cleanup any half-finished init return E_FAIL; }
BOOL CTextService::_IsKeyboardDisabled() { ITfCompartmentMgr *pCompMgr = NULL; ITfDocumentMgr *pDocMgrFocus = NULL; ITfContext *pContext = NULL; BOOL fDisabled = FALSE; if ((_pThreadMgr->GetFocus(&pDocMgrFocus) != S_OK) || (pDocMgrFocus == NULL)) { // if there is no focus document manager object, the keyboard // is disabled. fDisabled = TRUE; goto Exit; } if ((pDocMgrFocus->GetTop(&pContext) != S_OK) || (pContext == NULL)) { // if there is no context object, the keyboard is disabled. fDisabled = TRUE; goto Exit; } if (pContext->QueryInterface(IID_ITfCompartmentMgr, (void **)&pCompMgr) == S_OK) { ITfCompartment *pCompartmentDisabled; ITfCompartment *pCompartmentEmptyContext; // Check GUID_COMPARTMENT_KEYBOARD_DISABLED. if (pCompMgr->GetCompartment(GUID_COMPARTMENT_KEYBOARD_DISABLED, &pCompartmentDisabled) == S_OK) { VARIANT var; if (S_OK == pCompartmentDisabled->GetValue(&var)) { if (var.vt == VT_I4) // Even VT_EMPTY, GetValue() can succeed { fDisabled = (BOOL)var.lVal; } } pCompartmentDisabled->Release(); } // Check GUID_COMPARTMENT_EMPTYCONTEXT. if (pCompMgr->GetCompartment(GUID_COMPARTMENT_EMPTYCONTEXT, &pCompartmentEmptyContext) == S_OK) { VARIANT var; if (S_OK == pCompartmentEmptyContext->GetValue(&var)) { if (var.vt == VT_I4) // Even VT_EMPTY, GetValue() can succeed { fDisabled = (BOOL)var.lVal; } } pCompartmentEmptyContext->Release(); } pCompMgr->Release(); } Exit: if (pContext) pContext->Release(); if (pDocMgrFocus) pDocMgrFocus->Release(); return fDisabled; }
HRESULT CTextService::_HandleKey(TfEditCookie ec, ITfContext *pContext, WPARAM wParam) { /* * FIXME: the following keys are not handled: * shift left VK_LSHIFT * shift right VK_RSHIFT * caps lock VK_CAPITAL * page up VK_PRIOR * page down VK_NEXT * ctrl num * shift space * numlock num VK_NUMLOCK */ if (('A' <= wParam && wParam <= 'Z')) { chewing_handle_Default(mChewingContext, wParam - 'A' + 'a'); } else if ('0' <= wParam && wParam <= '9') { chewing_handle_Default(mChewingContext, wParam); } else { switch(wParam) { case VK_OEM_COMMA: chewing_handle_Default(mChewingContext, ','); break; case VK_OEM_MINUS: chewing_handle_Default(mChewingContext, '-'); break; case VK_OEM_PERIOD: chewing_handle_Default(mChewingContext, '.'); break; case VK_OEM_1: chewing_handle_Default(mChewingContext, ';'); break; case VK_OEM_2: chewing_handle_Default(mChewingContext, '/'); break; case VK_OEM_3: chewing_handle_Default(mChewingContext, '`'); break; case VK_SPACE: chewing_handle_Space(mChewingContext); break; case VK_ESCAPE: chewing_handle_Esc(mChewingContext); break; case VK_RETURN: chewing_handle_Enter(mChewingContext); break; case VK_DELETE: chewing_handle_Del(mChewingContext); break; case VK_BACK: chewing_handle_Backspace(mChewingContext); break; case VK_UP: chewing_handle_Up(mChewingContext); break; case VK_DOWN: chewing_handle_Down(mChewingContext); case VK_LEFT: chewing_handle_Left(mChewingContext); break; case VK_RIGHT: chewing_handle_Right(mChewingContext); break; case VK_HOME: chewing_handle_Home(mChewingContext); break; case VK_END: chewing_handle_End(mChewingContext); break; default: return S_OK; } } // Remove old candidate list. We will create a new one if necessary. _pCandidateList->_EndCandidateList(); ChewingCandidates candidate(mChewingContext); if (!candidate.IsEmpty()) { _SetCompositionDisplayAttributes(ec, pContext, _gaDisplayAttributeConverted); // // The document manager object is not cached. Get it from pContext. // ITfDocumentMgr *pDocumentMgr; if (pContext->GetDocumentMgr(&pDocumentMgr) == S_OK) { // // get the composition range. // ITfRange *pRange; if (_pComposition->GetRange(&pRange) == S_OK) { _pCandidateList->_StartCandidateList(_tfClientId, pDocumentMgr, pContext, ec, pRange, candidate); pRange->Release(); } pDocumentMgr->Release(); } return S_OK; } ChewingString commit(mChewingContext, CHEWING_STRING_COMMIT); if (!commit.IsEmpty()) { // FIXME: Need a better way to submit a string if (!_IsComposing()) _StartComposition(pContext); ULONG cFetched; BOOL fCovered; TF_SELECTION tfSelection; // FIXME: Why we need this here? // first, test where a keystroke would go in the document if an insert is done if (pContext->GetSelection(ec, TF_DEFAULT_SELECTION, 1, &tfSelection, &cFetched) != S_OK || cFetched != 1) return S_FALSE; // FIXME: Why we need this here? // is the insertion point covered by a composition? ITfRange *pRangeComposition; if (_pComposition->GetRange(&pRangeComposition) == S_OK) { fCovered = IsRangeCovered(ec, tfSelection.range, pRangeComposition); pRangeComposition->Release(); if (!fCovered) { goto End3; } } if (tfSelection.range->SetText(ec, 0, commit.GetString(), commit.GetLength()) != S_OK) goto End3; _TerminateComposition(ec, pContext); End3: // FIXME: RAII? tfSelection.range->Release(); } /* * Composition is mapped to preedit buffer + zuin buffer */ ChewingString preedit_zuin(mChewingContext, CHEWING_STRING_PREEDIT_ZUIN); if (preedit_zuin.IsEmpty()) { // Remove composition if (_IsComposing()) { ULONG cFetched; BOOL fCovered; TF_SELECTION tfSelection; // FIXME: Why we need this here? // first, test where a keystroke would go in the document if an insert is done if (pContext->GetSelection(ec, TF_DEFAULT_SELECTION, 1, &tfSelection, &cFetched) != S_OK || cFetched != 1) return S_FALSE; // FIXME: Why we need this here? // is the insertion point covered by a composition? ITfRange *pRangeComposition; if (_pComposition->GetRange(&pRangeComposition) == S_OK) { fCovered = IsRangeCovered(ec, tfSelection.range, pRangeComposition); pRangeComposition->Release(); if (!fCovered) { goto End; } } // Empties the composition tfSelection.range->SetText(ec, 0, L"", 0); _TerminateComposition(ec, pContext); End: // FIXME: RAII? tfSelection.range->Release(); } } else { if (!_IsComposing()) _StartComposition(pContext); ULONG cFetched; BOOL fCovered; TF_SELECTION tfSelection; // FIXME: Why we need this here? // first, test where a keystroke would go in the document if an insert is done if (pContext->GetSelection(ec, TF_DEFAULT_SELECTION, 1, &tfSelection, &cFetched) != S_OK || cFetched != 1) return S_FALSE; // FIXME: Why we need this here? // is the insertion point covered by a composition? ITfRange *pRangeComposition; if (_pComposition->GetRange(&pRangeComposition) == S_OK) { fCovered = IsRangeCovered(ec, tfSelection.range, pRangeComposition); pRangeComposition->Release(); if (!fCovered) { goto End2; } } if (tfSelection.range->SetText(ec, 0, preedit_zuin.GetString(), preedit_zuin.GetLength()) != S_OK) goto End2; _SetCompositionDisplayAttributes(ec, pContext, _gaDisplayAttributeInput); End2: // FIXME: RAII? tfSelection.range->Release(); } return S_OK; }
HRESULT COVTSF::_HandleCompositionConvert(TfEditCookie ec, _In_ ITfContext *pContext, BOOL isWildcardSearch) { HRESULT hr = S_OK; COVTSFArray<CCandidateListItem> candidateList; // // Get candidate string from composition processor engine // CCompositionProcessorEngine* pCompositionProcessorEngine = nullptr; pCompositionProcessorEngine = _pCompositionProcessorEngine; pCompositionProcessorEngine->GetCandidateList(&candidateList, FALSE, isWildcardSearch); // If there is no candlidate listin the current reading string, we don't do anything. Just wait for // next char to be ready for the conversion with it. int nCount = candidateList.Count(); if (nCount) { if (_pCandidateListUIPresenter) { _pCandidateListUIPresenter->_EndCandidateList(); delete _pCandidateListUIPresenter; _pCandidateListUIPresenter = nullptr; _candidateMode = CANDIDATE_NONE; _isCandidateWithWildcard = FALSE; } // // create an instance of the candidate list class. // if (_pCandidateListUIPresenter == nullptr) { _pCandidateListUIPresenter = new (std::nothrow) CCandidateListUIPresenter(this, Global::AtomCandidateWindow, CATEGORY_CANDIDATE, pCompositionProcessorEngine->GetCandidateListIndexRange(), FALSE); if (!_pCandidateListUIPresenter) { return E_OUTOFMEMORY; } _candidateMode = CANDIDATE_ORIGINAL; } _isCandidateWithWildcard = isWildcardSearch; // we don't cache the document manager object. So get it from pContext. ITfDocumentMgr* pDocumentMgr = nullptr; if (SUCCEEDED(pContext->GetDocumentMgr(&pDocumentMgr))) { // get the composition range. ITfRange* pRange = nullptr; if (SUCCEEDED(_pComposition->GetRange(&pRange))) { hr = _pCandidateListUIPresenter->_StartCandidateList(_tfClientId, pDocumentMgr, pContext, ec, pRange, pCompositionProcessorEngine->GetCandidateWindowWidth()); pRange->Release(); } pDocumentMgr->Release(); } if (SUCCEEDED(hr)) { _pCandidateListUIPresenter->_SetText(&candidateList, FALSE); } } return hr; }