uiautomation 0.16.0

UI Automation Framework for Windows
Documentation
use windows::Win32::UI::Accessibility::IUIAutomationElement;
use windows::Win32::UI::Accessibility::IUIAutomationEventHandler;
use windows::Win32::UI::Accessibility::IUIAutomationEventHandler_Impl;
use windows::Win32::UI::Accessibility::IUIAutomationFocusChangedEventHandler;
use windows::Win32::UI::Accessibility::IUIAutomationFocusChangedEventHandler_Impl;
use windows::Win32::UI::Accessibility::IUIAutomationPropertyChangedEventHandler;
use windows::Win32::UI::Accessibility::IUIAutomationPropertyChangedEventHandler_Impl;
use windows::Win32::UI::Accessibility::IUIAutomationStructureChangedEventHandler;
use windows::Win32::UI::Accessibility::IUIAutomationStructureChangedEventHandler_Impl;
use windows::Win32::UI::Accessibility::UIA_EVENT_ID;
use windows::Win32::UI::Accessibility::UIA_PROPERTY_ID;
use windows_core::implement;

use crate::types::StructureChangeType;
use crate::variants::SafeArray;
use crate::variants::Variant;
use crate::UIElement;

use super::CustomEventHandlerFn;
use super::CustomFocusChangedEventHandlerFn;
use super::CustomPropertyChangedEventHandlerFn;
use super::CustomStructureChangedEventHandlerFn;

#[implement(IUIAutomationEventHandler)]
pub struct AutomationEventHandler {
    handler: Box<CustomEventHandlerFn>
}

impl IUIAutomationEventHandler_Impl for AutomationEventHandler_Impl {
    fn HandleAutomationEvent(&self, sender: windows_core::Ref<'_, IUIAutomationElement>, eventid: UIA_EVENT_ID) -> windows_core::Result<()> {
        if let Some(e) = sender.as_ref() {
            let element = UIElement::from(e);
            let handler = &self.handler;
            match eventid.try_into() {
                Ok(event_id) => handler(&element, event_id).map_err(|e| e.into()),
                Err(e) => Err(e.into())
            }
        } else {
            Ok(())
        }
    }
}

impl From<Box<CustomEventHandlerFn>> for AutomationEventHandler {
    fn from(handler: Box<CustomEventHandlerFn>) -> Self {
        Self {
            handler
        }
    }
}

#[implement(IUIAutomationPropertyChangedEventHandler)]
pub struct AutomationPropertyChangedEventHandler {
    handler: Box<CustomPropertyChangedEventHandlerFn>
}

impl IUIAutomationPropertyChangedEventHandler_Impl for AutomationPropertyChangedEventHandler_Impl {
    fn HandlePropertyChangedEvent(&self, sender: windows_core::Ref<'_, IUIAutomationElement>, propertyid: UIA_PROPERTY_ID, newvalue: &windows::Win32::System::Variant::VARIANT) -> windows_core::Result<()> {
        if let Some(e) = sender.as_ref() {
            let element = UIElement::from(e);
            let value = Variant::from(newvalue);
            let handler = &self.handler;
            match propertyid.try_into() {
                Ok(property_id) => handler(&element, property_id, value).map_err(|e| e.into()),
                Err(e) => Err(e.into()),
            }
        } else {
            Ok(())
        }
    }
}

impl From<Box<CustomPropertyChangedEventHandlerFn>> for AutomationPropertyChangedEventHandler {
    fn from(handler: Box<CustomPropertyChangedEventHandlerFn>) -> Self {
        Self {
            handler
        }
    }
}

#[implement(IUIAutomationStructureChangedEventHandler)]
pub struct AutomationStructureChangedEventHandler { 
    handler: Box<CustomStructureChangedEventHandlerFn>
}

impl IUIAutomationStructureChangedEventHandler_Impl for AutomationStructureChangedEventHandler_Impl {
    fn HandleStructureChangedEvent(&self, sender: windows_core::Ref<'_, IUIAutomationElement>, changetype: windows::Win32::UI::Accessibility::StructureChangeType, runtimeid: *const windows::Win32::System::Com::SAFEARRAY) -> windows_core::Result<()> {
        if let Some(e) = sender.as_ref() {
            let handler = &self.handler;
            let element = UIElement::from(e);
            let arr = SafeArray::from(runtimeid);
            let change_type: StructureChangeType = match changetype.try_into() {
                Ok(change_type) => change_type,
                Err(e) => return Err(e.into()),
            };
            let ret = if arr.is_null() {
                handler(&element, change_type, None)
            } else {
                let runtime_id: Vec<i32> = match arr.try_into() {
                    Ok(arr) => arr,
                    Err(e) => return  Err(e.into())
                };
                handler(&element, change_type, Some(&runtime_id))
            };
            ret.map_err(|e| e.into())
        } else {
            Ok(())
        }
    }
}

impl From<Box<CustomStructureChangedEventHandlerFn>> for AutomationStructureChangedEventHandler {
    fn from(handler: Box<CustomStructureChangedEventHandlerFn>) -> Self {
        Self {
            handler
        }
    }
}

#[implement(IUIAutomationFocusChangedEventHandler)]
pub struct AutomationFocusChangedEventHandler {
    handler: Box<CustomFocusChangedEventHandlerFn>
}

impl IUIAutomationFocusChangedEventHandler_Impl for AutomationFocusChangedEventHandler_Impl {
    fn HandleFocusChangedEvent(&self, sender: windows_core::Ref<'_, IUIAutomationElement>) -> windows_core::Result<()> {
        if let Some(e) = sender.as_ref() {
            let element = UIElement::from(e);
            let handler = &self.handler;
            handler(&element).map_err(|e| e.into())
        } else {
            Ok(())
        }
    }
}

impl From<Box<CustomFocusChangedEventHandlerFn>> for AutomationFocusChangedEventHandler {
    fn from(handler: Box<CustomFocusChangedEventHandlerFn>) -> Self {
        Self {
            handler
        }
    }
}