Leaderboard
Popular Content
Showing content with the highest reputation on 10/07/2022 in all areas
-
Version 2021.8.30.2
10,226 downloads
Use MouseClick() need: #RequireAdmin Dll is already integrated in UDF ! ; #INDEX# =============================================================== ; Title .........: ImageSearch ; AutoIt Version : 3.x ; Language ......: English ; Description ...: Check image Appears or Not and Return the position of an image on the desktop ; Author(s) .....: Dao Van Trong - TRONG.LIVE ; ======================================================================= ; #CURRENT# ============================================================= ; _ImageSearch ; _ImageSearch_Area ; _ImageSearch_Wait ; _ImageSearch_WaitArea ; ======================================================================== ;========================================================================= ; ; Author:...........: AutoIT VietNam : Dao Van Trong - TRONG.LIVE ; Description:......: Check image Appears or Not ; Find and return the position of an image on the desktop ; Syntax:........... _ImageSearch_Area, _ImageSearch ; Parameter(s):..... $_ImagePath: The image to locate on the desktop ; May be a list of image by delimited by "|" ; i.e: $_ImagePath = "image1.bmp|image2.bmp|image3.bmp" ; $P_x1 $P_y1: Position of 1st point ; $P_x2 $P_y2: Position of 2nd point - Default is last botton right of desktop ; $_Tolerance: 0 for no tolerance (0-255). Needed when colors of image differ from desktop. e.g GIF ; $_CenterPos: boolen. True will return $array[1] x $array[2] is center of image found. ; False will return top-left position ; Return Value(s):.. Return an array has 3 item ; On Success: $array[0] 1 ; On Failure: $array[0] 0 ; DLL not found or other error: $array[0] -1 ; $array[1] x $array[2]: position of image what found on desktop ; ; Note:............. Use _ImageSearch to search the entire desktop ; _ImageSearch_Area to specify a desktop region to search ; $_ImagePath with more item need more time appear on screen before function can detect. ; Decrease sleep time in the loop to detect faster. But less performance. I.e CPULoad increased ; ;======================================================================== EG 1: ;~ Opt("MustDeclareVars", 1) ;~ #AutoIt3Wrapper_UseX64=y ;~ #AutoIt3Wrapper_Change2CUI=y #RequireAdmin #include "_ImageSearch_UDF.au3" HotKeySet("{Esc}", "_Exit") ; Press ESC for exit Func _Exit() Exit 0 EndFunc ;==>_Exit Global Const $Ask_On_Found = 0 Global Const $Mouse_Move_On_Found = 1 Global Const $Mouse_Click_On_Found = 0 Global Const $iSleep_Time=500 Global $sCount = 0, $_Image_1 = @ScriptDir & "\example.bmp" ; First, use this function to create a file bmp, maybe a desktop icon for example') MsgBox(64 + 262144, 'ImageSearch', 'At first, create a file bmp,' & @CRLF & 'photos that will search on the screen!') _ImageSearch_Create_BMP($_Image_1) ConsoleWrite("! Search for images: " & $_Image_1 & @CRLF & '! Searching on the screen ...' & @CRLF) While 1 ToolTip('(Press ESC for EXIT) Searching ...', 1, 1) Sleep($iSleep_Time) $sCount += 1 Local $return = _ImageSearch($_Image_1) If $return[0] = 1 Then ConsoleWrite('- [' & $sCount & '] Image found:' & " X=" & $return[1] & " Y=" & $return[2] & @CRLF) If $Mouse_Move_On_Found Then MouseMove($return[1], $return[2]) Sleep($iSleep_Time) EndIf If $Mouse_Click_On_Found Then MouseClick("left", $return[1], $return[2]) ToolTip('(Press ESC for EXIT) - [' & $sCount & "] Image found:" & " X=" & $return[1] & " Y=" & $return[2], 1, 1) If $Ask_On_Found Then Local $ask = MsgBox(6 + 262144, 'Success [' & $sCount & ']', 'Image found:' & " X=" & $return[1] & " Y=" & $return[2]) If $ask = 2 Or $ask = 3 Or $ask = 5 Or $ask = 7 Then Exit ;No, Abort, Cancel, and Ignore If $ask = 10 Then _ImageSearch_Create_BMP($_Image_1) ; Continue ;Try Again EndIf EndIf Sleep(200) WEnd Video demo: [+] When any problem or error occurs, please make sure that:- Downloaded and used the latest version.- Set screen Screen Scale and layout = 100%- Installed display driver.- Tried turning off the antivirus- Full installation: Microsoft Visual C++ Redistributable 2005->2022 [+] You can download the AIO version of the Visual C++ Redistributable here: -> https://www.mediafire.com/file/0ak8dcj9mdn7nyq/VisualCppRedist_AIO_2005-2022_x86_x64_%5Btrong.live%5D.zip/file -> FOR Windows XP: https://www.mediafire.com/file/5m5lnr1kfg73tc9/VisualCppRedist_AIO_2005-2019_x86_XP_%5Btrong.live%5D.zip/file <!> Password for Extract: trong.live [+] The last full version of SCITE4AutoIT supports windows XP: https://www.autoitscript.com/autoit3/scite/download/archive/v19.1127.1402.0-SciTE4AutoIt3.exe1 point -
Hi @robertocm I tried to "patch" that list a bit brutally to get it to work (at least for the "First name" field only). From some previous random experiments I did long ago, I noticed a few facts: to capture the events triggered by an object, it is convenient to use the reference to that specific object in the ObjEvent() function rather than referring generically to the "Document" object (although perhaps (some) events manage to reach the "Document" via bubbling) . Also, a quirk that I don't know why this happens, is that if get a reference to an html object that you want to manage, through the usual methods like .getElementById for example, well, ObjEvent() might not work. After several attempts, I then found that using the "ploy" I included in my _WebBrowser_JS_ElementGetRef() function, the returned reference will make the ObjEvent() function work "miraculously". I have therefore also used that function in this patch. I don't have much experience on how, when and which events can be used among that multitude of events described here: https://learn.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/hh801967(v=vs.85) but it would be interesting to try them all and catalog them by extracting the ones that will actually work in AutoIt .... here the patched list. p.s. (to simplify I also removed the <form> ... </form> tags from the HTML) #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> Global $g_idGUIEdit Example() Exit ; End of our Demo. Func Example() Local $hGUIMain = GUICreate("Event Test", 1000, 600) $g_idGUIEdit = GUICtrlCreateEdit("", 5, 405, 990, 175) ; GUICtrlSetBkColor(-1, 0x000000) ; GUICtrlSetColor(-1, 0x00FF00) GUICtrlSetFont(-1, 9, 400, -1, 'Courier New') GUICtrlCreateLabel("Below are some Browser events 'captured' from the above web page by AutoIt", 5, 385, 990, 20) Local $idGUIExit = GUICtrlCreateButton(" Close and exit", 5, 580, 990, 15) GUISetState() ;Show GUI ; We prepare the Internet Explorer as our test subject Global $oIE = ObjCreate("Shell.Explorer.2") $hIE = GUICtrlCreateObj($oIE, 5, 5, 990, 380) ; <- insert $oIE in the AutoIt GUI ; Here we load an example Web page just to have something viewed in the browser ;$oIE.navigate('http://samples.msdn.microsoft.com/workshop/samples/author/dhtml/refs/onmousemoveEX.htm') ;>>>> ;These lines from: Chimp, Jan 2017 (edited) ;Who is Who ? (a little drag&drop game) ;https://www.autoitscript.com/forum/topic/186422-who-is-who-a-little-dragdrop-game/ ;Global $oIE = ObjCreate("Shell.Explorer.2") ; Create a BrowserControl ;Local $hGUI = GUICreate("", 660, 600, 30, 30) ;GUICtrlCreateObj($oIE, 0, 0, 660, 600) ; Place BrowserControl on the GUI ;GUISetState() ;Show GUI $oIE.navigate('about:blank') ; file:///' & @ScriptDir & '\WhoIsWho.html') While Not String($oIE.readyState) = 'complete' ; wait for about:blank Sleep(100) WEnd ; this waits till the document is ready to be used (portion of code from IE.au3) While Not (String($oIE.readyState) = "complete" Or $oIE.readyState = 4) Sleep(100) WEnd While Not (String($oIE.document.readyState) = "complete" Or $oIE.document.readyState = 4) Sleep(100) WEnd $oIE.document.Write(_GetHTML()) ; inject lising directly to the HTML document: $oIE.document.close() ; close the write stream $oIE.document.execCommand("Refresh") While Not String($oIE.readyState) = 'complete' ; wait for readyState after a refresh Sleep(100) WEnd $oDocument = $oIE.document ;>>>> ;~ Sleep(1000) ; Give it some time to load the web page ;~ Do ; wait for document ;~ Sleep(250) ;~ $oDocument = $oIE.document ;~ Until IsObj($oDocument) ; + Scripting Object Interfaces ; | --------------------------- ; | https://msdn.microsoft.com/en-us/library/hh801967(v=vs.85).aspx ; | ; +--> HTMLDocumentEvents2 interface (catch OnClick, OnMouseOver, .... etc ; ----------------------------- ; https://msdn.microsoft.com/en-us/library/aa769764(v=vs.85).aspx ; Global $oEventObject = ObjEvent($oDocument, "IEEvent2_", "HTMLDocumentEvents2") If @error Then MsgBox($MB_OK, "AutoIt COM Test", _ "ObjEvent: Can't use event interface 'HTMLDocumentEvents2'. Error code: " & Hex(@error, 8)) Exit EndIf ; ============================================================== Local $MyRef = $oIE.document.getElementById('firstname') ; MsgBox(0,0,VarGetType($MyRef)) Local $hMyObj = _WebBrowser_JS_ElementGetRef($oIE, $MyRef) ; MsgBox(0,0, VarGetType($hMyObj) & @CRLF & $hMyObj) ; https://learn.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa753143(v=vs.85) Global $oEventObjectInput = ObjEvent($hMyObj, "IEEvent_Input_", "HTMLInputTextElementEvents2") If @error Then MsgBox($MB_OK, "AutoIt COM Test", _ "ObjEvent: Can't use event interface 'HTMLInputTextElementEvents2'. Error code: " & Hex(@error, 8)) Exit EndIf ; ============================================================== ; GUISwitch($hGUIMain) ; Switch back to our GUI in case IE stole the focus ; Waiting for user to close the GUI. Local $iMsg While 1 $iMsg = GUIGetMsg() If $iMsg = $GUI_EVENT_CLOSE Or $iMsg = $idGUIExit Then ExitLoop WEnd $oEventObject.Stop ; Tell IE we don't want to receive events. $oEventObject = 0 ; Kill the Event Object $oIE = 0 ; Remove IE from memory (not really necessary). GUIDelete() ; Remove GUI EndFunc ;==>Example ; A few Internet Explorer Event Functions ; ( reference to the Event Obj interface: ) ; ( https://msdn.microsoft.com/en-us/library/aa703876(v=vs.85).aspx ) ; Volatile Func IEEvent2_onClick($oEvent) ConsolePrint("mouse click: " & $oEvent.clientX & ',' & $oEvent.clientY & ' on ' & $oEvent.srcElement.NodeName & ' id: ' & $oEvent.srcElement.id) If $oEvent.srcElement.NodeName = "INPUT" Then If $oEvent.srcElement.type = "radio" Or $oEvent.srcElement.type = "checkbox" Then If $oEvent.srcElement.checked = True Then ConsolePrint("name: " & $oEvent.srcElement.name & " id " & $oEvent.srcElement.id & " True") Else ConsolePrint("name: " & $oEvent.srcElement.name & " id " & $oEvent.srcElement.id & " False") EndIf EndIf EndIf EndFunc ;==>IEEvent2_onClick Volatile Func IEEvent2_onDblClick($oEvent) ConsolePrint("mouse DoubleClick: @" & $oEvent.clientX & ',' & $oEvent.clientY) EndFunc ;==>IEEvent2_onDblClick ;~ Volatile Func IEEvent2_onMouseMove($oEvent) ;~ ConsolePrint("mouse moved to:" & @TAB & "Xpos = " & $oEvent.clientX & @TAB & "Ypos = " & $oEvent.clientY) ;~ EndFunc ;==>IEEvent2_onMouseMove ; =================================== Volatile Func IEEvent_Input_onkeydown($oEvent) ; onChange($oEvent) ConsolePrint("KeyCode: " & $oEvent.keyCode) EndFunc ;==>IEEvent_Input_onkeydown Volatile Func IEEvent_Input_onchange($oEvent) ; Fires when you exit from the input and ONLY IF YOU HAVE CHANGED IT'S CONTENT ; ---- ------------------------------------- ConsolePrint('Input content in "First name" field has changed') EndFunc ;==>IEEvent_Input_onchange ; =================================== Func ConsolePrint($sMsg) Local Const $iMaxLines = 9 ; keep last 9 log lines only $sMsg = @HOUR & ':' & @MIN & ':' & @SEC & ':' & @MSEC & @TAB & $sMsg & @CRLF $sMsg = StringReplace(GUICtrlRead($g_idGUIEdit) & $sMsg, @CR, @CR) If @extended > $iMaxLines Then ; more than $iMaxLines $sMsg = StringMid($sMsg, StringInStr($sMsg, @CR, 0, -1 * $iMaxLines) + 2) EndIf GUICtrlSetData($g_idGUIEdit, $sMsg) EndFunc ;==>ConsolePrint Func _GetHTML() ;form html code from: Marc Clifton, 16 Feb 2013, https://www.codeproject.com/Articles/547451/WebBrowser-Element-Events-and-Values Local $sHTML = _ "<!DOCTYPE HTML>" & @CRLF & _ "<html>" & @CRLF & _ "<head>" & @CRLF & _ "<meta http-equiv=""X-UA-Compatible"" content=""IE=edge"" />" & @CRLF & _ "<title>Test</title>" & @CRLF & _ "</head>" & @CRLF & _ "<body>" & @CRLF & _ '<button type="button" id="btnMenu">=</button>' & @CRLF & _ '<button type="button" id="btnClose">X</button>' & @CRLF & _ '' & _ ; '<form>' & @CRLF & _ ; 'First name: <input id="firstname" type="text" name="firstname"/><br/>' & @CRLF & _ 'Last name: <input id="lastname" type="text" name="lastname"/><br/>' & @CRLF & _ 'Password: <input id="password" type="password" name="pwd"/><br><br/>' & @CRLF & _ '<input type="radio" id="male" name="sex" value="male"/>Male<br/>' & @CRLF & _ '<input type="radio" id="female" name="sex" value="female"/>Female<br/><br/>' & @CRLF & _ '<input type="checkbox" id="bike" name="vehicle" value="Bike"/>I have a bike<br/>' & @CRLF & _ '<input type="checkbox" id="car" name="vehicle" value="Car"/>I have a car <br/><br/>' & @CRLF & _ '<input type="button" id="ok" value="OK"/><br/>' & @CRLF & _ '<input type="button" id="cancel" value="Cancel"/><br/><br/>' & @CRLF & _ '' & _ ; '</form>' & @CRLF & _ ; "</body>" & @CRLF & _ "</html>" Return $sHTML EndFunc ;==>_GetHTML ; see here: https://www.autoitscript.com/forum/topic/200338-browsercontrol-companion Func _WebBrowser_JS_ElementGetRef(ByRef $oIE_Server, $oElement) Local $oWindow = $oIE_Server.document.parentwindow ; .JSglobal Local $oElementByIdReference If $oElement.Id = '' Then $oElement.setAttribute('Id', 'DummyId') ; we need an ID (a temporary ID) $oElementByIdReference = Execute('$oWindow.' & $oElement.getAttribute('Id')) ; get element's reference by Id $oElement.setAttribute('Id', '') ; remove the temporary ID (we leave things as we found them) Else $oElementByIdReference = Execute('$oWindow.' & $oElement.getAttribute('Id')) EndIf Return $oElementByIdReference EndFunc ;==>_WebBrowser_JS_ElementGetRef1 point
-
Changing all coordinates in a long script to work on different monitor?
Musashi reacted to pixelsearch for a topic
To do that, you could modify directly a function in imagesearch udf (or in a copy of it, leaving the original untouched) and apply the _WinAPI_ScreenToClient function directly in imagesearch udf. This will modify the coords returned from the function, changing them automatically from screen coords to client coords, I succeeded to do it by adding : * 1 line in the calling script * modifying a function in imagesearch udf I never used imagesearch until now but it was an interesting challenge. The problem is that we're not using the same imagesearch udf. Looking at your code above, you're probably using the one found in this link (dll's from 2010 which crash my computer) and call the function like this : $T22 = _ImageSearch("Images\T22.png", 0, $x3, $y3, 40) ; 0 = return top & left coord, tolerance 40 My successful test was done on a more recent ImageSearch Udf found in this link, from user VIP Trong, which calls the function like that : Local $aRet = _ImageSearch($sImage_Name, 40, False) ; tolerance 40 , False = return top & left coord ; Array result : $aRet[0] = 1 (success, image found) => $aRet[1] = top coord, $aRet[2] = left coord Anyway, no matter the ImageSearch UDF used, the logic should be same in both ImageSearch UDF Calling script : #include <MsgBoxConstants.au3> #include "Copy of _ImageSearch_UDF.au3" Local $sImage_Name = "notepad-logo.bmp" Local $hGUI = GUICreate("Test with VIP's _ImageSearch", 800, 600, 100, 100) ; GUI left & top at 100, 100 Local $idPic = GUICtrlCreatePic($sImage_Name, 20, 40, 18, 25) ; 18 x 25 = original pic size GUISetState(@SW_SHOW) ;============================== $g_hGUI_ForClientCoords = $hGUI ; force _ImageSearch to return client cooords (this Global variable = 0 in Copy of _ImageSearch_UDF.au3) ;============================== Local $aRet = _ImageSearch($sImage_Name, 40, False) If $aRet[0] = 1 Then MsgBox($MB_TOPMOST, 'Success', 'Image found:' & " X=" & $aRet[1] & " Y=" & $aRet[2] & @CRLF & $sImage_Name) Else MsgBox($MB_TOPMOST, 'Failed', 'Image not found') EndIf GUIDelete($hGUI) VIP's ImageSearch UDF (the modified part) : ; 2 lines added at top of the UDF #include <WinAPIConv.au3> ; for _WinAPI_ScreenToClient Global $g_hGUI_ForClientCoords = 0 ; change it in calling script to return client coords ... Func _ImageSearch($_ImagePath, $_Tolerance = 0, $_CenterPos = True) ; Commented 1 original line from VIP Trong ; Return _ImageSearch_Area($_ImagePath, 0, 0, @DesktopWidth, @DesktopHeight, $_Tolerance, $_CenterPos) ; Added all the following lines Local $aRet = _ImageSearch_Area($_ImagePath, 0, 0, @DesktopWidth, @DesktopHeight, $_Tolerance, $_CenterPos) If $aRet[0] = 1 And $g_hGUI_ForClientCoords Then ; $aRet[0] = 1 means success Local $tPoint = DllStructCreate("int X;int Y") DllStructSetData($tPoint, "X", $aRet[1]) DllStructSetData($tPoint, "Y", $aRet[2]) _WinAPI_ScreenToClient($g_hGUI_ForClientCoords, $tPoint) $aRet[1] = $tPoint.X $aRet[2] = $tPoint.Y EndIf Return $aRet EndFunc ;==>_ImageSearch ; * -----:| Dao Van Trong - TRONG.LIVE So, as soon as this line in the calling script is active... $g_hGUI_ForClientCoords = $hGUI ...then the same client coords will always be returned, no matter the GUI is displayed at 100, 100 or 200, 200 . If you comment that line, then screen coords will be returned. Hope it helps1 point -
https://github.com/robertluwang/scite-setting/blob/master/scite-dark-theme.md1 point
-
Problem with GUICtrlRead in second GUI
abberration reacted to JB72 for a topic
Yes this works fine 🙂 I work with the ISN AutoIT Studio and i use the Forms-Studio 2 Editor. So in the "main".au3 ist the form inclueded, at the top of the script, but this does not work in this case. The include of the created gui must be in the function now. Func _CreateRadios() #include "Forms\ChooseScript.isf" $verzeichnisRadio = Iniread(@scriptdir&"\verzeichnis.ini", "Verzeichnis", "PfadRadio", ""); GUISetState(@SW_SHOW,$ChooseScript) $aArray = _FileListToArrayRec($verzeichnisRadio & "\", "Setup.vbs||*_bak*", $FLTAR_FILES, $FLTAR_RECUR, $FLTAR_SORT) $top = 10 For $ar = 1 To $aArray[0] Assign("Radio" & $ar, GUICtrlCreateRadio($aArray[$ar], 10, $top, 350, 20)) ;MsgBox(0,"",$aArray[$ar]) $top += 30 Next While 1 $nMsg = GUIGetMsg() Switch $nMsg .... Big thank you for the help. Now i understand the GUI handling better and also the to work with arrays. Now i build the code in my main script and test it.1 point -
Problem with GUICtrlRead in second GUI
JB72 reacted to abberration for a topic
OK, I think I understand the situation a little better. GUI1 should be your main GUI and GUI2 should be the radio selection (I think). Therefore you might want to structure your GUI2 to do all the reading file locations, making the radios and writing to the INI. Just for an example, I had the following code to write your selection in an INI in the script directory (and a little sample code (_WriteToINI) if you want to put INI writing off to another function). I might be wrong about all this, but here's an idea of how this might work... #include <Array.au3> #include <File.au3> #include <MsgBoxConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> $Form1 = GUICreate("Form1", 400, 278, 192, 124) $Button1 = GUICtrlCreateButton("Choose", 264, 208, 75, 25, $WS_GROUP) GUISetState(@SW_SHOW) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $Button1 _CreateRadios() EndSwitch WEnd Func _CreateRadios() $Form2 = GUICreate("Form2", 300, 293, 700, 218) $top = 10 $aArray = _FileListToArrayRec(@ScriptDir, "Setup.vbs||*_bak*", $FLTAR_FILES, $FLTAR_RECUR, $FLTAR_SORT) For $ar = 1 To $aArray[0] Assign("Radio" & $ar, GUICtrlCreateRadio($aArray[$ar], 10, $top, 350, 20)) $top += 30 Next $Button2 = GUICtrlCreateButton("Select", 136, 136, 75, 25, $WS_GROUP) GUISetState(@SW_SHOW) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE GUIDelete($Form2) ExitLoop Case $Button2 For $ar = 1 To $aArray[0] If GUICtrlRead(Eval("Radio" & $ar)) = $GUI_CHECKED Then IniWrite(@ScriptDir & "\verzeichnis.ini", "Verzeichnis", "VBS", GUICtrlRead(Eval("Radio" & $ar), 1)) _WriteToINI($aArray, $ar) MsgBox(0, "", "You chose: " & GUICtrlRead(Eval("Radio" & $ar), 1) & @CRLF & "It has been written to the INI @ script folder") EndIf Next GUIDelete($Form2) ExitLoop EndSwitch WEnd EndFunc ;==>_CreateRadios Func _WriteToINI($aArray, $ar) ; Other stuff you may want to write to an INI $verzeichnis = "scripts" & $aArray[$ar] IniWrite(@ScriptDir & "\verzeichnis.ini", "Verzeichnis", "VBS", $verzeichnis) $verzeichnis = @ScriptDir & "\scripts\" & StringRegExpReplace($aArray[$ar], "\\Setup.vbs", "") IniWrite(@ScriptDir & "\verzeichnis.ini", "Verzeichnis", "Pfad", $verzeichnis) EndFunc ;==>_WriteToINI1 point -
Just chiming in here a little bit. It's possible that the VPN connection is blocking ping / ICMP. If browsing still works, that means that DNS and HTTP/HTTPS is working properly. You could try a trace route (tracert) both on and off VPN to see where the pings stop.1 point