void CExtentMonitorTextService::_DumpExtent(TfEditCookie ec, ITfContext *pContext, UINT nEventId) { if (!_pMemStream) return; ClearStream(_pMemStream); switch (nEventId) { case DE_EVENTID_ACTIVATE: AddStringToStream(_pMemStream, L"Event: Activate\r\n"); break; case DE_EVENTID_ONSETFOCUS: AddStringToStream(_pMemStream, L"Event: OnSetFocus\r\n"); break; case DE_EVENTID_ONENDEDIT: AddStringToStream(_pMemStream, L"Event: OnEndEdit\r\n"); break; case DE_EVENTID_ONLAYOUTCHANGE: AddStringToStream(_pMemStream, L"Event: OnLayoutChange\r\n"); break; case DE_EVENTID_FROMLANGUAGEBAR: AddStringToStream(_pMemStream, L"Event: From LanguageBar\r\n"); break; default: AddStringToStream(_pMemStream, L"Event: Unknoen\r\n"); break; } WCHAR sz[512]; ITfContextView *pView = NULL; TF_SELECTION sel; memset(&_rcStartPos , 0, sizeof(RECT)); memset(&_rcEndPos , 0, sizeof(RECT)); memset(&_rcSelection , 0, sizeof(RECT)); memset(&_rcView , 0, sizeof(RECT)); if (SUCCEEDED(pContext->GetActiveView(&pView))) { ITfRange *pRange; RECT rc; BOOL fClipped; HWND hwnd; AddStringToStream(_pMemStream, L"Wnd Handle - "); if (SUCCEEDED(pView->GetWnd(&hwnd))) { WCHAR szWndClass[32]; if (IsWindow(hwnd)) { GetClassNameW(hwnd, szWndClass, ARRAYSIZE(szWndClass)); StringCchPrintf(sz, ARRAYSIZE(sz), L"%08x %s\r\n", (DWORD)(ULONG_PTR)hwnd, szWndClass); AddStringToStream(_pMemStream, sz); } else { AddStringToStream(_pMemStream, L"null window handle\r\n"); } } AddStringToStream(_pMemStream, L"Screen Ext\r\n"); if (SUCCEEDED(pView->GetScreenExt(&rc))) { StringCchPrintf(sz, ARRAYSIZE(sz), L" (%d, %d, %d, %d) - (%d, %d)\r\n", rc.left, rc.top, rc.right, rc.bottom, rc.right - rc.left, rc.bottom - rc.top); AddStringToStream(_pMemStream, sz); _rcView = rc; } AddStringToStream(_pMemStream, L"Start Pos\r\n"); if (SUCCEEDED(pContext->GetStart(ec, &pRange))) { if (SUCCEEDED(pView->GetTextExt(ec, pRange, &rc, &fClipped))) { StringCchPrintf(sz, ARRAYSIZE(sz), L" (%d, %d, %d, %d) - (%d, %d) %s\r\n", rc.left, rc.top, rc.right, rc.bottom, rc.right - rc.left, rc.bottom - rc.top, fClipped ? L"Clipped" : L""); AddStringToStream(_pMemStream, sz); _rcStartPos = rc; } pRange->Release(); } AddStringToStream(_pMemStream, L"End Pos\r\n"); if (SUCCEEDED(pContext->GetEnd(ec, &pRange))) { if (SUCCEEDED(pView->GetTextExt(ec, pRange, &rc, &fClipped))) { StringCchPrintf(sz, ARRAYSIZE(sz), L" (%d, %d, %d, %d) - (%d, %d) %s\r\n", rc.left, rc.top, rc.right, rc.bottom, rc.right - rc.left, rc.bottom - rc.top, fClipped ? L"Clipped" : L""); AddStringToStream(_pMemStream, sz); _rcEndPos = rc; } pRange->Release(); } AddStringToStream(_pMemStream, L"Selection Pos\r\n"); ULONG cFetched; if (SUCCEEDED(pContext->GetSelection(ec, 0, 1, &sel, &cFetched))) { if (sel.range) { if (SUCCEEDED(pView->GetTextExt(ec, sel.range, &rc, &fClipped))) { StringCchPrintf(sz, ARRAYSIZE(sz), L" (%d, %d, %d, %d) - (%d, %d) %s\r\n", rc.left, rc.top, rc.right, rc.bottom, rc.right - rc.left, rc.bottom - rc.top, fClipped ? L"Clipped" : L""); AddStringToStream(_pMemStream, sz); _rcSelection = rc; } AddStringToStream(_pMemStream, L" "); _DumpRange(ec, sel.range); AddStringToStream(_pMemStream, L"\r\n"); sel.range->Release(); } } AddStringToStream(_pMemStream, L"Char Pos\r\n"); if (SUCCEEDED(pContext->GetStart(ec, &pRange))) { LONG cch; memset(&_rcRanges[0] , 0, sizeof(RECT) * ARRAYSIZE(_rcRanges)); if (SUCCEEDED(pRange->ShiftEnd(ec, 1, &cch, NULL)) && cch) { for (int i = 0; i < ARRAYSIZE(_rcRanges); i++) { if (SUCCEEDED(pView->GetTextExt(ec, pRange, &rc, &fClipped))) { StringCchPrintf(sz, ARRAYSIZE(sz), L" (%d, %d, %d, %d) - (%d, %d) %s", rc.left, rc.top, rc.right, rc.bottom, rc.right - rc.left, rc.bottom - rc.top, fClipped ? L"Clipped" : L""); AddStringToStream(_pMemStream, sz); AddStringToStream(_pMemStream, L" "); ITfRange *pRangeTmp; if (SUCCEEDED(pRange->Clone(&pRangeTmp))) { _DumpRange(ec, pRangeTmp); pRangeTmp->Release(); } AddStringToStream(_pMemStream, L"\r\n"); OffsetRect(&rc, 0 - _rcView.left, 0 - _rcView.top); _rcRanges[i] = rc; } if (FAILED(pRange->ShiftEnd(ec, 1, &cch, NULL)) || !cch) break; if (FAILED(pRange->ShiftStart(ec, 1, &cch, NULL)) || !cch) break; } } pRange->Release(); } pView->Release(); } _EnsurePopupWindow(); if (IsShownExtentVisualWindows()) _UpdateExtentVisualWindows(); if (IsShownRangeExtentViewer()) _UpdateRangeExtentViewer(); return; }
HRESULT CTextService::_SetText(TfEditCookie ec, ITfContext *pContext, const std::wstring &text, LONG cchCursor, LONG cchOkuri, BOOL fixed) { TF_SELECTION tfSelection; ULONG cFetched = 0; LONG cch, cchRes; if(pContext == NULL && _pCandidateList != NULL) //辞書登録用 { _pCandidateList->_SetText(text, fixed, FALSE, FALSE); return S_OK; } if(!_IsComposing()) { if(!_StartComposition(pContext)) { return S_FALSE; } } if(pContext->GetSelection(ec, TF_DEFAULT_SELECTION, 1, &tfSelection, &cFetched) != S_OK) { return S_FALSE; } if(cFetched != 1) { SafeRelease(&tfSelection.range); return S_FALSE; } ITfRange *pRange; if(_IsComposing() && _pComposition->GetRange(&pRange) == S_OK) { if(_IsRangeCovered(ec, tfSelection.range, pRange)) { pRange->SetText(ec, 0, text.c_str(), (LONG)text.size()); // shift from end to start. // shift over mathematical operators (U+2200-U+22FF) is rejected by OneNote. if(cchCursor == 0) { cchRes = (LONG)cursoridx - (LONG)kana.size(); if((complement && okuriidx != 0) || (!cx_showmodemark && okuriidx != 0 && cursoridx <= okuriidx && cursoridx < kana.size())) { cchRes += 1; } } else { cchRes = cchCursor - (LONG)text.size(); if(cchRes > 0) { cchRes = 0; } else if(cchRes < -(LONG)text.size()) { cchRes = -(LONG)text.size(); } } tfSelection.range->ShiftEndToRange(ec, pRange, TF_ANCHOR_END); tfSelection.range->ShiftStartToRange(ec, pRange, TF_ANCHOR_END); tfSelection.range->ShiftStart(ec, cchRes, &cch, NULL); //decide cursor position tfSelection.range->Collapse(ec, TF_ANCHOR_START); pContext->SetSelection(ec, 1, &tfSelection); //composition attribute if(!fixed) { ITfRange *pRangeClone; if(pRange->Clone(&pRangeClone) == S_OK) { pRangeClone->ShiftEndToRange(ec, pRange, TF_ANCHOR_END); pRangeClone->ShiftStartToRange(ec, pRange, TF_ANCHOR_START); if(cchCursor == 0 || !showentry) { if(inputkey) { _SetCompositionDisplayAttributes(ec, pContext, pRangeClone, _gaDisplayAttributeInputMark); if(cx_showmodemark) { pRangeClone->ShiftStart(ec, 1, &cch, NULL); } } if(!display_attribute_series[1] || !inputkey) { _SetCompositionDisplayAttributes(ec, pContext, pRangeClone, _gaDisplayAttributeInputText); } if(cchOkuri != 0) { pRangeClone->ShiftStartToRange(ec, pRange, TF_ANCHOR_START); pRangeClone->ShiftStart(ec, cchOkuri, &cch, NULL); if(!display_attribute_series[2]) { _SetCompositionDisplayAttributes(ec, pContext, pRangeClone, _gaDisplayAttributeInputOkuri); } if(hintmode && text.find_first_of(CHAR_SKK_HINT) != std::wstring::npos) { LONG hintpos = (LONG)text.find_first_of(CHAR_SKK_HINT); if(cchOkuri < hintpos) { pRangeClone->ShiftStartToRange(ec, pRange, TF_ANCHOR_START); pRangeClone->ShiftStart(ec, hintpos, &cch, NULL); _SetCompositionDisplayAttributes(ec, pContext, pRangeClone, _gaDisplayAttributeInputText); } } } } else { _SetCompositionDisplayAttributes(ec, pContext, pRangeClone, _gaDisplayAttributeConvMark); if(cx_showmodemark) { pRangeClone->ShiftStart(ec, 1, &cch, NULL); } if(!display_attribute_series[4]) { _SetCompositionDisplayAttributes(ec, pContext, pRangeClone, _gaDisplayAttributeConvText); } if(cchOkuri != 0) { pRangeClone->ShiftStartToRange(ec, pRange, TF_ANCHOR_START); pRangeClone->ShiftStart(ec, cchOkuri, &cch, NULL); if(!display_attribute_series[5]) { _SetCompositionDisplayAttributes(ec, pContext, pRangeClone, _gaDisplayAttributeConvOkuri); } } pRangeClone->ShiftEndToRange(ec, pRange, TF_ANCHOR_END); pRangeClone->ShiftStartToRange(ec, tfSelection.range, TF_ANCHOR_END); if(!display_attribute_series[6]) { _SetCompositionDisplayAttributes(ec, pContext, pRangeClone, _gaDisplayAttributeConvAnnot); } } SafeRelease(&pRangeClone); } } // for Excel's PHONETIC function if(fixed && !text.empty()) { ITfProperty *pProperty; if(pContext->GetProperty(GUID_PROP_READING, &pProperty) == S_OK) { VARIANT var; var.vt = VT_BSTR; std::wstring phone(kana); if(okuriidx == 0) { switch(inputmode) { case im_hiragana: case im_katakana: case im_katakana_ank: //接辞 if(!abbrevmode && kana.size() >= 2) { if(kana.front() == L'>') { phone = kana.substr(1); } else if(kana.back() == L'>') { phone = kana.substr(0, kana.size() - 1); } } break; default: break; } } else { if(kana.size() > (okuriidx + 1)) { phone = kana.substr(0, okuriidx) + kana.substr(okuriidx + 1); } else if(kana.size() >= okuriidx) { phone = kana.substr(0, okuriidx); } } if(!phone.empty()) { var.bstrVal = SysAllocString(phone.c_str()); pProperty->SetValue(ec, pRange, &var); SysFreeString(var.bstrVal); } SafeRelease(&pProperty); } } } SafeRelease(&pRange); } SafeRelease(&tfSelection.range); return S_OK; }