锐英源软件
第一信赖

精通

英语

开源

擅长

开发

培训

胸怀四海 

第一信赖

当前位置:锐英源 / 开源技术 / C++平台框架库和混编开源 / TSF输入法开发候选窗口显示位置
服务方向
人工智能数据处理
人工智能培训
kaldi数据准备
小语种语音识别
语音识别标注
语音识别系统
语音识别转文字
kaldi开发技术服务
软件开发
运动控制卡上位机
机械加工软件
软件开发培训
Java 安卓移动开发
VC++
C#软件
汇编和破解
驱动开发
联系方式
固话:0371-63888850
手机:138-0381-0136
Q Q:396806883
微信:ryysoft

TSF输入法开发候选窗口显示位置


_GetTextExt(_Out_ RECT *lpRect)

{

    HRESULT hr = S_OK;
    BOOL isClipped = TRUE;
    CComPtr<ITfContextView> pContextView = nullptr;

    hr = _pContextDocument->GetActiveView(&pContextView);
    if (FAILED(hr))
    {
log_error("get active view failed!");
        return hr;
    }

    if (FAILED(hr = pContextView->GetTextExt(_tfEditCookie, _pRangeComposition, lpRect, &isClipped)))
    {
log_error("get text ext failed!");
        return hr;
    }

}

I used the function as above. In most apps it works ok.

but when I use use it in wps(a applicaions developed with QT) it can't get the right position to show candidate window.

I tried it in some other applicaions develope with QT(like QtCreator), it also can't get the right position.

how could I fix this problem.我使用了上面的功能。在大多数应用程序中都可以。

但是当我在wps(使用QT开发的应用程序)中使用它时,它无法获得显示候选窗口的正确位置。

我在用QT开发的其他一些应用程序中尝试过(例如QtCreator),但它也找不到正确的位置。

我该如何解决这个问题。

In order to help you solve the problem faster, please answer the following questions:

  • What the return value of GetTextExt?
  •  it can't get the right position to show candidate window.

       Do you mean it return the wrong position or return NULL?

  • Can you provide a Minimal, Reproducible Example?  

    为了帮助您更快地解决问题,请回答以下问题:

    • GetTextExt的返回值是  多少?
    •  它找不到显示候选窗口的正确位置。

           您是说它返回错误的位置还是返回NULL?

    • 您能否提供一个最小的,可复制的示例?  


It just return a wrong value.And the value never change even I have changed the insert position.

And I have resovled this issue by following code.它只是返回一个错误的值,即使我更改了插入位置,该值也不会改变。

我通过以下代码解决了这个问题。

HRESULT ShadowTSF::_AddComposingAndChar(TfEditCookie ec, _In_ ITfContext *pContext, _In_ const wstring& addString)
{
log_trace("cookie=%x, str=%s", ec, Utils::ToMultiByte(addString).c_str());
HRESULT hr = S_OK;

ULONG fetched = 0;
TF_SELECTION tfSelection;

if (pContext->GetSelection(ec, TF_DEFAULT_SELECTION, 1, &tfSelection, &fetched) != S_OK || fetched == 0)
return S_FALSE;

//
// make range start to selection
//
    ITfRange* pAheadSelection = nullptr;
   // hr = pContext->GetStart(ec, &pAheadSelection);
   // if (SUCCEEDED(hr))
   // {
   //     hr = pAheadSelection->ShiftEndToRange(ec, tfSelection.range, TF_ANCHOR_START);
   //     if (SUCCEEDED(hr))
   //     {
   //         ITfRange* pRange = nullptr;
   //         BOOL exist_composing = _FindComposingRange(ec, pContext, pAheadSelection, &pRange);
//log_trace("set input string ...");
   //         _SetInputString(ec, pContext, pRange, addString, exist_composing);
//log_trace("set input string completed!");

   //         if (pRange)
   //         {
   //             pRange->Release();
   //         }
   //     }
   // }
if (FAILED(_pComposition->GetRange(&pAheadSelection)))
return E_FAIL;
if (FAILED(pAheadSelection->SetText(ec, 0, addString.c_str(), (LONG)addString.length())))
return E_FAIL;

pAheadSelection->Collapse(ec, TF_ANCHOR_END);
tfSelection.range = pAheadSelection;
tfSelection.style.ase = TF_AE_NONE;
tfSelection.style.fInterimChar = FALSE;

_pContext->SetSelection(ec, 1, &tfSelection);

tfSelection.range->Release();

if (pAheadSelection)
{
pAheadSelection->Release();
}

return S_OK;
}

STDAPI CStartCompositionEditSession::DoEditSession(TfEditCookie ec)
{
    ITfInsertAtSelection* pInsertAtSelection = nullptr;
    ITfRange* pRangeInsert = nullptr;
    ITfContextComposition* pContextComposition = nullptr;
    ITfComposition* pComposition = nullptr;

    if (FAILED(_pContext->QueryInterface(IID_ITfInsertAtSelection, (void **)&pInsertAtSelection)))
    {
        goto Exit;
    }

    if (FAILED(pInsertAtSelection->InsertTextAtSelection(ec, TF_IAS_QUERYONLY, NULL, 0, &pRangeInsert)))
    {
        goto Exit;
    }

    if (FAILED(_pContext->QueryInterface(IID_ITfContextComposition, (void **)&pContextComposition)))
    {
        goto Exit;
    }

    if (SUCCEEDED(pContextComposition->StartComposition(ec, pRangeInsert, _pTextService, &pComposition)) && (nullptr != pComposition))
    {
        _pTextService->_SetComposition(pComposition);

// set selection to the adjusted range
pRangeInsert->SetText(ec, TF_ST_CORRECTION, L" ", 1);  // I added this line 
pRangeInsert->Collapse(ec, TF_ANCHOR_START);             //  I added this line
        // set selection to the adjusted range
        TF_SELECTION tfSelection;
        tfSelection.range = pRangeInsert;
        tfSelection.style.ase = TF_AE_NONE;
        tfSelection.style.fInterimChar = FALSE;

        _pContext->SetSelection(ec, 1, &tfSelection);
        _pTextService->_SaveCompositionContext(_pContext);
log_info("start composition succeed!");
    }

Exit:
    if (nullptr != pContextComposition)
    {
        pContextComposition->Release();
    }

    if (nullptr != pRangeInsert)
    {
        pRangeInsert->Release();
    }

    if (nullptr != pInsertAtSelection)
    {
        pInsertAtSelection->Release();
    }

    return S_OK;
}

Firstly, I wrote my code directed by SampleIME. but, It got this issue.

I modified my code like above(I have singed a line under the code). It works well now.

What I think is that could someone modify the SampleIME example. so that others will not get this issue again.

首先,我编写了由SampleIME指导的代码。但是,它遇到了这个问题。

我像上面那样修改了我的代码(我在代码下写了一行)。现在效果很好。

我认为这可能有人修改SampleIME示例。这样其他人就不会再遇到这个问题了。

感谢您的回答。

这是少有的关于TSF的好资料,大家认真关注。

友情链接
版权所有 Copyright(c)2004-2021 锐英源软件
公司注册号:410105000449586 豫ICP备08007559号 最佳分辨率 1024*768
地址:郑州大学北校区院(文化路97号院)内