win_wrap/
msaa.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
14pub mod event;
15pub mod object;
16
17use crate::{
18    common::{attach_thread_input, get_desktop_window, get_foreground_window, Result},
19    input::get_focus,
20    msaa::{
21        event::{WinEventHook, WinEventSource},
22        object::AccessibleObject,
23    },
24    threading::{get_current_thread_id, get_window_thread_process_id},
25};
26use std::sync::RwLock;
27use windows::Win32::UI::WindowsAndMessaging::{
28    EVENT_OBJECT_ACCELERATORCHANGE, EVENT_OBJECT_CLOAKED, EVENT_OBJECT_CONTENTSCROLLED,
29    EVENT_OBJECT_CREATE, EVENT_OBJECT_DEFACTIONCHANGE, EVENT_OBJECT_DESCRIPTIONCHANGE,
30    EVENT_OBJECT_DESTROY, EVENT_OBJECT_DRAGCANCEL, EVENT_OBJECT_DRAGCOMPLETE,
31    EVENT_OBJECT_DRAGDROPPED, EVENT_OBJECT_DRAGENTER, EVENT_OBJECT_DRAGLEAVE,
32    EVENT_OBJECT_DRAGSTART, EVENT_OBJECT_END, EVENT_OBJECT_FOCUS, EVENT_OBJECT_HELPCHANGE,
33    EVENT_OBJECT_HIDE, EVENT_OBJECT_HOSTEDOBJECTSINVALIDATED, EVENT_OBJECT_IME_CHANGE,
34    EVENT_OBJECT_IME_HIDE, EVENT_OBJECT_IME_SHOW, EVENT_OBJECT_INVOKED,
35    EVENT_OBJECT_LIVEREGIONCHANGED, EVENT_OBJECT_LOCATIONCHANGE, EVENT_OBJECT_NAMECHANGE,
36    EVENT_OBJECT_PARENTCHANGE, EVENT_OBJECT_REORDER, EVENT_OBJECT_SELECTION,
37    EVENT_OBJECT_SELECTIONADD, EVENT_OBJECT_SELECTIONREMOVE, EVENT_OBJECT_SELECTIONWITHIN,
38    EVENT_OBJECT_SHOW, EVENT_OBJECT_STATECHANGE, EVENT_OBJECT_TEXTEDIT_CONVERSIONTARGETCHANGED,
39    EVENT_OBJECT_TEXTSELECTIONCHANGED, EVENT_OBJECT_UNCLOAKED, EVENT_OBJECT_VALUECHANGE,
40    EVENT_OEM_DEFINED_END, EVENT_OEM_DEFINED_START, EVENT_SYSTEM_ALERT,
41    EVENT_SYSTEM_ARRANGMENTPREVIEW, EVENT_SYSTEM_CAPTUREEND, EVENT_SYSTEM_CAPTURESTART,
42    EVENT_SYSTEM_CONTEXTHELPEND, EVENT_SYSTEM_CONTEXTHELPSTART, EVENT_SYSTEM_DESKTOPSWITCH,
43    EVENT_SYSTEM_DIALOGEND, EVENT_SYSTEM_DIALOGSTART, EVENT_SYSTEM_DRAGDROPEND,
44    EVENT_SYSTEM_DRAGDROPSTART, EVENT_SYSTEM_END, EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_MENUEND,
45    EVENT_SYSTEM_MENUPOPUPEND, EVENT_SYSTEM_MENUPOPUPSTART, EVENT_SYSTEM_MENUSTART,
46    EVENT_SYSTEM_MINIMIZEEND, EVENT_SYSTEM_MINIMIZESTART, EVENT_SYSTEM_MOVESIZEEND,
47    EVENT_SYSTEM_MOVESIZESTART, EVENT_SYSTEM_SCROLLINGEND, EVENT_SYSTEM_SCROLLINGSTART,
48    EVENT_SYSTEM_SOUND, EVENT_SYSTEM_SWITCHEND, EVENT_SYSTEM_SWITCHSTART,
49};
50
51#[derive(Debug)]
52pub struct Msaa {
53    events: RwLock<Vec<WinEventHook>>,
54}
55
56impl Msaa {
57    /**
58    创建一个MSAA实例。
59    */
60    pub fn new() -> Self {
61        Self {
62            events: vec![].into(),
63        }
64    }
65
66    /**
67    获取桌面窗口的可访问性对象。
68    */
69    pub fn get_desktop_object(&self) -> Result<AccessibleObject> {
70        AccessibleObject::from_window(get_desktop_window())
71    }
72
73    /**
74    获取输入焦点的可访问性对象。
75    */
76    pub fn get_focus_object(&self) -> Result<AccessibleObject> {
77        let current_thread_id = get_current_thread_id();
78        let h_foreground = get_foreground_window();
79        let (remote_thread_id, _) = get_window_thread_process_id(h_foreground);
80        attach_thread_input(current_thread_id, remote_thread_id, true);
81        let obj = AccessibleObject::from_window(get_focus());
82        attach_thread_input(current_thread_id, remote_thread_id, false);
83        obj
84    }
85
86    /**
87    对象的 KeyboardShortcut 属性 已更改。 服务器应用程序为它们的辅助性对象发送该事件。
88    `func` 用于接收事件的监听器函数。
89    */
90    pub fn add_on_object_accelerator_change_listener(
91        &self,
92        func: impl Fn(WinEventSource) + Sync + Send + 'static,
93    ) {
94        self.events
95            .write()
96            .unwrap()
97            .push(WinEventHook::new(EVENT_OBJECT_ACCELERATORCHANGE, func));
98    }
99
100    /**
101    在隐藏窗口时发送。 隐藏的窗口仍然存在,但对用户不可见。
102    `func` 用于接收事件的监听器函数。
103    */
104    pub fn add_on_object_cloaked_listener(
105        &self,
106        func: impl Fn(WinEventSource) + Sync + Send + 'static,
107    ) {
108        self.events
109            .write()
110            .unwrap()
111            .push(WinEventHook::new(EVENT_OBJECT_CLOAKED, func));
112    }
113
114    //noinspection SpellCheckingInspection
115    /**
116    窗口对象的滚动已结束。 与 EVENT_SYSTEM_SCROLLEND不同,此事件与滚动窗口相关联。 无论滚动是水平滚动还是垂直滚动,只要滚动操作完成,都应发送此事件。
117    WinEventProc 回调函数的 hwnd 参数描述滚动窗口;idObject 参数OBJID_CLIENT,idChild 参数CHILDID_SELF。
118    `func` 用于接收事件的监听器函数。
119    */
120    pub fn add_on_object_content_scrolled_listener(
121        &self,
122        func: impl Fn(WinEventSource) + Sync + Send + 'static,
123    ) {
124        self.events
125            .write()
126            .unwrap()
127            .push(WinEventHook::new(EVENT_OBJECT_CONTENTSCROLLED, func));
128    }
129
130    /**
131    已创建 对象。 系统为以下用户界面元素发送此事件:插入点、 标题控件、 列表视图控件、 选项卡控件、 工具栏控件、 树视图控件和 窗口 对象。 服务器应用程序为它们的辅助性对象发送该事件。
132    在为父对象发送事件之前,服务器必须为对象的所有子对象发送事件。 服务器必须确保在父对象发送此事件之前,已完全创建所有子对象并准备好接受来自客户端的 IAccessible 调用。
133    由于父对象在其子对象之后创建,因此客户端必须确保在调用 IAccessible::get_accParent之前已创建对象的父对象,尤其是在使用上下文中挂钩函数的情况下。
134    `func` 用于接收事件的监听器函数。
135    */
136    pub fn add_on_object_create_listener(
137        &self,
138        func: impl Fn(WinEventSource) + Sync + Send + 'static,
139    ) {
140        self.events
141            .write()
142            .unwrap()
143            .push(WinEventHook::new(EVENT_OBJECT_CREATE, func));
144    }
145
146    /**
147    对象的 DefaultAction 属性 已更改。 操作系统为对话框发送该事件。 服务器应用程序为它们的辅助性对象发送该事件。
148    `func` 用于接收事件的监听器函数。
149    */
150    pub fn add_on_object_default_action_change_listener(
151        &self,
152        func: impl Fn(WinEventSource) + Sync + Send + 'static,
153    ) {
154        self.events
155            .write()
156            .unwrap()
157            .push(WinEventHook::new(EVENT_OBJECT_DEFACTIONCHANGE, func));
158    }
159
160    /**
161    对象的 Description 属性 已更改。 服务器应用程序为它们的辅助性对象发送该事件。
162    `func` 用于接收事件的监听器函数。
163    */
164    pub fn add_on_object_description_change_listener(
165        &self,
166        func: impl Fn(WinEventSource) + Sync + Send + 'static,
167    ) {
168        self.events
169            .write()
170            .unwrap()
171            .push(WinEventHook::new(EVENT_OBJECT_DESCRIPTIONCHANGE, func));
172    }
173
174    /**
175    对象已被销毁。 系统为以下用户界面元素发送此事件:插入点、标题控件、列表视图控件、选项卡控件、工具栏控件、树视图控件和窗口对象。 服务器应用程序为它们的辅助性对象发送该事件。
176    客户端假定当父对象发送此事件时,对象的所有子级都会被销毁。
177    收到此事件后,客户端不会调用对象的 IAccessible 属性或方法。 但是,只要由于 COM 规则) ,接口指针 (存在引用计数,接口指针必须保持有效,但 UI 元素可能不再存在。 对接口指针的进一步调用可能会返回失败错误;为了防止这种情况,服务器 会创建代理对象 并监视其生命周期。
178    `func` 用于接收事件的监听器函数。
179    */
180    pub fn add_on_object_destroy_listener(
181        &self,
182        func: impl Fn(WinEventSource) + Sync + Send + 'static,
183    ) {
184        self.events
185            .write()
186            .unwrap()
187            .push(WinEventHook::new(EVENT_OBJECT_DESTROY, func));
188    }
189
190    /**
191    用户开始拖动元素。 WinEventProc 回调函数的 h_wnd、id_object 和 id_child 参数标识要拖动的对象。
192    `func` 用于接收事件的监听器函数。
193    */
194    pub fn add_on_object_drag_start_listener(
195        &self,
196        func: impl Fn(WinEventSource) + Sync + Send + 'static,
197    ) {
198        self.events
199            .write()
200            .unwrap()
201            .push(WinEventHook::new(EVENT_OBJECT_DRAGSTART, func));
202    }
203
204    /**
205    用户已结束拖动操作,然后再将拖动的元素放在放置目标上。 WinEventProc 回调函数的 h_wnd、id_object 和 id_child 参数标识要拖动的对象。
206    `func` 用于接收事件的监听器函数。
207    */
208    pub fn add_on_object_drag_cancel_listener(
209        &self,
210        func: impl Fn(WinEventSource) + Sync + Send + 'static,
211    ) {
212        self.events
213            .write()
214            .unwrap()
215            .push(WinEventHook::new(EVENT_OBJECT_DRAGCANCEL, func));
216    }
217
218    /**
219    用户删除了放置目标上的元素。 WinEventProc 回调函数的 h_wnd、id_object 和 id_child 参数标识要拖动的对象。
220    `func` 用于接收事件的监听器函数。
221    */
222    pub fn add_on_object_drag_complete_listener(
223        &self,
224        func: impl Fn(WinEventSource) + Sync + Send + 'static,
225    ) {
226        self.events
227            .write()
228            .unwrap()
229            .push(WinEventHook::new(EVENT_OBJECT_DRAGCOMPLETE, func));
230    }
231
232    /**
233    用户将元素拖动到放置目标的边界。 WinEventProc 回调函数的 h_wnd、id_object 和 id_child 参数标识放置目标。
234    `func` 用于接收事件的监听器函数。
235    */
236    pub fn add_on_object_drag_enter_listener(
237        &self,
238        func: impl Fn(WinEventSource) + Sync + Send + 'static,
239    ) {
240        self.events
241            .write()
242            .unwrap()
243            .push(WinEventHook::new(EVENT_OBJECT_DRAGENTER, func));
244    }
245
246    /**
247    用户将元素拖出放置目标的边界。 WinEventProc 回调函数的 h_wnd、id_object 和 id_child 参数标识放置目标。
248    `func` 用于接收事件的监听器函数。
249    */
250    pub fn add_on_object_drag_leave_listener(
251        &self,
252        func: impl Fn(WinEventSource) + Sync + Send + 'static,
253    ) {
254        self.events
255            .write()
256            .unwrap()
257            .push(WinEventHook::new(EVENT_OBJECT_DRAGLEAVE, func));
258    }
259
260    /**
261    用户删除了放置目标上的元素。 WinEventProc 回调函数的 h_wnd、id_object 和 id_child 参数标识放置目标。
262    `func` 用于接收事件的监听器函数。
263    */
264    pub fn add_on_object_drag_dropped_listener(
265        &self,
266        func: impl Fn(WinEventSource) + Sync + Send + 'static,
267    ) {
268        self.events
269            .write()
270            .unwrap()
271            .push(WinEventHook::new(EVENT_OBJECT_DRAGDROPPED, func));
272    }
273
274    /**
275    最高的对象事件值。
276    `func` 用于接收事件的监听器函数。
277    */
278    pub fn add_on_object_end_listener(
279        &self,
280        func: impl Fn(WinEventSource) + Sync + Send + 'static,
281    ) {
282        self.events
283            .write()
284            .unwrap()
285            .push(WinEventHook::new(EVENT_OBJECT_END, func));
286    }
287
288    /**
289    对象已接收键盘焦点。 系统为以下用户界面元素发送此事件:列表视图控件、菜单栏、弹出菜单、切换窗口、选项卡控件、树视图控件和窗口对象。 服务器应用程序为它们的辅助性对象发送该事件。
290    WinEventProc 回调函数的 h_wnd 参数标识接收键盘焦点的窗口。
291    `func` 用于接收事件的监听器函数。
292    */
293    pub fn add_on_object_focus_listener(
294        &self,
295        func: impl Fn(WinEventSource) + Sync + Send + 'static,
296    ) {
297        self.events
298            .write()
299            .unwrap()
300            .push(WinEventHook::new(EVENT_OBJECT_FOCUS, func));
301    }
302
303    /**
304    对象的 帮助属性 已更改。 服务器应用程序为它们的辅助性对象发送该事件。
305    `func` 用于接收事件的监听器函数。
306    */
307    pub fn add_on_object_help_change_listener(
308        &self,
309        func: impl Fn(WinEventSource) + Sync + Send + 'static,
310    ) {
311        self.events
312            .write()
313            .unwrap()
314            .push(WinEventHook::new(EVENT_OBJECT_HELPCHANGE, func));
315    }
316
317    /**
318    对象已隐藏。 系统为以下用户界面元素发送此事件:插入点和光标。 服务器应用程序为它们的辅助性对象发送该事件。
319    为父对象生成此事件时,所有子对象都已隐藏。 服务器应用程序不会为子对象发送此事件。
320    隐藏的对象包括 STATE_SYSTEM_INVISIBLE 标志;shown 对象不包括此标志。 EVENT_OBJECT_HIDE 事件还指示已设置STATE_SYSTEM_INVISIBLE标志。 因此,在这种情况下,服务器不会发送 EVENT_OBJECT_STATECHANGE 事件。
321    `func` 用于接收事件的监听器函数。
322    */
323    pub fn add_on_object_hide_listener(
324        &self,
325        func: impl Fn(WinEventSource) + Sync + Send + 'static,
326    ) {
327        self.events
328            .write()
329            .unwrap()
330            .push(WinEventHook::new(EVENT_OBJECT_HIDE, func));
331    }
332
333    //noinspection SpellCheckingInspection
334    /**
335    承载其他可访问对象的窗口已更改托管对象。 客户端可能需要查询主机窗口以发现新的托管对象,尤其是在客户端一直在监视窗口中的事件时。 托管对象是与主机不同的辅助功能框架 (MSAA 或 UI 自动化) 的对象。 托管对象中与主机相同的框架中的更改应随结构更改事件一起处理,例如 MSAA 的EVENT_OBJECT_CREATE 。 有关详细信息,请参阅 winuser.h 中的注释。
336    `func` 用于接收事件的监听器函数。
337    */
338    pub fn add_on_object_hosted_objects_invalidated_listener(
339        &self,
340        func: impl Fn(WinEventSource) + Sync + Send + 'static,
341    ) {
342        self.events.write().unwrap().push(WinEventHook::new(
343            EVENT_OBJECT_HOSTEDOBJECTSINVALIDATED,
344            func,
345        ));
346    }
347
348    /**
349    IME 窗口已隐藏。
350    `func` 用于接收事件的监听器函数。
351    */
352    pub fn add_on_object_ime_hide_listener(
353        &self,
354        func: impl Fn(WinEventSource) + Sync + Send + 'static,
355    ) {
356        self.events
357            .write()
358            .unwrap()
359            .push(WinEventHook::new(EVENT_OBJECT_IME_HIDE, func));
360    }
361
362    /**
363    IME 窗口已变为可见。
364    `func` 用于接收事件的监听器函数。
365    */
366    pub fn add_on_object_ime_show_listener(
367        &self,
368        func: impl Fn(WinEventSource) + Sync + Send + 'static,
369    ) {
370        self.events
371            .write()
372            .unwrap()
373            .push(WinEventHook::new(EVENT_OBJECT_IME_SHOW, func));
374    }
375
376    /**
377    输入法窗口的大小或位置已更改。
378    `func` 用于接收事件的监听器函数。
379    */
380    pub fn add_on_object_ime_change_listener(
381        &self,
382        func: impl Fn(WinEventSource) + Sync + Send + 'static,
383    ) {
384        self.events
385            .write()
386            .unwrap()
387            .push(WinEventHook::new(EVENT_OBJECT_IME_CHANGE, func));
388    }
389
390    /**
391    已调用 对象;例如,用户单击了一个按钮。 此事件受常见控件支持,由 UI 自动化使用。
392    对于此事件,WinEventProc 回调函数的 h_wnd、id_object 和 id_child 参数标识所调用的项。
393    `func` 用于接收事件的监听器函数。
394    */
395    pub fn add_on_object_invoked_listener(
396        &self,
397        func: impl Fn(WinEventSource) + Sync + Send + 'static,
398    ) {
399        self.events
400            .write()
401            .unwrap()
402            .push(WinEventHook::new(EVENT_OBJECT_INVOKED, func));
403    }
404
405    /**
406    属于活动区域的对象已更改。 实时区域是应用程序频繁更改和/或异步更改的区域。
407    `func` 用于接收事件的监听器函数。
408    */
409    pub fn add_on_object_live_region_changed_listener(
410        &self,
411        func: impl Fn(WinEventSource) + Sync + Send + 'static,
412    ) {
413        self.events
414            .write()
415            .unwrap()
416            .push(WinEventHook::new(EVENT_OBJECT_LIVEREGIONCHANGED, func));
417    }
418
419    //noinspection SpellCheckingInspection
420    /**
421    对象已更改位置、形状和大小。 系统为以下用户界面元素发送此事件:插入点和窗口对象。 服务器应用程序为它们的辅助性对象发送该事件。
422    生成此事件以响应对象层次结构中顶级对象的更改;它不是为对象可能具有的任何子项生成的。 例如,如果用户调整窗口大小,系统会为窗口发送此通知,但不会针对菜单栏、标题栏、滚动条或其他也已更改的对象发送此通知。
423    当父窗口移动时,系统不会为所有非浮动子窗口发送该事件。 但是,如果应用程序由于调整父窗口的大小而显式调整子窗口的大小,系统将为重设大小的子窗口发送多个事件。
424    如果对象的 State 属性 设置为 STATE_SYSTEM_FLOATING,则每当对象更改位置时,服务器就会发送 EVENT_OBJECT_LOCATIONCHANGE 。 如果对象不具有此状态,则服务器仅在对象相对于其父级移动时才触发此事件。 对于此事件通知,WinEventProc 回调函数的 idChild 参数标识已更改的子对象。
425    `func` 用于接收事件的监听器函数。
426    */
427    pub fn add_on_object_location_change_listener(
428        &self,
429        func: impl Fn(WinEventSource) + Sync + Send + 'static,
430    ) {
431        self.events
432            .write()
433            .unwrap()
434            .push(WinEventHook::new(EVENT_OBJECT_LOCATIONCHANGE, func));
435    }
436
437    /**
438    对象的 Name 属性 已更改。 系统为以下用户界面元素发送此事件:检查框、光标、列表视图控件、推送按钮、单选按钮、状态栏控件、树视图控件和窗口对象。 服务器应用程序为它们的辅助性对象发送该事件。
439    `func` 用于接收事件的监听器函数。
440    */
441    pub fn add_on_object_name_change_listener(
442        &self,
443        func: impl Fn(WinEventSource) + Sync + Send + 'static,
444    ) {
445        self.events
446            .write()
447            .unwrap()
448            .push(WinEventHook::new(EVENT_OBJECT_NAMECHANGE, func));
449    }
450
451    /**
452    对象具有新的父对象。 服务器应用程序为它们的辅助性对象发送该事件。
453    `func` 用于接收事件的监听器函数。
454    */
455    pub fn add_on_object_parent_change_listener(
456        &self,
457        func: impl Fn(WinEventSource) + Sync + Send + 'static,
458    ) {
459        self.events
460            .write()
461            .unwrap()
462            .push(WinEventHook::new(EVENT_OBJECT_PARENTCHANGE, func));
463    }
464
465    /**
466    容器对象已添加、移除其子对象或对其子对象重新排序。 系统为以下用户界面元素发送此事件:标头控件、列表视图控件、工具栏控件和窗口对象。 服务器应用程序在适当的时候为它们的辅助性对象发送该事件。
467    例如,当子元素的数量或元素的顺序发生更改时,列表视图对象会生成此事件。 当子窗口的 Z 顺序更改时,父窗口也会发送此事件。
468    `func` 用于接收事件的监听器函数。
469    */
470    pub fn add_on_object_reorder_listener(
471        &self,
472        func: impl Fn(WinEventSource) + Sync + Send + 'static,
473    ) {
474        self.events
475            .write()
476            .unwrap()
477            .push(WinEventHook::new(EVENT_OBJECT_REORDER, func));
478    }
479
480    //noinspection SpellCheckingInspection
481    /**
482    容器对象中的选定内容已更改。 系统为以下用户界面元素发送此事件:列表视图控件、选项卡控件、树视图控件和窗口对象。 服务器应用程序为它们的辅助性对象发送该事件。
483    此事件指示单个选择:在以前不包含任何选定子项的容器中选择了子级,或者所选内容已从一个子级更改为另一个子级。
484    WinEventProc 回调函数的 hwnd 和 idObject 参数描述容器;idChild 参数标识所选的对象。 如果所选子级是同时包含 对象的窗口,则 idChild 参数 OBJID_WINDOW。
485    `func` 用于接收事件的监听器函数。
486    */
487    pub fn add_on_object_selection_listener(
488        &self,
489        func: impl Fn(WinEventSource) + Sync + Send + 'static,
490    ) {
491        self.events
492            .write()
493            .unwrap()
494            .push(WinEventHook::new(EVENT_OBJECT_SELECTION, func));
495    }
496
497    /**
498    容器对象中的子项已添加到现有选定内容中。 系统为以下用户界面元素发送此事件:列表框、列表视图控件和树视图控件。 服务器应用程序为它们的辅助性对象发送该事件。
499    WinEventProc 回调函数的 h_wnd 和 id_object 参数描述容器。 id_child 参数是添加到所选内容的子级。
500    `func` 用于接收事件的监听器函数。
501    */
502    pub fn add_on_object_selection_add_listener(
503        &self,
504        func: impl Fn(WinEventSource) + Sync + Send + 'static,
505    ) {
506        self.events
507            .write()
508            .unwrap()
509            .push(WinEventHook::new(EVENT_OBJECT_SELECTIONADD, func));
510    }
511
512    /**
513    容器对象中的项已从所选内容中删除。 系统为以下用户界面元素发送此事件:列表框、列表视图控件和树视图控件。 服务器应用程序为它们的辅助性对象发送该事件。
514    此事件指示子项已从现有选定内容中删除。
515    WinEventProc 回调函数的 h_wnd 和 id_object 参数描述容器;id_child 参数标识已从所选内容中删除的子级。
516    `func` 用于接收事件的监听器函数。
517    */
518    pub fn add_on_object_selection_remove_listener(
519        &self,
520        func: impl Fn(WinEventSource) + Sync + Send + 'static,
521    ) {
522        self.events
523            .write()
524            .unwrap()
525            .push(WinEventHook::new(EVENT_OBJECT_SELECTIONREMOVE, func));
526    }
527
528    //noinspection SpellCheckingInspection
529    /**
530    容器对象中发生了许多选择更改。 系统为列表框发送此事件;服务器应用程序为其可访问的对象发送它。
531    当控件中的选定项发生重大更改时,将发送此事件。 该事件通知客户端发生了许多选择更改,并且发送该事件而不是多个 EVENT_OBJECT_SELECTIONADD 或 EVENT_OBJECT_SELECTIONREMOVE 事件。 客户端通过调用容器对象的 IAccessible::get_accSelection 方法并枚举所选项来查询所选项。
532    对于此事件通知,WinEventProc 回调函数的 hwnd 和 idObject 参数描述发生更改的容器。
533    `func` 用于接收事件的监听器函数。
534    */
535    pub fn add_on_object_selection_within_listener(
536        &self,
537        func: impl Fn(WinEventSource) + Sync + Send + 'static,
538    ) {
539        self.events
540            .write()
541            .unwrap()
542            .push(WinEventHook::new(EVENT_OBJECT_SELECTIONWITHIN, func));
543    }
544
545    /**
546    显示隐藏的对象。 系统为下列用户界面元素发送此事件:插入符号、光标和窗口对象。 服务器应用程序为它们的辅助性对象发送该事件。
547    客户端假定当父对象发送此事件时,已显示所有子对象。 因此,服务器应用程序不会为子对象发送此事件。
548    隐藏的对象包括 STATE_SYSTEM_INVISIBLE 标志;shown 对象不包括此标志。 EVENT_OBJECT_SHOW 事件还指示已清除STATE_SYSTEM_INVISIBLE标志。 因此,在这种情况下,服务器不会发送 EVENT_OBJECT_STATECHANGE 事件。
549    `func` 用于接收事件的监听器函数。
550    */
551    pub fn add_on_object_show_listener(
552        &self,
553        func: impl Fn(WinEventSource) + Sync + Send + 'static,
554    ) {
555        self.events
556            .write()
557            .unwrap()
558            .push(WinEventHook::new(EVENT_OBJECT_SHOW, func));
559    }
560
561    /**
562    对象的状态已更改。 系统为以下用户界面元素发送此事件:检查框、组合框、标题控件、推送按钮、单选按钮、滚动条、工具栏控件、树视图控件、向上-向下控件和窗口对象。 服务器应用程序为它们的辅助性对象发送该事件。
563    例如,单击或释放按钮对象时,或者启用或禁用某个对象时,会发生状态更改。
564    对于此事件通知,WinEventProc 回调函数的 idChild 参数标识其状态已更改的子对象。
565    `func` 用于接收事件的监听器函数。
566    */
567    pub fn add_on_object_state_change_listener(
568        &self,
569        func: impl Fn(WinEventSource) + Sync + Send + 'static,
570    ) {
571        self.events
572            .write()
573            .unwrap()
574            .push(WinEventHook::new(EVENT_OBJECT_STATECHANGE, func));
575    }
576
577    /**
578    IME 组合中的转换目标已更改。 转换目标是 IME 组合的子集,主动选择作为用户发起的转换的目标。
579    `func` 用于接收事件的监听器函数。
580    */
581    pub fn add_on_object_text_edit_conversion_target_changed_listener(
582        &self,
583        func: impl Fn(WinEventSource) + Sync + Send + 'static,
584    ) {
585        self.events.write().unwrap().push(WinEventHook::new(
586            EVENT_OBJECT_TEXTEDIT_CONVERSIONTARGETCHANGED,
587            func,
588        ));
589    }
590
591    /**
592    对象的文本选择已更改。 此事件受常见控件支持,由 UI 自动化使用。
593    WinEventProc 回调函数的 h_wnd、id_object 和 id_child 参数描述更新的文本选择中包含的项。
594    `func` 用于接收事件的监听器函数。
595    */
596    pub fn add_on_object_text_selection_changed_listener(
597        &self,
598        func: impl Fn(WinEventSource) + Sync + Send + 'static,
599    ) {
600        self.events
601            .write()
602            .unwrap()
603            .push(WinEventHook::new(EVENT_OBJECT_TEXTSELECTIONCHANGED, func));
604    }
605
606    /**
607    在取消隐藏窗口时发送。 隐藏的窗口仍然存在,但对用户不可见。
608    `func` 用于接收事件的监听器函数。
609    */
610    pub fn add_on_object_uncloaked_listener(
611        &self,
612        func: impl Fn(WinEventSource) + Sync + Send + 'static,
613    ) {
614        self.events
615            .write()
616            .unwrap()
617            .push(WinEventHook::new(EVENT_OBJECT_UNCLOAKED, func));
618    }
619
620    /**
621    对象的 Value 属性 已更改。 系统为包括滚动条和以下控件的用户界面元素发送此事件:编辑、标头、热键、进度栏、滑块和向上。 服务器应用程序为它们的辅助性对象发送该事件。
622    `func` 用于接收事件的监听器函数。
623    */
624    pub fn add_on_object_value_change_listener(
625        &self,
626        func: impl Fn(WinEventSource) + Sync + Send + 'static,
627    ) {
628        self.events
629            .write()
630            .unwrap()
631            .push(WinEventHook::new(EVENT_OBJECT_VALUECHANGE, func));
632    }
633
634    /**
635    为 OEM 保留的事件常量值的最低范围。 有关详细信息,请参阅 WinEvent ID 的分配。
636    `func` 用于接收事件的监听器函数。
637    */
638    pub fn add_on_oem_defined_start_listener(
639        &self,
640        func: impl Fn(WinEventSource) + Sync + Send + 'static,
641    ) {
642        self.events
643            .write()
644            .unwrap()
645            .push(WinEventHook::new(EVENT_OEM_DEFINED_START, func));
646    }
647
648    /**
649    为 OEM 保留的事件常量值的最高范围。 有关详细信息,请参阅 WinEvent ID 的分配。
650    `func` 用于接收事件的监听器函数。
651    */
652    pub fn add_on_oem_defined_end_listener(
653        &self,
654        func: impl Fn(WinEventSource) + Sync + Send + 'static,
655    ) {
656        self.events
657            .write()
658            .unwrap()
659            .push(WinEventHook::new(EVENT_OEM_DEFINED_END, func));
660    }
661
662    /**
663    已生成警报。 服务器应用程序不应发送此事件。
664    `func` 用于接收事件的监听器函数。
665    */
666    pub fn add_on_system_alert_listener(
667        &self,
668        func: impl Fn(WinEventSource) + Sync + Send + 'static,
669    ) {
670        self.events
671            .write()
672            .unwrap()
673            .push(WinEventHook::new(EVENT_SYSTEM_ALERT, func));
674    }
675
676    /**
677    正在显示预览矩形。
678    `func` 用于接收事件的监听器函数。
679    */
680    pub fn add_on_system_arrangement_preview_listener(
681        &self,
682        func: impl Fn(WinEventSource) + Sync + Send + 'static,
683    ) {
684        self.events
685            .write()
686            .unwrap()
687            .push(WinEventHook::new(EVENT_SYSTEM_ARRANGMENTPREVIEW, func));
688    }
689
690    /**
691    窗口已丢失鼠标捕获。 此事件由系统发送,从不由服务器发送。
692    `func` 用于接收事件的监听器函数。
693    */
694    pub fn add_on_system_capture_end_listener(
695        &self,
696        func: impl Fn(WinEventSource) + Sync + Send + 'static,
697    ) {
698        self.events
699            .write()
700            .unwrap()
701            .push(WinEventHook::new(EVENT_SYSTEM_CAPTUREEND, func));
702    }
703
704    /**
705    窗口已收到鼠标捕获。 此事件由系统发送,从不由服务器发送。
706    `func` 用于接收事件的监听器函数。
707    */
708    pub fn add_on_system_capture_start_listener(
709        &self,
710        func: impl Fn(WinEventSource) + Sync + Send + 'static,
711    ) {
712        self.events
713            .write()
714            .unwrap()
715            .push(WinEventHook::new(EVENT_SYSTEM_CAPTURESTART, func));
716    }
717
718    /**
719    窗口已退出上下文相关帮助模式。 系统不一致地发送此事件。
720    `func` 用于接收事件的监听器函数。
721    */
722    pub fn add_on_system_context_help_end_listener(
723        &self,
724        func: impl Fn(WinEventSource) + Sync + Send + 'static,
725    ) {
726        self.events
727            .write()
728            .unwrap()
729            .push(WinEventHook::new(EVENT_SYSTEM_CONTEXTHELPEND, func));
730    }
731
732    /**
733    窗口已进入上下文相关帮助模式。 系统不一致地发送此事件。
734    `func` 用于接收事件的监听器函数。
735    */
736    pub fn add_on_system_context_help_start_listener(
737        &self,
738        func: impl Fn(WinEventSource) + Sync + Send + 'static,
739    ) {
740        self.events
741            .write()
742            .unwrap()
743            .push(WinEventHook::new(EVENT_SYSTEM_CONTEXTHELPSTART, func));
744    }
745
746    /**
747    已切换活动桌面。
748    `func` 用于接收事件的监听器函数。
749    */
750    pub fn add_on_system_desktop_switch_listener(
751        &self,
752        func: impl Fn(WinEventSource) + Sync + Send + 'static,
753    ) {
754        self.events
755            .write()
756            .unwrap()
757            .push(WinEventHook::new(EVENT_SYSTEM_DESKTOPSWITCH, func));
758    }
759
760    /**
761    对话框已关闭。 系统为标准对话框发送此事件;服务器将其发送到自定义对话框。 系统不一致地发送此事件。
762    `func` 用于接收事件的监听器函数。
763    */
764    pub fn add_on_system_dialog_end_listener(
765        &self,
766        func: impl Fn(WinEventSource) + Sync + Send + 'static,
767    ) {
768        self.events
769            .write()
770            .unwrap()
771            .push(WinEventHook::new(EVENT_SYSTEM_DIALOGEND, func));
772    }
773
774    /**
775    已显示一个对话框。 系统为使用资源模板或 Win32 对话框函数创建的标准对话框发送此事件。 服务器为自定义对话框发送此事件,这些对话框是充当对话框但不是以标准方式创建的窗口。
776    系统不一致地发送此事件。
777    `func` 用于接收事件的监听器函数。
778    */
779    pub fn add_on_system_dialog_start_listener(
780        &self,
781        func: impl Fn(WinEventSource) + Sync + Send + 'static,
782    ) {
783        self.events
784            .write()
785            .unwrap()
786            .push(WinEventHook::new(EVENT_SYSTEM_DIALOGSTART, func));
787    }
788
789    /**
790    应用程序将退出拖放模式。 支持拖放操作的应用程序必须发送此事件;系统不发送此事件。
791    `func` 用于接收事件的监听器函数。
792    */
793    pub fn add_on_system_drag_drop_end_listener(
794        &self,
795        func: impl Fn(WinEventSource) + Sync + Send + 'static,
796    ) {
797        self.events
798            .write()
799            .unwrap()
800            .push(WinEventHook::new(EVENT_SYSTEM_DRAGDROPEND, func));
801    }
802
803    /**
804    应用程序将进入拖放模式。 支持拖放操作的应用程序必须发送此事件,因为系统不会发送它。
805    `func` 用于接收事件的监听器函数。
806    */
807    pub fn add_on_system_drag_drop_start_listener(
808        &self,
809        func: impl Fn(WinEventSource) + Sync + Send + 'static,
810    ) {
811        self.events
812            .write()
813            .unwrap()
814            .push(WinEventHook::new(EVENT_SYSTEM_DRAGDROPSTART, func));
815    }
816
817    /**
818    最高的系统事件值。
819    `func` 用于接收事件的监听器函数。
820    */
821    pub fn add_on_system_end_listener(
822        &self,
823        func: impl Fn(WinEventSource) + Sync + Send + 'static,
824    ) {
825        self.events
826            .write()
827            .unwrap()
828            .push(WinEventHook::new(EVENT_SYSTEM_END, func));
829    }
830
831    //noinspection SpellCheckingInspection
832    /**
833    前景窗口已更改。 即使前台窗口已更改为同一线程中的另一个窗口,系统也会发送此事件。 服务器应用程序从不发送该事件。
834    对于此事件, WinEventProc 回调函数的 hwnd 参数是前台窗口的句柄, idObject 参数 OBJID_WINDOW, idChild 参数 CHILDID_SELF。
835    `func` 用于接收事件的监听器函数。
836    */
837    pub fn add_on_system_foreground_listener(
838        &self,
839        func: impl Fn(WinEventSource) + Sync + Send + 'static,
840    ) {
841        self.events
842            .write()
843            .unwrap()
844            .push(WinEventHook::new(EVENT_SYSTEM_FOREGROUND, func));
845    }
846
847    //noinspection SpellCheckingInspection
848    /**
849    弹出菜单已关闭。 系统为标准菜单发送此事件;服务器将其发送到自定义菜单。
850    当弹出菜单关闭时,客户端将收到此消息,然后 接收EVENT_SYSTEM_MENUEND 事件。
851    系统不一致地发送此事件。
852    `func` 用于接收事件的监听器函数。
853    */
854    pub fn add_on_system_menu_popup_end_listener(
855        &self,
856        func: impl Fn(WinEventSource) + Sync + Send + 'static,
857    ) {
858        self.events
859            .write()
860            .unwrap()
861            .push(WinEventHook::new(EVENT_SYSTEM_MENUPOPUPEND, func));
862    }
863
864    //noinspection SpellCheckingInspection
865    /**
866    已显示弹出菜单。 系统为标准菜单发送此事件,这些菜单由 HMENU 标识,并使用菜单模板资源或 Win32 菜单函数创建。 服务器为自定义菜单发送此事件,这些菜单是充当菜单但不以标准方式创建的用户界面元素。 系统不一致地发送此事件。
867    `func` 用于接收事件的监听器函数。
868    */
869    pub fn add_on_system_menu_popup_start_listener(
870        &self,
871        func: impl Fn(WinEventSource) + Sync + Send + 'static,
872    ) {
873        self.events
874            .write()
875            .unwrap()
876            .push(WinEventHook::new(EVENT_SYSTEM_MENUPOPUPSTART, func));
877    }
878
879    //noinspection SpellCheckingInspection
880    /**
881    菜单栏中的菜单已关闭。 系统为标准菜单发送此事件;服务器将其发送到自定义菜单。
882    对于此事件, WinEventProc 回调函数的 hwnd、 idObject 和 idChild 参数引用包含菜单栏的控件或激活上下文菜单的控件。 hwnd 参数是与事件相关的窗口的句柄。 idObject参数OBJID_MENU或OBJID_SYSMENU菜单,或弹出菜单的OBJID_WINDOW。 idChild参数CHILDID_SELF。
883    `func` 用于接收事件的监听器函数。
884    */
885    pub fn add_on_system_menu_end_listener(
886        &self,
887        func: impl Fn(WinEventSource) + Sync + Send + 'static,
888    ) {
889        self.events
890            .write()
891            .unwrap()
892            .push(WinEventHook::new(EVENT_SYSTEM_MENUEND, func));
893    }
894
895    //noinspection SpellCheckingInspection
896    /**
897    已选择菜单栏上的菜单项。 系统为标准菜单发送此事件,这些菜单由 HMENU 标识,使用菜单模板资源或 Win32 菜单 API 元素创建。 服务器为自定义菜单发送此事件,自定义菜单是充当菜单但不以标准方式创建的用户界面元素。
898    对于此事件, WinEventProc 回调函数的 hwnd、 idObject 和 idChild 参数引用包含菜单栏的控件或激活上下文菜单的控件。 hwnd 参数是与事件相关的窗口的句柄。 idObject 参数是菜单的OBJID_MENU或OBJID_SYSMENU,或弹出菜单的OBJID_WINDOW。 idChild参数CHILDID_SELF。
899    系统触发多个 EVENT_SYSTEM_MENUSTART 事件,这些事件并不总是与 EVENT_SYSTEM_MENUEND 事件相对应。
900    `func` 用于接收事件的监听器函数。
901    */
902    pub fn add_on_system_menu_start_listener(
903        &self,
904        func: impl Fn(WinEventSource) + Sync + Send + 'static,
905    ) {
906        self.events
907            .write()
908            .unwrap()
909            .push(WinEventHook::new(EVENT_SYSTEM_MENUSTART, func));
910    }
911
912    /**
913    即将还原窗口对象。 此事件由系统发送,从不由服务器发送。
914    `func` 用于接收事件的监听器函数。
915    */
916    pub fn add_on_system_minimize_end_listener(
917        &self,
918        func: impl Fn(WinEventSource) + Sync + Send + 'static,
919    ) {
920        self.events
921            .write()
922            .unwrap()
923            .push(WinEventHook::new(EVENT_SYSTEM_MINIMIZEEND, func));
924    }
925
926    /**
927    窗口对象即将最小化。 此事件由系统发送,从不由服务器发送。
928    `func` 用于接收事件的监听器函数。
929    */
930    pub fn add_on_system_minimize_start_listener(
931        &self,
932        func: impl Fn(WinEventSource) + Sync + Send + 'static,
933    ) {
934        self.events
935            .write()
936            .unwrap()
937            .push(WinEventHook::new(EVENT_SYSTEM_MINIMIZESTART, func));
938    }
939
940    /**
941    窗口的移动或调整大小已完成。 此事件由系统发送,从不由服务器发送。
942    `func` 用于接收事件的监听器函数。
943    */
944    pub fn add_on_system_move_size_end_listener(
945        &self,
946        func: impl Fn(WinEventSource) + Sync + Send + 'static,
947    ) {
948        self.events
949            .write()
950            .unwrap()
951            .push(WinEventHook::new(EVENT_SYSTEM_MOVESIZEEND, func));
952    }
953
954    /**
955    正在移动窗口或调整窗口的大小。 此事件由系统发送,从不由服务器发送。
956    `func` 用于接收事件的监听器函数。
957    */
958    pub fn add_on_system_move_size_start_listener(
959        &self,
960        func: impl Fn(WinEventSource) + Sync + Send + 'static,
961    ) {
962        self.events
963            .write()
964            .unwrap()
965            .push(WinEventHook::new(EVENT_SYSTEM_MOVESIZESTART, func));
966    }
967
968    //noinspection SpellCheckingInspection
969    /**
970    滚动条上的滚动已经结束。 此事件由系统为标准滚动条控件和附加到窗口的滚动条发送。 服务器为自定义滚动条发送此事件,这些滚动条是充当滚动条但不是以标准方式创建的用户界面元素。
971    发送到 WinEventProc 回调函数的 idObject参数OBJID_HSCROLL水平滚动条,垂直滚动条OBJID_VSCROLL。
972    `func` 用于接收事件的监听器函数。
973    */
974    pub fn add_on_system_scrolling_end_listener(
975        &self,
976        func: impl Fn(WinEventSource) + Sync + Send + 'static,
977    ) {
978        self.events
979            .write()
980            .unwrap()
981            .push(WinEventHook::new(EVENT_SYSTEM_SCROLLINGEND, func));
982    }
983
984    //noinspection SpellCheckingInspection
985    /**
986    滚动条上的滚动已经开始。 系统为标准滚动条控件和附加到窗口的滚动条发送此事件。 服务器为自定义滚动条发送此事件,这些滚动条是充当滚动条但不是以标准方式创建的用户界面元素。
987    发送到 WinEventProc 回调函数的 idObject 参数对水平滚动条OBJID_HSCROLL,垂直滚动条OBJID_VSCROLL。
988    `func` 用于接收事件的监听器函数。
989    */
990    pub fn add_on_system_scrolling_start_listener(
991        &self,
992        func: impl Fn(WinEventSource) + Sync + Send + 'static,
993    ) {
994        self.events
995            .write()
996            .unwrap()
997            .push(WinEventHook::new(EVENT_SYSTEM_SCROLLINGSTART, func));
998    }
999
1000    //noinspection SpellCheckingInspection
1001    /**
1002    已播放声音。 当系统声音(例如菜单声音)被播放时,系统发送此事件,即使没有声音 (,例如,由于缺少声音文件或声音卡) 。 每当自定义 UI 元素生成声音时,服务器都会发送此事件。
1003    对于此事件, WinEventProc 回调函数接收 OBJID_SOUND 值作为 idObject 参数。
1004    `func` 用于接收事件的监听器函数。
1005    */
1006    pub fn add_on_system_sound_listener(
1007        &self,
1008        func: impl Fn(WinEventSource) + Sync + Send + 'static,
1009    ) {
1010        self.events
1011            .write()
1012            .unwrap()
1013            .push(WinEventHook::new(EVENT_SYSTEM_SOUND, func));
1014    }
1015
1016    //noinspection SpellCheckingInspection
1017    /**
1018    用户已释放 Alt+TAB。 此事件由系统发送,从不由服务器发送。 WinEventProc 回调函数的 hwnd 参数标识用户已切换到的窗口。
1019    如果用户按下 Alt+TAB 时只有一个应用程序正在运行,则系统会发送此事件,而不发送相应的 EVENT_SYSTEM_SWITCHSTART 事件。
1020    `func` 用于接收事件的监听器函数。
1021    */
1022    pub fn add_on_system_switch_end_listener(
1023        &self,
1024        func: impl Fn(WinEventSource) + Sync + Send + 'static,
1025    ) {
1026        self.events
1027            .write()
1028            .unwrap()
1029            .push(WinEventHook::new(EVENT_SYSTEM_SWITCHEND, func));
1030    }
1031
1032    //noinspection SpellCheckingInspection
1033    /**
1034    用户已按 Alt+TAB,这会激活切换窗口。 此事件由系统发送,从不由服务器发送。 WinEventProc 回调函数的 hwnd 参数标识用户要切换到的窗口。
1035    如果用户按 Alt+TAB 时只有一个应用程序正在运行,则系统会发送 EVENT_SYSTEM_SWITCHEND 事件,而不发送相应的 EVENT_SYSTEM_SWITCHSTART 事件。
1036    `func` 用于接收事件的监听器函数。
1037    */
1038    pub fn add_on_system_switch_start_listener(
1039        &self,
1040        func: impl Fn(WinEventSource) + Sync + Send + 'static,
1041    ) {
1042        self.events
1043            .write()
1044            .unwrap()
1045            .push(WinEventHook::new(EVENT_SYSTEM_SWITCHSTART, func));
1046    }
1047
1048    /**
1049    移除所有注册的监听器。
1050    */
1051    pub fn remove_all_listeners(&self) {
1052        let mut lock = self.events.write().unwrap();
1053        for i in lock.iter() {
1054            i.unhook();
1055        }
1056        lock.clear();
1057    }
1058}
1059
1060impl Drop for Msaa {
1061    fn drop(&mut self) {
1062        self.remove_all_listeners()
1063    }
1064}
1065
1066#[cfg(test)]
1067mod test_msaa {
1068    use super::{super::common::get_desktop_window, object::ROLE_SYSTEM_WINDOW, Msaa};
1069
1070    #[test]
1071    fn main() {
1072        let msaa = Msaa::new();
1073        let obj = msaa.get_desktop_object().unwrap();
1074        assert!(obj.get_name(0).contains("桌面"));
1075        assert_eq!(obj.get_description(0), String::new());
1076        assert_eq!(obj.get_help(0), String::new());
1077        assert_eq!(obj.get_keyboard_shortcut(0), String::new());
1078        assert_eq!(obj.get_value(0), String::new());
1079        assert_eq!(obj.get_default_action(0), String::new());
1080        assert_eq!(obj.get_role(0), ROLE_SYSTEM_WINDOW);
1081        assert_eq!(obj.child_count(), 7);
1082        assert_eq!(obj.get_role_text(0), "窗口");
1083        assert_eq!(obj.get_state_text(0), "可设定焦点");
1084        assert_eq!(obj.window(), get_desktop_window());
1085
1086        let location = obj.location(0);
1087        dbg!(location);
1088        msaa.add_on_object_focus_listener(|src| {
1089            dbg!(src.get_object().unwrap());
1090        });
1091        std::thread::sleep(std::time::Duration::from_millis(5000));
1092        dbg!(msaa);
1093    }
1094}