Jump to content
junkew

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

Recommended Posts

Regarding the variable definitions with _UIA_setvar like simplespy is given those can be put in UIA.CFG like this

Example for notepad in 2 languages english/dutch

[notepad]
mainwindow=title:=((Naamloos.*Kladblok)|(Untitled.*pad));classname:=Notepad
mainwindow.edit=title:=;classname:=Edit
closewindow.save=title:=Save;classname:=CCPushButton
closewindow.Don'tSave=title:=((Don't Save)|(Niet opslaan));classname:=CCPushButton
closewindow.Cancel=title:=((Cancel)|(Annuleren));classname:=CCPushButton

Above instead of 

;~ Give logical names
_UIA_setVar("notepad.mainwindow","title:=((Naamloos.*Kladblok)|(.*Notepad));classname:=Notepad")
_UIA_setVar("notepad.mainwindow","title:=((Naamloos.*Kladblok)|(.*Npad));classname:=Notepad")
_UIA_setVar("notepad.mainwindow.edit","title:=;classname:=Edit")

;~ When closing when text is changed
_UIA_setVar("Notepad.closewindow","title:=((Kladblok)|(Notepad));classname:=#32770")
;~ The three buttons
_UIA_setVar("Notepad.closewindow.Save","title:=Save;classname:=CCPushButton")
_UIA_setVar("Notepad.closewindow.Don'tSave","title:=((Don't Save)|(Niet opslaan));classname:=CCPushButton")
_UIA_setVar("Notepad.closewindow.Cancel","title:=((Cancel)|(Annuleren));classname:=CCPushButton")

you just put the definitions in the separate configuration uia.cfg file so you can split your page definitions away from your coding.

Example 31 for notepad will then change to something like below

#include <Array.au3>
#include "UIAWrappers.au3"

AutoItSetOption("MustDeclareVars", 1)

; Run Notepad
Run("notepad.exe")

; Wait 10 seconds for the Notepad window to appear.
WinWaitActive("[CLASS:Notepad]", "", 10)

#REGION UIA_LOGICAL_NAMES
;~ see UIA.CFG section notepad
#ENDREGION
;~_arraydisplay($UIA_Vars)

#REGION ACTIONS
;~ Do some actions on the logical named objects
_UIA_action("notepad.mainwindow","setfocus")
_UIA_action("notepad.mainwindow","move",300,300)
_UIA_action("notepad.mainwindow","resize",300,300)
_UIA_action("notepad.mainwindow","minimize",300,300)
_UIA_action("notepad.mainwindow","maximize",300,300)
_UIA_action("notepad.mainwindow","resize",400,400)

_UIA_action("notepad.mainwindow.edit","setfocus")
_UIA_action("notepad.mainwindow.edit","setvalue","set value: hello world")
_UIA_action("notepad.mainwindow.edit","type","type command: hello world")

_UIA_action("notepad.mainwindow","close",400,400)
if _UIA_action("Notepad.closewindow","exists") Then
    _UIA_action("Notepad.closewindow.Don'tSave","click")
Else
EndIf
#ENDREGION

 

Share this post


Link to post
Share on other sites

Welcome
My problem is the same objects . 

I have an intranet page where I have to click on the next links in the table.
The identification of the link objects is not different.

UIA always finds the first object in which to indicate the next link?

The table that I serve has 200 rows. I can not put screenshots (confidential data).

To show what the problem I have created, the test.html and Simple UIA Spy code

sample.gif.f3811935b9ce41bca41888b661cad322.gif

test.html

How do you click View in the Piotr line?

#include-once
#include<UIAWrappers.au3>

Global $WindowChromePID
$sLink = @ScriptDir & "\test.html"

If FileExists("C:\Program Files (x86)\Google\Chrome\Application\chrome.exe") Then
    $WindowChromePID = Run("C:\Program Files (x86)\Google\Chrome\Application\chrome.exe --force-renderer-accessibility " & $sLink)
ElseIf FileExists("C:\Program Files\Google\Chrome\Application\chrome.exe") Then
    $WindowChromePID = Run("C:\Program Files\Google\Chrome\Application\chrome.exe --force-renderer-accessibility " & $sLink)
Else
    MsgBox(8192+16, "Error","Chrome.exe not found")
EndIf
Sleep(5000)


_UIA_setVar("oP1","Title:=test.html - Google Chrome;controltype:=UIA_PaneControlTypeId;class:=Chrome_WidgetWin_1")  ;test.html - Google Chrome
_UIA_setVar("oP2","Title:=;controltype:=UIA_DocumentControlTypeId;class:=Chrome_RenderWidgetHostHWND")  ;
_UIA_setVar("oP3","Title:=;controltype:=UIA_TableControlTypeId;class:=")    ;
_UIA_setVar("oP4","Title:=;controltype:=UIA_CustomControlTypeId;class:=")   ;
_UIA_setVar("oP5","Title:=View;controltype:=UIA_DataItemControlTypeId;class:=") ;View
_UIA_setVar("oP6","Title:=View;controltype:=UIA_HyperlinkControlTypeId;class:=")    ;View

;~ $oUIElement=_UIA_getObjectByFindAll("View.mainwindow", "title:=View;ControlType:=UIA_TextControlTypeId", $treescope_subtree)
_UIA_setVar("oUIElement","Title:=View;controltype:=UIA_TextControlTypeId;class:=") ;ControlType:=UIA_TextControlTypeId;classname:=")

;~ Actions split away from logical/technical definition above can come from configfiles

_UIA_Action("oP1","highlight")
;~ _UIA_Action("oP1","setfocus")
_UIA_Action("oP2","highlight")
;~ _UIA_Action("oP2","setfocus")
_UIA_Action("oP3","highlight")
;~ _UIA_Action("oP3","setfocus")
_UIA_Action("oP4","highlight")
;~ _UIA_Action("oP4","setfocus")
_UIA_Action("oP5","highlight")
;~ _UIA_Action("oP5","setfocus")
_UIA_Action("oP6","highlight")
;~ _UIA_Action("oP6","setfocus")

;~ _UIA_action("oUIElement","highlight")
_UIA_action("oUIElement","click")

Screen from MS Inspect

inspect.thumb.gif.1403c7251101da3d64c638369e69c29b.gif

Share this post


Link to post
Share on other sites

I'm having a bit of trouble getting the library to NOT create log xml files in the LOG directory.  I want the script to run daily, so I don't need log files every day.

I have added this line to the code:

; Turn off debug log file generation - Doesn't seem to work either.
_UIA_setVar("Global.Debug",false)

 

As well as setting these two in UIA.CFG:

[Global]
Debug=false
Debug.file=false

 

But I keep getting XML files in the LOG directory named:  20180729-130940736.XML

With this content:

<?xml version="1.0" encoding="UTF-8"?><log space="preserve"><logline level="5" timestamp="20190729-130940737"> <information> Information _UIA_VersionInfo version: T0.7-0; Release date: 20190501; OS Version: WIN_7</information></logline>
</log>
 

Help?

 

Share this post


Link to post
Share on other sites

I'm working on a simple login script where I create a GUI and call a function that opens chrome, finds an element types a username goes to the next element and types the password. when I run the function again I get the below error so I am guessing the array needs to be cleared out before I run the function again? I basically used simplespy to generate the code. It works perfectly when I just re-run the function in Scite, but when I include it into my GUI I get the below error on the second run, first run is fine.

here is the function only

Func website()

;~ Start chrome

If processexists($strChromeExeOnly) Then
    WinClose("website","")
    sleep (1000)
    run($strChromeExe & $strChromeStartup & " " &"--user-data-dir=C:\AutoLogontestCrome\userData" & " " & "--disable-single-click-autofill" & " " & $MedtronicURL,"", @SW_MAXIMIZE )
    ProcessWait($strChromeExeOnly)
    ;~ Just to give some time to start
    sleep(3000)

Else
    run($strChromeExe & $strChromeStartup & " " &"--user-data-dir=C:\AutoLogontestCrome\userData" & " " & "--disable-single-click-autofill" & " " & $MedtronicURL,"", @SW_MAXIMIZE )
    ProcessWait($strChromeExeOnly)
    ;~ Just to give some time to start
    sleep(3000)
EndIf

local $oChrome=_UIA_getFirstObjectOfElement($UIA_oDesktop,"class:=Chrome_WidgetWin_1", $treescope_children)
$oChrome.setfocus()


AutoItSetOption("MustDeclareVars", 1)

_UIA_setVar("oP1","Title:=website - Google Chrome;controltype:=UIA_PaneControlTypeId;class:=Chrome_WidgetWin_1")    ;website Network - Google Chrome
_UIA_setVar("oP2","Title:=Medtronic CareLink Network;controltype:=UIA_DocumentControlTypeId;class:=Chrome_RenderWidgetHostHWND")    ;website
_UIA_setVar("oP3","Title:=;controltype:=UIA_CustomControlTypeId;class:=")   ;
_UIA_setVar("oP4","Title:=;controltype:=UIA_CustomControlTypeId;class:=")   ;
_UIA_setVar("oP5","Title:=;controltype:=UIA_CustomControlTypeId;class:=")   ;
_UIA_setVar("oP6","Title:=;controltype:=UIA_TableControlTypeId;class:=")    ;
_UIA_setVar("oP7","Title:=;controltype:=UIA_CustomControlTypeId;class:=")   ;
_UIA_setVar("oP8","Title:=CareLink® Network • Sign In Please enter your User ID and password to enter the Medtronic CareLink Clinician Website. User ID: Password: Sign In Patient Information Site >> Forgot Password?;controltype:=UIA_DataItemControlTypeId;class:=") ;website • Sign In Please enter your User ID and password to enter the Website. User ID: Password: Sign In bla bla >> Forgot Password?
_UIA_setVar("oP9","Title:=;controltype:=UIA_CustomControlTypeId;class:=")   ;
_UIA_setVar("oP10","Title:=;controltype:=UIA_TableControlTypeId;class:=")   ;
_UIA_setVar("oP11","Title:=;controltype:=UIA_CustomControlTypeId;class:=")  ;

;~ $oUIElement=_UIA_getObjectByFindAll(".mainwindow", "title:=;ControlType:=UIA_DataItemControlTypeId", $treescope_subtree)
_UIA_setVar("oUIElement","Title:=;controltype:=UIA_DataItemControlTypeId;class:=") ;ControlType:=UIA_DataItemControlTypeId;classname:=")

;~ Actions split away from logical/technical definition above can come from configfiles

_UIA_Action("oP1","")
;;_UIA_Action("oP1","setfocus")
;~_UIA_Action("oP2","highlight")
;;_UIA_Action("oP2","setfocus")
;~_UIA_Action("oP3","highlight")
;;_UIA_Action("oP3","setfocus")
;~_UIA_Action("oP4","highlight")
;;_UIA_Action("oP4","setfocus")
;~_UIA_Action("oP5","highlight")
;;_UIA_Action("oP5","setfocus")
;~_UIA_Action("oP6","highlight")
;;_UIA_Action("oP6","setfocus")
;~_UIA_Action("oP7","highlight")
;;_UIA_Action("oP7","setfocus")
_UIA_Action("oP8","")
;;_UIA_Action("oP8","setfocus")
;~_UIA_Action("oP9","highlight")
;;_UIA_Action("oP9","setfocus")
;~_UIA_Action("oP10","highlight")
;;_UIA_Action("oP10","setfocus")
;~_UIA_Action("oP11","highlight")
;;_UIA_Action("oP11","setfocus")
_UIA_action("oP11","click")
Send("blabla")
sleep(500)
_UIA_action("oP10","click")
Send("blabla")
sleep(500)
;Send("{ENTER}")
;GUICtrlSetState($Button2, $GUI_ENABLE)
EndFunc

 

Output

>"C:\Program Files (x86)\AutoIt3\SciTE\..\AutoIt3.exe" "C:\Program Files (x86)\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.au3" /run /prod /ErrorStdOut /in "C:\AutoLogontestCrome\login_GUI_v2.au3" /UserParams    
+>19:35:18 Starting AutoIt3Wrapper v.19.102.1901.0 SciTE v.4.1.2.0   Keyboard:00000409  OS:WIN_10/  CPU:X64 OS:X64  Environment(Language:0409)  CodePage:0  utf8.auto.check:4
+>         SciTEDir => C:\Program Files (x86)\AutoIt3\SciTE   UserDir => C:\Users\user1\AppData\Local\AutoIt v3\SciTE\AutoIt3Wrapper   SCITE_USERHOME => C:\Users\user1\AppData\Local\AutoIt v3\SciTE
>Running AU3Check (3.3.14.5)  from:C:\Program Files (x86)\AutoIt3  input:C:\AutoLogontestCrome\login_GUI_v2.au3
+>19:35:19 AU3Check ended.rc:0
>Running:(3.3.14.5):C:\Program Files (x86)\AutoIt3\autoit3.exe "C:\AutoLogontestCrome\login_GUI_v2.au3"    
+>Setting Hotkeys...--> Press Ctrl+Alt+Break to Restart or Ctrl+Break to Stop
"C:\Program Files (x86)\AutoIt3\Include\UIAWrappers.au3" (1673) : ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.:
$x = Int($t[1] + ($t[3] / 2))
$x = Int($t[1] + (^ ERROR

->19:36:11 AutoIt3.exe ended.rc:1
+>19:36:11 AutoIt3Wrapper Finished.
>Exit code: 1    Time: 53.91

Share this post


Link to post
Share on other sites

You are right I basically cache things in the array by prefixing it with rti. For runtime type information whenever the object is found it reuses that info. As I am on holiday without laptop hard to say in which example I remove items from array that start with rti.

Share this post


Link to post
Share on other sites

Did anybody recently try to run the Firefox automation example? After doing some modifications, I have been able to access tree elements like tabs and click to them, so basic things work. But I can't access the document itself, I always get ""Action 6 failed". Any Ideas?

Thanks for any help.

Heinz

Share this post


Link to post
Share on other sites

Try if simplespy highlights your document area and or elements. Most likely during upgrades they change element order and as such your document identification or element tree changed. Which ff version are you running.

Share this post


Link to post
Share on other sites
On 8/8/2019 at 7:30 PM, junkew said:

Try if simplespy highlights your document area and or elements. Most likely during upgrades they change element order and as such your document identification or element tree changed. Which ff version are you running.

Today, I had the chance to do some more testing with simplespy.au3:

  • I used machine #1 with 64bit Windows 7 build 7601 and almost current Firefox 68.0 64bit
  • I ran the same tests on machine #2 with 32bit Windows 7 build 7601 and current Firefox 68.0.1 32bit
  • Same Tests were made on another machine #3 with 64bit Windows 10 1803 and current Firefox 68.0.1 32bit

More details about my environment:

  • All machines have German versions of Windows and Firefox.
  • On the 64bit machines #1 and #3, I executed simplespy.au3 in both modes x86 and x64, using "Run Script (x64)" and "Run Script (x86)"
  • During the tests, Firefox is already started when I run simplespy.au3
  • I have to confirm an UAC Dialog, before simplespy.au3 starts
  • I have autoit version 3.3.14.5 installed on all machines

How I did the tests:

  • I can place my mouse over almost any Element of Firefox (tried toolbar, address bar, favourite bookmarks), press Ctrl+W and get information about that element in the simplespy window on any machine.
  • If i place my mouse anywhere in the content area of the browser (where the web content is displayed) and press Ctrl+W there, simpplespy.au3 crashes on machines #1 and #2 (with the additional information as shown below). On machine #3, everything works as expected.

Conclusion:

  • Access to content area of firefox doesn't seem to be possible with windows 7, but works fine with windows 10

Do you have any idea what's going wrong with Windows 7?

 

Appendix - Additional Error Information

Machine #1, 32bit mode and Machine #2, 32bit mode

Problemsignatur:
  Problemereignisname:    APPCRASH
  Anwendungsname:    AutoIt3.exe
  Anwendungsversion:    3.3.14.5
  Anwendungszeitstempel:    5aaa71bf (different each time, of course)
  Fehlermodulname:    uiautomationcore.dll
  Fehlermodulversion:    7.0.0.0
  Fehlermodulzeitstempel:    56f58458 (different each time, of course)
  Ausnahmecode:    c0000005
  Ausnahmeoffset:    00053671
  Betriebsystemversion:    6.1.7601.2.1.0.256.48
  Gebietsschema-ID:    1031
  Zusatzinformation 1:    0a9e
  Zusatzinformation 2:    0a9e372d3b4ad19135b953a78882e789
  Zusatzinformation 3:    0a9e
  Zusatzinformation 4:    0a9e372d3b4ad19135b953a78882e789

Machine #1, 64bit mode

Problemsignatur:
  Problemereignisname:    APPCRASH
  Anwendungsname:    AutoIt3_x64.exe
  Anwendungsversion:    3.3.14.5
  Anwendungszeitstempel:    5aaa71d3
  Fehlermodulname:    uiautomationcore.dll
  Fehlermodulversion:    7.0.0.0
  Fehlermodulzeitstempel:    56f58b9a
  Ausnahmecode:    c0000005
  Ausnahmeoffset:    000000000005bffe
  Betriebsystemversion:    6.1.7601.2.1.0.256.48
  Gebietsschema-ID:    1031
  Zusatzinformation 1:    a04c
  Zusatzinformation 2:    a04c4c7ad5cbb615489808b507a01638
  Zusatzinformation 3:    c91a
  Zusatzinformation 4:    c91af45283a621aa3e02406f3227c8f3

 

 

Share this post


Link to post
Share on other sites
1 hour ago, Heinzl said:

Access to content area of firefox doesn't seem to be possible with windows 7

Browse to about:config, confirm the risk, find all parameters browser.tabs.remote.autostart, browser.tabs.remote.autostart.1, browser.tabs.remote.autostart.2 etc, turn them all to false and restart Firefox. Now you will see only one process Firefox.exe but IUIAutomation should work.

Oops... this worked on version 67 but does not work on 68. Sorry.

Edited by InnI

Share this post


Link to post
Share on other sites

Hard to say but I feel its a firefox issue.

 

You can doublecheck with inspect.exe whats happening and if you can reproduce report a bug with mozilla firefox and/or feature request.

I am on W10 nowadays and not working iwth W7 machines so hard to help in anlalysing.

validate these links on FF. I have been reading this and see litlle info on UIA but they support MSAA (and UIA puts a layer if needed overMSAA)

about:config in addressbar and then type accessibility maybe you can tweak some settings

 

 

Share this post


Link to post
Share on other sites

Thank you junkew and InnI for your assistance!

I won't spend any more time on Windows 7 and will continue work with Windows 10.

Now that I am able to find the content object of type UIA_DocumentControlTypeId, I have another question:

Is there a way to "convert" this to something that is more similar to a DomTree (like ISimpleDom)? Or, in other words: How do I acces porperties like innerHTML or innerText?

Thank you for any assistance

Share this post


Link to post
Share on other sites

This is an example on how to get whole DOM thru javascript and addressbar in chrome/ff/edge/IE.

  • Its easier in general to test this information thru IE (when its correct there chances are low its different in other browser)
  • I use UIA mainly for "black box" testing and then you are less interested in the html code itself but as you can see you can get to the information you want.
  • In 99% of the cases I just alert what I need to a popup/message alertbox and read that with "standard" functions.
  • Below example makes an additional textarea where I can put anything I want with multiple javascript miniscripts I execute thru addressbar

This textarea I then read with _UIA_action( <ID of textarea>,"getvalue). So after below script is finished you should see at the bottom of your html page a huge textarea( normally I make them 1x1 pixel)

;~ *** Standard code maintainable ***
#include "UIAWrappers.au3"
AutoItSetOption("MustDeclareVars", 1)

_UIA_setVar("oChromeWindow",".*Google Chrome;controltype:=UIA_PaneControlTypeId;class:=Chrome_WidgetWin_1") ;AutoIt General Help and Support - AutoIt Forums - Google Chrome
_UIA_setVar("oAdressbar","Title:=Adres") ;ControlType:=UIA_ButtonControlTypeId;classname:=")

_UIA_Action("oChromeWindow","setfocus")

;~ _UIA_action("oAdressbar","highlight")
;~ _UIA_action("oAdressbar","setfocus")

local $jsSource="javascript:"
$jsSource&="var UIAel=document.createElement(""textarea"");"
$jsSource&="UIAel.cols=80;"
$jsSource&="UIAel.rows=40;"
$jsSource&="UIAel.value=document.body.innerHTML;"
$jsSource&="document.body.appendChild(UIAel);"
$jsSource&="void(0);"

consolewrite(stringreplace($jsSource,";",";"&@CRLF))
;~ Alternative
;~ $jsSource="javascript:alert(document.body.innerHTML;"
;~ $jsSource&="void(0);"

_UIA_action("oAdressbar","setvalue",$jsSource)
sleep(1500)
_UIA_action("oAdressbar","sendkeys","{ENTER}")

more advanced

never needed it and only made a demo once with websockets

https://www.tutorialspoint.com/html5/html5_websocket.htm

with javascript approach you can start a websocket in the page and communicate with it from AutoIT

 

Edited by junkew
added websocket info

Share this post


Link to post
Share on other sites

Thank you for your sample code. Unfortunately, javascript is not an option in my case. So I try to slowly approach the ISimpleDomNode. According to https://developer.mozilla.org/en-US/docs/Mozilla/Tech/Accessibility/AT-APIs/ImplementationFeatures/MSAA#ISimpleDOMNode this should be possible in Firefox. In your sample file ex30_ISimpleDom.au3, I found that you are doing quite the same thing for chrome. So I tried to create a very simple test, which looks like this:
 

; Test for Firefox Access

#include "UIAWrappers.au3"

#AutoIt3Wrapper_UseX64=Y  ;Should be used for stuff like tagpoint having right struct etc. when running on a 64 bits os

; find Firefox Window
ConsoleWrite("Find Firefox ... ")
Local $oFF = _UIA_getFirstObjectOfElement($UIA_oDesktop, "class:=MozillaWindowClass", $treescope_children)
If IsObj($oFF) Then
    ConsoleWrite("found" & @CRLF)
Else
    _UIA_DumpThemAll($UIA_oDesktop, $treescope_children)
EndIf

; find Google TAB
ConsoleWrite("Find Document ... ")
Local $oDoc = _UIA_getObjectByFindAll($oFF, "Title:=.*Google Search;controltype:=UIA_DocumentControlTypeId", $treescope_subtree)
If IsObj($oDoc) Then
    ConsoleWrite("found" & @CRLF)
Else
    _UIA_DumpThemAll($oFF, $treescope_subtree)
EndIf

; convert to Accessible
Local $oAccessible = ObjCreateInterface($oDoc, $sIID_IAccessible, $dtagIAccessible)
If IsObj($oAccessible) Then
    ConsoleWrite("Converted to IAccessible" & @CRLF)
else
    ConsoleWrite("Conversion failed" & @CRLF)
EndIf

I would expect to get an Instance of IAccessible, but I get the following output instead:

Find Firefox ... found
Find Document ... found
Conversion failed

Maybe this is because ObjCreateInterface expects a pointer not an object?

Can you give any advice? Thanks in advance

Heinz

Share this post


Link to post
Share on other sites

I get an error right off the bat with a new copy of UIAWrappers.au3... it says "Variable used without being declared" and it points to "$UIA_OptimizeForVisualContentPropertyId"... Am I missing a required include or something?

Edit: (I'm following the quickstart guide with UIA_V0_70 and AutoIt V3.3.14.5)

Edit 2: Even stranger is that I can run the 'simple uia spy' without issue. There must a missing include file.

Edit 3: No idea how it happened, but apparently I had an old CUIAutomation2 file in my includes which didn't have that variable. Worked fine in the download folder because it was in the zip.

Edited by seadoggie01

All my code provided is Public Domain... but it may not work. ;) Use it, change it, break it, whatever you want.

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...