diff --git a/WeaselTSF/Composition.cpp b/WeaselTSF/Composition.cpp index fea184032..0ae2a7490 100644 --- a/WeaselTSF/Composition.cpp +++ b/WeaselTSF/Composition.cpp @@ -155,30 +155,81 @@ class CGetTextExtentEditSession : public CEditSession { }; STDAPI CGetTextExtentEditSession::DoEditSession(TfEditCookie ec) { - com_ptr pInsertAtSelection; - com_ptr pRangeComposition; - ITfRange* pRange; - RECT rc; - BOOL fClipped; - TF_SELECTION selection; - ULONG nSelection; - - if (FAILED(_pContext->QueryInterface(IID_ITfInsertAtSelection, - (LPVOID*)&pInsertAtSelection))) - return E_FAIL; - if (FAILED(_pContext->GetSelection(ec, TF_DEFAULT_SELECTION, 1, &selection, - &nSelection))) - return E_FAIL; + com_ptr pInsertAtSelection; + com_ptr pRangeComposition; + ITfRange* pRange = nullptr; + RECT rc = {0}; + BOOL fClipped = FALSE; + TF_SELECTION selection; + ULONG nSelection = 0; + + // 获取 ITfInsertAtSelection 接口 + if (FAILED(_pContext->QueryInterface(IID_ITfInsertAtSelection, (LPVOID*)&pInsertAtSelection))) { + return E_FAIL; + } - if (_pComposition != nullptr && _pComposition->GetRange(&pRange) == S_OK) { - pRange->Collapse(ec, TF_ANCHOR_START); - } else { - // composition end - // note: selection.range is always an empty range - pRange = selection.range; - } + // 获取当前选择范围 + if (FAILED(_pContext->GetSelection(ec, TF_DEFAULT_SELECTION, 1, &selection, &nSelection))) { + return E_FAIL; + } - return S_OK; + // 获取组合范围或使用选择范围 + if (_pComposition != nullptr && _pComposition->GetRange(&pRange) == S_OK) { + pRange->Collapse(ec, TF_ANCHOR_START); + } else { + // 组合结束,选择范围总是一个空范围 + pRange = selection.range; + } + + // 获取范围的屏幕坐标 + if (SUCCEEDED(_pContextView->GetTextExt(ec, pRange, &rc, &fClipped)) && + (rc.left != 0 || rc.top != 0)) { + + // 检查是否启用了增强位置 + if (_enhancedPosition) { + HWND hwnd = GetForegroundWindow(); + if (hwnd == NULL) { + // 前台窗口无法获取 + return E_FAIL; + } + + // 检查窗口句柄的有效性 + if (!IsWindow(hwnd)) { + return E_FAIL; + } + + RECT rcForegroundWindow = {0}; + if (!::GetWindowRect(hwnd, &rcForegroundWindow)) { + // 无法获取前台窗口的矩形 + return E_FAIL; + } + + // 检查范围是否超出前台窗口边界 + if (rc.left < rcForegroundWindow.left || rc.left > rcForegroundWindow.right || + rc.top < rcForegroundWindow.top || rc.top > rcForegroundWindow.bottom) { + + POINT pt = {0}; + bool hasCaret = ::GetCaretPos(&pt); // 检查光标位置 + int offsetx = rcForegroundWindow.left - rc.left + (hasCaret ? pt.x : 0); + int offsety = rcForegroundWindow.top - rc.top + (hasCaret ? pt.y : 0); + + rc.left += offsetx; + rc.right += offsetx; + rc.top += offsety; + rc.bottom += offsety; + } + } + + // 更新组合位置 + _pTextService->_SetCompositionPosition(rc); + } + + // 释放分配的资源 + if (pRange != nullptr) { + pRange->Release(); + } + + return S_OK; } /* Composition Window Handling */