【问题标题】:C++ UIA TextPattern is not found on RichEdit control in Win 7, but C# UIA does find it在 Win 7 的 RichEdit 控件上找不到 C++ UIA TextPattern,但 C# UIA 确实找到了
【发布时间】:2021-03-27 17:50:05
【问题描述】:

在带有便捷更新的 Win 7 SP1(已发布的最新 Win 7)上,我使用 Windows 自动化 3.0 中的CUIAutomation 的 C++ 代码无法从内置写字板应用程序中的 RichEdit 控件获取 TextPattern。但是,使用 UIAutomationClientUIAutomationTypes 的等效 C# 代码可以。

在 Win 10 上取得更好的成功:C++ 代码和 C# 代码都成功获得了 TextPattern。

我的主项目与另一个 C# UIA 应用程序存在兼容性问题,当我在 Win 10 上使用 C++ 代码时,该问题就消失了。所以我真的很想在 Win 7 上使用 C++ 代码。有谁知道为什么 C++ 代码失败以及如何修复它?我很惊讶从内置的 RichEdit 控件中获取一个简单的 TextPattern 并不能可靠地工作!

这是 C# 代码(更容易阅读!),然后是 C++ 代码:

using System;
using System.Threading;
using System.Windows.Automation;

namespace UIAutomationNET
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Getting element at cursor in 3 seconds...");
            Thread.Sleep(3000);

            var element = AutomationElement.FocusedElement;

            if (element != null)
            {
                var textPatternElement = element.FindFirst(
                    TreeScope.Subtree,
                    new PropertyCondition(AutomationElement.IsTextPatternAvailableProperty, true));

                if (textPatternElement == null)
                    Console.WriteLine("No element supporting TextPattern found.");
                else
                    Console.WriteLine("TextPattern is supported!  :-)");
            }
        }
    }
}

以下C++代码基于this MSDN Code Gallery sample

#include <windows.h>
#include <ole2.h>
#include <uiautomation.h>
#include <strsafe.h>

IUIAutomation *_automation;


int _cdecl wmain(_In_ int argc, _In_reads_(argc) WCHAR* argv[])
{
    UNREFERENCED_PARAMETER(argc);
    UNREFERENCED_PARAMETER(argv);

    // Initialize COM before using UI Automation
    HRESULT hr = CoInitialize(NULL);
    if (FAILED(hr))
    {
        wprintf(L"CoInitialize failed, HR:0x%08x\n", hr);
    }
    else
    {
        // Use CUIAutomation instead of CUIAutomation8 on Win 7
        hr = CoCreateInstance(__uuidof(CUIAutomation), NULL,
            CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&_automation));
        if (FAILED(hr))
        {
            wprintf(L"Failed to create a CUIAutomation, HR: 0x%08x\n", hr);
        }
        else
        {
            IUIAutomationElement *element = NULL;
            wprintf( L"Getting element at cursor in 3 seconds...\n" );
            Sleep(3000);

            POINT pt;
            GetCursorPos(&pt);
            hr = _automation->ElementFromPoint(pt, &element);
            if (FAILED(hr))
            {
                wprintf( L"Failed to ElementFromPoint, HR: 0x%08x\n\n", hr );
            }

            if (SUCCEEDED(hr) && element != NULL)
            {
                IUIAutomationElement *textElement = NULL;

                // Create a condition that will be true for anything that supports Text Pattern
                // Use UIA_IsTextPatternAvailablePropertyId instead of UIA_IsTextPattern2AvailablePropertyId on Win 7
                IUIAutomationCondition* textPatternCondition;
                VARIANT trueVar;
                trueVar.vt = VT_BOOL;
                trueVar.boolVal = VARIANT_TRUE;
                hr = _automation->CreatePropertyCondition(UIA_IsTextPatternAvailablePropertyId, trueVar, &textPatternCondition);

                if (FAILED(hr))
                {
                    wprintf(L"Failed to CreatePropertyCondition, HR: 0x%08x\n", hr);
                }
                else
                {
                    // Actually do the search
                    hr = element->FindFirst(TreeScope_Subtree, textPatternCondition, &textElement);
                    if (FAILED(hr))
                    {
                        wprintf(L"FindFirst failed, HR: 0x%08x\n", hr);
                    }
                    else if (textElement == NULL)
                    {
                        wprintf(L"No element supporting TextPattern found.\n");
                        hr = E_FAIL;
                    }
                    else
                    {
                        wprintf(L"TextPattern is supported!  :-)\n");
                    }
                    textPatternCondition->Release();
                }
            }
            _automation->Release();
        }
        CoUninitialize();
    }

    return 0;
}

【问题讨论】:

    标签: c# visual-c++ ui-automation microsoft-ui-automation


    【解决方案1】:

    如果我没记错的话,Win7 原生 UI 自动化提供程序不支持 TextPattern,而托管 UI 自动化提供程序支持。

    原生 UI 自动化提供程序直到 Windows 8 才添加 TextPattern 支持。

    【讨论】:

    • 是的,在 Win 7 中,对 TextPattern 的 RichEdit 支持仅在托管客户端提供程序中提供。这导致了很多头发拉扯。
    猜你喜欢
    • 1970-01-01
    • 2013-03-16
    • 1970-01-01
    • 1970-01-01
    • 2011-08-05
    • 1970-01-01
    • 2016-05-14
    • 1970-01-01
    • 2017-04-02
    相关资源
    最近更新 更多