在 Win 7 中的 RichEdit 控件上找不到 C++ UIA TextPattern,但 C# UIA 确实找到了它
C++ UIA TextPattern is not found on RichEdit control in Win 7, but C# UIA does find it
在带有便捷更新的 Win 7 SP1(最新发布的 Win 7)上,我使用来自 Windows Automation 3.0 的 CUIAutomation
的 C++ 代码无法从内置的 RichEdit 控件中获取 TextPattern-在写字板应用程序中。但是,使用 UIAutomationClient
和 UIAutomationTypes
的等效 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;
}
如果我没记错的话,Win7 本机 UI 自动化提供程序不支持 TextPattern,而托管 UI 自动化提供程序支持。
原生 UI 自动化提供程序直到 Windows 8.
才添加 TextPattern 支持
在带有便捷更新的 Win 7 SP1(最新发布的 Win 7)上,我使用来自 Windows Automation 3.0 的 CUIAutomation
的 C++ 代码无法从内置的 RichEdit 控件中获取 TextPattern-在写字板应用程序中。但是,使用 UIAutomationClient
和 UIAutomationTypes
的等效 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;
}
如果我没记错的话,Win7 本机 UI 自动化提供程序不支持 TextPattern,而托管 UI 自动化提供程序支持。
原生 UI 自动化提供程序直到 Windows 8.
才添加 TextPattern 支持