Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 12/10/2019 in all areas

  1. LarsJ

    UI Automation Events

    UI Automation Events In standard Windows GUI code, you can respond to Windows messages by registering and implementing a message handler function. A WM_NOTIFY message handler is registered and implemented in this way: ; Registration GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" ) ; Implementation Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam ) ; Code EndFunc The WM_NOTIFY function is a callback function. In UI Automation code, you can respond to UI Automation events by registering and implementing an event handler object. A FocusChangedEventHandler object is registered and implemented in this way: ; Registration UIAEH_FocusChangedEventHandlerCreate() $oUIAutomation.AddFocusChangedEventHandler( 0, $oUIAEH_FocusChangedEventHandler ) ; Implementation ; This is the function that receives events Func UIAEH_FocusChangedEventHandler_HandleFocusChangedEvent( $pSelf, $pSender ) ; Code EndFunc $oUIAEH_FocusChangedEventHandler is the event handler object. It's a callback object. This thread is about how to respond to UI Automation events by registering, implementing and using event handler objects. User Defined Functions Registering and implementing the event handler object in the code above is very simple. To make it that simple, it's necessary to include a few functions in a UDF. The zip-file at bottom of post contains a UIAEH_FocusChangedEventHandler.au3 UDF that allows the registration and implementation of the event handler object as simple as shown above. UIAEH_FocusChangedEventHandlerCreate() is a function in this UDF. The function creates the $oUIAEH_FocusChangedEventHandler object. Because this is a callback object it must be implemented through ObjectFromTag() (coded in ObjectFromTag.au3 in zip-file) function by trancexx and not through the usual ObjCreateInterface() which is used to create other UI Automation objects. (The warning at top of the help text is much more an error in the help text than an error in the function. Thousands of examples show that ObjCreateInterface() works flawlessly.) You don't need to use ObjectFromTag() in your own code. This function is completely handled in the UDFs. UIAEH_FocusChangedEventHandler_HandleFocusChangedEvent() is the function that receives events. This function is coded but commented out in UIAEH_FocusChangedEventHandler.au3. Copy this function to your own code. See FocusChangedEventHandler example below. UIA Event Handlers The first version of Microsoft's UI Automation code (the Windows 7 version that works on Windows XP, Windows Vista, Windows 7 and all later versions) implements four different event handler objects. In addition to the FocusChangedEventHandler object, it's the AutomationEventHandler, PropertyChangedEventHandler and StructureChangedEventHandler objects. The zip-file at the bottom contains the corresponding three event handler UDFs. By the way, these four event handlers are implemented in AutoIt several years ago in this and the following posts. FocusChangedEventHandler exposes a method to handle events that are raised when the keyboard focus moves to another UI Automation element. AutomationEventHandler exposes a method to handle Microsoft UI Automation events. These events include MenuOpened ($UIA_MenuOpenedEventId) and Window_WindowOpened ($UIA_Window_WindowOpenedEventId) events. See module UIA_EventIds in UIA_Constants.au3 for a complete list. Note that EventIds that belong to Windows 8 or later cannot be used in this version of the event handler. But they can be used after code updates over the coming weeks. 2019-12-15 If you select Desktop, AutomationEvent and all Events (Event Ids) in UI Automation Event Monitor below and click Start, you'll see the following output in SciTE console: $oUIAEH_AutomationEventHandler OK Desktop: AddAutomationEventHandler() = AsyncContentLoaded OK Desktop: AddAutomationEventHandler() = AutomationFocusChanged ERR Desktop: AddAutomationEventHandler() = AutomationPropertyChanged OK Desktop: AddAutomationEventHandler() = InputDiscarded OK Desktop: AddAutomationEventHandler() = InputReachedOtherElement OK Desktop: AddAutomationEventHandler() = InputReachedTarget OK Desktop: AddAutomationEventHandler() = Invoke_Invoked OK Desktop: AddAutomationEventHandler() = LayoutInvalidated OK Desktop: AddAutomationEventHandler() = MenuClosed OK Desktop: AddAutomationEventHandler() = MenuModeEnd OK Desktop: AddAutomationEventHandler() = MenuModeStart OK Desktop: AddAutomationEventHandler() = MenuOpened OK Desktop: AddAutomationEventHandler() = Selection_Invalidated OK Desktop: AddAutomationEventHandler() = SelectionItem_ElementAddedToSelection OK Desktop: AddAutomationEventHandler() = SelectionItem_ElementRemovedFromSelection OK Desktop: AddAutomationEventHandler() = SelectionItem_ElementSelected OK Desktop: AddAutomationEventHandler() = StructureChanged OK Desktop: AddAutomationEventHandler() = Text_TextChanged OK Desktop: AddAutomationEventHandler() = Text_TextSelectionChanged OK Desktop: AddAutomationEventHandler() = ToolTipClosed OK Desktop: AddAutomationEventHandler() = ToolTipOpened OK Desktop: AddAutomationEventHandler() = Window_WindowClosed OK Desktop: AddAutomationEventHandler() = Window_WindowOpened OK Note the error for the AutomationFocusChanged event handler (at the top of the list). I've found that there is an error, but so far have no explanation for it. PropertyChangedEventHandler exposes a method to handle Microsoft UI Automation events that occur when a property is changed. These events include Name ($UIA_NamePropertyId) and ValueValue ($UIA_ValueValuePropertyId) changes. See module UIA_PropertyIds in UIA_Constants.au3 for a complete list. Note that PropertyIds that belong to Windows 8 or later cannot be used in this version of the event handler. But they can be used after code updates over the coming weeks. StructureChangedEventHandler exposes a method to handle events that occur when the Microsoft UI Automation tree structure is changed. This event handler seems to be more valuable in eg. screen readers than in usual UI Automation code. NotificationEventHandler exposes a method to handle Microsoft UI Automation notification events. See this post. FocusChangedEventHandler example This is full code in Examples\FocusChangedEventHandlerEx.au3. Run the code in SciTE with F5. #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 ;#AutoIt3Wrapper_UseX64=y Opt( "MustDeclareVars", 1 ) #include "..\Includes\UIAEH_FocusChangedEventHandler.au3" Example() Func Example() UIAEH_FocusChangedEventHandlerCreate() If Not IsObj( $oUIAEH_FocusChangedEventHandler ) Then Return ConsoleWrite( "$oUIAEH_FocusChangedEventHandler ERR" & @CRLF ) ConsoleWrite( "$oUIAEH_FocusChangedEventHandler OK" & @CRLF ) Local $oUIAutomation = ObjCreateInterface( $sCLSID_CUIAutomation, $sIID_IUIAutomation, $dtag_IUIAutomation ) If Not IsObj( $oUIAutomation ) Then Return ConsoleWrite( "$oUIAutomation ERR" & @CRLF ) ConsoleWrite( "$oUIAutomation OK" & @CRLF ) Local $iError = $oUIAutomation.AddFocusChangedEventHandler( 0, $oUIAEH_FocusChangedEventHandler ) If $iError Then Return ConsoleWrite( "AddFocusChangedEventHandler() ERR" & @CRLF ) ConsoleWrite( "AddFocusChangedEventHandler() OK" & @CRLF ) HotKeySet( "{ESC}", "Quit" ) While Sleep(10) WEnd EndFunc Func Quit() UIAEH_FocusChangedEventHandlerDelete() Exit EndFunc ; This is the function that receives events Func UIAEH_FocusChangedEventHandler_HandleFocusChangedEvent( $pSelf, $pSender ) ; Ret: long Par: ptr ConsoleWrite( @CRLF & "UIAEH_FocusChangedEventHandler_HandleFocusChangedEvent: " & $pSender & @CRLF ) Local $oSender = ObjCreateInterface( $pSender, $sIID_IUIAutomationElement, $dtag_IUIAutomationElement ) $oSender.AddRef() ConsoleWrite( "Title = " & UIAEH_GetCurrentPropertyValue( $oSender, $UIA_NamePropertyId ) & @CRLF & _ "Class = " & UIAEH_GetCurrentPropertyValue( $oSender, $UIA_ClassNamePropertyId ) & @CRLF & _ "Ctrl type = " & UIAEH_GetCurrentPropertyValue( $oSender, $UIA_ControlTypePropertyId ) & @CRLF & _ "Ctrl name = " & UIAEH_GetCurrentPropertyValue( $oSender, $UIA_LocalizedControlTypePropertyId ) & @CRLF & _ "Handle = " & "0x" & Hex( UIAEH_GetCurrentPropertyValue( $oSender, $UIA_NativeWindowHandlePropertyId ) ) & @CRLF & _ "Value = " & UIAEH_GetCurrentPropertyValue( $oSender, $UIA_ValueValuePropertyId ) & @CRLF ) Return 0x00000000 ; $S_OK #forceref $pSelf EndFunc ; Auxiliary function (for simple properties only) ; There must be only one instance of this function Func UIAEH_GetCurrentPropertyValue( $oSender, $iPropertyId ) Local $vPropertyValue $oSender.GetCurrentPropertyValue( $iPropertyId, $vPropertyValue ) Return $vPropertyValue EndFunc Test the code by opening the Desktop context menu and move the mouse over the menu items. When the mouse hovers over a menu item it gets focus. Exit with Esc. AutomationEventHandlerEx.au3 Test the example by opening some windows, menus and tooltips. PropertyChangedEventHandlerEx.au3 Open Windows Task Manager (Ctrl+Shift+Esc) and you'll get a whole bunch of property changed events. Note that to access Windows Task Manager (and other programs) on Windows 10, use #RequireAdmin in the script and run SciTE as administrator. StructureChangedEventHandlerEx.au3 Clicking on a folder in File/Windows Explorer treeview generates a lot of structure changed events. New examples will be added over the coming weeks. UI Automation Event Monitor UI Automation Event Monitor is a tool to detect UI Automation events. The first group of toolbar buttons is used to set up the UI Automation event handler. The images have a PropertyChangedEventHandler set up to monitor Name ($UIA_NamePropertyId) and ValueValue ($UIA_ValueValuePropertyId) property changes in Windows Task Manager. Note that to access Windows Task Manager (and other programs) on Windows 10, use #RequireAdmin in the script (UIAEHEvents.au3) and run SciTE as administrator. These four toolbar buttons are hot-track enabled with the technique used in this example. The buttons open four listviews to set up the event handler. All listviews have multiple selections enabled. Select multiple items at once and check a single item in/out to check all selected items in/out. Use mouse or Space key to check an item in/out. In the first image, the mouse hovers over the Top Windows button so that it's selected. In the second image, the Top Windows button is clicked so that the listview is opened. Moving the mouse over the next three buttons automatically opens the corresponding listviews due to hot-tracking. Click the toolbar button again to close the listview or move the mouse above the title bar. Windows Task Manager is checked in the Top Windows listview. The Event Handlers listview is enabled when a Top Window is checked. The Event Ids listview is enabled when the AutomationEvent event handler is checked. The Property Ids listview is enabled when the PropertyChanged event handler is checked. In Event Ids and Property Ids listview you can select an item by pressing the first letter on the keyboard. The second group of toolbar buttons is used to Start/Stop the event handler (or multiple event handlers), Pause/Continue updating the Events listview, and Clear the listview. Note that the Pause button only stops updating the listview. Events are still detected and stored in $aEvents array. All new events are added at the bottom of the listview when you click Continue or Stop. The Pause Main Loop button is used to stop the GUI main loop, which significantly increases the performance of the Events listview. When the GUI main loop is paused you can only click the Continue Main Loop button (same button as Pause Main Loop) and you can close the GUI. Events listview The Events listview is a virtual listview because of performance and to make it easy to constantly add new rows to the bottom of the listview. Nevertheless, there can still be performance issues when a lot of events are generated. To remedy these issues, it's possible to stop the GUI main loop with the Pause Main Loop button. This significantly increases the performance of the Events listview. When there are a large number of events (when many new rows are added quickly at the bottom of the listview), this procedure must be followed to stop the event handler (or multiple event handlers): Make sure the GUI main loop isn't paused. Click the Pause button (second toolbar group) to pause Events listview updates. Click the Stop button to stop the event handler. When there are a small number of events you can immediately click the Stop button. To test the UI Automation Event Monitor, try performing the four examples (in Examples\, briefly described above) through the monitor GUI. There'll probably be some GUI updates in the coming weeks. UIA Menu, Tooltip and Window Events Monitor is a simpler version of UI Automation Event Monitor that detects only MenuOpened, ToolTipOpened and Window_WindowOpened events (AutomationEvents). Updates Windows 8, Windows 8.1 and Windows 10 updates Threads UI Automation UDFs contains all include files. UIASpy - UI Automation Spy Tool is a GUI tool that provides information about windows and controls and their interconnection and provides functionality to generate sample code. UIASpy is essential for creating UI Automation code. In Using UI Automation Code in AutoIt you can find and download examples and read information about using UIA code. IUIAutomation MS framework automate chrome, FF, IE, .... created by junkew August 2013 is the first AutoIt thread on UIA code. Zip-file The zip contains source files for GUIs and examples. Note that UI Automation UDFs must be installed in the Includes folder. You need AutoIt 3.3.12 or later. Tested on Windows 7 and Windows 10. Note that under Windows 7 and earlier versions, only the original four event handlers (AutomationEventHandler, FocusChangedEventHandler, PropertyChangedEventHandler, StructureChangedEventHandler) introduced in Windows 7 can be used. Comments are welcome. Let me know if there are any issues. UIAEHEvents.7z
    2 points
  2. Wow, you really put our resident word-wallers to shame. How about a short, concise description of what you're trying to accomplish? I got lost somewhere around Chapter 3
    2 points
  3. Understood, and agree in this specific case. But "AutoIt can't see individual controls or elements" isn't a statement we would want coming up in a Google search for someone trying to automate a browser, without at least some explanation.
    1 point
  4. Wow, yeah that is interesting. I wonder what the [LAST] keyword is doing internally. I assumed that when AutoIt did title matching it was just saving the handle from the most recent title match, and swapping that in whenever it encountered the [LAST] keyword, but I just tried this: $iCount = 0 HotKeySet('{ESC}', '_Exit') WinWait('[CLASS:TaskManagerWindow]') ; Let's use the classname so we don't have to translate each time ;) Do $iCount += 1 ConsoleWrite($iCount & ') =============================================' & @CRLF) ConsoleWrite('WinGetHandle: ' & WinGetHandle('[last]') & @CRLF) ; Always returns a valid handle ConsoleWrite('WinExists: ' & WinExists('[last]') & @CRLF) ; Always returns 1 ConsoleWrite('WinGetHandle(WinGetHandle): ' & WinGetHandle(WinGetHandle('[last]')) & @CRLF) ; Properly returns 0 ConsoleWrite('WinExists(WinGetHandle): ' & WinExists(WinGetHandle('[last]')) & @CRLF) ; Properly returns 0 Until WinWaitClose('[last]', '', 1) ;Until WinWaitClose(WinGetHandle('[last]'), '', 1) ; <- This line will detect properly Func _Exit() Exit EndFunc And as you'll see, WinGetHandle on [LAST] will give the same handle even after the window is closed, but WinGetHandle ON that handle, will return 0. So if it were a simple swap of [LAST] for an HWND, then the first WinGetHandle would also return 0. Maybe someone in the know can weigh in and explain what's happening with [LAST] behind the scenes.
    1 point
  5. After reconsideration, I have come to the conclusion that you are right. E.g. WinExists reports true even if the window has already been closed. Here is a little script to play around with : HotKeySet("{ESC}", "_Terminate") Local $iCount = 0 WinWait('Windows Task-Manager') ; title in german (==> use titel in your language instead, e.g. 'Task Manager') ConsoleWrite("> >>>> WinGetTitle = " & WinGetTitle("[LAST]") & @CRLF) ; just a check : "[LAST]" with WinExists If WinExists("[LAST]") Then ConsoleWrite("> >>>> WinExists = TRUE" & @CRLF) Else ConsoleWrite("! >>>> WinExists = FALSE" & @CRLF) EndIf ; just a check : "[LAST]" with WinActive If WinActive("[LAST]") Then ConsoleWrite("> >>>> WinActive = TRUE" & @CRLF) Else ConsoleWrite("! >>>> WinActive = FALSE" & @CRLF) EndIf ; =========================================================== ; Remove the comment for the desired area : ; =========================================================== ; Variation 1 : WinWaitClose ;~ WinWaitClose("[LAST]") ; <=== waits endlessly ;~ WinWaitClose(WinGetTitle("[LAST]")) ; <=== works ; Variation 2 : WinClose <=== works ;~ Sleep(2000) ;~ WinClose("[LAST]") ; Variation 3 : While WinExists <=== runs endlessly While WinExists("[LAST]") ConsoleWrite("> >>>> While WinExists -> " & $iCount & @CRLF) $iCount += 1 Sleep(250) WEnd ; Final message : ConsoleWrite("> >>>> CLOSED" & @CRLF) Func _Terminate() ConsoleWrite("! >>>> TERMINATED by ESC" & @CRLF) Exit EndFunc ;==>_Terminate
    1 point
  6. Chrome time is based on UTC, add / subtract the offset to your own timezone. Edit - This works fine for me: #include <array.au3> #include <Constants.au3> #include <Date.au3> ; 13218946054701800 = 22/11/2019 22:27:34 $EPOCHtime = 13220446295000000 / 1000000 ;------------------ convert from microseconds to seconds --------------------- $a_TimeZoneInfo = _Date_Time_GetTimeZoneInformation() $EPOCHtime -= $a_TimeZoneInfo[1]*60 ConsoleWrite("$EPOCHtime = "&$EPOCHtime &@CRLF) $time1 = _DateAdd('s', Int($EPOCHtime), "1601/01/01 00:00:00"); Chrome time base, 1601 ConsoleWrite("$time1 = " & $time1 & @CRLF) $decimalPart=$EPOCHtime -Int($EPOCHtime) ConsoleWrite("$decimalPart= "&$decimalPart&@CRLF) $time2 = _DateAdd('s',Int($decimalPart), $time1 ) ConsoleWrite("$time2 = " & $time2 & @CRLF)
    1 point
  7. TheDcoder

    _ReadIniSectionNames

    Those results are pretty wacky, AutoIt is performing some memory tradeoff to make string concatenation more efficient, which is good for people who want simple and fast code and don't mind some extra memory use. Anyway, the only remotely expensive operation in the timed parts of my code is the ReDim operation, which is only done once when the $iSectionCount guess is wrong (and it is right most of the time assuming not many INI files have the [ character as a value in one of their keys). The only other modification is: $SectionNames[0] += 1 $SectionNames[$SectionNames[0]] = $INIsection Which is supposed to be an almost instant operation, certainly when compared to string concatenation So there are other factors at play, and performance is not always reliable, especially when attempting to measure it according to my personal experience. In any case, my code doesn't depend on assumptions and trade-offs being made by the interperter (AutoIt) and it is pretty solid.
    1 point
  8. Jos

    Where have my posts gone ?

    @JLogan3o13, Just a FYI: I got fed up with him and clicked the "spammer" button after he created a new thread and wanted to have a play... (what an idiot) . Jos
    1 point
  9. Valik is no longer an active member or part of the development team. As mentioned, the ternary operator is alive and well in the current release. The mood when it comes to implementing new features is also much different than the response you got those many years ago. That said, I believe we will close this out for posterity. Any future feature requests can use the appropriate channel of the link below. Please be sure to read the post on what the development team won't be doing before posting any feature requests. That said, hopefully you have matured some since your previous "don't ban me or I'll spam the forum" posts. https://www.autoitscript.com/trac/autoit https://www.autoitscript.com/trac/autoit/wiki/AutoItNotOnToDoList
    1 point
  10. https://developer.servicenow.com/app.do#!/home
    1 point
  11. It should be possible, but you really haven't provided the necessary information to know for sure. I'm assuming that their API provides some form of web-based REST interface, so you would likely use the WinHTTP UDF to interact with it using the appropriate commands (Get, Post, Delete, etc). Good luck!
    1 point
  12. Did you try something like this ? http://octopart.com/api/v3/parts/search?apikey=REPLACE_ME&q=SN74S7&pretty_print=true
    1 point
  13. UIASpy updates to Windows 10 version 1809 Documentation for Windows 10 version 1809 updates can be found in Windows 8, Windows 8.1 and Windows 10 updates. This post is pretty much completely rewritten. In addition, there are a few minor updates that are documented below. A small but significant update is that in Sample code to find the application top window, $TreeScope_Descendants is replaced by $TreeScope_Children. The application top window is always a direct child of the Desktop. See the treeview in UIASpy. Therefore, this update can be made. This is a major performance update when the application window is not at the top of the Z-order of windows. UIA_MouseClick() in UIA_Functions.au3 is extended with right-click functionality. Sample code can be generated through Sample code | Code snippets ... In UIASpy.ini, through the DisplayScale key, you can specify the display scale you want when UIASpy starts up. Still not implemented update: Integrating $PropertyConditionFlags_MatchSubstring (Windows 10 1809) into Sample code. New zip-file at bottom of first post.
    1 point
  14. The explanation on this thread was the clearest at least to me, and I hope it can help someone else. Simple, i am not looking for any trouble, let me know if i should remove it ?
    1 point
  15. I have no idea what that means
    1 point
  16. Jos

    Where have my posts gone ?

    Sure... bye ...
    1 point
  17. Realm

    Where have my posts gone ?

    He better not try, He will get his IP banned, then He will not be able to read the site either.
    1 point
  18. ;;Step 1: Read data from file into an array $filenamein = "in.csv" $filehandle = FileOpen($filenamein, 0) Dim $data[1024][2] $count = 0 While 1 $read = FileReadLine($filehandle) If @Error = -1 Then ExitLoop $read = StringSplit($read, ",") $data[$count][0] = $read[1] $data[$count][1] = $read[2] $count += 1 WEnd FileClose($filehandle) ;; Step 2: Resize the array to the correct size ReDim $data[$count][2] ;; Step 3: Preform a sort operation, in this case it is the "Bubble Sort" algorithum. $swapped = 1 While $swapped = 1 $swapped = 0 For $i = 0 to $count-2 If Number($data[$i][1]) > Number($data[$i+1][1]) Then ;;Swap values $temp1 = $data[$i][1] $temp2 = $data[$i][0] $data[$i][1] = $data[$i+1][1] $data[$i][0] = $data[$i+1][0] $data[$i+1][1] = $temp1 $data[$i+1][0] = $temp2 $swapped = 1 EndIf Next WEnd ;; Step 4: Output result to file $fileout = "out.csv" $filehandle = FileOpen ( $fileout, 2 ) For $i = 0 to $count-1 FileWriteLine($filehandle, $data[$i][0]&","&$data[$i][1]) Next FileClose($filehandle) #)
    1 point
  19. Jos

    Where have my posts gone ?

    Ban evasion ... bye bye ....
    0 points
×
×
  • Create New...