Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passing hwnd to UIAutomation::element_from_handle #44

Closed
ddebta opened this issue Nov 10, 2023 · 2 comments
Closed

Passing hwnd to UIAutomation::element_from_handle #44

ddebta opened this issue Nov 10, 2023 · 2 comments

Comments

@ddebta
Copy link

ddebta commented Nov 10, 2023

Objective

Owing to stringent time constraints, instead of TreeWalk or via element childrens, directly get element_from_handle

Failed attempt # 1:

[using cargo.toml]

#[allow( unused_variables )]
use uiautomation::core::UIAutomation;

fn main() {
    let ui = UIAutomation::new().unwrap();
    let el = ui.element_from_handle( 0x2006C6 ).unwrap();
}

error[E0308]: mismatched types
let el = ui.element_from_handle( 0x2006C6 ).unwrap();
---------------------------------- ^^^^^^^^ expected Handle, found integer
-----------|arguments to this method are incorrect

Failed attempt # 2:

[using cargo.toml]

#[allow( unused_variables )]

use winapi::shared::windef::HWND;
use uiautomation::core::UIAutomation;

fn main() {
    let ui = UIAutomation::new().unwrap();
    let el = ui.element_from_handle( 0x2006C6 as HWND ).unwrap();
}

error[E0308]: mismatched types
let el = ui.element_from_handle( 0x2006C6 as HWND ).unwrap();
-------------------------------- ^^^^^^^^^^^^^^^^ expected Handle, found *mut HWND__
----------|arguments to this method are incorrect
note: expected struct Handle
found raw pointer *mut HWND__

Issue:

Although the errors are understandable, considering the parameters that element_from_handle method takes in, but got no clue how to resolve it !?


P. S. (rant)

Newly migrating from Python to Rust. Python's library uiautomation works like charm to read that integer as HWND, but, its slow. Hence, this migration.

In Python:

import uiautomation as ui

if __name__ == '__main__':
	el = ui.ControlFromHandle( 0x2006C6 )
	print( el )

Bingo "straightaway":

ControlType: TableControl
ClassName: WindowsForms10.Window.8.app.0.129c866_r8_ad1
AutomationId: dgv
Rect: (2150,123,2644,684)[494x561]
Name: 'DataGridView'
Handle: 0x2006C6(2098886)

Upon digging uiautomation python open source code, ControlFromHandle( integer ) simply returns ElementFromHandle(), like so:

def ControlFromHandle(handle: int) -> Control:
    """
    Call IUIAutomation.ElementFromHandle with a native handle.
    handle: int, a native window handle.
    Return `Control` subclass or None.
    """
    if handle:
        return Control.CreateControlFromElement(_AutomationClient.instance().IUIAutomation.ElementFromHandle(handle))

Furthermore, CreateControlFromElement() is simply:

@staticmethod
def CreateControlFromElement(element) -> 'Control':
    """
    Create a concreate `Control` from a com type `IUIAutomationElement`.
    element: `ctypes.POINTER(IUIAutomationElement)`.
    Return a subclass of `Control`, an instance of the control's real type.
    """
    if element:
        controlType = element.CurrentControlType
        if controlType in ControlConstructors:
            return ControlConstructors[controlType](element=element)
        else:
            Logger.WriteLine("element.CurrentControlType returns {}, invalid ControlType!".format(controlType), ConsoleColor.Red)  # rarely happens

Bottomline

In Python, the IUIAutomation wrapper's method ElementFromHandle accepts integer datatype for its handle parameter.
In Rust, the UIAutomation (same MS IUIAutomation wrapper) method element_from_handle needs what?

Something is missing, may be the answer lies in uiautomation::types::Handle!

@leexgone
Copy link
Owner

Supported in v0.7.2.
Now the isize can be converted into Handle.

    fn test_search_from_handle() {
        let auto = UIAutomation::new().unwrap();
        let _ = auto.element_from_handle(Handle::from(0x2006C6));
    }

@ddebta
Copy link
Author

ddebta commented Nov 11, 2023

Oh! I was using (crap):

use winapi::shared::windef::HWND;

As kindly shown by @leexgone, correct one is:

use windows::Win32::Foundation::HWND;

And many thanks to you @leexgone for this new implementation impl From<isize> for Handle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants