use std::ffi::c_void;
use std::fmt::Debug;
use std::fmt::Display;
use uiautomation_derive::EnumConvert;
use uiautomation_derive::map_as;
use windows::Win32::Foundation::HWND;
use windows::Win32::Foundation::POINT;
use windows::Win32::Foundation::RECT;
#[derive(Clone, Copy, PartialEq, Default)]
pub struct Point(POINT);
impl Point {
pub fn new(x: i32, y: i32) -> Self {
Self(POINT {
x,
y
})
}
pub fn get_x(&self) -> i32 {
self.0.x
}
pub fn set_x(&mut self, x: i32) {
self.0.x = x;
}
pub fn get_y(&self) -> i32 {
self.0.y
}
pub fn set_y(&mut self, y: i32) {
self.0.y = y;
}
}
impl Eq for Point {
}
impl Debug for Point {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Point").field("x", &self.0.x).field("y", &self.0.y).finish()
}
}
impl Display for Point {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "({}, {})", self.0.x, self.0.y)
}
}
impl From<POINT> for Point {
fn from(point: POINT) -> Self {
Self(point)
}
}
impl Into<POINT> for Point {
fn into(self) -> POINT {
self.0
}
}
impl AsRef<POINT> for Point {
fn as_ref(&self) -> &POINT {
&self.0
}
}
impl AsMut<POINT> for Point {
fn as_mut(&mut self) -> &mut POINT {
&mut self.0
}
}
#[derive(Clone, Copy, PartialEq, Default)]
pub struct Rect(RECT);
impl Rect {
pub fn new(left: i32, top: i32, right: i32, bottom: i32) -> Self {
Self(RECT {
left,
top,
right,
bottom
})
}
pub fn get_left(&self) -> i32 {
self.0.left
}
pub fn set_left(&mut self, left: i32) {
self.0.left = left;
}
pub fn get_top(&self) -> i32 {
self.0.top
}
pub fn set_top(&mut self, top: i32) {
self.0.top = top;
}
pub fn get_right(&self) -> i32 {
self.0.right
}
pub fn set_right(&mut self, right: i32) {
self.0.right = right;
}
pub fn get_bottom(&self) -> i32 {
self.0.bottom
}
pub fn set_bottom(&mut self, bottom: i32) {
self.0.bottom = bottom;
}
pub fn get_top_left(&self) -> Point {
Point::new(self.get_left(), self.get_top())
}
pub fn get_right_bottom(&self) -> Point {
Point::new(self.get_right(), self.get_bottom())
}
pub fn get_width(&self) -> i32 {
self.0.right - self.0.left + 1
}
pub fn get_height(&self) -> i32 {
self.0.bottom - self.0.top + 1
}
}
impl Eq for Rect {
}
impl Debug for Rect {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Rect").field("left", &self.0.left).field("top", &self.0.top).field("right", &self.0.right).field("bottom", &self.0.bottom).finish()
}
}
impl Display for Rect {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "[({}, {}), ({}, {})]", self.0.left, self.0.top, self.0.right, self.0.bottom)
}
}
impl From<RECT> for Rect {
fn from(rect: RECT) -> Self {
Self(rect)
}
}
impl Into<RECT> for Rect {
fn into(self) -> RECT {
self.0
}
}
impl AsRef<RECT> for Rect {
fn as_ref(&self) -> &RECT {
&self.0
}
}
impl AsMut<RECT> for Rect {
fn as_mut(&mut self) -> &mut RECT {
&mut self.0
}
}
#[derive(Default, Clone, Copy)]
pub struct Handle(HWND);
impl Debug for Handle {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let v: isize = unsafe {
std::mem::transmute(self.0.0)
};
write!(f, "Handle(0x{:X})", v)
}
}
impl Display for Handle {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self.0)
}
}
impl From<HWND> for Handle {
fn from(hwnd: HWND) -> Self {
Self(hwnd)
}
}
impl Into<HWND> for Handle {
fn into(self) -> HWND {
self.0
}
}
impl AsRef<HWND> for Handle {
fn as_ref(&self) -> &HWND {
&self.0
}
}
impl From<isize> for Handle {
fn from(value: isize) -> Self {
let hwd: *mut c_void = unsafe {
std::mem::transmute(value)
};
Self(HWND(hwd))
}
}
impl Into<isize> for Handle {
fn into(self) -> isize {
unsafe {
std::mem::transmute(self.0.0)
}
}
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumConvert)]
#[map_as(windows::Win32::UI::Accessibility::UIA_PROPERTY_ID)]
pub enum UIProperty {
RuntimeId = 30000i32,
BoundingRectangle = 30001i32,
ProcessId = 30002i32,
ControlType = 30003i32,
LocalizedControlType = 30004i32,
Name = 30005i32,
AcceleratorKey = 30006i32,
AccessKey = 30007i32,
HasKeyboardFocus = 30008i32,
IsKeyboardFocusable = 30009i32,
IsEnabled = 30010i32,
AutomationId = 30011i32,
ClassName = 30012i32,
HelpText = 30013i32,
ClickablePoint = 30014i32,
Culture = 30015i32,
IsControlElement = 30016i32,
IsContentElement = 30017i32,
LabeledBy = 30018i32,
IsPassword = 30019i32,
NativeWindowHandle = 30020i32,
ItemType = 30021i32,
IsOffscreen = 30022i32,
Orientation = 30023i32,
FrameworkId = 30024i32,
IsRequiredForForm = 30025i32,
ItemStatus = 30026i32,
IsDockPatternAvailable = 30027i32,
IsExpandCollapsePatternAvailable = 30028i32,
IsGridItemPatternAvailable = 30029i32,
IsGridPatternAvailable = 30030i32,
IsInvokePatternAvailable = 30031i32,
IsMultipleViewPatternAvailable = 30032i32,
IsRangeValuePatternAvailable = 30033i32,
IsScrollPatternAvailable = 30034i32,
IsScrollItemPatternAvailable = 30035i32,
IsSelectionItemPatternAvailable = 30036i32,
IsSelectionPatternAvailable = 30037i32,
IsTablePatternAvailable = 30038i32,
IsTableItemPatternAvailable = 30039i32,
IsTextPatternAvailable = 30040i32,
IsTogglePatternAvailable = 30041i32,
IsTransformPatternAvailable = 30042i32,
IsValuePatternAvailable = 30043i32,
IsWindowPatternAvailable = 30044i32,
ValueValue = 30045i32,
ValueIsReadOnly = 30046i32,
RangeValueValue = 30047i32,
RangeValueIsReadOnly = 30048i32,
RangeValueMinimum = 30049i32,
RangeValueMaximum = 30050i32,
RangeValueLargeChange = 30051i32,
RangeValueSmallChange = 30052i32,
ScrollHorizontalScrollPercent = 30053i32,
ScrollHorizontalViewSize = 30054i32,
ScrollVerticalScrollPercent = 30055i32,
ScrollVerticalViewSize = 30056i32,
ScrollHorizontallyScrollable = 30057i32,
ScrollVerticallyScrollable = 30058i32,
SelectionSelection = 30059i32,
SelectionCanSelectMultiple = 30060i32,
SelectionIsSelectionRequired = 30061i32,
GridRowCount = 30062i32,
GridColumnCount = 30063i32,
GridItemRow = 30064i32,
GridItemColumn = 30065i32,
GridItemRowSpan = 30066i32,
GridItemColumnSpan = 30067i32,
GridItemContainingGrid = 30068i32,
DockDockPosition = 30069i32,
ExpandCollapseExpandCollapseState = 30070i32,
MultipleViewCurrentView = 30071i32,
MultipleViewSupportedViews = 30072i32,
WindowCanMaximize = 30073i32,
WindowCanMinimize = 30074i32,
WindowWindowVisualState = 30075i32,
WindowWindowInteractionState = 30076i32,
WindowIsModal = 30077i32,
WindowIsTopmost = 30078i32,
SelectionItemIsSelected = 30079i32,
SelectionItemSelectionContainer = 30080i32,
TableRowHeaders = 30081i32,
TableColumnHeaders = 30082i32,
TableRowOrColumnMajor = 30083i32,
TableItemRowHeaderItems = 30084i32,
TableItemColumnHeaderItems = 30085i32,
ToggleToggleState = 30086i32,
TransformCanMove = 30087i32,
TransformCanResize = 30088i32,
TransformCanRotate = 30089i32,
IsLegacyIAccessiblePatternAvailable = 30090i32,
LegacyIAccessibleChildId = 30091i32,
LegacyIAccessibleName = 30092i32,
LegacyIAccessibleValue = 30093i32,
LegacyIAccessibleDescription = 30094i32,
LegacyIAccessibleRole = 30095i32,
LegacyIAccessibleState = 30096i32,
LegacyIAccessibleHelp = 30097i32,
LegacyIAccessibleKeyboardShortcut = 30098i32,
LegacyIAccessibleSelection = 30099i32,
LegacyIAccessibleDefaultAction = 30100i32,
AriaRole = 30101i32,
AriaProperties = 30102i32,
IsDataValidForForm = 30103i32,
ControllerFor = 30104i32,
DescribedBy = 30105i32,
FlowsTo = 30106i32,
ProviderDescription = 30107i32,
IsItemContainerPatternAvailable = 30108i32,
IsVirtualizedItemPatternAvailable = 30109i32,
IsSynchronizedInputPatternAvailable = 30110i32,
OptimizeForVisualContent = 30111i32,
IsObjectModelPatternAvailable = 30112i32,
AnnotationAnnotationTypeId = 30113i32,
AnnotationAnnotationTypeName = 30114i32,
AnnotationAuthor = 30115i32,
AnnotationDateTime = 30116i32,
AnnotationTarget = 30117i32,
IsAnnotationPatternAvailable = 30118i32,
IsTextPattern2Available = 30119i32,
StylesStyleId = 30120i32,
StylesStyleName = 30121i32,
StylesFillColor = 30122i32,
StylesFillPatternStyle = 30123i32,
StylesShape = 30124i32,
StylesFillPatternColor = 30125i32,
StylesExtendedProperties = 30126i32,
IsStylesPatternAvailable = 30127i32,
IsSpreadsheetPatternAvailable = 30128i32,
SpreadsheetItemFormula = 30129i32,
SpreadsheetItemAnnotationObjects = 30130i32,
SpreadsheetItemAnnotationTypes = 30131i32,
IsSpreadsheetItemPatternAvailable = 30132i32,
Transform2CanZoom = 30133i32,
IsTransformPattern2Available = 30134i32,
LiveSetting = 30135i32,
IsTextChildPatternAvailable = 30136i32,
IsDragPatternAvailable = 30137i32,
DragIsGrabbed = 30138i32,
DragDropEffect = 30139i32,
DragDropEffects = 30140i32,
IsDropTargetPatternAvailable = 30141i32,
DropTargetDropTargetEffect = 30142i32,
DropTargetDropTargetEffects = 30143i32,
DragGrabbedItems = 30144i32,
Transform2ZoomLevel = 30145i32,
Transform2ZoomMinimum = 30146i32,
Transform2ZoomMaximum = 30147i32,
FlowsFrom = 30148i32,
IsTextEditPatternAvailable = 30149i32,
IsPeripheral = 30150i32,
IsCustomNavigationPatternAvailable = 30151i32,
PositionInSet = 30152i32,
SizeOfSet = 30153i32,
Level = 30154i32,
AnnotationTypes = 30155i32,
AnnotationObjects = 30156i32,
LandmarkType = 30157i32,
LocalizedLandmarkType = 30158i32,
FullDescription = 30159i32,
FillColor = 30160i32,
OutlineColor = 30161i32,
FillType = 30162i32,
VisualEffects = 30163i32,
OutlineThickness = 30164i32,
CenterPoint = 30165i32,
Rotation = 30166i32,
Size = 30167i32,
IsSelectionPattern2Available = 30168i32,
Selection2FirstSelectedItem = 30169i32,
Selection2LastSelectedItem = 30170i32,
Selection2CurrentSelectedItem = 30171i32,
Selection2ItemCount = 30172i32,
HeadingLevel = 30173i32,
IsDialog = 30174i32,
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumConvert)]
#[map_as(windows::Win32::UI::Accessibility::WindowInteractionState)]
pub enum WindowInteractionState {
Running = 0i32,
Closing = 1i32,
ReadyForUserInteraction = 2i32,
BlockedByModalWindow = 3i32,
NotResponding = 4i32
}
#[repr(i32)]
enum Test {
A = 0i32,
B = 1i32,
}
impl TryFrom<i32> for Test {
type Error = ();
fn try_from(value: i32) -> Result<Self, Self::Error> {
match value {
0 => Ok(Self::A),
1 => Ok(Self::B),
_ => Err(())
}
}
}
impl TryFrom<windows::Win32::UI::Accessibility::WindowInteractionState> for Test {
type Error = ();
fn try_from(value: windows::Win32::UI::Accessibility::WindowInteractionState) -> Result<Self, Self::Error> {
value.0.try_into()
}
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumConvert)]
#[map_as(windows::Win32::UI::Accessibility::DockPosition)]
pub enum DockPosition {
Top = 0i32,
Left = 1i32,
Bottom = 2i32,
Right = 3i32,
Fill = 4i32,
None = 5i32,
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumConvert)]
#[map_as(windows::Win32::UI::Accessibility::ExpandCollapseState)]
pub enum ExpandCollapseState {
Collapsed = 0i32,
Expanded = 1i32,
PartiallyExpanded = 2i32,
LeafNode = 3i32
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumConvert)]
#[map_as(windows::Win32::UI::Accessibility::NavigateDirection)]
pub enum NavigateDirection {
Parent = 0i32,
NextSibling = 1i32,
PreviousSibling = 2i32,
FirstChild = 3i32,
LastChild = 4i32
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumConvert)]
#[map_as(windows::Win32::UI::Accessibility::RowOrColumnMajor)]
pub enum RowOrColumnMajor {
RowMajor = 0i32,
ColumnMajor = 1i32,
Indeterminate = 2i32
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumConvert)]
#[map_as(windows::Win32::UI::Accessibility::ScrollAmount)]
pub enum ScrollAmount {
LargeDecrement = 0i32,
SmallDecrement = 1i32,
NoAmount = 2i32,
LargeIncrement = 3i32,
SmallIncrement = 4i32
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumConvert)]
#[map_as(windows::Win32::UI::Accessibility::SupportedTextSelection)]
pub enum SupportedTextSelection {
None = 0i32,
Single = 1i32,
Multiple = 2i32,
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumConvert)]
#[map_as(windows::Win32::UI::Accessibility::ToggleState)]
pub enum ToggleState {
Off = 0i32,
On = 1i32,
Indeterminate = 2i32,
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumConvert)]
#[map_as(windows::Win32::UI::Accessibility::ZoomUnit)]
pub enum ZoomUnit {
NoAmount = 0i32,
LargeDecrement = 1i32,
SmallDecrement = 2i32,
LargeIncrement = 3i32,
SmallIncrement = 4i32,
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumConvert)]
#[map_as(windows::Win32::UI::Accessibility::WindowVisualState)]
pub enum WindowVisualState {
Normal = 0i32,
Maximized = 1i32,
Minimized = 2i32
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumConvert)]
#[map_as(windows::Win32::UI::Accessibility::TextUnit)]
pub enum TextUnit {
Character = 0i32,
Format = 1i32,
Word = 2i32,
Line = 3i32,
Paragraph = 4i32,
Page = 5i32,
Document = 6i32,
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumConvert)]
#[map_as(windows::Win32::UI::Accessibility::TextPatternRangeEndpoint)]
pub enum TextPatternRangeEndpoint {
Start = 0i32,
End = 1i32,
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumConvert)]
#[map_as(windows::Win32::UI::Accessibility::OrientationType)]
pub enum OrientationType {
None = 0i32,
Horizontal = 1i32,
Vertical = 2i32
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumConvert)]
#[map_as(windows::Win32::UI::Accessibility::PropertyConditionFlags)]
pub enum PropertyConditionFlags {
None = 0i32,
IgnoreCase = 1i32,
MatchSubstring = 2i32,
All = 3i32
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumConvert)]
#[map_as(windows::Win32::UI::Accessibility::TreeScope)]
pub enum TreeScope {
None = 0i32,
Element = 1i32,
Children = 2i32,
Descendants = 4i32,
Parent = 8i32,
Ancestors = 16i32,
Subtree = 7i32
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumConvert)]
#[map_as(windows::Win32::UI::Accessibility::UIA_ANNOTATIONTYPE)]
pub enum AnnotationType {
Unknown = 60000i32,
SpellingError = 60001i32,
GrammarError = 60002i32,
Comment = 60003i32,
FormulaError = 60004i32,
TrackChanges = 60005i32,
Header = 60006i32,
Footer = 60007i32,
Highlighted = 60008i32,
Endnote = 60009i32,
Footnote = 60010i32,
InsertionChange = 60011i32,
DeletionChange = 60012i32,
MoveChange = 60013i32,
FormatChange = 60014i32,
UnsyncedChange = 60015i32,
EditingLockedChange = 60016i32,
ExternalChange = 60017i32,
ConflictingChange = 60018i32,
Author = 60019i32,
AdvancedProofingIssue = 60020i32,
DataValidationError = 60021i32,
CircularReferenceError = 60022i32,
Mathematics = 60023i32,
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumConvert)]
#[map_as(windows::Win32::UI::Accessibility::UIA_HEADINGLEVEL_ID)]
pub enum HeadingLevel {
HeadingLevelNone = 80050i32,
HeadingLevel1 = 80051i32,
HeadingLevel2 = 80052i32,
HeadingLevel3 = 80053i32,
HeadingLevel4 = 80054i32,
HeadingLevel5 = 80055i32,
HeadingLevel6 = 80056i32,
HeadingLevel7 = 80057i32,
HeadingLevel8 = 80058i32,
HeadingLevel9 = 80059i32
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumConvert)]
#[map_as(windows::Win32::UI::Accessibility::UIA_STYLE_ID)]
pub enum StyleType {
Custom = 70000i32,
Heading1 = 70001i32,
Heading2 = 70002i32,
Heading3 = 70003i32,
Heading4 = 70004i32,
Heading5 = 70005i32,
Heading6 = 70006i32,
Heading7 = 70007i32,
Heading8 = 70008i32,
Heading9 = 70009i32,
Title = 70010i32,
Subtitle = 70011i32,
Normal = 70012i32,
Emphasis = 70013i32,
Quote = 70014i32,
BulletedList = 70015i32,
NumberedList = 70016i32,
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumConvert)]
#[map_as(windows::Win32::UI::Accessibility::UIA_TEXTATTRIBUTE_ID)]
pub enum TextAttribute {
AnimationStyle = 40000i32,
BackgroundColor = 40001i32,
BulletStyle = 40002i32,
CapStyle = 40003i32,
Culture = 40004i32,
FontName = 40005i32,
FontSize = 40006i32,
FontWeight = 40007i32,
ForegroundColor = 40008i32,
HorizontalTextAlignment = 40009i32,
IndentationFirstLine = 40010i32,
IndentationLeading = 40011i32,
IndentationTrailing = 40012i32,
IsHidden = 40013i32,
IsItalic = 40014i32,
IsReadOnly = 40015i32,
IsSubscript = 40016i32,
IsSuperscript = 40017i32,
MarginBottom = 40018i32,
MarginLeading = 40019i32,
MarginTop = 40020i32,
MarginTrailing = 40021i32,
OutlineStyles = 40022i32,
OverlineColor = 40023i32,
OverlineStyle = 40024i32,
StrikethroughColor = 40025i32,
StrikethroughStyle = 40026i32,
Tabs = 40027i32,
TextFlowDirections = 40028i32,
UnderlineColor = 40029i32,
UnderlineStyle = 40030i32,
AnnotationTypes = 40031i32,
AnnotationObjects = 40032i32,
StyleName = 40033i32,
StyleId = 40034i32,
Link = 40035i32,
IsActive = 40036i32,
SelectionActiveEnd = 40037i32,
CaretPosition = 40038i32,
CaretBidiMode = 40039i32,
LineSpacing = 40040i32,
BeforeParagraphSpacing = 40041i32,
AfterParagraphSpacing = 40042i32,
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumConvert)]
#[map_as(windows::Win32::UI::Accessibility::AutomationElementMode)]
pub enum ElementMode {
None = 0i32,
Full = 1i32
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumConvert)]
#[map_as(windows::Win32::UI::Accessibility::StructureChangeType)]
pub enum StructureChangeType {
ChildAdded = 0i32,
ChildRemoved = 1i32,
ChildrenInvalidated = 2i32,
ChildrenBulkAdded = 3i32,
ChildrenBulkRemoved = 4i32,
ChildrenReordered = 5i32
}
#[cfg(test)]
mod tests {
use windows::Win32::UI::Accessibility;
use super::WindowInteractionState;
#[test]
fn test_window_interaction_state() {
assert_eq!(Ok(WindowInteractionState::Running), WindowInteractionState::try_from(0));
assert_eq!(Ok(WindowInteractionState::NotResponding), WindowInteractionState::try_from(4));
assert!(WindowInteractionState::try_from(100).is_err());
assert_eq!(1i32, WindowInteractionState::Closing as i32);
assert_eq!(Accessibility::WindowInteractionState_ReadyForUserInteraction, WindowInteractionState::ReadyForUserInteraction.into());
assert_eq!(WindowInteractionState::Running, Accessibility::WindowInteractionState_Running.try_into().unwrap());
let running = format!("{}", WindowInteractionState::Running);
assert_eq!(running, "Running");
}
#[test]
fn test_handle() {
let handle = crate::types::Handle::from(0x001);
assert_eq!(windows::Win32::Foundation::HWND(unsafe { std::mem::transmute(0x001isize) } ), handle.into());
}
}