Jump to content
junkew

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

Recommended Posts

Ok will fix it that xml should not be created in later version

Has this been fixed? I had a modified UIAWrappers where the xml's were not generated. I lost that file and for some reason I can't get this to work.

Share this post


Link to post
Share on other sites

Thats a nice assumption that i remember something said 5 months ago. Download stuff from first post. Then retry and if not working ask for help preferably in general support section with clear reproducing script.

Share this post


Link to post
Share on other sites

I am trying to update a very old script that used IE.au3 on Win2003 and IE7, we had to finally update system and that script no longer works :(

I am now using this IUIautomation and Firefox but having issues, I am not finding links in the pages when I look for them.  The HTML comes from ASP and unfortunately I can't change it, it seems that most links do not have a "name" attribute, just a "id". The first part I thought was working but it turns out that with only 2 fields it was just working by default, I am now trying to "click a link" but I can't find when I do a UIA_getObject... I get the messages that I cant find UserNameTextBox but as I mentioned that continues and works.  I can't get the Import part to work.

consolewrite("Log In" & @CRLF)
    $oFFToolbar=_UIA_getFirstObjectOfElement($oFF,$cToolbarByName, $treescope_subtree)
    $oFFAddressBar=_UIA_getObjectByFindAll($oFFToolbar, $cAddressBarByName  , $treescope_subtree)
    _UIA_action($oFFAddressBar,"setvalue using keys","MDID/{ENTER}")
    ;~  give some time to open website
    sleep(2000)
    $oDocument=_UIA_getObjectByFindAll($oFF,$cstrDocument, $treescope_subtree)
    $oUserNameBox=_UIA_getObjectByFindAll($oDocument,"name:=UsernameTextBox", $treescope_subtree) ;FAILS but because there are only 2 fields on the form, it works.
    if not isobj($oUserNameBox) Then
        ConsoleWrite("Failed to find UserNAme textbox even though we know its there" & @CRLF)
        _UIA_DumpThemAll($oFF,$treescope_subtree)
    EndIf
    _UIA_action($oUserNameBox,"setvalue using keys","XYZ{TAB}")
    $oPasswordTextBox=_UIA_getObjectByFindAll($oFF,"name:=PasswordTextBox", $treescope_subtree)
    _UIA_action($oPasswordTextBox,"setvalue using keys","XYZ{ENTER}")
    consolewrite("Log In Finished" & @CRLF)

    sleep(3000)

    consolewrite("Go to Import page" & @CRLF)
    ;since I can't seem to find links on the page AND I am logged in successfully, enter the URL manually (would rather go clicking around on links though)
    _UIA_action($oFFAddressBar,"setvalue using keys","http://mdid/import.aspx?id=29{ENTER}")
    sleep(3000)
    ;button created by <input name="FileUpload" id="FileUpload" type="file" /> in html that I can't change.
    $oBrowseButton=_UIA_getObjectByFindAll($oFF,"FileUpload", $treescope_subtree) ; Also tried "text:=Read File;indexrelative:=2" since button has ID but no "name"
    if not isobj($oBrowseButton) Then
        ConsoleWrite("Failed to find input button FileUpload even though we know its there" & @CRLF)
        _UIA_DumpThemAll($oFF,$treescope_subtree)
    EndIf
    ;_UIA_action($oBrowseButton,"leftclick")
    ; Move the mouse to do what I can't seem to do up above.
MouseMove(237,490)
MouseDown("left")
MouseUp("left")
    consolewrite("Import page Finished" & @CRLF)

 

Share this post


Link to post
Share on other sites

So I am learning this stuff (a little bit) and I am brutally murdering the IE example and making it work piece by piece by learning what I can reference objects by and how to find them under the parent object.

I have this working so far but have a few questions.

1.) Is there a "wait to load" so that we do not have to use Sleep() and hope things have loaded before the next step executes?  

2.) If I try to run the script without closing the IE window first it gives an error instead of simply loading another window, why is that?

 

#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <constants.au3>
#include <WinAPI.au3>
#include <debug.au3>
#include "CUIAutomation2.au3"
#include "UIAWrappers.au3"

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

;~ Make this language specific
const $cToolbarByName = "class:=Address Band Root" ;Navigation bar
const $cAddressBarByName = "name:=Address and search using Bing"
const $cIENewTabByName="name:=New Tab.*"
const $cBrowser="classname:=IEFrame"
;~ const $cDocumentWindow="controltype:=" & $UIA_DocumentControlTypeId
const $cDocumentWindow="classname:=Internet Explorer_Server"
const $cBoardItem="name:=controlsend doesn't work"
const $cEdtSearch="name:=Search.*"
const $cSearchButton="name:=Search.*; indexrelative:=3"

$strIEExeFolder=@programfilesdir & "\Internet Explorer\"
$strIEStartup=""
$strIEExe=$strIEExeFolder & "iexplore.exe "

;~ Start chrome
if fileexists($strIEExe) Then
    if not processexists("iexplore.exe") Then
        run($strIEExe & $strIEStartup,"", @SW_MAXIMIZE )
        ProcessWait("iexplore.exe")
        ;~ Just to give some time to start
        sleep(10000)
    endif
Else
    consolewrite("No clue where to find IE on your system, please start manually:" & @CRLF )
    consolewrite($strIEExe & $strIEStartup & @CRLF)
EndIf

;~ Find the IE window
$oIE=_UIA_getFirstObjectOfElement($UIA_oDesktop, $cBrowser, $treescope_children)
if not isobj($oIE) Then
    _UIA_DumpThemAll($UIA_oDesktop,$treescope_children)
EndIf

;~ Make sure chrome is front window
$oIE.setfocus()

 ;get the IE toolbar
;~  $oIEToolbar=_UIA_getFirstObjectOfElement($oIE,"controltype:=" & $UIA_ToolBarControlTypeId, $treescope_subtree)
    $oIEToolbar=_UIA_getFirstObjectOfElement($oIE,$cToolbarByName, $treescope_subtree)
    if not isobj($oIEToolbar) Then
        _UIA_DumpThemAll($oIE,$treescope_subtree)
    EndIf

consolewrite("Action 5" & @CRLF)
    $oIEAddressBar=_UIA_getObjectByFindAll($oIEToolbar, $cAddressBarByName  , $treescope_subtree) ;works in chrome 29

    if not isobj($oIEAddressbar) Then
        _UIA_DumpThemAll($oIEToolbar,$treescope_subtree)
    EndIf

    $t=stringsplit(_UIA_getPropertyValue($oIEAddressBar, $UIA_BoundingRectanglePropertyId),";")
    ;_UIA_DrawRect($t[1],$t[3]+$t[1],$t[2],$t[4]+$t[2])
    _UIA_action($oIEAddressBar,"leftclick")
    _UIA_action($oIEAddressBar,"setvalue using keys","www.autoitscript.com/{ENTER}")


    ;~  give some time to open website
    sleep(2000)
    $oDocument=_UIA_getFirstObjectOfElement($oIE,$cDocumentWindow, $treescope_subtree)
    if not isobj($oDocument) Then
        _UIA_DumpThemAll($oIE,$treescope_subtree)
    Else
        $t=stringsplit(_UIA_getPropertyValue($oDocument, $UIA_BoundingRectanglePropertyId),";")
        _UIA_DrawRect($t[1],$t[3]+$t[1],$t[2],$t[4]+$t[2])
    EndIf

    sleep(500)


    $oForumLink=_UIA_getObjectByFindAll($oDocument,"name:=Forum", $treescope_subtree)
;~ All document items
    if not isobj($oForumLink) Then
        _UIA_DumpThemAll($oDocument,$treescope_subtree)
    EndIf
    _UIA_action($oForumLink,"leftclick")
    sleep(3000)

    $oDonateLink= _UIA_getObjectByFindAll($oDocument,"name:=Donate and help the website!", $treescope_subtree)
        if not isobj($oDonateLink) Then
        _UIA_DumpThemAll($oDocument,$treescope_subtree)
    EndIf
    _UIA_action($oDonateLink,"leftclick")
    sleep(3000)

As I get the hang of it, its very nifty!  I think the gist is just everything is an object and you need to filter down from a parent object to the child you need to interact with based on some identifying property and then interact with that child object as needed.

So what I need to do is find the best way to find all those objects, what interactions I can have, and keep practicing.

Somebody who really knows this should do a video tutorial, I sure will when I am good enough but I am far from right now.  

All the _UIA_DumpThemAll() where does it actually dump that info by the way?  I have not seen it in my Scite console or anywhere else. 

Share this post


Link to post
Share on other sites

Logging depends on if you turn it on or off. There should be an xml when you turn it on. Video tutorial is a nice suggestion but learning it is just start doing it. Its hard to have one tool that can see all objects. Unfortunately there is no standard way of determining ready state it differs per browser what is smart to do. Sleep helps but checking pixels , hourglass or certain text to be on screen is more stable to synchronize.

Share this post


Link to post
Share on other sites

I have given up trying to find links on the screen in my example above and just maximizing Firefox and then moving the mouse to where it needs to be.  I know this is resolution dependent but it works.

 Now my question is how to search the screen for specific text, using IE.au3 I was doing

While 1
        _IELoadWait($oIE) ; wait for any refreshes to complete
        $tmpHTML = _IEBodyReadText($oIE)
        If StringInStr($tmpHTML, "The last data import for this collection successfully finished.") Then ExitLoop
        Sleep(1000)
    WEnd

 Not finding (yet) the equivalent in this new way with Firefox.

Share this post


Link to post
Share on other sites

More practice moved on to try Outlook 2010 out.

Got this working.  My issues finding the New Message Window I thought name:=string.* acted as a wildcard but for me it refused to find the window until I gave it an exact title including the space at the end of the string.

Tried invoke to click on things but guess that only works on some things so ended up using "leftclick" action.

Also if my window is minimized .SetFocus does not bring it to the front or restore/maximise.  Is there a way to do that?

Here is what I was able to scramble together, would like feedback on what to do better and such.

P.S.  You can use name (title) class, and I saw in some of the examples classname (I had not had much luck with that yet) but can you use the ID's? If so what is the proper way to state the use of an ID?

#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <constants.au3>
#include <WinAPI.au3>
#include <debug.au3>
#include "CUIAutomation2.au3"
#include "UIAWrappers.au3"

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

$oOutlook=_UIA_getFirstObjectOfElement($UIA_oDesktop,"class:=rctrl_renwnd32", $treescope_children)
if not isobj($oOutlook) Then
    _UIA_DumpThemAll($UIA_oDesktop,$treescope_children)
EndIf

;~ Make sure Outlook is front window
$oOutlook.setfocus()

$oOutlookHome = _UIA_getFirstObjectOfElement($oOutlook, "name:=Home", $treescope_subtree)
_UIA_action($oOutlookHome,"leftclick")

$oNewMail =_UIA_getFirstObjectOfElement($oOutlook, "name:=New E-mail", $treescope_subtree)
_UIA_action($oNewMail,"leftclick")
Sleep(1000)

$oOutlookMessage=_UIA_getFirstObjectOfElement($UIA_oDesktop,"name:=Untitled - Message (HTML) ", $treescope_children)
$oOutlookMessage.setfocus()
$oWriteMessage =_UIA_getFirstObjectOfElement($oOutlookMessage, "name:=Insert", $treescope_subtree)
_UIA_action($oWriteMessage, "leftclick")
$oBody = _UIA_getFirstObjectOfElement($oOutlookMessage, "class:=_WwG", $treescope_subtree)
;_UIA_action($oBody, "leftclick")
_UIA_action($oBody,"setvalue using keys","Test of auto typing a new email.") ;

 

Share this post


Link to post
Share on other sites

Practiced over the weekend, made good progress I think!

Came up with a couple of new questions.

To help navigate items where you may need to wait, if we have a Next button greyed out can we check its status similar to how it can be done with ControlCommand()?

While Not ControlCommand("Outlook 2007 Startup", "", "Button2", "IsEnabled", "")
    Sleep(500)
WEnd

Also while I like the red boxes for debugging and building the script, is there a global flag to change on the final script to remove the red boxes highlighting everything?

Regards,

Share this post


Link to post
Share on other sites

Yes there are flags to turn highlighting off. Search in the udf for highlight. The concept of iuiautomation is different so hard to give a generic approach on simulating controlcommand logic and difference between ff chrome and ie browser.

Share this post


Link to post
Share on other sites

Enabled / disabled stuff

["IsEnabled", $UIA_IsEnabledPropertyId]

_UIA_getPropertyValue($UIA_oMyObject, $UIA_IsEnabledPropertyId)

click/leftclick are synonyms

maximize window

first check property ["WindowCanMaximize", $UIA_WindowCanMaximizePropertyId]

_UIA_Action($MyWindow,"maximize") which is implemented like

        Case "maximize"
            $tPattern = _UIA_getPattern($obj2ActOn, $UIA_WindowPatternId)
            $tPattern.SetWindowVisualState($WindowVisualState_Maximized)

settings like highlight / debug

should come from a config file but seems not stable so use so workaround use true/false

;~     Some settings to use as a default
    _UIA_setVar("Global.Debug", True)
    _UIA_setVar("Global.Debug.File", True)
    _UIA_setVar("Global.Highlight", True)

using id's

["id", $UIA_AutomationIdPropertyId]

so it should be like:     id:=<yourid>

simplespy should give the actual id to use

 

Share this post


Link to post
Share on other sites

Hi all,

I am quite new with AutoIt but I must have missed something. I just installed AutoIt and I want to run the ISimpleDom example. The first time is says : CLSISFromString "Unknown function name" in module ISimpleDom.au3.

So I try to find some code or it and found:

Func CLSIDFromString($sGUID)
    Local $tGUID = DllStructCreate("ulong Data1;ushort Data2;ushort Data3;byte Data4[8]")
    DllCall("ole32.dll", "long", "CLSIDFromString", "wstr", $sGUID, "struct*", $tGUID)
    Return $tGUID
EndFunc   ;==>CLSIDFromString

After it complained about redefined Constants in MSAccessibility.au3. Again I found in a comment that you should comment some lines ;-(

It finally ran but I sson as I clicked on the Chrome window it said : WindowFromAccessibleObject "unknown function name"

Either I have missed something in my setup or AutoIt had changed or ...?

Thanks in advance

Dominque

Share this post


Link to post
Share on other sites

I DON"T NEED YOUR STUPID XML FILE! IT LITTERED MY DESKTOP.

Secondly, where is documentation of _UIA_getPropertyValue,_UIA_getObjectByFindAll,_UIA_getFirstObjectOfElement etc.

Share this post


Link to post
Share on other sites

@Domdom: AutoIT does not install the iuiautomation and iaccessible and isimpledom stuff you should get it from this thread. Did you try to run the examples. I will have some time coming weeks so I will try to rerun all stuff with latest AutoIT and Windows 10 combinatons. (including EDGE browser)

@Palpatin: Not sure if I should answer. The logfile can be turned off with  _UIA_setVar("Global.Debug.File", False)
  documentation should not be needed if you just study the examples and read this thread it should not be that difficult but feel free to volunteer on making a help file

Share this post


Link to post
Share on other sites

Could I make a suggestion? I think it would be nice for some users like me to have some reading abilities inside _UIA_action. I myself enabled that by adding these few lines to the big Switch statement at line 1440 of the UIAWrappers.au3 file, just after DumpThemAll:

        case "PickName"; useful to get the label of a button, for example
            $retVal=_UIA_getPropertyValue($obj2ActOn, $UIA_NamePropertyId)
        case "PickValue";useful to get the value inside an edit box, for example
            $retVal=_UIA_getPropertyValue($obj2ActOn, $UIA_ValueValuePropertyId)
        case "IsEnabled"; useful to get the status of a button, if enabled, that is, clickable (returns True), or not (returns False)
            $retVal=_UIA_getPropertyValue($obj2ActOn, $UIA_IsEnabledPropertyId)
        case "IsSelected"; useful to get the status of a radio button, True for selected, False for not selected
            $retVal=_UIA_getPropertyValue($obj2ActOn, $UIA_SelectionItemIsSelectedPropertyId)

I imagine there are many other of such small additions, I only listed 4 that are specifically useful for me.

By the way, excellent job, junkew, you are an inspiration!

Share this post


Link to post
Share on other sites

Thx for suggestions. I am still in doubt about staying on the larger growing case statemen  or make many small wrapperfunction. The idea is to have a base case statement and if an action is unknown do an eval("ext" &  straction) so implementation and extension can be independent.

Func ext......

Endfunc

Share this post


Link to post
Share on other sites

I have some questions about this amazing UDF:

  • When will it be available inside the core of AutoIt? Is it still planned?
  • Could we automate javafx, qt, gtk+, wxwidgets based gui applications in the future?
  • I saw your github and I am wondering why do you use AutoIt and not C# for this library?

Share this post


Link to post
Share on other sites

lot of work to properly document for a udf to become core.

qt 5 is working the others are dependent if those widgets implemen iuiautomation clientproviders

c# implementation examples you can find at microsoft as its their native accessibility library

Share this post


Link to post
Share on other sites

Hello all , 

i'm new to Autoit,and trying to retrieve the url information from Chrome.I tried the example 5, but getting the error " Error on Opening file #include "CUIAutomation2.au3". I have included the "CUIAutomation2.au3" and "UIAWrappers.au3" in include folder of AutoIT.

Can anyone please assist me on getting the chrome url

 

Versions

Auto IT : 3.3.14

Chrome : 47

Thanks in advance

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