jpm Posted December 30, 2025 Posted December 30, 2025 You could be rigth but I don't want to develop the corresponding StringReplace equivalent to the StringRegExpReplace example If you have one just postit donnyh13 1
pixelsearch Posted December 30, 2025 Posted December 30, 2025 (edited) 6 hours ago, jpm said: If you have one just post it Hellooo jpm, wishing you a very good year 2026, great timing I just scripted the following example, it seems to confirm this : * Case sensitive : StringReplace is faster than StringRegExpReplace * Case insensitive : the opposite, StringRegExpReplace is faster, just like written in the help file. expandcollapse popup#include <MsgBoxConstants.au3> #include <StringConstants.au3> Opt("MustDeclareVars", 1) Example() Func Example() Local $sSubject ; Subject definition For $i = 65 To 90 $sSubject &= Chr($i) & Chr($i + 32) ; "AaBb...YyZz" : 52 chars (26*2) Next For $i = 1 To 17 ; Do not increase this loop too much, it would quickly generate a very big subject ! $sSubject &= $sSubject Next ConsoleWrite("Subject is " & StringLen($sSubject) & " long" & @crlf & @crlf) ; 6,815,744 chars when 17 in For loop _CompareSpeed($sSubject, True) ; case sensitive _CompareSpeed($sSubject, False) ; case insensitive EndFunc ;==>Example Func _CompareSpeed(ByRef $sSubject, $bSensitive) Local $sSearch, $sReplace, $hTimer, $sOutput1, $sOutput2 ; Search string and Replace string $sSearch = "Aa" $sReplace = "12" ConsoleWrite("Case " & ($bSensitive ? "" : "in") & "sensitive :" & @crlf) ; StringReplace $hTimer = TimerInit() $sOutput1 = StringReplace($sSubject, $sSearch, $sReplace, 0, ($bSensitive ? $STR_CASESENSE : $STR_NOCASESENSE)) ConsoleWrite(@extended & " replacements with StringReplace Timer : " & TimerDiff($hTimer) & @crlf) ; StringRegExpReplace $hTimer = TimerInit() $sOutput2 = StringRegExpReplace($sSubject, ($bSensitive ? "" : "(?i)") & $sSearch, $sReplace) ConsoleWrite(@extended & " replacements with StringRegExpReplace Timer : " & TimerDiff($hTimer) & @crlf & @crlf) ; Keep this ? If Not ($sOutput1 == $sOutput2) Then MsgBox($MB_TOPMOST, "No way", "StringReplace output <> StringRegExpReplace output !") EndIf EndFunc ;==>_CompareSpeed Edit: Same script below, one function instead of two : expandcollapse popup#include <MsgBoxConstants.au3> #include <StringConstants.au3> Opt("MustDeclareVars", 1) Example() Func Example() Local $sSubject, $sSearch, $sReplace, $hTimer, $sOutput1, $sOutput2 ; Subject definition For $i = 65 To 90 $sSubject &= Chr($i) & Chr($i + 32) ; "AaBb...YyZz" : 52 chars (26*2) Next For $i = 1 To 17 ; Do not increase this loop too much, it would quickly generate a very big subject ! $sSubject &= $sSubject Next ConsoleWrite("Subject is " & StringLen($sSubject) & " long" & @crlf & @crlf) ; 6,815,744 chars when 17 in For loop ; Search string and Replace string $sSearch = "Aa" $sReplace = "12" ; Speed comparison For $bSensitive = 1 To 0 Step -1 ConsoleWrite("Case " & ($bSensitive ? "" : "in") & "sensitive :" & @crlf) ; StringReplace $hTimer = TimerInit() $sOutput1 = StringReplace($sSubject, $sSearch, $sReplace, 0, ($bSensitive ? $STR_CASESENSE : $STR_NOCASESENSE)) ConsoleWrite(@extended & " replacements with StringReplace Timer : " & TimerDiff($hTimer) & @crlf) ; StringRegExpReplace $hTimer = TimerInit() $sOutput2 = StringRegExpReplace($sSubject, ($bSensitive ? "" : "(?i)") & $sSearch, $sReplace) ConsoleWrite(@extended & " replacements with StringRegExpReplace Timer : " & TimerDiff($hTimer) & @crlf & @crlf) ; Keep this ? If Not ($sOutput1 == $sOutput2) Then MsgBox($MB_TOPMOST, "No way", "StringReplace output <> StringRegExpReplace output !") EndIf Next EndFunc ;==>Example Edited December 30, 2025 by pixelsearch added same 2nd script (one function instead of 2) donnyh13 1 "I think you are searching a bug where there is no bug... don't listen to bad advice."
jchd Posted December 30, 2025 Posted December 30, 2025 (edited) 1 hour ago, pixelsearch said: * Case sensitive : StringReplace is faster than StringRegExpReplace * Case insensitive : the opposite, StringRegExpReplace is faster, just like written in the help file. No big surprise here: when comparing raw codepoints AutoIt internals can make use of very fast machine instructions, while any regex engine has to dissect and compile the pattern and loop over the string & pattern. On the contrary, when it comes to process codepoints in any non-raw way or when the pattern isn't a bare string compare, regexes use very fast code using internal tables while AutoIt relies on Windows low-level primitives in a loop. Just tried a third compare run with regex including (*UCP) and the outcome is almost identical. Edited December 30, 2025 by jchd This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)
pixelsearch Posted December 30, 2025 Posted December 30, 2025 @jchd how great, you're here too. So a very good year 2026 to you and best wishes Thanks for your explanation & confirmation of the preceding speed comparison results. By the way, I'd like to ask you : here is the list of the 12 RegEx metacharacters found in AutoIt help file, topic StringRegExp ? \ . ^ $ | [ ( { * + ? # If we look at this original pcre doc, they also indicate 12 metacharacters but : 1) they exclude the # which (I guess) needs to be escaped only when the option (?x) is used in the pattern (to be confirmed) 2) Most important, they include the closing parenthesis ==> ) Here is a short example showing that the closing parenthesis must be escaped, which should mean it is a metacharacter : Subject : 123)456 Pättern1: ) Pättern2: \) Pattern1 will fail, when pattern2 will retrieve the closing parenthesis, because it is escaped in the pattern. So my question is : shouldn't the closing parenthesis be added to the list of metacharacters in AutoIt help file ? Thanks ! "I think you are searching a bug where there is no bug... don't listen to bad advice."
jpm Posted December 31, 2025 Posted December 31, 2025 Thanks @pixelsearch best wishes to you and your family I will add a 2nd example as you proposed for the escape doc I wait the final answer Cheers donnyh13 1
jchd Posted December 31, 2025 Posted December 31, 2025 9 hours ago, pixelsearch said: 1) they exclude the # which (I guess) needs to be escaped only when the option (?x) is used in the pattern (to be confirmed) 2) Most important, they include the closing parenthesis ==> ) @pixelsearch you're right on 2) About 1) and (*X), that PCRE_EXTRA option is something you can ever use only after digging deep in PCRE code, only helpful in very VERY dark corner cases you should avoid at any rate. Hence # should be removed from the list in help. Omitting ) is a much bigger mistake, one which will haunt me for the rest of the year! BTW, I whish a peaceful 2026 to everyone in and, most importantly, outside the AutoIt community. This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)
pixelsearch Posted December 31, 2025 Posted December 31, 2025 @jpm thanks for adding the 2nd example to the StringReplace topic. So In his post above, jchd just confirmed that the list of 12 metacharacters should be changed in the AutoIt help file, removing # and adding ) This list is found in 2 different topics : StringRegExp (of course) and StringReplace (remarks section) jpm, if you don't mind, I got 2 other points I'd like to discuss with you, then I promise to set you free as soon as 2026 starts 1) Three missing constants in AutoIt : SB_LEFT (6) SB_RIGHT (7) SB_ENDSCROLL (8) . When I needed them, I found their values in WinUser.h . Could we add them to the include file ScrollBarsConstants.au3 ? 2) Please have a look at this post. OP is right, the documentation is confusing and I got caught myself a few days ago for the same reason : the help file shouldn't state this in the ControlGetPos topic : ControlGetPos Retrieves the position and size of a control relative to its window. As shown in his example, a control placed in a child window doesn't have its ControlGetPos "relative to its window" (the child window in his case), it's relative to its top level window (the GUI in his case). So could we please amend the help file like the following, or any other sentence that you'd find more accurate : ControlGetPos Retrieves the position and size of a control relative to its top level window. Thanks 1 hour ago, jchd said: Omitting ) is a much bigger mistake, one which will haunt me for the rest of the year! This made me laugh so much. I should have posted this tomorrow so you'd be haunted 365 days instead of 12 hours 1 hour ago, jchd said: I wish a peaceful 2026 to everyone in and, most importantly, outside the AutoIt community. "outside" is the keyword in your wishes. Great thoughts & nicely expressed "I think you are searching a bug where there is no bug... don't listen to bad advice."
jchd Posted December 31, 2025 Posted December 31, 2025 19 minutes ago, pixelsearch said: I should have posted this tomorrow so you'd be haunted 365 days instead of 12 hours Then I'd have said: "... for the rest of the day". 71 now, but I still can count for some time! This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)
jpm Posted December 31, 2025 Posted December 31, 2025 @pixelsearch about 2 I agree to update the doc at least it is coherent with the usage in MoveMove() #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Local $hWndParent = GUICreate("ControlGetPos in a child GUI") Local $idInfo = GUICtrlCreateLabel("", 20, 150, 300, 100) Local $hWndChild = GUICreate("Child", 100, 100, 5, 5, BitOR($WS_BORDER, $WS_CHILD, $WS_VISIBLE), -1, $hWndParent) Local $idBtn = GUICtrlCreateButton("BTN", 10, 10, 60, 40) Local $aPOS = ControlGetPos($hWndChild, '', $idBtn) Local $sText = "BTN in Child Window" & @CRLF & @CRLF & " relative to parent window" & @CRLF & "Position: " & $aPos[0] & ", " & $aPos[1] & @CRLF & "Size: " & $aPos[2] & ", " & $aPos[3] GUICtrlSetData($idInfo, $sText) GUISetState(@SW_SHOW, $hWndParent) ControlClick($hWndChild, "", $idBtn, "left", 1, $aPOS[0], $aPOS[1]) Opt("MouseCoordMode", 2) ; coord in client area MouseMove($aPOS[0], $aPOS[1]) While 1 Switch (GUIGetMsg()) Case $idBtn GUICtrlSetData($idInfo, $sText & @CRLF & @CRLF & " >>>>>>>>> BTN clicked <<<<<<<<<<<<<<<") Case $GUI_EVENT_CLOSE Exit EndSwitch Sleep(10) WEnd
pixelsearch Posted December 31, 2025 Posted December 31, 2025 3 hours ago, jpm said: about 2 I agree to update the doc [of ControlGetPos] at least it is coherent with the usage in MouseMove() Thanks for your example ! So we just need a better way to rephrase this in the help file (ControlGetPos topic), avoiding the term "relative to its window". If you look at the following example I just scripted (3 Gui's), maybe the "ancestor" word could be clearer, if we're sure it is accurate in all cases ? Because when it comes to a control created inside a child window, then the terms "parent" or "relative to its window" are wrong and confusing (concerning ControlGetPos) when "ancestor" could be more appropriate, as you'll notice in the MessageBox. Anyway you'll decide. For the record, imagine how simpler all this would have been if the 3 lines found in the code below returned 3 different results... Local $aPos = ControlGetPos($hChild_2, "", $idBtn) ; Local $aPos = ControlGetPos($hChild_1, "", $idBtn) : same result :( ; Local $aPos = ControlGetPos($hGUI, "", $idBtn) ; same result :( ...then we won't have to use constantly ScreentoCli, CliToScreen and the whole gang. Well... we can always dream, can't we ? expandcollapse popup#include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include <WinAPISysWin.au3> #include <WindowsConstants.au3> Opt("MustDeclareVars", 1) ;============== Local $hGUI = GUICreate("Main GUI", 300, 200) ;============== Local $hChild_1 = GUICreate("Child_1", 280, 180, 10, 10, $WS_CHILD, -1, $hGUI) ; 10 pixels inside GUI GUISetBkColor(0xFFFF00) ; yellow ;============== Local $hChild_2 = GUICreate("Child_2", 240, 140, 20, 20, $WS_CHILD, -1, $hChild_1) ; + 20 pixels inside $hChild_1 GUISetBkColor(0xC0FFFF) ; light blue Local $idBtn = GUICtrlCreateButton("Button", 40, 40, 80, 30) ; + 40 pixels inside $hChild_2 (that's 10+20+40 = 70 pixels inside GUI) Local $hBtn = GUICtrlGetHandle($idBtn) Local $aPos = ControlGetPos($hChild_2, "", $idBtn) ; Local $aPos = ControlGetPos($hChild_1, "", $idBtn) : same result :( ; Local $aPos = ControlGetPos($hGUI, "", $idBtn) ; same result :( Local $hAncestor = _WinAPI_GetAncestor($hBtn, $GA_ROOT) Local $hParent = _WinAPI_GetParent($hBtn) GUISetState(@SW_SHOW, $hGUI) GUISetState(@SW_SHOW, $hChild_1) GUISetState(@SW_SHOW, $hChild_2) MsgBox($MB_TOPMOST, "Infos 3 GUI's and Button", _ "$hGUI = " & $hGUI & " $hChild_1 = " & $hChild_1 & " $hChild_2 = " & $hChild_2 & @crlf & @crlf & _ "Button ControlGetPos X / Y : $aPos[0] = "& $aPos[0] & " / $aPos[1] = " & $aPos[1] & @crlf & @crlf & _ "Button Ancestor ($GA_ROOT) = " & $hAncestor & " Button Parent = " & $hParent) While 1 Switch (GUIGetMsg()) Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd Jean-Paul, all the best for 2026, just stay healthy, always alive & kicking "I think you are searching a bug where there is no bug... don't listen to bad advice."
jpm Posted 14 hours ago Posted 14 hours ago I agree ControlGetPos must return different coord according to corresponding the guicreate I will look at it Anyway Happy new year pixelsearch 1
pixelsearch Posted 3 hours ago Posted 3 hours ago (edited) 11 hours ago, jpm said: I agree ControlGetPos must return different coord according to corresponding the guicreate I will look at it Thanks for that You know, I'm not really sure ControlGetPos could ever be amended as it would be script-breaking for many people, who didn't care about its 1st parameter, indicating any window handle in it (Ancestor, parent etc...) for the same result. But an additional function could be helpful. For example I tried _ControlGetPosEx() in the script below, though I scripted it without error checking and having no idea about the way to handle its 2nd parameter $sTxt . Basically it's just a wrapper for _WinAPI_ScreenToClient (when the window handle passed as 1st parameter is not the Ancestor) to make it easier for the user when calling the function. Anyway, it's a start... as long as the 1st param. is a window handle and the 2nd param stays empty "" , At least I'll start to use it from now on, reporting if something goes bad. expandcollapse popup#include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include <WinAPIConv.au3> #include <WinAPISysWin.au3> #include <WindowsConstants.au3> Opt("MustDeclareVars", 1) ;============== Local $hGUI = GUICreate("Main GUI v2", 300, 200) ;============== Local $hChild_1 = GUICreate("Child_1", 280, 180, 10, 10, $WS_CHILD, -1, $hGUI) ; 10 pixels inside GUI GUISetBkColor(0xFFFF00) ; yellow ;============== Local $hChild_2 = GUICreate("Child_2", 240, 140, 20, 20, $WS_CHILD, -1, $hChild_1) ; + 20 pixels inside $hChild_1 GUISetBkColor(0xC0FFFF) ; light blue Local $idBtn = GUICtrlCreateButton("Button", 40, 40, 80, 30) ; + 40 pixels inside $hChild_2 (that's 10+20+40 = 70 pixels inside GUI) Local $hBtn = GUICtrlGetHandle($idBtn) Local $aPos2 = ControlGetPos($hChild_2, "", $idBtn) Local $aPos1 = ControlGetPos($hChild_1, "", $idBtn) ; same result :( Local $aPos0 = ControlGetPos($hGUI, "", $idBtn) ; same result :( Local $aPosEx2 = _ControlGetPosEx($hChild_2, "", $idBtn) Local $aPosEx1 = _ControlGetPosEx($hChild_1, "", $idBtn) Local $aPosEx0 = _ControlGetPosEx($hGUI, "", $idBtn) Local $hAncestor = _WinAPI_GetAncestor($hBtn, $GA_ROOT) Local $hParent = _WinAPI_GetParent($hBtn) GUISetState(@SW_SHOW, $hGUI) GUISetState(@SW_SHOW, $hChild_1) GUISetState(@SW_SHOW, $hChild_2) MsgBox($MB_TOPMOST, "Infos 3 GUI's and Button v2", _ "$hGUI = " & $hGUI & " $hChild_1 = " & $hChild_1 & " $hChild_2 = " & $hChild_2 & @crlf & _ "Button Ancestor ($GA_ROOT) = " & $hAncestor & " Button Parent = " & $hParent & @crlf & _ @crlf & _ "Button ControlGetPos (Child2) = " & $aPos2[0] & "/" & $aPos2[1] & "/" & $aPos2[2] & "/" & $aPos2[3] & @crlf & _ "Button ControlGetPos (Child1) = " & $aPos1[0] & "/" & $aPos1[1] & "/" & $aPos1[2] & "/" & $aPos1[3] & @crlf & _ "Button ControlGetPos (GUI ) = " & $aPos0[0] & "/" & $aPos0[1] & "/" & $aPos0[2] & "/" & $aPos0[3] & @crlf & _ @crlf & _ "Button _ControlGetPosEx (Child2) = " & $aPosEx2[0] & "/" & $aPosEx2[1] & "/" & $aPosEx2[2] & "/" & $aPosEx2[3] & @crlf & _ "Button _ControlGetPosEx (Child1) = " & $aPosEx1[0] & "/" & $aPosEx1[1] & "/" & $aPosEx1[2] & "/" & $aPosEx1[3] & @crlf & _ "Button _ControlGetPosEx (GUI ) = " & $aPosEx0[0] & "/" & $aPosEx0[1] & "/" & $aPosEx0[2] & "/" & $aPosEx0[3]) While 1 Switch (GUIGetMsg()) Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd Func _ControlGetPosEx($hWnd, $sTxt, $hCtrl) If Not IsHWnd($hCtrl) Then $hCtrl = GUICtrlGetHandle($hCtrl) Local $hAncestor = _WinAPI_GetAncestor($hCtrl, $GA_ROOT) If $hAncestor = $hWnd Then Local $aRet = ControlGetPos($hWnd, $sTxt, $hCtrl) Else Local $aPos = WinGetPos($hCtrl, $sTxt) Local $tPoint = DllStructCreate("int X;int Y") DllStructSetData($tPoint, "X", $aPos[0]) DllStructSetData($tPoint, "Y", $aPos[1]) _WinAPI_ScreenToClient($hWnd, $tPoint) Local $aRet[4] = [$tPoint.X, $tPoint.Y, $aPos[2], $aPos[3]] EndIf Return $aRet EndFunc ;==>_ControlGetPosEx Edited 3 hours ago by pixelsearch typo "I think you are searching a bug where there is no bug... don't listen to bad advice."
jpm Posted 1 hour ago Posted 1 hour ago I understand the point but I thing That it is a bug so I found the same solution inside ControlGetPos() so I propose the following doc Quote ###Function### ControlGetPos ###Description### Retrieves the position and size of a control relative to its window or control. ###Syntax### ControlGetPos ( "title", "text", controlID ) ###Parameters### @@ParamTable@@ title The title/hWnd/class of the window or control to access. See <a href="../intro/windowsadvanced.htm">Title special definition</a>. text The text of the window to access. See <a href="../intro/windowsbasic.htm#specialtext">Text special definition</a>. controlID The control to interact with. See <a href="../intro/controls.htm">Controls</a>. @@End@@ ###ReturnValue### @@ReturnTable@@ Success: an array containing the size and the control's position relative to its client window or control: $aArray[0] = X position $aArray[1] = Y position $aArray[2] = Width $aArray[3] = Height Failure: sets the @error flag to 1. @@End@@ ###Remarks### The title/text is referencing the parent window, so be careful with "", which references the active window which may not be the one containing the controlID control. ###Related### ControlCommand, ControlMove ###Example### @@IncludeExample@@
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now