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; } }
STDAPI CTextService::OnTestKeyDown(ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten) { if(pfEaten == NULL) { return E_INVALIDARG; } int eaten = _IsKeyEaten(pic, wParam, lParam, TRUE, TRUE); if(eaten == -1) { *pfEaten = TRUE; return S_OK; } *pfEaten = (eaten == TRUE); _EndInputModeWindow(); if(!_IsKeyboardDisabled() && _IsKeyboardOpen() && !_IsComposing()) { WCHAR ch = _GetCh((BYTE)wParam); if(_IsKeyVoid(ch, (BYTE)wParam)) { _GetActiveFlags(); _UpdateLanguageBar(); } } return S_OK; }
void CTextService::_UpdateLanguageBar(BOOL showinputmode) { if(_pLangBarItem != nullptr) { _pLangBarItem->_Update(); } if(_pLangBarItemI != nullptr) { _pLangBarItemI->_Update(); } if(showinputmode && _ShowInputMode && !_IsComposing()) { _StartInputModeWindow(); } else { _EndInputModeWindow(); } }
STDAPI CTextService::Deactivate() { if(_pThreadMgr == nullptr) { return S_OK; } _SaveUserDic(); _EndCandidateList(); _EndInputModeWindow(); _UninitFunctionProvider(); _UninitPreservedKey(0); _UninitPreservedKey(1); _UninitKeyEventSink(); _UninitLanguageBar(); _InitTextEditSink(nullptr); _UninitCompartmentEventSink(); _UninitThreadFocusSink(); _UninitThreadMgrEventSink(); _UninitD2D(); SafeRelease(&_pThreadMgr); _ClientId = TF_CLIENTID_NULL; return S_OK; }
HRESULT CTextService::_Update(TfEditCookie ec, ITfContext *pContext, BOOL fixed, BOOL back) { std::wstring comptext; WCHAR candidatecount[16]; WCHAR useraddmode = REQ_USER_ADD_1; LONG cchCursor = 0; LONG cchOkuri = 0; BOOL showmodemark = cx_showmodemark; if(pContext == NULL) //辞書登録用 { showmodemark = TRUE; } if(showentry && ( (fixed && showcandlist) || (cx_untilcandlist == 0) || (candidx + 1 < cx_untilcandlist) || (candidates.size() + 1 == cx_untilcandlist) )) { if(!candidates.empty() && candidx < candidates.size()) { if(!fixed && showmodemark) { comptext.append(markHenkan); } comptext.append(candidates[candidx].first.first); if(okuriidx != 0) { cchOkuri = (LONG)comptext.size(); comptext.append(kana.substr(okuriidx + 1)); useraddmode = REQ_USER_ADD_0; } cchCursor = (LONG)comptext.size(); if(!fixed) { if(purgedicmode) { comptext.append(L" [削除?(Y/n)]"); } else { if(cx_annotation && !cx_annotatlst && !candidates[candidx].first.second.empty()) { comptext.append(markAnnotation + candidates[candidx].first.second); } if(cx_untilcandlist == 0 && cx_dispcandnum) { comptext.append(L" ("); _snwprintf_s(candidatecount, _TRUNCATE, L"%u", (UINT)candidx + 1); comptext.append(candidatecount); comptext.append(L"/"); _snwprintf_s(candidatecount, _TRUNCATE, L"%u", (UINT)candidates.size()); comptext.append(candidatecount); comptext.append(L")"); } if(!showmodemark && comptext.empty()) { comptext.append(markSP); } } } //ユーザー辞書登録 if(fixed && !candidates[candidx].second.first.empty()) { _AddUserDic(useraddmode, ((candorgcnt <= candidx) ? searchkey : searchkeyorg), candidates[candidx].second.first, candidates[candidx].second.second); } } else { //候補なし or 候補が尽きた if(!fixed) { if(!showmodemark) { if(kana.empty()) { comptext.append(markSP); } } else { comptext.append(markHenkan); } } if(okuriidx == 0) { comptext.append(kana); } else { comptext.append(kana.substr(0, okuriidx)); cchOkuri = (LONG)comptext.size(); if(!fixed && showmodemark) { comptext.append(markOkuri); } comptext.append(kana.substr(okuriidx + 1)); } cchCursor = (LONG)comptext.size(); if(pContext == NULL && _pCandidateList != NULL) //辞書登録用 { _pCandidateList->_SetText(comptext, FALSE, FALSE, TRUE); return S_OK; } else { _SetText(ec, pContext, comptext, cchCursor, cchOkuri, FALSE); //辞書登録表示開始 return _ShowCandidateList(ec, pContext, TRUE, FALSE); } } } else { if(inputkey) { if(!fixed) { if(!showmodemark) { if(kana.empty() && roman.empty()) { comptext.append(markSP); } } else { if(showentry && (candidx + 1 == cx_untilcandlist)) { comptext.append(markHenkan); } else { comptext.append(markMidashi); } } } if(!roman.empty() || !kana.empty()) { if(okuriidx == 0) { comptext.append(kana); if(pContext == NULL && !fixed && cursoridx != kana.size()) //辞書登録用 { comptext.insert(cursoridx + (comptext.size() - kana.size()), markCursor); } } else { comptext.append(kana.substr(0, okuriidx)); cchOkuri = (LONG)comptext.size(); if(!fixed && showmodemark && !complement) { comptext.append(markOkuri); } if(okuriidx + 1 < kana.size()) { comptext.append(kana.substr(okuriidx + 1)); } if(pContext == NULL && !fixed && roman.empty() && cursoridx != kana.size()) //辞書登録用 { if(!showmodemark) { if(cursoridx < okuriidx) { comptext.insert(cursoridx, markCursor); } else { comptext.insert(cursoridx - 1, markCursor); } } else { if(complement && okuriidx != 0) { comptext.insert(okuriidx + 1, L" ["); comptext.append(L"]"); } comptext.insert(cursoridx + 1, markCursor); } } } if(!fixed && !roman.empty()) { if(!showmodemark) { if(okuriidx != 0 && okuriidx < cursoridx) { if(cx_showroman) { comptext.insert(cursoridx - 1, roman); } else { comptext.insert(cursoridx - 1, markSP); } } else { if(cx_showroman) { comptext.insert(cursoridx, roman); } else { comptext.insert(cursoridx, markSP); } } } else { if(cx_showroman) { comptext.insert(cursoridx + 1, roman); } else { comptext.insert(cursoridx + 1, markSP); } } if(okuriidx != 0 && cursoridx <= okuriidx) { if(cx_showroman) { cchOkuri += (LONG)roman.size(); } else { cchOkuri += 1; } } } } if(showentry && (candidx + 1 == cx_untilcandlist)) { cchCursor = (LONG)comptext.size(); } } else { if(!kana.empty()) { comptext.append(kana); } else { if(!fixed) { if(cx_showroman) { comptext.append(roman); } else { comptext.append(markSP); } } } } } if(fixed && back && cx_backincenter && !comptext.empty()) { // surrogate pair if(comptext.size() >= 2 && IS_SURROGATE_PAIR(comptext[comptext.size() - 2], comptext[comptext.size() - 1])) { comptext.pop_back(); comptext.pop_back(); } else { comptext.pop_back(); } } _EndInputModeWindow(); if(inputkey && !fixed && !showcandlist && showentry && (((cx_untilcandlist != 1) && (candidx + 1 == cx_untilcandlist)) || (cx_untilcandlist == 1)) && (candidates.size() + 1 != cx_untilcandlist)) { if(pContext == NULL && _pCandidateList != NULL) //辞書登録用 { showcandlist = TRUE; candidx = 0; _pCandidateList->_SetText(comptext, FALSE, TRUE, FALSE); return S_OK; } else { _SetText(ec, pContext, comptext, cchCursor, cchOkuri, fixed); //候補一覧表示開始 showcandlist = TRUE; candidx = 0; return _ShowCandidateList(ec, pContext, FALSE, FALSE); } } if(pContext == NULL && _pCandidateList != NULL) //辞書登録用 { _pCandidateList->_SetText(comptext, fixed, FALSE, FALSE); return S_OK; } else { return _SetText(ec, pContext, comptext, cchCursor, cchOkuri, fixed); } }