Windows UI自动化无法识别按钮控件 [英] Windows UI Automation doesn't recognize button controls
问题描述
尝试通过 Windows UI Automation 识别 Notification Area 窗口内的按钮控件时遇到问题(类名: ToolbarWindow32 ):
I'm having problems trying to identify via Windows UI Automation the button controls that are inside the Notification Area window (classname: ToolbarWindow32):
我通过部署在 Windows SDK 中的 Windows UI自动化工具验证了这些图标"是 ControlType.Button
类型的控件,但是,当我尝试运行下面的代码时,我得到了空引用异常,因为我使用的搜索条件无法获得任何控制.
I verified via the Windows UI Automation tools deployed in the Windows SDK that those "icons" are controls of type ControlType.Button
, however when I try to run the code below I get a null-reference exception because the search condition I use doesn't get any control.
我做错了什么,或者我在 Windows UI Automation 中发现了某种限制?
I'm doing something wrong, or maybe I found some kind of limitation in Windows UI Automation ?
这是代码,我将其与WinAPI调用混合在一起,以方便可能喜欢使用该方法的帮助用户.
This is the code, I mixed it with WinAPI calls just to facilitate the task for the helper users who maybe preffers to use that methodology.
Dim tskBarClassName As String = "Shell_TrayWnd"
Dim tskBarHwnd As IntPtr = NativeMethods.FindWindow(tskBarClassName, Nothing)
Dim systrayBarClassName As String = "TrayNotifyWnd"
Dim systrayBarHwnd As IntPtr = NativeMethods.FindWindowEx(tskBarHwnd, IntPtr.Zero, systrayBarClassName, Nothing)
Dim ntfyBarClassName As String = "ToolbarWindow32"
Dim ntfyBarHwnd As IntPtr = NativeMethods.FindWindowEx(systrayBarHwnd, IntPtr.Zero, ntfyBarClassName, Nothing)
Dim window As AutomationElement = AutomationElement.FromHandle(ntfyBarHwnd)
Dim condition As New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button)
Dim button As AutomationElement = window.FindFirst(TreeScope.Descendants, condition)
MsgBox(button.Current.Name) ' Here throws the null-reference exception.
有什么解决办法吗?
推荐答案
我通过Windows SDK中部署的Windows UI自动化工具验证了那些图标"是ControlType.Button类型的控件
I verified via the Windows UI Automation tools deployed in the Windows SDK that those "icons" are controls of type ControlType.Button
您是正确的 一些 .从技术上讲,它们不在ToolbarWindow32中,而在Shell_TrayWnd 中.我检查了该区域,发现这些按钮实际上在 ToolBar
中,因此您需要查找 ControlType.ToolBar
.接下来,您需要 FindAll
,它将返回满足 PropertyCondition
...
You are correct somewhat. Technically they are not in ToolbarWindow32, rather Shell_TrayWnd. I inspected the area and found out, those buttons are actually in a ToolBar
, so you need to look for the ControlType.ToolBar
. Next you need to FindAll
which will return all AutomationElements that would satisfy the PropertyCondition
...
注意:第一个循环是获取用户升级通知区域".下一个有趣的循环是获取正在运行的应用程序"按钮...(代码正在WIN7,WIN8和WIN10上运行)
在下面的示例中,我遵循了 Shell_TrayWnd
,它将为我们提供所需的东西.然后我遍历一下,找到我们要使用的 ToolBar
,然后循环遍历 Button
...
Here in my example below, I go after the Shell_TrayWnd
which will get us what we would need. Then I go through and find what ToolBar
we are after, then loop through and FindAll
ControlTypes of Button
...
Dim arrText As New List(Of String)
Dim tskBarClassName As String = "Shell_TrayWnd"
Dim tskBarHwnd As IntPtr = FindWindow(tskBarClassName, Nothing)
Dim window As AutomationElement = AutomationElement.FromHandle(tskBarHwnd)
Dim condition As New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.ToolBar)
Dim elementCollection As AutomationElementCollection = window.FindAll(TreeScope.Descendants, condition)
'for fun get all we can...
For Each aE As AutomationElement In elementCollection
If aE.Current.Name.Equals("User Promoted Notification Area") Then
For Each ui As AutomationElement In aE.FindAll(TreeScope.Descendants, New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button))
arrText.Add("Notification Area - " & Replace(ui.Current.HelpText, Chr(10), " "c)) 'removed line break as when shown it would show some on a new line in messagebox
Next
ElseIf aE.Current.Name.Equals("Running applications") Then
For Each ui As AutomationElement In aE.FindAll(TreeScope.Descendants, New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button))
arrText.Add("Toolbar Area - " & Replace(ui.Current.Name, Chr(10), " "c)) 'removed line break as when shown it would show some on a new line in messagebox
Next
End If
Next
If arrText.Count > 0 Then
MessageBox.Show(String.Join(Environment.NewLine, arrText.ToArray))
End If
如果您有任何疑问,请告诉我.下图(出于安全原因我将某些内容注释掉了)
If you have any questions, please let me know. Image below (some things I commented out for secure reasons)
这篇关于Windows UI自动化无法识别按钮控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!