CoffeeJoe Posted October 16, 2021 Share Posted October 16, 2021 Group, I have read here that 'Execute' is a less than favorable method in your scripts and it will possibly go away... I ran into a case where it seems execute is the only way - can anyone suggest an alternative? $var = BitOr($SS_CENTER, $SS_CENTERIMAGE) [...] Func ParseCommand($var) $result = Execute($var) Return $result EndFunc This is exactly what I want / need to accomplish I'm trying to make a front end where I can select options for what I'm building (click) and it "builds" the commands ... Then I have to parse them to Call("_GDIPlus_LineBrushCreate", $aParms) (or similar) My Parsing routine has the BitOr([...]) off by itself but I need to programmatically turn that into the number it represents ~ this seems necessary for the script to ignore the extra commas inside the parentheses when I put this in the aParams array Maybe I'm approaching this from the wrong direction / not sure, but I want to be able to do a series of calls like this to be able to tweak / add or remove GDI+ drawings while looking at the result... Any help would be appreciated - and to be clear I'm not having a GDI+ problem, it's an Execute() problem Thanks in advance Link to comment Share on other sites More sharing options...
Developers Jos Posted October 16, 2021 Developers Share Posted October 16, 2021 (edited) Is that code snipped supposed to show what you want to accomplish? I changed it to this but really do not understand what Execute(0 is supposed to do here as $var contains the result value of the BitOr() function: #include <StaticConstants.au3> $var = BitOr($SS_CENTER, $SS_CENTERIMAGE) ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $var = ' & $var & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : ParseCommand($var) = ' & ParseCommand($var) & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console Func ParseCommand($var) $result = Execute($var) Return $result EndFunc Please adapt this snipped in a way that it is clear what you need to get done. Edited October 16, 2021 by Jos SciTE4AutoIt3 Full installer Download page - Beta files Read before posting How to post scriptsource Forum etiquette Forum Rules Live for the present, Dream of the future, Learn from the past. Link to comment Share on other sites More sharing options...
CoffeeJoe Posted October 16, 2021 Author Share Posted October 16, 2021 4 minutes ago, Jos said: as $var contains the result value of the BitOr() function: Not according to the Msgbox I tested it with - it still sees it as a string and reads it back to me exactly the way it read it in... (from the edit control where I typed it) Yes I confirmed that what you did puts the value in $var But I did StringInStr($sStr, "BitOr") and StringinStr($sStr, ")", 0, 1) Then fished it out with StringMid() and tried to "convert it" to its numeric value... Link to comment Share on other sites More sharing options...
CoffeeJoe Posted October 16, 2021 Author Share Posted October 16, 2021 expandcollapse popup$line = "$statusbar = GUICtrlCreateLabel("" Status"", 0, ($GUIh-18), $GUIw, 18, BitOR($SS_SUNKEN, $SS_CENTERIMAGE))" If StringLeft($line, 1) = "$" Then $split = StringSplit($line, "=") $var = $split[1] If $split[0] > 2 Then For $i = 2 To $split[0] If $i < $split[0] Then $function &= $split[$i] & "=" Else $function &= $split[$i] EndIf Next Else $function = $split[2] EndIf Else $function = $line EndIf $split = StringSplit($function, "(") $function = $split[1] If $split[0] > 2 Then For $i = 2 To $split[0] $sPrams &= "(" & $split[$i] Next Else $sPrams = "(" & $split[2] EndIf $sPrams = StringTrimLeft($sPrams, 1) $sPrams = StringTrimRight($sPrams, 1) StringReplace($sPrams," ","") If $sPrams = "" Then $iReplace = 0 While $iReplace > 0 $iReplace = StringInStr($sPrams, "Bitor", 0, 1) If $iReplace > 0 Then $iEnd = StringInStr($sPrams, ")", 0, 1, $iReplace) $sStr = StringMid($sPrams, $iReplace, (($iEnd-$iReplace)+1)) ;MsgBox(0,"",$sStr) $sResult = Execute($sStr) ;MsgBox(0,"",$sResult) $sPrams = StringReplace($sPrams, $sStr, $sResult, 1) EndIf MsgBox(0,"",$sPrams) WEnd $aPrams = StringSplit($sPrams, ",") _ArrayDisplay($aPrams) This is what I have, the contents of $line are just a random line I grabbed - I'm only using it because it has an assignment and a BitOr - my parser will need to be able to handle both. Link to comment Share on other sites More sharing options...
Developers Jos Posted October 16, 2021 Developers Share Posted October 16, 2021 Did you look at my snipped and try? ... Anyway: Guess you missed this bit... no need for other stuff that makes it confusing for me. 1 hour ago, Jos said: Please adapt this snipped in a way that it is clear what you need to get done. SciTE4AutoIt3 Full installer Download page - Beta files Read before posting How to post scriptsource Forum etiquette Forum Rules Live for the present, Dream of the future, Learn from the past. Link to comment Share on other sites More sharing options...
CoffeeJoe Posted October 16, 2021 Author Share Posted October 16, 2021 1 hour ago, Jos said: Did you look at my snipped and try? ... Anyway: Guess you missed this bit... no need for other stuff that makes it confusing for me. Sorry I didn’t understand - I see what you wanted - I’m away from my desk right now, I’ll see if I can get you the output you asked for later tonight Link to comment Share on other sites More sharing options...
CoffeeJoe Posted October 16, 2021 Author Share Posted October 16, 2021 Jos, Here you go #include <StaticConstants.au3> $sString = "$statusbar = GUICtrlCreateLabel(""Status"", 0, ($GUIh-18), $GUIw, 18, BitOR($SS_SUNKEN, $SS_CENTERIMAGE))" $result = ParseCommand($sString) $var = $result $sString = StringReplace($sString, $result, $var, 1, 0) Msgbox(0, "Parse Test", $sString) ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $var = ' & $var & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : ParseCommand($var) = ' & ParseCommand($var) & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console Func ParseCommand($sString) $result = StringMid($sString, 69, 34) Return $result EndFunc Link to comment Share on other sites More sharing options...
mistersquirrle Posted October 17, 2021 Share Posted October 17, 2021 (edited) Is this more what you're looking for? #include <StaticConstants.au3> $sString = "$statusbar = GUICtrlCreateLabel(""Status"", 0, ($GUIh-18), $GUIw, 18, BitOR($SS_SUNKEN, $SS_CENTERIMAGE))" $sParsedCommand = ParseCommand($sString, 69, 34) $sExeResult = Execute($sParsedCommand) ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $sParsedCommand = ' & $sParsedCommand & @CRLF ) ;### Debug Console ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $sExeResult = ' & $sExeResult & @CRLF ) ;### Debug Console ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : BitOR = ' & BitOR($SS_SUNKEN, $SS_CENTERIMAGE) & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console Func ParseCommand($sString, $iStart, $iLength) ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $sString = ' & $sString & @CRLF ) ;### Debug Console $sParsedCommand = StringMid($sString, $iStart, $iLength) Return $sParsedCommand EndFunc ;==>ParseCommand Seems like that Execute works just fine for me, I get 4608 when I either run the BitOR directly or using Execute. So as Jos mentioned if this doesn't help, can you provide an example/sample code using Execute where it's not doing what you're expecting? As for an alternative to Execute... Would probably be to build a function to process BitOR manually, and use Eval() to calculate the values of the variables in the string. I think something like this: expandcollapse popup; https://www.autoitscript.com/forum/topic/206841-replacement-for-execute/ #include <StaticConstants.au3> ;~ #include <Array.au3> $sString = "$statusbar = GUICtrlCreateLabel(""Status"", 0, ($GUIh-18), $GUIw, 18, BitOR($SS_SUNKEN, $SS_CENTERIMAGE))" Local $iBitOrPos = StringInStr($sString, 'BitOR') If $iBitOrPos = 0 Then Exit $sParsedCommand = ParseCommand($sString, _ ; String $iBitOrPos, _ ; Start (StringInStr($sString, ')', 0, 1, $iBitOrPos) - $iBitOrPos) + 1 _ ; Length ) $sExeResult = Execute($sParsedCommand) $sParsedBitOr = ParseBitOR($sParsedCommand) ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $sParsedCommand = ' & $sParsedCommand & @CRLF) ;### Debug Console ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $sExeResult = ' & $sExeResult & @CRLF) ;### Debug Console ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : BitOR = ' & BitOR($SS_SUNKEN, $SS_CENTERIMAGE) & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $sParsedBitOr = ' & $sParsedBitOr & @CRLF) ;### Debug Console Func ParseCommand($sString, $iStart, $iLength) ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $sString = ' & $sString & @CRLF) ;### Debug Console Local $sParsedCommand = StringMid($sString, $iStart, $iLength) Return $sParsedCommand EndFunc ;==>ParseCommand Func ParseBitOR($sString) Local $iReturn = 0 ;, $iOpenParenPos = StringInStr($sString, '(') Local $aRegExVars = StringRegExp($sString, '(?i)\$([a-z0-9_]+)', 3) ; Only valid variable characters. Local $sVarTemp ;~ _ArrayDisplay($aRegExVars) For $iVar = 0 To UBound($aRegExVars) - 1 Step 1 $sVarTemp = StringStripWS($aRegExVars[$iVar], 8) ; Remove whitespace If Not IsDeclared($sVarTemp) Then ContinueLoop ; Make sure the variable exists ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $aRegExVars[' & $iVar & '] = ' & $sVarTemp & ' = ' & Eval($sVarTemp) & @CRLF) ;### Debug Console If $iVar == 0 Then ; Special condition for the first variable $iReturn = Eval($sVarTemp) ContinueLoop EndIf $iReturn = BitOR($iReturn, Eval($sVarTemp)) ; BitOR the current value with next variable Next Return $iReturn EndFunc ;==>ParseBitOR Edited October 17, 2021 by mistersquirrle variables cleanup in code, switched to using RegEx We ought not to misbehave, but we should look as though we could. Link to comment Share on other sites More sharing options...
CoffeeJoe Posted October 17, 2021 Author Share Posted October 17, 2021 mistersquirrle - You are a genius! 🙃 I was thinking about it wrong and getting in my own way... The contents of a BitOR are System Variables that Eval can easily reconcile... I was stuck on "gotta run this expression..." Thanks for the reminder - I will tackle this again tomorrow and let you know how it worked out. Thanks again Link to comment Share on other sites More sharing options...
CoffeeJoe Posted October 18, 2021 Author Share Posted October 18, 2021 mistersquirrle I see you edited your post and the function does indeed return the bitor'ed result without doing an Execute()... I like the RegEx and I'm going to have to learn how to use it ... Eventually. (I think too literally to get it intuitively - its going to take some study to get it) As best I can tell your code pulls each variable out and puts them in an array then does a Bitor with them all. That was enough for me to figure out the next bit. (If there are more than 1 bitor operation or any other variables I think your example will include them) I came up with a bunch of shuffling of variables but a proof of concept after I saw how you converted them. #include <StaticConstants.au3> $sString = "$statusbar = GUICtrlCreateLabel(""Status"", 0, ($GUIh-18), $GUIw, 18, BitOR($SS_SUNKEN, $SS_CENTERIMAGE))" $sString2 = ParseCommand($sString) Msgbox(0, "Parse Test", $sString2) Func ParseCommand($sString) $first = StringInStr($sString, "BitOr(") $second = StringInStr($sString, ")", 0, 1, $first) $str = StringMid($sString, $first, (($second+1)-$first)) MsgBox(0, "", $str) $split = StringSplit($str, "(") $str2 = StringTrimRight($split[2],1) $split = StringSplit($str2, ",") $temp1 = StringTrimLeft($split[1], 1) $temp2 = StringTrimLeft($split[2], 1) $val = BitOR(Eval($temp1), Eval($temp2)) $result = StringReplace($sString, $str, $val, 1) Return $result EndFunc Its ugly and specific to this one example, but I can flesh it out and smooth the edges from here. Thanks, CoffeeJoe Link to comment Share on other sites More sharing options...
mistersquirrle Posted October 19, 2021 Share Posted October 19, 2021 10 hours ago, CoffeeJoe said: I like the RegEx and I'm going to have to learn how to use it ... Eventually. (I think too literally to get it intuitively - its going to take some study to get it) It's definitely useful, I recommend checking out this website for learning and testing RegEx: https://regex101.com/r/Y9jUBu/2 (this link is specifically to what I used in my code, take note that the (?i) at the start of the pattern in my code is the "case insensitive" flag, otherwise you would just add A-Z to the pattern like: [a-zA-Z0-9_]). It walks through (on the right) what each part of the pattern does. The AutoIt documentation for StringRegExp() also has some good information on it, and options specific to AutoIt. And indeed, for my ParseBitOR function you can pass in a string like: BitOR($SS_SUNKEN, $SS_CENTERIMAGE) or $SS_SUNKEN, $SS_CENTERIMAGE and the RegEx matches only the variable names, excluding the $ (since it's outside of the parenthesis in the RegEx pattern). It then loops through each variable and BitOR's it with the previous variables already BitOR'd value. I tested it with up to 4 variables, and it returns the same result as doing it directly. Also an advantage that it had over Execute was that it didn't fail when there was only 1 variable, which should fail BitOR because it requires 2+. It doesn't fail because it just returns the first variables value. Technically though if you were creating code that was making a BitOR with only 1 variable, you've got other problems. We ought not to misbehave, but we should look as though we could. Link to comment Share on other sites More sharing options...
CoffeeJoe Posted October 19, 2021 Author Share Posted October 19, 2021 2 hours ago, mistersquirrle said: you've got other problems. 😆 Thx - I have those information sources and I've made a few regex expressions - but my approach is always very literal - I need some more practice / time Hey, thx for the assist ☕ Link to comment Share on other sites More sharing options...
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