【发布时间】:2020-04-29 19:49:27
【问题描述】:
有一个窗口,我想使用 WinAPI 调用从中读取特定文本(下面的屏幕截图中的10.024)。
这是这个窗口在 Spy++ 中的样子:
要从该标签中读取值,我首先确定窗口的句柄:
private TargetWindowInfo FindScrivenerWindow()
{
IntPtr targetWindowHandle = new IntPtr(0);
String windowTitle = "";
Process[] scrivenerProcesses = Process.GetProcessesByName("scrivener");
if (scrivenerProcesses.Length < 1)
{
return null; // Scrivener is not started
}
foreach (var handle in EnumerateProcessWindowHandles(scrivenerProcesses.First().Id))
{
StringBuilder message = new StringBuilder(1000);
SendMessage(handle, WM_GETTEXT, message.Capacity, message);
String curWindowTitle = message.ToString();
if (curWindowTitle.EndsWith("Project Targets"))
{
bool windowVisible = IsWindowVisible(handle);
if (windowVisible)
{
windowTitle = curWindowTitle;
targetWindowHandle = handle;
var result = new TargetWindowInfo();
result.ProjectName = windowTitle.Substring(0, windowTitle.IndexOf(" Project Targets"));
result.Handle = handle;
return result;
}
}
}
return null;
}
var targetWindowInfo = FindScrivenerWindow();
然后我尝试应用this answer 来读取窗口中的所有字符串,并希望在其中找到所需的字符串(10.024)(targetWindowInfo.Handle 是FindScrivenerWindow 的结果):
List<WinText> windows = new List<WinText>();
//find the "first" window
IntPtr hWnd = targetWindowInfo.Handle;
while (hWnd != IntPtr.Zero)
{
//find the control window that has the text
IntPtr hEdit = FindWindowEx(hWnd, IntPtr.Zero, null, null);
//initialize the buffer. using a StringBuilder here
System.Text.StringBuilder sb = new System.Text.StringBuilder(255); // or length from call with GETTEXTLENGTH
//get the text from the child control
int RetVal = SendMessage(hEdit, WM_GETTEXT, sb.Capacity, sb);
windows.Add(new WinText() { hWnd = hWnd, Text = sb.ToString() });
//find the next window
hWnd = FindWindowEx(IntPtr.Zero, hWnd, "scrivener", null);
}
//do something clever
windows.OrderBy(x => x.Text).ToList().ForEach(y => Console.Write("{0} = {1}\n", y.hWnd, y.Text));
Console.Write("\n\nFound {0} window(s).", windows.Count);
windows 始终只有一个元素,文本为空字符串。
如何读取标签的值?考虑到窗口的属性,是否有可能?
更新 1: UI Automation Inspect 报告标签的以下值:
How found: Selected from tree...
Name: ""
BoundingRectangle: {l:1437 t:455 r:1484 b:475}
IsEnabled: true
IsOffscreen: false
IsKeyboardFocusable: false
HasKeyboardFocus: false
AccessKey: ""
ProcessId: 6488
ProviderDescription: "[pid:6488,providerId:0x0 Main(parent link):Microsoft: MSAA Proxy (unmanaged:uiautomationcore.dll)]"
IsPassword: false
HelpText: ""
IsDialog: false
LegacyIAccessible.ChildId: 0
LegacyIAccessible.DefaultAction: "SetFocus"
LegacyIAccessible.Description: ""
LegacyIAccessible.Help: ""
LegacyIAccessible.KeyboardShortcut: ""
LegacyIAccessible.Name: ""
LegacyIAccessible.Role: Client (0xA)
LegacyIAccessible.State: normal (0x0)
LegacyIAccessible.Value: ""
IsAnnotationPatternAvailable: false
IsDragPatternAvailable: false
IsDockPatternAvailable: false
IsDropTargetPatternAvailable: false
IsExpandCollapsePatternAvailable: false
IsGridItemPatternAvailable: false
IsGridPatternAvailable: false
IsInvokePatternAvailable: false
IsItemContainerPatternAvailable: false
IsLegacyIAccessiblePatternAvailable: true
IsMultipleViewPatternAvailable: false
IsObjectModelPatternAvailable: false
IsRangeValuePatternAvailable: false
IsScrollItemPatternAvailable: false
IsScrollPatternAvailable: false
IsSelectionItemPatternAvailable: false
IsSelectionPatternAvailable: false
IsSpreadsheetItemPatternAvailable: false
IsSpreadsheetPatternAvailable: false
IsStylesPatternAvailable: false
IsSynchronizedInputPatternAvailable: false
IsTableItemPatternAvailable: false
IsTablePatternAvailable: false
IsTextChildPatternAvailable: false
IsTextEditPatternAvailable: false
IsTextPatternAvailable: false
IsTextPattern2Available: false
IsTogglePatternAvailable: false
IsTransformPatternAvailable: false
IsTransform2PatternAvailable: false
IsValuePatternAvailable: false
IsVirtualizedItemPatternAvailable: false
IsWindowPatternAvailable: false
IsCustomNavigationPatternAvailable: false
IsSelectionPattern2Available: false
FirstChild: [null]
LastChild: [null]
Next: ""
Previous: ""
Other Props: Object has no additional properties
Children: Container has no children
Ancestors: "short-story-4 Project Targets" Fenster
"short-story-4 - Scrivener" Fenster
"Desktop 1" Bereich
[ No Parent ]
【问题讨论】:
-
如果不回避UI Automation,您会看到更少的惊喜。使用 Inspect.exe 工具快速验证目标窗口是否合适。
-
@IInspectable 我从 Inspect.exe 粘贴了这个特定控件的值。是否可以使用通常的 WinAPI/UIAutomation 方法从该标签中提取文本?
-
您的第一个 Spy++ 屏幕截图显示“short-story-4 Project Targets”窗口没有任何子窗口,这意味着它正在使用无窗口控件(即,它们是直接自定义绘制的到父对话框窗口上),在这种情况下 UIAutomation 是远程访问它们的唯一方法,如果 UI 框架甚至实现了对它的支持(
Inspect.exe似乎说不是这种情况)。QTool和QWidget表明 Qt 是使用的 UI 框架,它确实可以选择使用无窗口控件 (doc.qt.io/qt-5/qwidget.html#native-widgets-vs-alien-widgets) -
@RemyLebeau 谢谢。如果您提交您的评论作为答案,我会接受。
-
@DmitriiPisarenko 随时回答你自己,Accept Your Own Answers 结束这个话题。