如何从另一个应用程序的文本框中获取插入符的位置? (不是坐标,而是文本框内的实际索引)

问题描述 投票:0回答:1

我需要在聚焦窗口的文本框中检索插入符号的索引,如果有的话,可以使用UI Automation或Win32 API函数。我要强调的是,我并不是指x,y坐标,而是指文本框文本内的插入符号的索引。我怎样才能做到这一点?另请参见this类似问题。

c# winapi automation mouseevent
1个回答
0
投票

您可以为此使用UI Automation,尤其是具有IUIAutomationTextPattern2方法的GetCaretRange界面。

这里是示例Consoleapp C ++代码,该代码连续运行并在鼠标下显示当前元素的插入符位置:

int main()
{
    CoInitializeEx(NULL, COINIT_MULTITHREADED);
    {
        CComPtr<IUIAutomation> automation;

        // make sure you use CLSID_CUIAutomation8, *not* CLSID_CUIAutomation
        automation.CoCreateInstance(CLSID_CUIAutomation8);
        do
        {
            POINT pt;
            if (GetCursorPos(&pt))
            {
                CComPtr<IUIAutomationElement> element;
                automation->ElementFromPoint(pt, &element);
                if (element)
                {
                    CComBSTR name;
                    element->get_CurrentName(&name);
                    wprintf(L"Watched element %s\n", name);

                    CComPtr<IUIAutomationTextPattern2> text;
                    HRESULT hr = element->GetCurrentPatternAs(UIA_TextPattern2Id, IID_PPV_ARGS(&text));
                    if (text)
                    {
                        // get document range
                        CComPtr<IUIAutomationTextRange> documentRange;
                        text->get_DocumentRange(&documentRange);

                        // get caret range
                        BOOL active = FALSE;
                        CComPtr<IUIAutomationTextRange> range;
                        text->GetCaretRange(&active, &range);
                        if (range)
                        {
                            // compare caret start with document start
                            int caretPos = 0;
                            range->CompareEndpoints(TextPatternRangeEndpoint_Start, documentRange, TextPatternRangeEndpoint_Start, &caretPos);
                            wprintf(L" caret is at %i\n", caretPos);
                        }
                    }
                }
            }
            Sleep(500);
        } while (TRUE);
    }
    CoUninitialize();
    return 0;
}

技巧是使用IUIAutomationTextRange::CompareEndpoints方法,该方法允许您将插入符号范围与另一个范围(例如整个文档范围)进行比较。

注意有缺点:

  • 某些应用程序根本不支持任何MSAA / UIA自省,或不支持文本模式。对于这些,根本没有解决方案(即使使用Windows API)
  • 某些应用程序错误地报告了插入符号,尤其是当您select文本(移动插入符号)时。例如,使用记事本,在按住SHIFT键的同时向左移动会向后选择,但由于某些原因,UIA不会更新插入符号位置。我认为这是记事本的问题,因为它与IME(输入法编辑器,如表情符号编辑器,您可以使用Win +组合召唤)有关的插入符号有关。例如,写字板没有问题。
© www.soinside.com 2019 - 2024. All rights reserved.