win_wrap/uia/pattern/container.rs
1/*
2 * Copyright (c) 2024. The RigelA open source project team and
3 * its contributors reserve all rights.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software distributed under the
10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 * See the License for the specific language governing permissions and limitations under the License.
12 */
13
14use std::{
15 fmt::{Debug, Formatter},
16 sync::Weak,
17};
18
19use crate::uia::{
20 element::UiAutomationElement,
21 pattern::{PatternCreatorWithAutomation, PatternError},
22 property::UiaPropertyId,
23};
24use windows::Win32::{
25 System::Variant::VARIANT,
26 UI::Accessibility::{
27 IUIAutomation6, IUIAutomationItemContainerPattern, UIA_ItemContainerPatternId,
28 UIA_PATTERN_ID,
29 },
30};
31
32/**
33公开从容器(如虚拟列表)检索项的方法。
34此接口不限于虚拟化容器使用。任何可以实现高效名称查找的容器都可以支持此控件模式,使客户端能够比使用find_first等方法更快地查找名称,后者必须遍历Microsoft UI自动化树。
35*/
36pub struct UiAutomationItemContainerPattern(
37 Weak<IUIAutomation6>,
38 IUIAutomationItemContainerPattern,
39);
40
41impl TryFrom<(IUIAutomationItemContainerPattern, Weak<IUIAutomation6>)>
42 for UiAutomationItemContainerPattern
43{
44 type Error = PatternError;
45
46 fn try_from(
47 value: (IUIAutomationItemContainerPattern, Weak<IUIAutomation6>),
48 ) -> Result<Self, Self::Error> {
49 Ok(Self(value.1, value.0))
50 }
51}
52
53impl PatternCreatorWithAutomation<IUIAutomationItemContainerPattern>
54 for UiAutomationItemContainerPattern
55{
56 const PATTERN: UIA_PATTERN_ID = UIA_ItemContainerPatternId;
57}
58
59//noinspection SpellCheckingInspection
60/// <https://learn.microsoft.com/en-us/windows/win32/api/uiautomationclient/nn-uiautomationclient-iuiautomationitemcontainerpattern>
61impl UiAutomationItemContainerPattern {
62 /*
63 根据指定的属性值检索包含元素中的元素。
64 如果匹配元素被虚拟化,则提供程序可以返回实际的UiAutomationElement接口或占位符。
65 如果请求的属性不是容器支持搜索的属性,则此方法返回E_INVALIDARG。预计大多数容器都将支持Name属性,如果适用于容器,则支持AutomationId和IsSelected。
66 此方法可能很慢,因为它可能需要遍历多个对象才能找到匹配的对象。当在循环中用于返回多个项目时,只要每个项目只返回一次(即循环应终止),就不会定义特定的顺序。此方法也是以项目为中心,而不是以 UI 为中心,因此具有多个 UI 表示形式的项目只需点击一次。
67 当 property_id 参数指定为 0(零)时,提供程序应返回 start_after 之后的下一项。如果将 start_after 指定为 None 且 property_id 为 0,则提供程序应返回容器中的第一项。当 property_id 指定为 0 时,value 参数应为 VT_EMPTY。
68 `start_after` 指向搜索开始的元素,或None搜索所有元素。
69 `property_id` 属性标识符。有关属性 ID 的列表,请参阅属性标识符。
70 `value` 属性值。
71 */
72 pub fn find_item_by_property<T>(
73 &self,
74 start_after: Option<&UiAutomationElement>,
75 property_id: UiaPropertyId,
76 value: T,
77 ) -> Option<UiAutomationElement>
78 where
79 VARIANT: From<T>,
80 {
81 unsafe {
82 let Ok(r) = (match start_after {
83 None => self.1.FindItemByProperty(
84 None,
85 property_id.into(),
86 &VARIANT::try_from(value).unwrap(),
87 ),
88 Some(x) => self.1.FindItemByProperty(
89 x.get_raw(),
90 property_id.into(),
91 &VARIANT::try_from(value).unwrap(),
92 ),
93 }) else {
94 return None;
95 };
96 Some(UiAutomationElement::obtain(self.0.clone(), r))
97 }
98 }
99}
100
101impl Debug for UiAutomationItemContainerPattern {
102 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
103 write!(f, "UiAutomationItemContainerPattern()")
104 }
105}