各位 V 友,最近在用 UI Automation (UIA) 时遇到了一个很奇怪的问题,卡了好几天了。
若方法有效感谢🙏200RMB
目标: 获取记事本( Notepad )编辑框的 TextPattern 。
我用 Accessibility Insights for Windows 去看,明明确确显示记事本的编辑框是支持 TextPattern 的。
我自己的代码,无论用哪种方式,都检测不到 TextPattern 。
我试过的两种方法:
通过 GetFocusedElement 拿到元素,然后 GetCurrentPattern(TextPattern.Pattern),结果是拿不到。
我以为是我的姿势不对,[找到源码]( GitHub - microsoft/accessibility-insights-windows: Accessibility Insights for Windows),引用 Axe.Windows 库,完全模拟 AI 的工作流程,调用 PopulateAllPropertiesWithLiveData() 等方法,结果依然检测不到 TextPattern 。
UIAccess 权限、COM 线程模型( STA )、元素句柄有效性等都检查过了,没问题。其他 Pattern 比如 ValuePattern 是可以正常获取的。
Accessibility Insights 到底用了什么魔法? 为什么它能看到 TextPattern ,而我直接调用 UIA API 或者用它的核心库都复现不了?是不是需要什么特殊的初始化步骤,或者 Windows 对记事本这个“亲儿子”有什么特殊的处理? 有大佬了解其中机制吗?或者有其他调试思路也行。
如果能提供解决方案或关键思路,可有偿指导,感谢!
微信:Delightpl
![]() |
1
dandycheung 5 小时 24 分钟前 via Android
看你这过程,不像是小白啊。你要是能把你说的那个软件自己编译成功,逐步调试的话,会不会好点?还有就是有没可能是人家的 manifest 里向系统申请了什么权限之类的,而你自己的落下了?好久不玩 Windows 编程了, 纯属瞎蒙啊。主要是拒绝 0 回复……
|
2
dereklu4 4 小时 30 分钟前
请问是要这种效果吗
 |
3
dereklu4 4 小时 23 分钟前
@dereklu4 效果的 gif 版: https://imgur.com/a/JGnqc8M
|
5
ck125s OP @dandycheung 好的 谢谢老哥
|
6
dereklu4 4 小时 20 分钟前

|
7
maggch97 1 小时 57 分钟前
![]() 让 AI 写的,好像一次过 ``` #include <iostream> #include <windows.h> #include <comdef.h> #include <UIAutomation.h> #include <atlbase.h> #include <thread> #include <chrono> #pragma comment(lib, "ole32.lib") #pragma comment(lib, "oleaut32.lib") HWND consoleWindow = nullptr; std::wstring lastSelectedText; HRESULT GetTextFromActiveWindow(IUIAutomation* automation, std::wstring& selectedText) { HWND foregroundWindow = GetForegroundWindow(); if (!foregroundWindow || foregroundWindow == consoleWindow) { return E_FAIL; } CComPtr<IUIAutomationElement> windowElement; HRESULT hr = automation->ElementFromHandle(foregroundWindow, &windowElement); if (FAILED(hr) || !windowElement) { return hr; } CComPtr<IUIAutomationTextPattern> textPattern; hr = windowElement->GetCurrentPatternAs(UIA_TextPatternId, IID_PPV_ARGS(&textPattern)); if (FAILED(hr) || !textPattern) { CComPtr<IUIAutomationElement> focusedElement; hr = automation->GetFocusedElement(&focusedElement); if (FAILED(hr) || !focusedElement) { return hr; } hr = focusedElement->GetCurrentPatternAs(UIA_TextPatternId, IID_PPV_ARGS(&textPattern)); if (FAILED(hr) || !textPattern) { return hr; } } CComPtr<IUIAutomationTextRangeArray> textRangeArray; hr = textPattern->GetSelection(&textRangeArray); if (FAILED(hr) || !textRangeArray) { return hr; } int length = 0; hr = textRangeArray->get_Length(&length); if (FAILED(hr) || length == 0) { return hr; } selectedText.clear(); for (int i = 0; i < length; i++) { CComPtr<IUIAutomationTextRange> textRange; hr = textRangeArray->GetElement(i, &textRange); if (SUCCEEDED(hr) && textRange) { BSTR text = nullptr; hr = textRange->GetText(-1, &text); if (SUCCEEDED(hr) && text) { selectedText += text; SysFreeString(text); } } } return S_OK; } void MonitorSelectedText(IUIAutomation* automation) { while (true) { std::wstring currentSelectedText; HRESULT hr = GetTextFromActiveWindow(automation, currentSelectedText); if (SUCCEEDED(hr) && !currentSelectedText.empty() && currentSelectedText != lastSelectedText) { lastSelectedText = currentSelectedText; HWND foregroundWindow = GetForegroundWindow(); wchar_t windowTitle[256]; GetWindowTextW(foregroundWindow, windowTitle, 256); std::wcout << L"\n=== 检测到新的选中文本 ===" << std::endl; std::wcout << L"窗口: " << windowTitle << std::endl; std::wcout << L"选中内容: " << currentSelectedText << std::endl; std::wcout << L"========================\n" << std::endl; } std::this_thread::sleep_for(std::chrono::milliseconds(200)); } } int main() { CoInitializeEx(NULL, COINIT_MULTITHREADED); consoleWindow = GetConsoleWindow(); CComPtr<IUIAutomation> automation; HRESULT hr = CoCreateInstance(CLSID_CUIAutomation, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&automation)); if (FAILED(hr)) { std::wcout << L"无法创建 UI Automation 对象" << std::endl; CoUninitialize(); return -1; } std::wcout << L"文本选择监控程序已启动..." << std::endl; std::wcout << L"程序将在后台监控其他窗口中的文本选择" << std::endl; std::wcout << L"按 Ctrl+C 退出程序\n" << std::endl; std::thread monitorThread(MonitorSelectedText, automation.p); monitorThread.detach(); std::wcin.get(); CoUninitialize(); return 0; } ``` |
8
spritecn 1 小时 42 分钟前
太久不折腾 win 编辑了,记忆中 ahk/au3 带的工具不错
|