Jump to content
junkew

IUIAutomation MS framework automate chrome, FF, IE, ....

Recommended Posts

Thank you for information LarsJ. I was able to use the Spy script at the site provided and it worked perfectly. 

Good point on the enabling/disabling of UI Automation (needing a good reason to remove the functionality).

Do you know if Silverlight 5 works with UI Automation? I have seen some posts that say it wasn't supported / hasn't been implemented yet but they were out of date.

Share this post


Link to post
Share on other sites

What is the difference between the two versions of cuiautomation2.au3?

The Small one has fixes but not compatible with uiawrappers and all examples. I will make things compatible with the smallest cuiautomation over time and then the other one will be removed.

Share this post


Link to post
Share on other sites

Another bunch of weird applications I need to automate...

This time I struggle with ListBox control (not ordinary List control), which provides no information except RunTimeIds although each listItem has a text label associated with each listItem.

I try to create RunTimeId condition but it looks like it's the most sophisticated thing I've ever tried to do in my life.

Since RunTimeId is an integer array and CreateCondition method takes VARIANT parameter I need a way to convert my int array into VARIANT.

But VARIANT includes only pointer to SafeArray, so first I need to convert my array into SafeArray.

Can anyone provide any information how to deal with SafeArrays and VARIANT data types so I can perform the following simplest thing

  Local $array[] = [42, 459113, 2, 5] ; RunTimeId

  $oUIAutomation.CreatePropertyCondition($UIA_RuntimeIdPropertyId, $array, $pControlTypeCondition)

Share this post


Link to post
Share on other sites

Another bunch of weird applications I need to automate...

This time I struggle with ListBox control (not ordinary List control), which provides no information except RunTimeIds although each listItem has a text label associated with each listItem.

I try to create RunTimeId condition but it looks like it's the most sophisticated thing I've ever tried to do in my life.

Since RunTimeId is an integer array and CreateCondition method takes VARIANT parameter I need a way to convert my int array into VARIANT.

But VARIANT includes only pointer to SafeArray, so first I need to convert my array into SafeArray.

Can anyone provide any information how to deal with SafeArrays and VARIANT data types so I can perform the following simplest thing

  Local $array[] = [42, 459113, 2, 5] ; RunTimeId

  $oUIAutomation.CreatePropertyCondition($UIA_RuntimeIdPropertyId, $array, $pControlTypeCondition)

 

See SafeArray UDF by LarsJ above

Message Posted 01 February 2014 - 07:06 AM

Share this post


Link to post
Share on other sites

Local $pRuntimeIdCondition
  Local $aArray[] = [42, 7996200, 2, 5]
  ;Local $aSafeArray = __Au3Obj_CreateSafeArrayVariant($aArray)
  ;$oUIAutomation.CreatePropertyCondition($UIA_RuntimeIdPropertyId, $aSafeArray, $pNameCondition)
  Local $pVar = _AutoItObject_VariantSet(0, $aArray)
  $oUIAutomation.CreatePropertyCondition($UIA_RuntimeIdPropertyId, $pVar, $pRuntimeIdCondition)
  If Not $pRuntimeIdCondition Then Return
  ConsoleWrite(@CRLF & "--- Line of Glory ---" & @CRLF & @CRLF)
I've found AutoItObject.au3 file and tried to use it but still doesn't work.

On msdn it is said that CreatePropertyCondition takes

[in] VARIANT value,

But _AutoItObject_VariantSet returns

Success - Pointer to the VARIANT

How can I dereference the pointer to pass it into CreatePropertyCondition ?

Or maybe I didn't get properly what RuntimeId should look like: in UISpy I get 42 7996200 2 5. Is it the same as $aArray[] = [42, 7996200, 2, 5] ?

UPD. Thanx ValeryVal. Just saw your message. Looks like it's exactly what I'm searching for!

UPD. No. After 20 hours still understand nothing...

CreatePropertyCondition takes VARIANT

VARIANT is a structure
{
  VARTYPE intEnumVal;  // VT_ARRAY = 0x2000 (safe array) looks good but since we cannot pass SafeArray into CreatePropertyCondition (only pointer to SafeArray) so we choose SAFEARRAY* pArray

  ...
  union
  {
    SAFEARRAY* pArray; // The chosen son!
    ...
    
  }
Next step:

Func SafeArrayCreateVector( $sType, $iRows ) // Call it like this: $ptrSafeArray = SafeArrayCreateVector ("int", 4)
  ...

  Return $pSafeArray // pointer - perfect

EndFunc



// RuntimeId property construction

SafeArrayPutElement($ptrSafeArray, 0, 45)

SafeArrayPutElement($ptrSafeArray, 1, 7996200)

SafeArrayPutElement($ptrSafeArray, 2, 2)

SafeArrayPutElement($ptrSafeArray, 3, 5)
Last step:
$oUIAutomation.CreatePropertyCondition($UIA_RuntimeIdPropertyId, $ptrSafeArray, $pRuntimeIdCondition)
Breaks on this line:
If Not $pRuntimeIdCondition Then Return
Edited by Kolokolcev

Share this post


Link to post
Share on other sites

One additional notice:

RuntimeId learned from junkew's SpyTool.au3:

UIA_RuntimeIdPropertyId :=42;3670368;2;-2147483647;3670368;-4;6
 

RuntimeId learned from MS UI Spy:

RuntimeId: "42 3670368 2 5"
Looks like one of the tools returns incorrect value.

Share this post


Link to post
Share on other sites

MS UI Spy is an old program based on MSAA. That's the reason why it gives wrong (UI Automation) results. If you use Inspect.exe (also MS) and selects UI Automation mode, you'll get exactly the same results as the Spy tool by junkew.

It's not easy to create a property condition with this code:

$oUIAutomation.CreatePropertyCondition($UIA_RuntimeIdPropertyId, $variant, $pRuntimeIdCondition)

I've done a few tests, but I have not succeeded.

The middle parameter is a variant (not a safearray) that contains an array (a safearray). You can define a variant in this way:

Local Const $tagVARIANT = "word vt;word r1;word r2;word r3;ptr data; ptr;"
Local $tVARIANT = DllStructCreate( $tagVARIANT )

vt should look like this:

Local Const $VT_I4      = 3
Local Const $VT_ARRAY   = 0x2000
DllStructSetData( $tVARIANT, "vt", BitOR( $VT_ARRAY, $VT_I4 ) )

You can create a safearry as shown in post #167. Alternatively you can use this code:

Local $tInt = DllStructCreate( "int[4]" )
DllStructSetData( $tInt, 1, 45, 1 )
DllStructSetData( $tInt, 1, 7996200, 2 )
DllStructSetData( $tInt, 1, 2, 3 )
DllStructSetData( $tInt, 1, 5, 4 )
Local $pSafeArray
$oUIAutomation.IntNativeArrayToSafeArray( DllStructGetPtr( $tInt ), 4, $pSafeArray )
If Not $pSafeArray Then
  ConsoleWrite( "IntNativeArrayToSafeArray: ERR" & @CRLF )
  Return
EndIf
ConsoleWrite( "IntNativeArrayToSafeArray: OK" & @CRLF )

Now you can add the safearray to the variant:

DllStructSetData( $tVARIANT, "data", $pSafeArray )

To be able to create the property condition you must redefine the description of CreatePropertyCondition:

"CreatePropertyCondition hresult(int;ptr;ptr*);"

Running this code will lead to an immediate crash:

Local $pRuntimeIdCondition
$oUIAutomation.CreatePropertyCondition( $UIA_RuntimeIdPropertyId, DllStructGetPtr( $tVARIANT ), $pRuntimeIdCondition )

I do not know what is wrong. The code is probably too simplistic. I will look at it over the weekend. I'll be back.

Share this post


Link to post
Share on other sites

Be aware that uiawrappers.au3 in 

;~ Just return a single property or if its an array string them together
func _UIA_getPropertyValue($obj, $id)
    local $tval
    local $tStr

    if not isobj($obj) Then
        seterror(1,0,0)
        return "** NO PROPERTYVALUE DUE TO NONEXISTING OBJECT **"
    EndIf

    $obj.GetCurrentPropertyValue($Id,$tVal)
    $tStr=""
    if isarray($tVal) Then
        $tStr="array:"
        for $i=0 to ubound($tval)-1
            $tStr=$tStr & $tVal[$i]
            if $i <> ubound($tVal)-1 Then
                $tStr=$tStr & ";"
            endif
        Next
        return $tStr
    endIf
    return $tVal
EndFunc 

is concatening arrays to a string splittable by a semicolon thats the reason simple spy returns with semicolon for runtimeid

above slightly modified function to prefix with array: just for demonstrational purpose

I have runtime ids with variable number of integers in the array

this one for scite tab example has an array of 7 integers

UIA_RuntimeIdPropertyId :=array:42;198014;2;-2147483647;198014;-4;36

Edited by junkew

Share this post


Link to post
Share on other sites

LarsJ, why we need to do this:

To be able to create the property condition you must redefine the description of CreatePropertyCondition:

"CreatePropertyCondition hresult(int;ptr;ptr*);"

 

variant type is not convenient?

I've also changed IntNativeArrayToSafeArray description from

"IntNativeArrayToSafeArray hresult(int;int;ptr*);" & _
to
"IntNativeArrayToSafeArray hresult(int;ptr;ptr*);" & _

but still no success.

I've tried all the following combinations of VARIANT structure depending of whether _CreateSafeArray function returns SAFEARRAY* pSafeArray or SAFEARRAY** ppSafeArray (in case of IntNativeArrayToSafeArray ):

vt = VT_I4 | VT_ARRAY
data = pSafeArray

vt = VT_I4 | VT_ARRAY
data = ppSafeArray

vt = VT_SAFEARRAY
data = pSafeArray

vt = VT_SAFEARRAY
data = ppSafeArray

vt = VT_PTR
data = pSafeArray

vt = VT_PTR
data = ppSafeArray

... with no success :(

 
P.S. However it looks like there is no VT_SAFEARRAY and VT_PTR types in UIAutomation:
typedef unsigned short VARTYPE;
enum VARENUM {
  VT_EMPTY = 0, 
  VT_NULL = 1, 
  VT_I2 = 2, 
  VT_I4 = 3, 
  VT_R4 = 4, 
  VT_R8 = 5, 
  VT_CY = 6, 
  VT_DATE = 7, 
  VT_BSTR = 8, 
  VT_DISPATCH = 9, 
  VT_ERROR = 10, 
  VT_BOOL = 11, 
  VT_VARIANT = 12, 
  VT_UNKNOWN = 13, 
  VT_UI1 = 17, 
};
VT_RESERVED = 0x8000
VT_BYREF = 0x4000
VT_ARRAY = 0x2000

When we construct VARIANT structure what kind of information we should place in vt field: type of the element or type of the whole structure. How to distinguish in vt field the following types: SAFEARRAY, SAFEARRAY* and SAFEARRAY**?

Edited by Kolokolcev

Share this post


Link to post
Share on other sites

I got it to work last night, but it was late. Here it is.

To run this example you need CUIAutomation2.au3 (the smallest) in post #1 and SafeArray.au3 in post #135.

You must change the description string for CreatePropertyCondition method of the IUIAutomation object in CUIAutomation2.au3. You still need the old description, so create a copy.

If you are running a 32 bit script, you must change the CreatePropertyCondition description in this way:

"CreatePropertyCondition hresult(int;uint64;uint64;ptr*);"

If you are running a 64 bit script, you must change the CreatePropertyCondition description in this way:

"CreatePropertyCondition hresult(int;ptr;ptr*);"

You need this description for an advanced data type like a structure (created with DllStructCreate). For simple data types like numbers and strings, you still use the old description with a variant. The reason for two new defitions are caused by differences in parameter transfer on 32 and 64 bit systems.

Kolokolcev, Your redefinition of IntNativeArrayToSafeArray is wrong, and tells me that you are running a 32 bit script, since this definition will not work for a 64 bit script.

To run the example you must fill out $aRuntimeIdPropertyId[] in top of the script with the Spy tool:

#include "CUIAutomation2.au3"
#include "SafeArray.au3"

Opt( "MustDeclareVars", 1 )

Global $oUIAutomation

; Insert RuntimeIdPropertyId values from Spy tool in array (probably 2 - 7 rows)
Global $aRuntimeIdPropertyId[]  = [ 42, 328472, 1, -2147483647, 328472, -2, 0 ] ; Windows Explorer title bar
;Global $aRuntimeIdPropertyId[] = [ 42, 787258, 1, -2147483647, 787258, -2, 0 ] ; Calculator title bar

MainFunc( $aRuntimeIdPropertyId )


Func MainFunc( $aRnTmIdPrpId )

  Local Const $tagSAFEARRAY = "ushort cDims; ushort fFeatures; ulong cbElements; ulong cLocks; ptr pvData; ulong cElements; long lLbound"
  Local Const $tagVARIANT = "word vt;word r1;word r2;word r3;ptr data; ptr;"
  Local Const $VT_I4      = 3
  Local Const $VT_ARRAY   = 0x2000

  ; RuntimeIdPropertyId array
  If Not IsArray( $aRnTmIdPrpId ) Then Return
  Local $iRnTmIdPrpId = UBound( $aRnTmIdPrpId )

  ; Window handle
  Local $hWindow = WinGetHandle( "[REGEXPCLASS:^(Cabinet|Explore)WClass$]" ) ; Windows Explorer: XP, Vista, 7, 8
  ;Local $hWindow = WinGetHandle( "Calculator" )                             ; Calculator
  If Not $hWindow Then Return

  ; Create UI Automation object
  $oUIAutomation = ObjCreateInterface( $sCLSID_CUIAutomation, $sIID_IUIAutomation, $dtagIUIAutomation )
  If Not IsObj( $oUIAutomation ) Then Return

  ; Get UI Automation element from window handle
  Local $pWindow, $oWindow
  $oUIAutomation.ElementFromHandle( $hWindow, $pWindow )
  $oWindow = ObjCreateInterface( $pWindow, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
  If Not IsObj( $oWindow ) Then Return

  ; --- Create integer safearray ---

  ConsoleWrite( @CRLF & "Safearray" & @CRLF )
  Local $tInt = DllStructCreate( "int[" & $iRnTmIdPrpId & "]" )
  For $i = 0 To $iRnTmIdPrpId - 1
    DllStructSetData( $tInt, 1, $aRnTmIdPrpId[$i], $i+1 )
  Next

  Local $pSafeArray
  $oUIAutomation.IntNativeArrayToSafeArray( DllStructGetPtr( $tInt ), $iRnTmIdPrpId, $pSafeArray )
  If Not $pSafeArray Then Return ConsoleWrite( "Safearray: ERR" & @CRLF & @CRLF )
  ConsoleWrite( "Safearray: OK" & @CRLF )

  Local $iUBound
  SafeArrayGetUBound( $pSafeArray, $iUBound )
  ConsoleWrite( "Safearrays are zero based" & @CRLF )
  ConsoleWrite( "Safearray upper bound = " & $iUBound & @CRLF )

  Local $fFeatures = DllStructGetData( DllStructCreate( $tagSAFEARRAY, $pSafeArray ), "fFeatures" )
  ConsoleWrite( "Safearray: $fFeatures = 0x" & Hex( $fFeatures, 4 ) & @CRLF )
  ConsoleWrite( "(0x2080 (array of variants) is OK)" & @CRLF )

  Local $vValue
  ConsoleWrite( "Safearray values:" & @CRLF )
  For $i = 0 To $iUBound
    SafeArrayGetElement( $pSafeArray, $i, $vValue )
    ConsoleWrite( "$vValue " & $i & " = " & $vValue & @CRLF )
  Next

  ; --- Create variant containing a safearray ---

  ConsoleWrite( @CRLF & "Variant" & @CRLF )
  Local $tVARIANT = DllStructCreate( $tagVARIANT  )
  ConsoleWrite( "Variant size = " & DllStructGetSize( $tVARIANT ) & " bytes" & @CRLF )
  DllStructSetData( $tVARIANT, "vt", BitOR( $VT_ARRAY, $VT_I4 ) )
  Local $vt = DllStructGetData( $tVARIANT, "vt" )
  ConsoleWrite( "Variant: $vt = 0x" & Hex( $vt, 4 ) & @CRLF )
  ConsoleWrite( "(0x2003 (array of integer variants) is OK)" & @CRLF )
  DllStructSetData( $tVARIANT, "data", $pSafeArray )

  ; --- Create $UIA_RuntimeIdPropertyId property condition ---

  Local $pCondition
  ConsoleWrite( @CRLF & "$UIA_RuntimeIdPropertyId property condition" & @CRLF )
  If @AutoItX64 Then
    $oUIAutomation.CreatePropertyCondition( $UIA_RuntimeIdPropertyId, DllStructGetPtr( $tVARIANT ), $pCondition )
  Else
    Local $tVar = DllStructCreate( "uint64[2];", DllStructGetPtr( $tVARIANT ) )
    $oUIAutomation.CreatePropertyCondition( $UIA_RuntimeIdPropertyId, DllStructGetData( $tVar, 1, 1 ), DllStructGetData( $tVar, 1, 2 ), $pCondition )
  EndIf
  If Not $pCondition Then Return ConsoleWrite( "$UIA_RuntimeIdPropertyId property condition: ERR" & @CRLF & @CRLF )
  ConsoleWrite( "$UIA_RuntimeIdPropertyId property condition: OK" & @CRLF )

  ; --- Find element based on $UIA_RuntimeIdPropertyId property condition ---

  ; Find element
  ConsoleWrite( @CRLF & "Find element" & @CRLF )
  Local $pElem, $oElem, $sName
  $oWindow.FindFirst( $TreeScope_Descendants, $pCondition, $pElem )
  $oElem = ObjCreateInterface( $pElem, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
  If Not IsObj( $oElem ) Then Return ConsoleWrite( "Cannot find element" & @CRLF & @CRLF )
  ConsoleWrite( "Element found" & @CRLF )

  ; Element name
  Local $sNameProperty, $sLegacyMSAAValue
  $oElem.GetCurrentPropertyValue( $UIA_NamePropertyId, $sNameProperty )
  ConsoleWrite( "NamePropertyId: " & $sNameProperty & @CRLF )
  $oElem.GetCurrentPropertyValue( $UIA_LegacyIAccessibleValuePropertyId, $sLegacyMSAAValue )
  ConsoleWrite( "LegacyMSAAValue: " & $sLegacyMSAAValue & @CRLF & @CRLF )

EndFunc
The script tries to find the element based on a $UIA_RuntimeIdPropertyId property condition and prints the name of the element.

I have tested with the title bars for Windows Explorer and Calculator. This is the output in Scite console form the Calculator title bar:

Safearray
Safearray: OK
Safearrays are zero based
Safearray upper bound = 6
Safearray: $fFeatures = 0x2080
(0x2080 (array of variants) is OK)
Safearray values:
$vValue 0 = 42
$vValue 1 = 787258
$vValue 2 = 1
$vValue 3 = -2147483647
$vValue 4 = 787258
$vValue 5 = -2
$vValue 6 = 0

Variant
Variant size = 24 bytes
Variant: $vt = 0x2003
(0x2003 (array of integer variants) is OK)

$UIA_RuntimeIdPropertyId property condition
$UIA_RuntimeIdPropertyId property condition: OK

Find element
NamePropertyId: 
LegacyMSAAValue: Calculator
Edited by LarsJ

Share this post


Link to post
Share on other sites

I think you should use SafeArrayCreateVector
 

see Best Practices for Using Safe Arrays in ui automation fundamentals

 

All safe arrays that are used with the UI Automation client API methods are zero-based, one-dimensional arrays. To create a safe array for a UI Automation client method, use the SafeArrayCreateVector function, and to read from and write to a safe array, use the SafeArrayGetElement and SafeArrayPutElement functions. When you finish using a safe array, always destroy it by using the SafeArrayDestroy function, whether you created the safe array or received it from a UI Automation client method.

 

Share this post


Link to post
Share on other sites

Thank you, LarsJ.

It works. I would never have found out the reason of parameter transfer incompatibility (don't even know which tools to use to check it). 

Thank you. It's a big step to move forward now.

Share this post


Link to post
Share on other sites

Kolokolcev, You're welcome. I don't think there are any tools to check for bad parameters. When I test problems like this, I nearly always start to test with 32 bit scripts. In the afternoon last Wednesday I was focusing on the variant and the safearray, without realizing that this was not the problem. In the evening I was watching the soccer match (Champions League), and in the middle of the match I suddenly realized that it was a parameter issue. I did a few more tests and it worked.

junkew, IntNativeArrayToSafeArray does create a vector array. And since it creates and fills the array with one single command, it's significantly faster than using SafeArrayCreateVector to create the array, and several SafeArrayPutElement commands to fill the array.

Share this post


Link to post
Share on other sites

I've been studying this post since I am working on a project that its requiring me to do automation. I am new in Autoit but I think its amazing and sublime the work done by @junkew. Thanks a lot for all the effort. 

I am working with the software called: 

HOBOnode Viewer Utility

http://www.onsetcomp.com/products/software/hvu

I want to automate the process of getting data from the sensors and exporting it to a txt document. I have been using IUIAutomation library created by @junkew and with the tool provided I have been able to identify the elements of the software. The script that I currently have allows me to detect and highlight the main window and the subwindow area where the buttons to export the data are located. I have been able to locate and highlight also the buttons but when I try to click a button its not working. I am going one step at the time and I know that if figure out how to be able to click on the buttons and select the sensors from the list I will be done with this. 

Here is my code. Do you guys have any suggestions?

Thanks for all your help.

#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <constants.au3>
#include <WinAPI.au3>
#include <debug.au3>
#include "CUIAutomation2.au3"
#include "UIAWrappers.au3"
HotKeySet("{ESC}", "Terminate")

;~ Set the system under test variables
_UIA_setVar("SUT1.Folder","C:\Program Files (x86)\Onset Computer Corporation\HOBOnode Viewer Utility")
_UIA_setVar("SUT1.Workingdir","C:\Program Files (x86)\Onset Computer Corporation\HOBOnode Viewer Utility\")
_UIA_setVar("SUT1.EXE","HOBOnode Viewer Utility.exe")
_UIA_setVar("SUT1.Fullname", _UIA_getVar("SUT1.Folder") & "\"& _UIA_getVar("SUT1.EXE"))
_UIA_setVar("SUT1.Parameters","")
_UIA_setVar("SUT1.Processname","HOBOnode Viewer Utility.exe")
_UIA_setVar("SUT1.Windowstate",@SW_RESTORE)

_UIA_setVar("SUT1.Fullname", _UIA_getVar("SUT1.Folder") & "\"& _UIA_getVar("SUT1.EXE"))
_UIA_setVar("SUT1.Parameters","")
_UIA_setVar("SUT1.Processname","HOBOnode Viewer Utility.exe")




;~ Set the system under test objects to recognize

_UIA_setVar("HOBO.mainwindow", "classname:=WindowsForms10.Window.8.app.0.141b42a_r13_ad1")
_UIA_setVar("HOBO.subwindow", "classname:=WindowsForms10.SysTabControl32.app.0.141b42a_r13_ad1")
;~_UIA_setVar("HOBO.subwindow", "name:=Data Search")
_UIA_setVar("HOBO.DeviceSearch", "name:=")
_UIA_setVar("HOBO.Refresh", "name:=Get/Refresh Time Range")
_UIA_setVar("HOBO.Generate", "name:=Generate Data Streams")
_UIA_setVar("HOBO.Save", "name:=Save Data")


$oHOBO=_UIA_getVar("RTI.HOBO.mainwindow")
;~$oHOBOsub=_UIA_getVar("RTI.HOBO.mainwindow")

;~ Get the main HOBO element
_UIA_DEBUG("Action 1 Finding main window" & @CRLF)
$oHOBO=_UIA_getFirstObjectOfElement($oDesktop, _UIA_getVar("HOBO.mainwindow"), $treescope_children)
$oHOBO.setfocus()

;~ Get subwindow
_UIA_DEBUG("Action 2 Finding subwindow" & @CRLF)
$oHOBOsub=_UIA_getFirstObjectOfElement($oHOBO, _UIA_getVar("HOBO.subwindow"), $treescope_children)
$oHOBOsub.setfocus()


_UIA_DEBUG("Action 3 Find Refresh button" & @CRLF)
$oRefreshButton=_UIA_getObjectByFindAll($oHOBOsub, _UIA_getVar("HOBO.Refresh"), $treescope_subtree)
$oRefreshButton.setfocus()
_UIA_action($oRefreshButton,"left")


_UIA_DEBUG("Action 4 Find Save button" & @CRLF)
$oSaveButton=_UIA_getObjectByFindAll($oHOBOsub, _UIA_getVar("HOBO.Save"), $treescope_subtree)
_UIA_action($oSaveButton,"left""left")

This is also the properties of the save button in case the problem is related to that:

Mouse position is retrieved 1268-576
At least we have an element [Save Data...][WindowsForms10.BUTTON.app.0.141b42a_r13_ad1]
Having the following values for all properties: 
Title is: <Save Data...>    Class   := <WindowsForms10.BUTTON.app.0.141b42a_r13_ad1>    controltype:= <UIA_PaneControlTypeId>   ,<50033>    , (0000C371)    
*** Parent Information ***
Title is: <Data Search> Class   := <WindowsForms10.Window.8.app.0.141b42a_r13_ad1>  controltype:= <UIA_PaneControlTypeId>   ,<50033>    , (0000C371)    
*** Detailed properties of the highlighted element ***
UIA_AcceleratorKeyPropertyId :=
UIA_AccessKeyPropertyId :=
UIA_AriaPropertiesPropertyId :=
UIA_AriaRolePropertyId :=
UIA_AutomationIdPropertyId :=
UIA_BoundingRectanglePropertyId :=1195;558;102;31
UIA_ClassNamePropertyId :=WindowsForms10.BUTTON.app.0.141b42a_r13_ad1
UIA_ClickablePointPropertyId :=
UIA_ControllerForPropertyId :=
UIA_ControlTypePropertyId :=50033
UIA_CulturePropertyId :=0
UIA_DescribedByPropertyId :=
UIA_DockDockPositionPropertyId :=5
UIA_ExpandCollapseExpandCollapseStatePropertyId :=3
UIA_FlowsToPropertyId :=
UIA_FrameworkIdPropertyId :=WinForm
UIA_GridColumnCountPropertyId :=0
UIA_GridItemColumnPropertyId :=0
UIA_GridItemColumnSpanPropertyId :=1
UIA_GridItemContainingGridPropertyId :=
UIA_GridItemRowPropertyId :=0
UIA_GridItemRowSpanPropertyId :=1
UIA_GridRowCountPropertyId :=0
UIA_HasKeyboardFocusPropertyId :=False
UIA_HelpTextPropertyId :=
UIA_IsContentElementPropertyId :=True
UIA_IsControlElementPropertyId :=True
UIA_IsDataValidForFormPropertyId :=False
UIA_IsDockPatternAvailablePropertyId :=False
UIA_IsEnabledPropertyId :=True
UIA_IsExpandCollapsePatternAvailablePropertyId :=False
UIA_IsGridItemPatternAvailablePropertyId :=False
UIA_IsGridPatternAvailablePropertyId :=False
UIA_IsInvokePatternAvailablePropertyId :=False
UIA_IsItemContainerPatternAvailablePropertyId :=False
UIA_IsKeyboardFocusablePropertyId :=True
UIA_IsLegacyIAccessiblePatternAvailablePropertyId :=True
UIA_IsMultipleViewPatternAvailablePropertyId :=False
UIA_IsOffscreenPropertyId :=False
UIA_IsPasswordPropertyId :=False
UIA_IsRangeValuePatternAvailablePropertyId :=False
UIA_IsRequiredForFormPropertyId :=False
UIA_IsScrollItemPatternAvailablePropertyId :=False
UIA_IsScrollPatternAvailablePropertyId :=False
UIA_IsSelectionItemPatternAvailablePropertyId :=False
UIA_IsSelectionPatternAvailablePropertyId :=False
UIA_IsSynchronizedInputPatternAvailablePropertyId :=False
UIA_IsTableItemPatternAvailablePropertyId :=False
UIA_IsTablePatternAvailablePropertyId :=False
UIA_IsTextPatternAvailablePropertyId :=False
UIA_IsTogglePatternAvailablePropertyId :=False
UIA_IsTransformPatternAvailablePropertyId :=False
UIA_IsValuePatternAvailablePropertyId :=False
UIA_IsVirtualizedItemPatternAvailablePropertyId :=False
UIA_IsWindowPatternAvailablePropertyId :=False
UIA_ItemStatusPropertyId :=
UIA_ItemTypePropertyId :=
UIA_LabeledByPropertyId :=
UIA_LegacyIAccessibleChildIdPropertyId :=0
UIA_LegacyIAccessibleDefaultActionPropertyId :=
UIA_LegacyIAccessibleDescriptionPropertyId :=
UIA_LegacyIAccessibleHelpPropertyId :=
UIA_LegacyIAccessibleKeyboardShortcutPropertyId :=
UIA_LegacyIAccessibleNamePropertyId :=Save Data...
UIA_LegacyIAccessibleRolePropertyId :=10
UIA_LegacyIAccessibleSelectionPropertyId :=
UIA_LegacyIAccessibleStatePropertyId :=1048576
UIA_LegacyIAccessibleValuePropertyId :=
UIA_LocalizedControlTypePropertyId :=pane
UIA_MultipleViewCurrentViewPropertyId :=0
UIA_MultipleViewSupportedViewsPropertyId :=
UIA_NamePropertyId :=Save Data...
UIA_NativeWindowHandlePropertyId :=656900
UIA_OrientationPropertyId :=0
UIA_ProcessIdPropertyId :=6320
UIA_ProviderDescriptionPropertyId :=[pid:8408,hwnd:0xA0604 Annotation:Microsoft: Annotation Proxy (unmanaged:uiautomationcore.dll); Main:Microsoft: MSAA Proxy (unmanaged:uiautomationcore.dll); Hwnd(parent link):Microsoft: HWND Proxy (unmanaged:uiautomationcore.dll)]
UIA_RangeValueIsReadOnlyPropertyId :=True
UIA_RangeValueLargeChangePropertyId :=0
UIA_RangeValueMaximumPropertyId :=0
UIA_RangeValueMinimumPropertyId :=0
UIA_RangeValueSmallChangePropertyId :=0
UIA_RangeValueValuePropertyId :=0
UIA_RuntimeIdPropertyId :=42;656900
UIA_ScrollHorizontallyScrollablePropertyId :=False
UIA_ScrollHorizontalScrollPercentPropertyId :=0
UIA_ScrollHorizontalViewSizePropertyId :=100
UIA_ScrollVerticallyScrollablePropertyId :=False
UIA_ScrollVerticalScrollPercentPropertyId :=0
UIA_ScrollVerticalViewSizePropertyId :=100
UIA_SelectionCanSelectMultiplePropertyId :=False
UIA_SelectionIsSelectionRequiredPropertyId :=False
UIA_SelectionselectionPropertyId :=
UIA_SelectionItemIsSelectedPropertyId :=False
UIA_SelectionItemSelectionContainerPropertyId :=
UIA_TableColumnHeadersPropertyId :=
UIA_TableItemColumnHeaderItemsPropertyId :=
UIA_TableRowHeadersPropertyId :=
UIA_TableRowOrColumnMajorPropertyId :=2
UIA_TableItemRowHeaderItemsPropertyId :=
UIA_ToggleToggleStatePropertyId :=2
UIA_TransformCanMovePropertyId :=False
UIA_TransformCanResizePropertyId :=False
UIA_TransformCanRotatePropertyId :=False
UIA_ValueIsReadOnlyPropertyId :=True
UIA_ValueValuePropertyId :=
UIA_WindowCanMaximizePropertyId :=False
UIA_WindowCanMinimizePropertyId :=False
UIA_WindowIsModalPropertyId :=False
UIA_WindowIsTopmostPropertyId :=False
UIA_WindowWindowInteractionStatePropertyId :=0
UIA_WindowWindowVisualStatePropertyId :=0

Here is a screenshot of the software and the current result of the script:

1.jpg

Share this post


Link to post
Share on other sites

casma, You can try this code:

#include "CUIAutomation2.au3"

Opt( "MustDeclareVars", 1 )

MainFunc()


Func MainFunc()

  Local $hWindow = WinGetHandle( "HOBOnode Viewer Utility" )
  If Not $hWindow Then Return ConsoleWrite( "Window handle ERR" & @CRLF )
  ConsoleWrite( "Window handle OK" & @CRLF )

  ; Create UI Automation object
  Local $oUIAutomation = ObjCreateInterface( $sCLSID_CUIAutomation, $sIID_IUIAutomation, $dtagIUIAutomation )
  If Not IsObj( $oUIAutomation ) Then Return ConsoleWrite( "UI Automation object ERR" & @CRLF )
  ConsoleWrite( "UI Automation object OK" & @CRLF )

  ; Get UI Automation element from window handle
  Local $pWindow, $oWindow
  $oUIAutomation.ElementFromHandle( $hWindow, $pWindow )
  $oWindow = ObjCreateInterface( $pWindow, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
  If Not IsObj( $oWindow ) Then Return ConsoleWrite( "Automation element from window ERR" & @CRLF )
  ConsoleWrite( "Automation element from window OK" & @CRLF )

  ; Condition to find "Save Data..." button
  Local $pCondition, $pCondition1, $pCondition2
  $oUIAutomation.CreatePropertyCondition( $UIA_ControlTypePropertyId, $UIA_ButtonControlTypeId, $pCondition1 )
  $oUIAutomation.CreatePropertyCondition( $UIA_NamePropertyId, "Save Data...", $pCondition2 )
  $oUIAutomation.CreateAndCondition( $pCondition1, $pCondition2, $pCondition )
  If Not $pCondition Then Return ConsoleWrite( "Property condition ERR" & @CRLF )
  ConsoleWrite( "Property condition OK" & @CRLF )

  ; Find "Save Data..." button
  Local $pButton, $oButton
  $oWindow.FindFirst( $TreeScope_Descendants, $pCondition, $pButton )
  $oButton = ObjCreateInterface( $pButton, $sIID_IUIAutomationElement, $dtagIUIAutomationElement )
  If Not IsObj( $oButton ) Then Return ConsoleWrite( "Find button ERR" & @CRLF )
  ConsoleWrite( "Find button OK" & @CRLF )

  ; Click (invoke) "Save Data..." button
  Local $pInvoke, $oInvoke
  $oButton.GetCurrentPattern( $UIA_InvokePatternId, $pInvoke )
  $oInvoke = ObjCreateInterface( $pInvoke, $sIID_IUIAutomationInvokePattern, $dtagIUIAutomationInvokePattern )
  If Not IsObj( $oInvoke ) Then Return ConsoleWrite( "Invoke pattern ERR" & @CRLF )
  ConsoleWrite( "Invoke pattern OK" & @CRLF )
  $oInvoke.Invoke()

EndFunc

Share this post


Link to post
Share on other sites

LarsJ

Thanks a lot for taking the time.I tried your sample code. It appears that is not working. Nothing happens. 

Share this post


Link to post
Share on other sites

Did you get any errors in Scite console? In case of an error the script just stops.

(To run this simple script the window must be open, the "Data Search" tab must be selected, and the "Save Data..." button must be enabled.)

I did a test yesterday with the "Get/Refresh Device List" button, and it worked. It printed some text to one of the boxes (to test this button you just have to replace "Save Data..." in the script with "Get/Refresh Device List").

Share this post


Link to post
Share on other sites

Hi LarsJ

Thanks a lot for your help. I run it again and also replace the name for the "Get/Refresh Device List" and in both cases it gives an error:

>"C:\Program Files (x86)\AutoIt3\SciTE\..\autoit3.exe" /ErrorStdOut "C:\Users\richi\Desktop\HOBO_MAIN.au3"    
Action 1 Finding main window
matched: classname30012
Matching: 30012 for WindowsForms10.Window.8.app.0.141b42a_r13_ad1
Action 2 Finding subwindow
matched: classname30012
Matching: 30012 for WindowsForms10.SysTabControl32.app.0.141b42a_r13_ad1
Action 3 Find Refresh button
Action 1 leftdoubleclick on 
   Action 3 Find Save button
Action 2 leftdoubleclick on 
   Window handle OK
UI Automation object OK
Automation element from window OK
Property condition OK
Find button ERR
>Exit code: 0    Time: 1.003

I don't know how to check if there is an exact error number or more detail about it. When you said that it worked for you, it was the exact same script that you posted?

Once again, thanks a lot for your help.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • By bobmcrae
      I am experimenting with UIAWrappers.au3 from junkew to complete an application which presents absolutely no control information using AutoIT Window Info.  While I am able to complete the form successfully, I am not happy with the speed.  As a benchmark, the simple Send method occurs in far less than 1-second, but the UIAutomation approach takes 3-seconds.  I am wondering whether performance gains may be achieved by specifying the controls more precisely; but I am unsure how to do that.  I was able to speed things up a bit by setting $UIA_DefaultWaitTime=0.  The controls of interest are 5-levels deep, as show in the simplespy output below.  It seems I do get faster response by specifying the target/top-level window, as show in the code below.  Any ideas?
      #include "UIAWrappers.au3" _UIA_setVar("Global.Debug", False) _UIA_setVar("Global.Debug.File", False) _UIA_setVar("Global.Highlight", False) _UIA_setVar("DPN","Title:=NC-stat DPNCheck Communicator;controltype:=UIA_WindowControlTypeId;class:=Window") _UIA_action('DPN','setFocus') _UIA_setVar("DPN.firstName","AutomationId:=txtFirstName") _UIA_setVar("DPN.lastName", "AutomationId:=txtLastName") _UIA_Action('DPN.lastName','setvalue','last name') _UIA_setVar("DPN.ID", "AutomationId:=txtSubjectId") _UIA_setVar("DPN.DOB", "AutomationId:=PART_TextBox") _UIA_setVar("DPN.Ft", "AutomationId:=txtSubjectHeight") _UIA_setVar("DPN.In", "AutomationId:=txtSubjectHeight2") _UIA_Action('DPN.firstName','setvalue','first name') _UIA_Action('DPN.ID','setvalue','ID012345') _UIA_Action('DPN.DOB','setvalue','1/31/1932') _UIA_Action('DPN.Ft','setvalue','6') _UIA_Action('DPN.In','setvalue','1') SimpleSpy output:
      ;~ *** Standard code *** #include "UIAWrappers.au3" AutoItSetOption("MustDeclareVars", 1) Local $oP4=_UIA_getObjectByFindAll($UIA_oDesktop, "Title:=NC-stat DPNCheck Communicator;controltype:=UIA_WindowControlTypeId;class:=Window", $treescope_children) _UIA_Action($oP4,"setfocus") Local $oP3=_UIA_getObjectByFindAll($oP4, "Title:=;controltype:=UIA_PaneControlTypeId;class:=Frame", $treescope_children) Local $oP2=_UIA_getObjectByFindAll($oP3, "Title:=;controltype:=UIA_TabControlTypeId;class:=TabControl", $treescope_children) Local $oP1=_UIA_getObjectByFindAll($oP2, "Title:=Patient;controltype:=UIA_TabItemControlTypeId;class:=TabItem", $treescope_children) Local $oP0=_UIA_getObjectByFindAll($oP1, "Title:=;controltype:=UIA_PaneControlTypeId;class:=Frame", $treescope_children) ;~ First find the object in the parent before you can do something ;~$oUIElement=_UIA_getObjectByFindAll(".mainwindow", "title:=;ControlType:=UIA_EditControlTypeId", $treescope_subtree) Local $oUIElement=_UIA_getObjectByFindAll($oP0, "title:=;ControlType:=UIA_EditControlTypeId", $treescope_subtree) _UIA_action($oUIElement,"click")  
    • By jackchen
      OK,I've made my "Chrome_KeepLastTab.au3" work.This script adds some features to Chrome browser:
      1. Double click on a tab to close the tab.
      2. Keep last tab:This script monitors your mouse clicks and hotkeys,if you are about to close the last tab within Chrome(click close button on the last tab, middle click/double click on the last tab or press Ctrl + w or Ctrl + {F4}), a new tab will be open and then the old tab be closed.
      #include <WindowsConstants.au3> #include <WinAPI.au3> #include "CUIAutomation2.au3" #AutoIt3Wrapper_UseX64=Y ;Should be used for stuff like tagpoint having right struct etc. when running on a 64 bits os ConsoleWrite("@OSArch: " & @OSArch & ", @AutoItX64: " & @AutoItX64 & @CRLF) Global $DoubleClickTime = 500 Global $UIA_oUIAutomation ; The main library core CUI automation reference Global $hMouseEvent, $hMouseHook Global $aMouseEvent[2] Global $KeepLastTab = True ; settings from ini file If $KeepLastTab Then ;The main object with acces to the windows automation api 3.0 $UIA_oUIAutomation = ObjCreateInterface($sCLSID_CUIAutomation, $sIID_IUIAutomation, $dtagIUIAutomation) If IsObj($UIA_oUIAutomation) Then HotKeySet("^w", "Hotkey_Event") ; Ctrl + w to close tab HotKeySet("^{F4}", "Hotkey_Event") ; Ctrl + {F4} to close tab $DoubleClickTime = DllCall("user32.dll", "uint", "GetDoubleClickTime")[0] OnAutoItExitRegister("UnhookMouse") ; Register mouse events callback $hMouseEvent = DllCallbackRegister("Mouse_Event", "int", "int;ptr;ptr") $hMouseHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, DllCallbackGetPtr($hMouseEvent), _WinAPI_GetModuleHandle(0)) EndIf EndIf While 1 Sleep(100) WEnd ToolTip("") ; https://www.autoitscript.com/forum/topic/103362-monitoring-mouse-events/ Func Mouse_Event($nCode, $wParam, $lParam) Local $info, $mouseData, $time, $timeDiff If $nCode < 0 Then Return _WinAPI_CallNextHookEx($hMouseHook, $nCode, $wParam, $lParam) ; Continue processing EndIf $tPoint = _WinAPI_GetMousePos() $hWnd = _WinAPI_WindowFromPoint($tPoint) ; if mouse is on the widget window(class: Chrome_RenderWidgetHostHWND), ; use $hWnd = _WinAPI_GetParent($hWnd) to get the parent Chrome window If Not StringInStr(_WinAPI_GetClassName($hWnd), "Chrome_WidgetWin_") Then ; Chrome_WidgetWin_1: Chrome window ; Chrome_WidgetWin_2: Chrome menu ; ignore non Chrome window Return _WinAPI_CallNextHookEx($hMouseHook, $nCode, $wParam, $lParam) EndIf ToolTip($hWnd & " - " & _WinAPI_GetClassName($hWnd)) ;$tagPOINT = "struct;long X;long Y;endstruct" Local Const $MSLLHOOKSTRUCT = $tagPOINT & ";dword mouseData;dword flags;dword time;ulong_ptr dwExtraInfo" $info = DllStructCreate($MSLLHOOKSTRUCT, $lParam) $mouseData = DllStructGetData($info, 3) $time = DllStructGetData($info, 5) $timeDiff = $time - $aMouseEvent[1] Local $block Switch $wParam Case $WM_LBUTTONUP $aMouseEvent[1] = $time If $aMouseEvent[0] = "LClick" And ($timeDiff) < $DoubleClickTime Then $aMouseEvent[0] = "LDClick" Else $aMouseEvent[0] = "LClick" EndIf $block = KeepLastTab($hWnd, $aMouseEvent[0]) Case $WM_MBUTTONUP $aMouseEvent[1] = $time If $aMouseEvent[0] = "MClick" And ($timeDiff) < $DoubleClickTime Then $aMouseEvent[0] = "MDClick" Else $aMouseEvent[0] = "MClick" $block = KeepLastTab($hWnd, $aMouseEvent[0]) EndIf EndSwitch If Not $block Then _WinAPI_CallNextHookEx($hMouseHook, $nCode, $wParam, $lParam) ; Continue processing EndIf EndFunc ;==>Mouse_Event Func UnhookMouse() _WinAPI_UnhookWindowsHookEx($hMouseHook) $hMouseHook = 0 DllCallbackFree($hMouseEvent) $hMouseEvent = 0 EndFunc ;==>UnhookMouse Func Hotkey_Event() Local $block Local $hWnd = WinGetHandle(WinGetTitle("[ACTIVE]")) If StringInStr(_WinAPI_GetClassName($hWnd), "Chrome_WidgetWin_1") Then ; Chrome_WidgetWin_1, Chrome window $block = KeepLastTab($hWnd, "Hotkey") EndIf If Not $block Then HotKeySet("^w") Send(@HotKeyPressed) HotKeySet("^w", "Hotkey_Event") EndIf EndFunc Func KeepLastTab($hWnd, $action = "LClick") ; Possible $action value: LClick, LDClick, MClick, Hotkey ConsoleWrite(@CRLF & $action & " on a Chrome window: " & $hWnd & @CRLF) Local $aMousePos = MouseGetPos() Local $pChrome, $oChrome $UIA_oUIAutomation.ElementFromHandle($hWnd, $pChrome) ; Window $oChrome = ObjCreateInterface($pChrome, $sIID_IUIAutomationElement, $dtagIUIAutomationElement) If Not IsObj($oChrome) Then ConsoleWrite("Failed to get Chrome object from hWnd." & @CRLF) Return EndIf ;$UIA_ControlTypePropertyId = 30003 $oChromeTabs = UIA_getFirstElement($oChrome, $UIA_ControlTypePropertyId, $UIA_TabControlTypeId, $treescope_subtree) If Not IsObj($oChromeTabs) Then ConsoleWrite("Failed to get Chrome tab bar object." & @CRLF) Return EndIf Local $t $oChromeTabs.GetCurrentPropertyValue($UIA_BoundingRectanglePropertyId, $t) If UBound($t) < 4 Then Return If $action <> "Hotkey" And ($aMousePos[0] < $t[0] Or $aMousePos[0] > $t[2]+$t[0] Or $aMousePos[1] < $t[1] Or $aMousePos[1] > $t[3]+$t[1]) Then ; Mouse not on tabs bar ConsoleWrite("Mouse is not on the tab bar. Ignore and return..." & @CRLF) Return EndIf Local $pTrueCondition, $pElements, $iLength, $oAutomationElementArray $UIA_oUIAutomation.CreateTrueCondition($pTrueCondition) $oCondition = ObjCreateInterface($pTrueCondition, $sIID_IUIAutomationCondition, $dtagIUIAutomationCondition) If Not IsObj($oCondition) Then Return $oChromeTabs.FindAll($treescope_children, $oCondition, $pElements) $oAutomationElementArray = ObjCreateInterface($pElements, $sIID_IUIAutomationElementArray, $dtagIUIAutomationElementArray) If Not IsObj($oAutomationElementArray) Then ConsoleWrite("Failed to find all Chrome tabs. " & @CRLF) Return EndIf $oAutomationElementArray.Length($iLength) Local $UIA_pUIElement, $oTab2 Local $iTabs = $iLength - 1 If $iTabs > 1 Then ; more than one tab If $action = "LDClick" Then ConsoleWrite("There are " & $iTabs & " tabs within Chrome window. " & @CRLF) For $i = 1 To $iTabs $oAutomationElementArray.GetElement($i, $UIA_pUIElement) $oTab2 = ObjCreateInterface($UIA_pUIElement, $sIID_IUIAutomationElement, $dtagIUIAutomationElement) If Not IsObj($oTab2) Then ContinueLoop $oTab2.GetCurrentPropertyValue($UIA_BoundingRectanglePropertyId, $t) If UBound($t) < 4 Then ContinueLoop If $aMousePos[0] >= $t[0] And $aMousePos[0] <= $t[2]+$t[0] And $aMousePos[1] >= $t[1] And $aMousePos[1] <= $t[3]+$t[1] Then ConsoleWrite("You double clicked on one of " & $iTabs & " tabs. Close the tab and return..." & @CRLF) HotKeySet("^w") Send("^w") HotKeySet("^w", "Hotkey_Event") Return True EndIf Next EndIf Return EndIf ConsoleWrite("There is ONLY one tab within Chrome window. " & @CRLF) $oAutomationElementArray.GetElement(1, $UIA_pUIElement) $oTab = ObjCreateInterface($UIA_pUIElement, $sIID_IUIAutomationElement, $dtagIUIAutomationElement) If Not IsObj($oTab) Then ConsoleWrite("Failed to get the last tab object." & @CRLF) Return EndIf Local $rtTab $oTab.GetCurrentPropertyValue($UIA_BoundingRectanglePropertyId, $rtTab) If UBound($rtTab) < 4 Then Return If $action <> "Hotkey" And ($aMousePos[0] < $rtTab[0] Or $aMousePos[0] > $rtTab[2]+$rtTab[0] Or $aMousePos[1] < $rtTab[1] Or $aMousePos[1] > $rtTab[3]+$rtTab[1]) Then ; Mouse not on the last tab ConsoleWrite("Mouse is not on the last tab. Ignore and return..." & @CRLF) Return EndIf If $action = "LClick" Then $oTabClose = UIA_getFirstElement($oTab, $UIA_ControlTypePropertyId, $UIA_ButtonControlTypeId, $treescope_subtree) If Not IsObj($oTabClose) Then ConsoleWrite("Failed to get the last tab close object." & @CRLF) Return EndIf $oTabClose.GetCurrentPropertyValue($UIA_BoundingRectanglePropertyId, $t) If UBound($t) < 4 Then Return If $aMousePos[0] < $t[0] Or $aMousePos[0] > $t[2]+$t[0] Or $aMousePos[1] < $t[1] Or $aMousePos[1] > $t[3]+$t[1] Then ; Mouse not on the tab close button Return EndIf EndIf ; open a new tab within chrome ConsoleWrite("The last tab is about to be closed, so we have to open a new tab to prevent Chrome window from closing." & @CRLF) Send("^t") ConsoleWrite("A new tab created!" & @CRLF) Sleep(100) ConsoleWrite("Close the old tab and return..." & @CRLF) ;~ Local $pPattern ;~ $oTabClose.GetCurrentPattern($UIA_InvokePatternId, $pPattern) ;~ $oPattern = ObjCreateInterface($pPattern, $sIID_IUIAutomationInvokePattern, $dtagIUIAutomationInvokePattern) ;~ If IsObj($oPattern) Then ;~ ConsoleWrite("Invoke to close the tab..." & @CRLF) ;~ $oTabClose.SetFocus() ;~ $oPattern.Invoke() ;~ EndIf _WinAPI_UnhookWindowsHookEx($hMouseHook) $aMousePos = MouseGetPos() If $aMousePos[0] >= $rtTab[0] And $aMousePos[0] <= $rtTab[2]+$rtTab[0] And $aMousePos[1] >= $rtTab[1] And $aMousePos[1] <= $rtTab[3]+$rtTab[1] Then MouseClick("middle", $aMousePos[0], $aMousePos[1], 1, 0) Else MouseClick("middle", $rtTab[0]+$rtTab[2]/2, $rtTab[1]+$rtTab[3]/2, 1, 0) ; close the tab MouseMove($aMousePos[0], $aMousePos[1], 0) ; move mouse back to previous position EndIf ;~ _WinAPI_Mouse_Event($MOUSEEVENTF_MIDDLEDOWN, $rtTab[0]+$rtTab[2]/2, $rtTab[1]+$rtTab[3]/2) ;~ Sleep(100) ;~ _WinAPI_Mouse_Event($MOUSEEVENTF_MIDDLEUP, $rtTab[0]+$rtTab[2]/2, $rtTab[1]+$rtTab[3]/2) $hMouseHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, DllCallbackGetPtr($hMouseEvent), _WinAPI_GetModuleHandle(0)) Return True ; to block mouse click/hot key EndFunc Func UIA_getFirstElement($obj, $propertyID, $tval, $treeScope) Local $pCondition, $oCondition $UIA_oUIAutomation.CreatePropertyCondition($propertyID, $tval, $pCondition) $oCondition = ObjCreateInterface($pCondition, $sIID_IUIAutomationPropertyCondition, $dtagIUIAutomationPropertyCondition) Local $UIA_oUIElement, $UIA_pUIElement $t = $obj.Findfirst($treeScope, $oCondition, $UIA_pUIElement) $UIA_oUIElement = ObjCreateInterface($UIA_pUIElement, $sIID_IUIAutomationElement, $dtagIUIAutomationElement) If IsObj($UIA_oUIElement) Then Return $UIA_oUIElement Return SetError(1, 0, "") EndFunc ;==>UIA_getFirstElement My question is related to #AutoIt3Wrapper_UseX64 when run this script on 64-bit Win 7.
      No mater I set #AutoIt3Wrapper_UseX64=Y or #AutoIt3Wrapper_UseX64=N, this script works very well on hotkey event, while mouse clicks sometimes works if #AutoIt3Wrapper_UseX64=N and sometimes works on Y. Can some one test this and finger out what's wrong?
      Info from SciTe if #AutoIt3Wrapper_UseX64=Y :
      @OSArch: X64, @AutoItX64: 1 Hotkey on a Chrome window: 0x0000000000140330 There is ONLY one tab within Chrome window. The last tab is about to be closed, so we have to open a new tab to prevent Chrome window from closing. A new tab created! Close the old tab and return... LClick on a Chrome window: 0x0000000000140330 There is ONLY one tab within Chrome window. The last tab is about to be closed, so we have to open a new tab to prevent Chrome window from closing. A new tab created! Close the old tab and return... Info if #AutoIt3Wrapper_UseX64=N or comment out this line:
      @OSArch: X64, @AutoItX64: 0 Hotkey on a Chrome window: 0x00140330 There is ONLY one tab within Chrome window. The last tab is about to be closed, so we have to open a new tab to prevent Chrome window from closing. A new tab created! Close the old tab and return... LClick on a Chrome window: 0x00140330 Failed to get Chrome tab bar object. Hotkey events and mouse click events share the same function KeepLastTab($hWnd, $action = "LClick"),Why this function triggered by hotkey works on both 32-bit and 64-bit while that triggered by mouse events failed on 32-bit autoit?
×
×
  • Create New...