win_wrap/uia/pattern/
table.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/*
 * Copyright (c) 2024. The RigelA open source project team and
 * its contributors reserve all rights.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software distributed under the
 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and limitations under the License.
 */

use std::{
    fmt::{Debug, Formatter},
    sync::Weak,
};

use crate::{
    ext::VecExt,
    uia::{
        element::UiAutomationElement,
        pattern::{PatternCreatorWithAutomation, PatternError},
    },
};
use windows::Win32::UI::Accessibility::{
    IUIAutomation6, IUIAutomationTableItemPattern, IUIAutomationTablePattern,
    RowOrColumnMajor_ColumnMajor, RowOrColumnMajor_Indeterminate, RowOrColumnMajor_RowMajor,
    UIA_TableItemPatternId, UIA_TablePatternId, UIA_PATTERN_ID,
};

/**
提供对控件的访问,该控件充当子元素集合的容器。此元素的子元素支持 UiAutomationTableItemPattern,并按行和列遍历的二维逻辑坐标系进行组织。
*/
pub struct UiAutomationTablePattern(IUIAutomationTablePattern, Weak<IUIAutomation6>);

impl TryFrom<(IUIAutomationTablePattern, Weak<IUIAutomation6>)> for UiAutomationTablePattern {
    type Error = PatternError;

    fn try_from(
        value: (IUIAutomationTablePattern, Weak<IUIAutomation6>),
    ) -> Result<Self, Self::Error> {
        Ok(Self(value.0, value.1))
    }
}

impl PatternCreatorWithAutomation<IUIAutomationTablePattern> for UiAutomationTablePattern {
    const PATTERN: UIA_PATTERN_ID = UIA_TablePatternId;
}

/// <https://learn.microsoft.com/en-us/windows/win32/api/uiautomationclient/nn-uiautomationclient-iuiautomationtablepattern>
impl UiAutomationTablePattern {
    /**
    查询表的主要遍历方向。此属性是只读的。
    */
    #[allow(non_upper_case_globals)]
    pub fn row_or_column_major(&self) -> RowOrColumnMajor {
        unsafe {
            match self.0.CurrentRowOrColumnMajor() {
                Ok(x) => match x {
                    RowOrColumnMajor_ColumnMajor => RowOrColumnMajor::Column,
                    RowOrColumnMajor_Indeterminate => RowOrColumnMajor::Indeterminate,
                    RowOrColumnMajor_RowMajor => RowOrColumnMajor::Row,
                    _ => RowOrColumnMajor::None,
                },
                Err(_) => RowOrColumnMajor::None,
            }
        }
    }

    /**
    查询表示表中所有列标题的 UI 自动化元素的集合。
    */
    pub fn column_headers(&self) -> Vec<UiAutomationElement> {
        unsafe {
            match self.0.GetCurrentColumnHeaders() {
                Ok(x) => x
                    .to_vec()
                    .iter()
                    .map(|x| UiAutomationElement::obtain(self.1.clone(), x.clone()))
                    .collect(),
                Err(_) => vec![],
            }
        }
    }
}

pub enum RowOrColumnMajor {
    Row,
    Column,
    Indeterminate,
    None,
}

/// 提供对支持 UiAutomationTablePattern 的容器中的子元素的访问。
/// 支持此接口的元素还必须支持 UiAutomationGridItemPattern,以提供不特定于表的属性。
pub struct UiAutomationTableItemPattern(Weak<IUIAutomation6>, IUIAutomationTableItemPattern);

impl TryFrom<(IUIAutomationTableItemPattern, Weak<IUIAutomation6>)>
    for UiAutomationTableItemPattern
{
    type Error = PatternError;

    fn try_from(
        value: (IUIAutomationTableItemPattern, Weak<IUIAutomation6>),
    ) -> Result<Self, Self::Error> {
        Ok(Self(value.1, value.0))
    }
}

impl PatternCreatorWithAutomation<IUIAutomationTableItemPattern> for UiAutomationTableItemPattern {
    const PATTERN: UIA_PATTERN_ID = UIA_TableItemPatternId;
}

/// <https://learn.microsoft.com/en-us/windows/win32/api/uiautomationclient/nn-uiautomationclient-iuiautomationtableitempattern>
impl UiAutomationTableItemPattern {
    /**
    查询与表项或单元格关联的列标题。
    */
    pub fn get_column_header_items(&self) -> Option<Vec<UiAutomationElement>> {
        unsafe {
            if let Ok(arr) = self.1.GetCurrentColumnHeaderItems() {
                return Some(
                    arr.to_vec()
                        .iter()
                        .map(|i| UiAutomationElement::obtain(self.0.clone(), i.clone()))
                        .collect(),
                );
            }
            None
        }
    }

    /**
    查询与表项或单元格关联的行标题。
    */
    pub fn get_row_header_items(&self) -> Option<Vec<UiAutomationElement>> {
        unsafe {
            if let Ok(arr) = self.1.GetCurrentRowHeaderItems() {
                return Some(
                    arr.to_vec()
                        .iter()
                        .map(|i| UiAutomationElement::obtain(self.0.clone(), i.clone()))
                        .collect(),
                );
            }
            None
        }
    }
}

impl Debug for UiAutomationTableItemPattern {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        write!(f, "UiAutomationTableItemPattern()")
    }
}