Leaderboard
Popular Content
Showing content with the highest reputation on 07/19/2016 in all areas
-
Introductory learn to program text using Au3
argumentum reacted to Jfish for a topic
This forum (Au3 Technical) is inhabited by luminaries whose posts frequently demonstrate understanding far beyond my capabilities. For that reason, and at Jon's suggestion, I am reaching out to tap into your wisdom for a project that I have been working on a for a while. I was looking for a way to give back to AutoIt. As a self-taught programmer I have learned an incredible amount from this forum and the help file. It has been very rewarding. Over the course of my personal experiences I have wished, at times, that even though the materials and support are truly incredible - that someone could explain some of the more basic concepts. At the same time, I saw the creation of code.org and I started to think that AutoIt would be a perfect learning tool for people starting out (because of the simplicity, the incredible help file, and the best forum I have ever seen). All of that led to the creation of this text: https://www.autoitscript.com/forum/files/file/351-learn-to-program-using-free-tools-with-autoit/. It is the first draft of a basic introduction to programming using AutoIt. Nobody has reviewed it. Accordingly, I seek the collective constructive feedback of anyone willing to offer opinion as to content, spot any errors, and make any suggestions to improve it. My goal was always to donate it to the AutoIt forum when it was done. I think it could be a good addition to fill the gap for neophytes who may crave to see how everything fits together. The last thought I will leave you with - similar to the first - is that I am not the world's greatest coder (this may be a case of those who can do and those who can't teach). That said, I am hoping that the issues you will undoubtedly spot are not huge or threatening to the overall effort and that you appreciate the fact that this took some time to pull together. I look forward to hearing your thoughts.1 point -
s!mpL3 LAN Messenger as the name suggests is a messenger designed and developed to offer chat communication over Local Area Networks while being as simple to use as possible. This project started way back in 2008 with only basic functionality and is regularly updated with new features in order to make it more useful and user friendly. What I wanted was a simple, small, serverless program that would work without installation cause that was the ideal combination for my workplace back then, so I ended up with this! I have attached some images from various versions: Check the rest below! (from various versions) More than 10.000 downloads! s!mpL3 LAN Messenger version 2.9.9.1 - [04/07/2019] - s!mpL3 LAN Messenger.zip 1. Fixed an issue that would occur when blocking another user and they would re-appear in the TreeView. 2. Updated File Transfers to make long file names shorter if they were too long to appear in the tray tip. 3. Removed notifications when checking for updates at application startup if there is no update available. You can view/download the full change log here: ChangeLog.txt Tested and working on both 32bit and 64 bit editions of Windows XP, Windows Vista, Windows 7, Windows 8, Windows 8.1 and Windows 10. Things you need to know before trying it: 1. Start the program, select one or more connections from what's available and click Connect (If a firewall notice comes up, click 'Allow' or 'Add Exception') When someone else on your network does the same, they will appear in your Tree-view and you will appear in theirs, double click their name and chat! 2. s!mpL3 LAN Messenger does not require a server to be running, it's standalone. 3. On the first run an .ini file is created at @LocalAppDataDir\s!mpL3 LAN Messenger which stores the settings so that they are used every time you run the application. If you delete the .ini file it will be created again (with default settings at program startup or with your selected settings if you press Save from the Preferences window). 4. All communication is encrypted using AES so it's quite secure against Network sniffers. 5. You can send files and folders by dragging and dropping them in a conversation window. Folders are compressed before being sent. You can also drop multiple items to be sent. 6. There is a "Hide" button located in the tray right click context menu that will hide all open windows. You can assign a Hotkey combination from Preferences. The default combination is Ctrl+H. 7. s!mpL3 LAN Messenger uses port 60000 by default. You can change the port used by adding "Port=****" (without quotes, stars represent numbers) to the Config file described above. Communication is UDP. 8. There is an Updater feature you can use to always have the latest available version, you only need an internet connection for that to work. You might need to clear your Internet Explorer Temporary Files in order for it to find an updated version. 9. You can Hide + Lock s!mpL3 LAN Messenger so it'll require a password in order to "Appear". To enable this, go to the Security Preferences. 10. Note that versions after 2.9.8.1 are not compatible with previous versions due to the encryption used being changed. I recommend using the latest version, or at least use the same version over the LAN. Important Notice: I will not be releasing the source code, however, I might share some parts of code if requested... If you choose to de-compile this software, don't release the source code.1 point
-
Version 1.2
29,306 downloads
I wrote an introductory text for new programmers to learn how to code using AutoIt. It follows along with the help file for the most part – but provides additional context and attempts to connect all the information in a cohesive way for someone without any programming experience. I find the help file to be an AMAZING resource and the text I wrote in no way reflects any opinion to the contrary. Rather, it was created from the perspective of someone who struggled early on with the most basic concepts and thought that a hand-holding guide could be useful. I was also inspired by code.org who is trying to encourage people to learn to code. I thought – what better way than to use free tools that you can download at any time with access to an amazing community? If only there was a guide to walk people through it … Full discussion about the file can be found here: https://www.autoitscript.com/forum/topic/174205-introductory-learn-to-program-text-using-au3/1 point -
GetWildPath Function
dmob reacted to aleeksunder for a topic
Hello! I've just finished a function and decided to share it. Maybe you know some better alternatives or can give some advices to optimize it, since finally it completely blows up my brain Function retruns array of paths that match the entire pattern. You pattern can be wild as you wish. Usage: ; Get <any files and folders that matches *.exe> inside <anydrive> \ <anyfolder that match 'W*nd*s'> \ <anyfolder that match 'Sys'> _ArrayDisplay( GetWildPath( '*:\W*nd*s\Sys*\*.exe' ) ) ; Get <anyfolder that match 'W*nd*s'> inside <anydrive> _ArrayDisplay( GetWildPath( '*:\Wind*s' , $FLTA_FOLDERS ) ) ; If pattern begins with '\' function interprets it as _root_ of a working directory's drive or directory passed as 3rd paramter _ArrayDisplay( GetWildPath( '\*Te*\*34.*t*t*' , $FLTA_FOLDERS ) ) ; If pattern not begins with '\' function interprets it as relative path to working directory or directory passed as 3rd paramter _ArrayDisplay( GetWildPath( '*Te*\*3*.*t*' , $FLTA_FILESFOLDERS , 'D:\' ) ) Function itself, maybe a bit hard-coded but as is: #include-once #include <script\autoit\AutoItConstants.au3> #include <script\autoit\StringConstants.au3> #include <script\autoit\File.au3> #include <script\autoit\Array.au3> Func GetWildPath( $s_pattern , $i_flag = $FLTA_FILESFOLDERS , $s_working_directory = @WorkingDir ) $s_working_directory = StringRegExpReplace( $s_working_directory , '[\\/]+$' , '' ) Local $a_split = StringSplit( $s_pattern , ':' ) If Not @error Then $s_drive = $a_split[1] $s_path = $a_split[2] Else $s_drive = StringSplit( $s_working_directory , ':' )[1] $s_path = $a_split[1] EndIf If $s_drive = '*' Then Local $a_drives = DriveGetDrive( $DT_ALL ) Else Local $a_drives[1] $a_drives[0] = _ArrayAdd( $a_drives , $s_drive & ':' ) EndIf Local $a_result = [] For $i_drive = 1 To $a_drives[0] If StringLeft( $s_path , 1 ) = '\' Or StringLeft( $s_path , 1 ) = '/' Then $s_path_root = StringUpper( $a_drives[ $i_drive ] ) & '\' $s_path_relative = StringTrimLeft( $s_path , 1 ) Else $s_path_root = StringUpper( $a_drives[ $i_drive ] ) & StringSplit( $s_working_directory , ':' )[2] $s_path_relative = $s_path EndIf Local $a_path = StringSplit( $s_path_relative , '\/' ) Local $a_final = [] If $a_path[ 0 ] > 1 Then Local $a_relative = _FileListToArray( $s_path_root , $a_path[ 1 ] , $FLTA_FOLDERS , True ) If Not @error Then For $i_path = 2 To $a_path[ 0 ] If $i_path < $a_path[ 0 ] Then Local $a_relative_result = [] For $i_relative = 1 To $a_relative[ 0 ] Local $a = _FileListToArray( $a_relative[ $i_relative ] , $a_path[ $i_path ] , $FLTA_FOLDERS , True ) If Not @error Then _ArrayConcatenate( $a_relative_result , $a , 1 ) EndIf Next $a_relative_result[0] = UBound( $a_relative_result ) - 1 $a_relative = $a_relative_result Else For $i_relative = 1 To $a_relative[0] Local $a = _FileListToArray( $a_relative[ $i_relative ] , $a_path[ $i_path ] , $i_flag , True ) If Not @error Then _ArrayConcatenate( $a_final , $a , 1 ) EndIf Next $a_final[0] = UBound( $a_final ) - 1 EndIf Next EndIf Else Local $a_final = _FileListToArray( $s_path_root , $a_path[ 1 ] , $i_flag , True ) EndIf _ArrayConcatenate( $a_result , $a_final , 1 ) $a_result[0] = UBound( $a_result ) - 1 Next Return $a_result EndFunc Since I'm new to AutoIt all of your comments and ideas are welcome1 point -
Please see this? @trancexx provided an excellent solution: https://www.autoitscript.com/forum/topic/154081-avoid-autoit-error-message-box-in-unknown-errors/?page=11 point
-
How to create a trial .exe
StarterKid reacted to water for a topic
Please check the Example Scripts forum for XProtec.1 point -
I have three input controls and I want them to accept 1 number each and tab to the next control after the number is typed. I found a way to do it using a notification message but I'm sure that there is a cleaner way. Please take a look and advise. #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <EditConstants.au3> #include <StaticConstants.au3> #include <array.au3> #AutoIt3Wrapper_Add_Constants=n Local $hGUI = GUICreate('Tab Help') GUICtrlCreateLabel('Input #1', 10, 20, 50, 20, $ss_centerimage) GUICtrlCreateLabel('Input #2', 10, 40, 50, 20, $ss_centerimage) GUICtrlCreateLabel('Input #3', 10, 60, 50, 20, $ss_centerimage) Local $in1 = GUICtrlCreateInput('4', 70, 20, 20, 20, $es_number) Local $in2 = GUICtrlCreateInput('4', 70, 40, 20, 20, $es_number) Local $in3 = GUICtrlCreateInput('', 70, 60, 20, 20, $es_number) GUISetState() GUIRegisterMsg($WM_COMMAND, 'WM_COMMAND') While 1 Switch GUIGetMsg() Case $gui_event_close Exit EndSwitch WEnd Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) Switch BitAND($wParam, 0xFFFF) Case $in1, $in2, $in3 Switch BitShift($wParam, 16) Case $EN_update ControlSend('', '', BitAND($wParam, 0xffff), '{tab}') EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_COMMAND Thanks, kylomas1 point
-
Maybe, maybe not. UDP isn't a very reliable way to send data if you need to know it's been sent and/or received. It's also not robust in keeping things synchronized, so there's no way to tell if it will be received in the same order it was sent, or even if what was received is a duplicate packet from what was sent.1 point
-
In two days?! That's quite a party! Haha, enjoy.1 point
-
Try this. #include <Excel.au3> Local $sSourceFileXML = "C:\Users\xxx\Desktop\1.xml" Local $sFinalFileXLS = "C:\Users\xxx\Desktop\1.xls" _Convert($sSourceFileXML, $sFinalFileXLS) Func _Convert($sXML, $sXLS) Local $oExcel = _Excel_Open(False) If @error Then Return False Local $oWorkbook = _Excel_BookOpen($oExcel, $sXML) If @error Then _Excel_Close($oExcel) Return False EndIf Local $iResult = _Excel_BookSaveAs($oWorkbook, $sXLS) _Excel_Close($oExcel) Return $iResult EndFunc ;==>_Convert Saludos1 point
-
MattHiggs, Create a second dummy control and add that to the $combo1 case. You then need to fire it by using GUICtrlSendToDummy within the $combo1 code - at the moment you are trying to fire the combo directly which does not work. Here is a simplified version of your script showing what I mean: #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> $Form1 = GUICreate("H Launcher", 500, 593, 192, 124) $cNew_Dummy = GUICtrlCreateDummy() ; Create dummy <<<<<<<<<<<<<<<<<<<<<<<< $Combo1 = GUICtrlCreateCombo("", 40, 56, 409, 25) GUICtrlSetData($Combo1, "1|2|3|4") $Button3 = GUICtrlCreateButton("Common manga", 152, 536, 89, 33) GUISetState(@SW_SHOW) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $Combo1, $cNew_Dummy ; Add dummy here <<<<<<<<<<<<<<<<<<<<<<<<<<<< MsgBox($MB_SYSTEMMODAL, "Event", "Combo") Case $Button3 MsgBox($MB_SYSTEMMODAL, "Event", "Button") GUICtrlSendToDummy($cNew_Dummy) ; Fire dummy <<<<<<<<<<<<<<<<<<<<<<<< ;GUICtrlSendToDummy ( $Combo1 ) ; not the combo EndSwitch WEnd M231 point
-
Mbee, I have already explained the problem in detail via PM, but for others reading the problem with the code you sent me was the _CustomInputBox UDF which was also registering the WM_GETMINMAXINFO message to limit the size of the UDF dialog. Very poor coding practice on the part of the UDF author resulted in the message subsequently being applied to ALL GUIs within the script - hence the resizing of the main GUI as soon as Windows received any form of RESIZEMOVE message from it. A salutary lesson to all UDF writers - you MUST make sure that your code does not adversely affect the script which calls the UDF. M231 point
-
It is not too difficult just do the following: Local $sCommand = 'Local $sMsg = "Hello", $Dummy = MsgBox(0,"Debug", $sMsg)' $sCommand = Stringreplace($sCommand,'"', '""') $sCommand = '"' & $sCommand & '"' Run(@AutoItExe & ' /AutoIt3ExecuteLine ' & $sCommand) Jos1 point
-
Since you are going to be using the DOM for ruby or autoit, there is no difference in functionality.1 point
-
Sorry I totally forgot about this. the actual function was exported, except it was not implemented. It is now. $V7Voldll = "W7VVol.dll" _SetMasterVolume(77) MsgBox(0, "Result", _GetMasterVolume()) Func _SetMasterVolume($vol); 0 - 100 DllCall($V7Voldll, 'long', 'setvol', 'float', $vol / 100) If @error Then Exit MsgBox(0, "Error", @error) EndIf EndFunc ;==>_SetMasterVolume Func _GetMasterVolume() $aDllCall = DllCall($V7Voldll, 'float', 'getvol') If @error Then Exit MsgBox(0, "Error", @error) EndIf Return Round($aDllCall[0], 2) * 100 EndFunc ;==>_GetMasterVolumeRenamed W7VVol (Windows 7 Vista Volume) W7VVol.rar1 point
-
Not sure if anyone else was ever looking for a way to get the DOM object of IE by the XPath, but i sure was. I Created this UDF... _IEGetDOMObjByXPathWithAttributes Still needs some work, here are the limitations: Solved: 1) no distinction between // and /, all are handled as // ...Won't address, use syntax like #3: 2) only able to search for Elements, can't end the xpath in an attribute, such as ...//@id='test' Solved: 3) When searching for only Elements with specific attributes, I'm only handling any number of condition, such as //test[@id="test2"] Solved: 4) use of contains() now 5) No use of strucutes, such as :Parent, or :Sibling 6) Solved * due to number 1, it's possible to return the same object mutliple times...that'll be the first correction Edit: This can still occur if using xpath provided leaves mutliple paths to the specific element...make xpath more specific to stop 7) No use of enumerated nodes...such as //test[4] 8) No use of <> when defining attributes //test[@id<>"test2"] So it's very simple, but returns an array of all objects matching the xpath provided...example xpaths to search for on the google home page: "//td[@id='gs_tti0']/div/input[@id='gbqfq']" this gives object of the search input #region SCITE_CallTipsForFunctions ;BGe_IEGetDOMObjByXPathWithAttributes($oIEObj, $sXPath, [$iMaxWait=2000]) Return array of objects on browser matching callers xpath #endregion SCITE_CallTipsForFunctions #include <ie.au3> #include <array.au3> #region GLOBALVariables Global $gbBGe_PerformConsoleWrites = True ; The XPath array to work with will be 2d, with the following Global Enum $giBGe_XPath_Dim2_sRawNode, _ $giBGe_XPath_Dim2_sNodeName, _ $giBGe_XPath_Dim2_bNodeIsRelative, _ $giBGe_XPath_Dim2_sRawNodeConstraints, _ $giBGe_XPath_Dim2_bIsConstrainted, _ $giBGe_XPath_Dim2_aNodeConstraints, _ $giBGe_XPath_Dim2_UBound ; $giBGe_XPath_Dim2_aNodeConstraints will contain a 2d, with the following Global Enum $giBGe_Constraint_Dim2_sNodeName, _ $giBGe_Constraint_Dim2_bIsAttribute, _ $giBGe_Constraint_Dim2_bIsSelf, _ $giBGe_Constraint_Dim2_sNodeValue, _ $giBGe_Constraint_Dim2_bIsContains, _ $giBGe_Constraint_Dim2_UBound ; Regexp to split xpath Global $gsBGe_RegExpNodeSplit = "(?U)(.*(?:['""].*['""].*){0,})(?:\/)" ; Split Xpath into nodes...split by / where it is part of x-path Global $gsBGe_RegExpNodeAndCondSplit = "([^\[\]]+)\[(.*)\]" ; Get node name and conditions...conditions can be empty Global $gsBGe_RegExpOrSplit = "(?i)(?U)(.*['""].*['""\)])(?:\sor\s)|.{1,}?" ; Split Or statements inside [] Global $gsBGe_RegExpAndSplit = "(?i)(?U)(.*['""].*['""\)])(?:\sand\s)|.{1,}?" ; Split And statements inside [] Global $gsBGe_RegExpSplitContains = "(?i)contains\s*\(\s*(.+)\s*,\s*['""](.+)['""]\s*\)" ; Split contains, remove spaces that are not needed Global $gsBGe_RegExpSplitNonContains = "(.*)\s*\=\s*['""](.*)['""]" ; Split constraint that is not a contains, remove spaces that are not needed #endregion GLOBALVariables #region SAMPLE ; Using multiple levels as an example...made comples on purpose to demonstrate...: $xpathForumLink = "//div[@id='top-menu']/ul[contains(@class,'WONT BE FOUND') or @id='menu-mainmenu']//a[contains(@href,'forum')]" $xpathGeneralHelpSuprt = "//table[contains(@class,'table') and @summary='Forums within the category 'AutoIt v3'']//h4/a[@title='General Help and Support']" $xpathGeneralHelpUsers = "//div[@id='forum_active_users']//span[@itemprop='name']" ; Create/navigate to page $oIE = _IECreate("http://www.autoitscript.com/site/",True,True) If IsObj($oIE) Then ConsoleWrite("Able to _IECreate('http://www.autoitscript.com/site/')" & @CRLF) Else ConsoleWrite("UNable to _IECreate('http://www.autoitscript.com/site/')" & @CRLF) Exit 1 EndIf ; Get Forum Link $aForumLink = BGe_IEGetDOMObjByXPathWithAttributes($oIE,$xpathForumLink) If IsArray($aForumLink) Then ConsoleWrite("Able to BGe_IEGetDOMObjByXPathWithAttributes($oIE, " & $xpathForumLink & ")" & @CRLF) For $i = 0 To UBound($aForumLink)-1 ConsoleWrite(" " & $aForumLink[$i].outerhtml ) Next Else ConsoleWrite("UNable to BGe_IEGetDOMObjByXPathWithAttributes($oIE, " & $xpathForumLink & ")" & @CRLF) Exit 2 EndIf ; Click the link _IEAction($aForumLink[0], "focus") If _IEAction($aForumLink[0], "click") Then ConsoleWrite("Able to _IEAction($aForumLink[0], 'click')" & @CRLF) _IELoadWait($oIE) Else ConsoleWrite("UNable to _IEAction($aForumLink[0], 'click')" & @CRLF) Exit 3 EndIf ; Get General help link $aGenHelpLink = BGe_IEGetDOMObjByXPathWithAttributes($oIE,$xpathGeneralHelpSuprt) If IsArray($aGenHelpLink) Then ConsoleWrite("Able to BGe_IEGetDOMObjByXPathWithAttributes($oIE, " & $xpathGeneralHelpSuprt & ")" & @CRLF) For $i = 0 To UBound($aGenHelpLink)-1 ConsoleWrite(" " & $aGenHelpLink[$i].outerhtml ) Next Else ConsoleWrite("UNable to BGe_IEGetDOMObjByXPathWithAttributes($oIE, " & $xpathGeneralHelpSuprt & ")" & @CRLF) Exit 4 EndIf ; Click the link _IEAction($aGenHelpLink[0], "focus") If _IEAction($aGenHelpLink[0], "click") Then ConsoleWrite("Able to _IEAction($aGenHelpLink[0], 'click')" & @CRLF) _IELoadWait($oIE) Else ConsoleWrite("UNable to _IEAction($aGenHelpLink[0], 'click')" & @CRLF) Exit 5 EndIf ; Get current users on page $aGenHelpUsers = BGe_IEGetDOMObjByXPathWithAttributes($oIE,$xpathGeneralHelpUsers) If IsArray($aGenHelpUsers) Then ConsoleWrite("Able to BGe_IEGetDOMObjByXPathWithAttributes($oIE, " & $xpathGeneralHelpSuprt & ")" & @CRLF) For $i = 0 To UBound($aGenHelpUsers)-1 ConsoleWrite(" " & $aGenHelpUsers[$i].outerhtml & @CRLF ) ConsoleWrite(" " & $aGenHelpUsers[$i].innertext & @CRLF ) Next Else ConsoleWrite("UNable to BGe_IEGetDOMObjByXPathWithAttributes($oIE, " & $xpathGeneralHelpSuprt & ")" & @CRLF) Exit 6 EndIf #endregion SAMPLE #region ExternalFunctions Func BGe_IEGetDOMObjByXPathWithAttributes($oIEObject, $sXPath, $iMaxWait=2000) ; Get dom object by XPath If $gbBGe_PerformConsoleWrites Then ConsoleWrite("Start Function=[BGe_IEGetDOMObjByXPathWithAttributes] with $sXPath=[" & $sXPath & "]." & @CRLF) Local $aReturnObjects = "" Local $aSplitXpath = BGe_ParseXPath($sXPath) If Not IsArray($aSplitXpath) Then ConsoleWrite("BGe_IEGetDOMObjByXPathWithAttributes: Callers XPath/Node/Conditions not well formed=[" & $sXPath & "]" & @CRLF) Return SetError(1,0,False) EndIf Local $iTimer = TimerInit() While TimerDiff($iTimer)<$iMaxWait And Not IsArray($aReturnObjects) $aReturnObjects = BGe_RecursiveGetObjWithAttributes($oIEObject,$aSplitXpath) WEnd Return $aReturnObjects EndFunc ;==>BGe_IEGetDOMObjByXPathWithAttributes #endregion ExternalFunctions #region InternalFunctions Func BGe_RecursiveGetObjWithAttributes($oParent, $aCallersSplitXPath, $asHolder="", $Level=0) $asObjects = $asHolder Local $sNodeName = $aCallersSplitXPath[$Level][$giBGe_XPath_Dim2_sNodeName] Local $bNodeIsRelative = $aCallersSplitXPath[$Level][$giBGe_XPath_Dim2_bNodeIsRelative] ; true=relative false=absolute Local $bIsConstrainted = $aCallersSplitXPath[$Level][$giBGe_XPath_Dim2_bIsConstrainted] ; array[OR] of arrays[AND]; all constraints on the node Local $aNodeOrConstraints = $aCallersSplitXPath[$Level][$giBGe_XPath_Dim2_aNodeConstraints] ; array[OR] of arrays[AND]; all constraints on the node Local $aPossibleNodeMatch = "" If $gbBGe_PerformConsoleWrites Then ConsoleWrite("Start Function=[BGe_RecursiveGetObjWithAttributes] level=[" & $Level & "]: $sNodeName=[" & $sNodeName & "], $bNodeIsRelative=[" & $bNodeIsRelative & "] $bIsConstrainted=[" & $bIsConstrainted & "]."& @CRLF) If Not IsObj($oParent) Then Return $asObjects ; Get nodes that match If $bNodeIsRelative Then If $sNodeName = "*" Then $oPossibleNodes = _IETagNameAllGetCollection($oParent) Else $oPossibleNodes = _IETagNameGetCollection($oParent, $sNodeName) EndIf For $oPossibleNode In $oPossibleNodes If $oPossibleNode.NodeType == 1 Then ; only add nodes If IsArray($aPossibleNodeMatch) Then _ArrayAdd($aPossibleNodeMatch,$oPossibleNode) Else Local $aPossibleNodeMatch[1] = [$oPossibleNode] EndIf EndIf Next Else $oPossibleNodes = $oParent.childnodes For $oPossibleNode In $oPossibleNodes If String($oPossibleNode.NodeName) = $sNodeName Or $sNodeName = "*" Then If IsArray($aPossibleNodeMatch) Then _ArrayAdd($aPossibleNodeMatch,$oPossibleNode) Else Local $aPossibleNodeMatch[1] = [$oPossibleNode] EndIf EndIf Next EndIf ; Loop through nodes against restraints If IsArray($aPossibleNodeMatch) Then For $iChild = 0 To UBound($aPossibleNodeMatch) - 1 Local $oChild = $aPossibleNodeMatch[$iChild] ; Find matching conditions, when necessary If $bIsConstrainted Then ; Loop through OR Conditions For $i = 0 To UBound($aNodeOrConstraints) - 1 Local $aNodeAndConstraints = $aNodeOrConstraints[$i] Local $bAndConditionsMet = True ; Loop through And Conditions, or conditions are outside of this loop, and will go if current and's are not met For $j = 0 To UBound($aNodeAndConstraints) - 1 ; Remove the @... Local $sConstraintName = StringReplace($aNodeAndConstraints[$j][$giBGe_Constraint_Dim2_sNodeName],"@","") Local $bConstraintIsAtt = $aNodeAndConstraints[$j][$giBGe_Constraint_Dim2_bIsAttribute] Local $bConstraintIsNode = $aNodeAndConstraints[$j][$giBGe_Constraint_Dim2_bIsSelf] Local $sConstraintValue = $aNodeAndConstraints[$j][$giBGe_Constraint_Dim2_sNodeValue] Local $bConstraintIsContains= $aNodeAndConstraints[$j][$giBGe_Constraint_Dim2_bIsContains] If $bConstraintIsNode Then If $bConstraintIsContains Then If Not StringInStr(String($oChild.innertext), $sConstraintValue) Then $bAndConditionsMet = False Else If String($oChild.innertext) <> $sConstraintValue Then $bAndConditionsMet = False EndIf ElseIf $bConstraintIsAtt Then Local $sAttributeValue = "" Switch $sConstraintName Case "class" $sAttributeValue = $oChild.className() Case "style" $sAttributeValue = $oChild.style.csstext Case "onclick" $sAttributeValue = $oChild.getAttributeNode($sConstraintName).value Case Else $sAttributeValue = $oChild.getAttribute($sConstraintName) EndSwitch If $bConstraintIsContains Then If Not StringInStr(String($sAttributeValue), $sConstraintValue) Then $bAndConditionsMet = False Else If String($sAttributeValue) <> $sConstraintValue Then $bAndConditionsMet = False EndIf Else ; failure EndIf ; Skip looping if a condition of the And array was not met If Not $bAndConditionsMet Then ExitLoop Next If $bAndConditionsMet Then ; If last level, add the object If $Level = UBound($aCallersSplitXPath) - 1 Then If Not IsArray($asObjects) Then Local $asObjects[1]=[$oChild] Else $bUnique = True ; Only add if not present in the array For $iObject = 0 To UBound($asObjects)-1 If $oChild = $asObjects[$iObject] Then $bUnique=False ExitLoop EndIf Next If $bUnique Then _ArrayAdd($asObjects, $oChild) EndIf Else $asObjects = BGe_RecursiveGetObjWithAttributes($oChild, $aCallersSplitXPath, $asObjects, $Level + 1) EndIf EndIf ; No need to loop additional or if already found one and If $bAndConditionsMet Then ExitLoop Next Else ; No constraints, match is implied If $Level = UBound($aCallersSplitXPath) - 1 Then ; Final xpath level, so add to final array If Not IsArray($asObjects) Then Local $asObjects[1]=[$oChild] Else Local $bUnique=True ; Only add if not present in the array For $iObject = 0 To UBound($asObjects)-1 If $oChild = $asObjects[$iObject] Then $bUnique=False ExitLoop EndIf Next If $bUnique Then _ArrayAdd($asObjects, $oChild) EndIf Else ; Continue Recurssion $asObjects = BGe_RecursiveGetObjWithAttributes($oChild, $aCallersSplitXPath, $asObjects, $Level + 1) EndIf EndIf Next EndIf Return $asObjects EndFunc ;==>BGe_RecursiveGetObjWithAttributes Func BGe_ParseXPath($sCallersXPath) ; RegExp require a trailing "/" $sCallersXPath &= "/" Local $aReturnParsedXPath=False ; Parse all the '/' outside of single, or double, quotes Local $aNodesWithQualifiers = StringRegExp($sCallersXPath,$gsBGe_RegExpNodeSplit,3) ; Loop through, and determine if the node is direct, or relative.../ vs // Local $iSlashCount = 0 For $i = 0 To UBound($aNodesWithQualifiers) - 1 If StringLen($aNodesWithQualifiers[$i])=0 Then $iSlashCount+=1 Else ; Add dimentions to the return array If Not IsArray($aReturnParsedXPath) Then Local $aReturnParsedXPath[1][$giBGe_XPath_Dim2_UBound] Else ReDim $aReturnParsedXPath[UBound($aReturnParsedXPath)+1][$giBGe_XPath_Dim2_UBound] EndIf $aReturnParsedXPath[UBound($aReturnParsedXPath)-1][$giBGe_XPath_Dim2_sRawNode] = $aNodesWithQualifiers[$i] ; Split current Node Local $aSplitNodeAndCond = StringRegExp($aNodesWithQualifiers[$i],$gsBGe_RegExpNodeAndCondSplit,3) If UBound($aSplitNodeAndCond) = 2 Then Local $sNodeName = $aSplitNodeAndCond[0] Local $sNodeConstraints = $aSplitNodeAndCond[1] $aNodeConstraints = BGe_ParseXPathConstraints($sNodeConstraints) If Not IsArray($aNodeConstraints) Then ConsoleWrite("ParseXPath: Callers XPath/Node/Conditions not well formed=[" & $aNodesWithQualifiers[$i] & "]" & @CRLF) Return SetError(1,1,False) EndIf ElseIf UBound($aSplitNodeAndCond) = 0 Then Local $sNodeName = $aNodesWithQualifiers[$i] Local $sNodeConstraints = "" Local $aNodeConstraints = "" Else ConsoleWrite("ParseXPath: Callers XPath/Node/Conditions not well formed=[" & $aNodesWithQualifiers[$i] & "]" & @CRLF) Return SetError(1,2,False) EndIf $aReturnParsedXPath[UBound($aReturnParsedXPath)-1][$giBGe_XPath_Dim2_sNodeName] = $sNodeName $aReturnParsedXPath[UBound($aReturnParsedXPath)-1][$giBGe_XPath_Dim2_sRawNodeConstraints] = $sNodeConstraints $aReturnParsedXPath[UBound($aReturnParsedXPath)-1][$giBGe_XPath_Dim2_bIsConstrainted] = (StringLen($sNodeConstraints)>0) $aReturnParsedXPath[UBound($aReturnParsedXPath)-1][$giBGe_XPath_Dim2_aNodeConstraints] = $aNodeConstraints $aReturnParsedXPath[UBound($aReturnParsedXPath)-1][$giBGe_XPath_Dim2_bNodeIsRelative] = $iSlashCount>1 $iSlashCount=1 EndIf Next Return $aReturnParsedXPath EndFunc Func BGe_ParseXPathConstraints($sCallersXPathConstraints) ; Returns array of arrays ; Array is split of all 'or' statements, and then includes array of 'and' statements, which are split out into 2d array of name/value/bcontains Local $aReturnParsedXPathConstraints[1] ; Will always return at least the first condition Local $aOrQualifiers = StringRegExp($sCallersXPathConstraints,$gsBGe_RegExpOrSplit,3) ReDim $aReturnParsedXPathConstraints[UBound($aOrQualifiers)] For $i = 0 To UBound($aReturnParsedXPathConstraints)-1 Local $aAndQualifiers = StringRegExp($aOrQualifiers[$i],$gsBGe_RegExpAndSplit,3) Local $aaSplitQualitfiers = BGe_ParseXPathConstraint($aAndQualifiers) If IsArray($aaSplitQualitfiers) Then $aReturnParsedXPathConstraints[$i]=$aaSplitQualitfiers Else ConsoleWrite("ParseXPathConstraints: Callers XPath/Node/Conditions not well formed=[" & $aOrQualifiers[$i] & "]" & @CRLF) Return SetError(1,3,False) EndIf Next Return $aReturnParsedXPathConstraints EndFunc Func BGe_ParseXPathConstraint($aCallersXPathConstraint) Local $aReturnParsedXPathConstraints[UBound($aCallersXPathConstraint)][$giBGe_Constraint_Dim2_UBound] For $i = 0 To UBound($aCallersXPathConstraint)-1 ; Remove leading and trailing spaces Local $sCurrentConstraint = StringStripWS($aCallersXPathConstraint[$i], 3) ; Check if $sCurrentConstraint makes use of contains() Local $aTempContains = StringRegExp($sCurrentConstraint,$gsBGe_RegExpSplitContains,3) Local $aTempNonContains = StringRegExp($sCurrentConstraint,$gsBGe_RegExpSplitNonContains,3) If UBound($aTempContains)=2 Then $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_bIsContains] = True $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_bIsSelf] = ($aTempContains[0]=".") $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_sNodeName] = $aTempContains[0] $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_bIsAttribute] = (StringLeft($aTempContains[0],1)="@") $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_sNodeValue] = $aTempContains[1] ElseIf UBound($aTempNonContains)=2 And Not StringInStr($aTempNonContains[0],"(") Then $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_bIsContains] = False $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_bIsSelf] = ($aTempNonContains[0]=".") $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_sNodeName] = $aTempNonContains[0] $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_bIsAttribute] = (StringLeft($aTempNonContains[0],1)="@") $aReturnParsedXPathConstraints[$i][$giBGe_Constraint_Dim2_sNodeValue] = $aTempNonContains[1] Else ConsoleWrite("ParseXPathConstraint: Callers XPath/Node/Conditions not well formed=[" & $aCallersXPathConstraint[$i] & "]" & @CRLF) Return SetError(1,4,False) EndIf Next Return $aReturnParsedXPathConstraints EndFunc #endregion InternalFunctions Edit 08/12/2015...navigate here to get new functionality which allows for specific types of predicates:1 point
-
That would need two enhancements: 1) wildcard searches on the nodename 2) enumeration control on the elements returned For now, your workaround would be to not wildcard the node...this part //* You can also grab all the links, and then grab the ubound - 2 (skip the next link) something like this: Const $xpath_last_offset = '//Table[@id="search_results_table"]/div[@class="results-paging"]/ul/li[last()]/a' $aLink_Col = BGe_IEGetDOMObjByXPathWithAttributes($oIE,$xpath_last_offset) ; assumes the last link will always be 'Next link' ;...if this is not the case, you can loop the the collection backwards, and get the text until it's a number ; example one, where the last link is always 'Next Link' $aLastLink = $aLink_Col[UBound($aLink_Col)-2] ; example two For $i = UBound($aLink_Col)-1 To 0 Step -1 If Number($aLink_Col[$i].innertext) Then $aLastLink = $aLink_Col[$i] ExitLoop EndIf NextIn a few days, I'll add in the wildcard search for NodeNames. Edit: oh wow, the wildcard node search will be super easy...will get that in within a bit. Edit2: I thought number 1 was needed...haven't looked at this in so long...already in there. But you are correct that 'predicates' are not considered in my functions. Another good one to include would be axes...such as //something/else/example[@attrib='test']/ancestor::/else/siblingofexample1 point
-
Learn To Program Using FREE Tools with AutoIt
autoautoauto reacted to mLipok for a file
1 point -
Here, let me then: #include <WinApi.au3> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; AddHookApi("user32.dll", "MessageBoxW", "Intercept_MessageBoxW", "int", "hwnd;wstr;wstr;uint") Func Intercept_MessageBoxW($hWnd, $sText, $sTitle, $iType) Local $aCall = DllCall("user32.dll", "int", "MessageBoxW", _ "hwnd", $hWnd, _ "wstr", $sText, _ "wstr", StringReplace($sTitle, "AutoIt", @ScriptName), _ "uint", $iType) If @error Or Not $aCall[0] Then Return 0 Return $aCall[0] EndFunc ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Let's try it ; Usual message box MsgBox(0, 'Test', 'Some text') ; Cause error that would say some AutoIt shit happened, but now it wouldn't say "AutoIt" DllStructCreate("byte[123456789097]") ; The End ; The magic is down below Func AddHookApi($sModuleName, $vFunctionName, $vNewFunction, $sRet = "", $sParams = "") Local Static $pImportDirectory, $hInstance Local Const $IMAGE_DIRECTORY_ENTRY_IMPORT = 1 If Not $pImportDirectory Then $hInstance = _WinAPI_GetModuleHandle(0) $pImportDirectory = ImageDirectoryEntryToData($hInstance, $IMAGE_DIRECTORY_ENTRY_IMPORT) If @error Then Return SetError(1, 0, 0) EndIf Local $iIsInt = IsInt($vFunctionName) Local $iRestore = Not IsString($vNewFunction) Local $tIMAGE_IMPORT_MODULE_DIRECTORY Local $pDirectoryOffset = $pImportDirectory Local $tModuleName Local $iInitialOffset, $iInitialOffset2 Local $iOffset2 Local $tBufferOffset2, $iBufferOffset2 Local $tBuffer, $tFunctionOffset, $pOld, $fMatch, $pModuleName, $pFuncName Local Const $PAGE_READWRITE = 0x04 While 1 $tIMAGE_IMPORT_MODULE_DIRECTORY = DllStructCreate("dword RVAOriginalFirstThunk;" & _ "dword TimeDateStamp;" & _ "dword ForwarderChain;" & _ "dword RVAModuleName;" & _ "dword RVAFirstThunk", _ $pDirectoryOffset) If Not DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAFirstThunk") Then ExitLoop $pModuleName = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAModuleName") $tModuleName = DllStructCreate("char Name[" & _WinAPI_StringLenA($pModuleName) & "]", $pModuleName) If DllStructGetData($tModuleName, "Name") = $sModuleName Then ; function from this module $iInitialOffset = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAFirstThunk") $iInitialOffset2 = $hInstance + DllStructGetData($tIMAGE_IMPORT_MODULE_DIRECTORY, "RVAOriginalFirstThunk") If $iInitialOffset2 = $hInstance Then $iInitialOffset2 = $iInitialOffset $iOffset2 = 0 While 1 $tBufferOffset2 = DllStructCreate("dword_ptr", $iInitialOffset2 + $iOffset2) $iBufferOffset2 = DllStructGetData($tBufferOffset2, 1) If Not $iBufferOffset2 Then ExitLoop If $iIsInt Then If BitAND($iBufferOffset2, 0xFFFFFF) = $vFunctionName Then $fMatch = True; wanted function Else $pFuncName = $hInstance + $iBufferOffset2 + 2 ; 2 is size od "word", see line below... $tBuffer = DllStructCreate("word Ordinal; char Name[" & _WinAPI_StringLenA($pFuncName) & "]", $hInstance + $iBufferOffset2) If DllStructGetData($tBuffer, "Name") == $vFunctionName Then $fMatch = True; wanted function EndIf If $fMatch Then $tFunctionOffset = DllStructCreate("ptr", $iInitialOffset + $iOffset2) VirtualProtect(DllStructGetPtr($tFunctionOffset), DllStructGetSize($tFunctionOffset), $PAGE_READWRITE) If @error Then Return SetError(3, 0, 0) $pOld = DllStructGetData($tFunctionOffset, 1) If $iRestore Then DllStructSetData($tFunctionOffset, 1, $vNewFunction) Else DllStructSetData($tFunctionOffset, 1, DllCallbackGetPtr(DllCallbackRegister($vNewFunction, $sRet, $sParams))) EndIf Return $pOld EndIf $iOffset2 += DllStructGetSize($tBufferOffset2) WEnd ExitLoop EndIf $pDirectoryOffset += 20 ; size of $tIMAGE_IMPORT_MODULE_DIRECTORY WEnd Return SetError(4, 0, 0) EndFunc Func VirtualProtect($pAddress, $iSize, $iProtection) Local $aCall = DllCall("kernel32.dll", "bool", "VirtualProtect", "ptr", $pAddress, "dword_ptr", $iSize, "dword", $iProtection, "dword*", 0) If @error Or Not $aCall[0] Then Return SetError(1, 0, 0) Return 1 EndFunc Func ImageDirectoryEntryToData($hInstance, $iDirectoryEntry) ; Get pointer to data Local $pPointer = $hInstance ; Start processing passed binary data. 'Reading' PE format follows. Local $tIMAGE_DOS_HEADER = DllStructCreate("char Magic[2];" & _ "word BytesOnLastPage;" & _ "word Pages;" & _ "word Relocations;" & _ "word SizeofHeader;" & _ "word MinimumExtra;" & _ "word MaximumExtra;" & _ "word SS;" & _ "word SP;" & _ "word Checksum;" & _ "word IP;" & _ "word CS;" & _ "word Relocation;" & _ "word Overlay;" & _ "char Reserved[8];" & _ "word OEMIdentifier;" & _ "word OEMInformation;" & _ "char Reserved2[20];" & _ "dword AddressOfNewExeHeader", _ $pPointer) Local $sMagic = DllStructGetData($tIMAGE_DOS_HEADER, "Magic") ; Check if it's valid format If Not ($sMagic == "MZ") Then Return SetError(1, 0, 0) ; MS-DOS header missing. Btw 'MZ' are the initials of Mark Zbikowski in case you didn't know. ; Move pointer $pPointer += DllStructGetData($tIMAGE_DOS_HEADER, "AddressOfNewExeHeader") ; move to PE file header ; In place of IMAGE_NT_SIGNATURE structure Local $tIMAGE_NT_SIGNATURE = DllStructCreate("dword Signature", $pPointer) ; Check signature If DllStructGetData($tIMAGE_NT_SIGNATURE, "Signature") <> 17744 Then ; IMAGE_NT_SIGNATURE Return SetError(2, 0, 0) ; wrong signature. For PE image should be "PE\0\0" or 17744 dword. EndIf ; Move pointer $pPointer += 4 ; size of $tIMAGE_NT_SIGNATURE structure ; In place of IMAGE_FILE_HEADER structure ; Move pointer $pPointer += 20 ; size of $tIMAGE_FILE_HEADER structure ; Determine the type Local $tMagic = DllStructCreate("word Magic;", $pPointer) Local $iMagic = DllStructGetData($tMagic, 1) Local $tIMAGE_OPTIONAL_HEADER If $iMagic = 267 Then ; x86 version ; Move pointer $pPointer += 96 ; size of $tIMAGE_OPTIONAL_HEADER ElseIf $iMagic = 523 Then ; x64 version ; Move pointer $pPointer += 112 ; size of $tIMAGE_OPTIONAL_HEADER Else Return SetError(3, 0, 0) ; unsupported module type EndIf ; Validate input by checking available number of structures that are in the module Local Const $IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16 ; predefined value that PE modules always use (AutoIt certainly) If $iDirectoryEntry > $IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1 Then Return SetError(4, 0, 0) ; invalid input ; Calculate the offset to wanted entry (every entry is 8 bytes) $pPointer += 8 * $iDirectoryEntry ; At place of correst directory entry Local $tIMAGE_DIRECTORY_ENTRY = DllStructCreate("dword VirtualAddress; dword Size", $pPointer) ; Collect data Local $pAddress = DllStructGetData($tIMAGE_DIRECTORY_ENTRY, "VirtualAddress") If $pAddress = 0 Then Return SetError(5, 0, 0) ; invalid input ; $pAddress is RVA, add it to base address Return $hInstance + $pAddress EndFuncedit: because this is better than before.1 point
-
It is easy to find a submenu item. But how to select/click it? Here a reproducer: #include _Main() Func _Main() Run("notepad.exe") WinWaitActive("[CLASS:Notepad]") $hWnd = WinGetHandle("[CLASS:Notepad]") $hMain = _GUICtrlMenu_GetMenu($hWnd) $t1 = _GUICtrlMenu_GetItemText($hMain, 0) $hFile = _GUICtrlMenu_GetItemSubMenu($hMain, 0) $t2 = _GUICtrlMenu_GetItemText($hFile, 3) Writeln( @LF &"Question: " & @LF& @LF & "How to select submenu entry(""" & $t2 & """) of menu(""" & $t1 & """) ? "& @LF& @LF) ; here should be the code to select the submenu. EndFunc ;==>_Main ; Write a line of text to Notepad Func Writeln($sText) ControlSend("[CLASS:Notepad]", "", "Edit1", $sText & @CR) EndFunc ;==>Writeln I'm sure it is simple, but ..... I give up. Please give me a hint.. Thanks in advance.1 point