Leaderboard
Popular Content
Showing content with the highest reputation on 11/02/2021 in all areas
-
Introduction JSON (Javascript Object Notation) is a popular data-interchange format and supported by a lot of script languages. On AutoIt, there is already a >JSON UDF written by Gabriel Boehme. It is good but too slow, and not supports unicode and control characters very well. So I write a new one (and of course, fast one as usual). I use a machine code version of JSON parser called "jsmn". jsmn not only supports standard JSON, but also accepts some non-strict JSON string. See below for example. Important Update!! I rename the library from jsmn.au3 to json.au3. All function names are changed, too. Decoding Function Json_Decode($Json) $Json can be a standard or non-standard JSON string. For example, it accepts: { server: example.com port: 80 message: "this looks like a config file" } The most JSON data type will be decoded into corresponding AutoIt variable, including 1D array, string, number, true, false, and null. JSON object will be decoded into "Windows Scripting Dictionary Object" retuned from ObjCreate("Scripting.Dictionary"). AutoIt build-in functions like IsArray, IsBool, etc. can be used to check the returned data type. But for Object and Null, Json_IsObject() and Json_IsNull() should be used. If the input JSON string is invalid, @Error will be set to $JSMN_ERROR_INVAL. And if the input JSON string is not finish (maybe read from stream?), @Error will be set to $JSMN_ERROR_PART. Encoding Function Json_Encode($Data, $Option = 0, $Indent = "\t", $ArraySep = ",\r\n", $ObjectSep = ",\r\n", $ColonSep = ": ") $Data can be a string, number, bool, keyword(default or null), 1D arrry, or "Scripting.Dictionary" COM object. Ptr will be converted to number, Binary will be converted to string in UTF8 encoding. Other unsupported types like 2D array, dllstruct or object will be encoded into null. $Option is bitmask consisting following constant: $JSON_UNESCAPED_ASCII ; Don't escape ascii charcters between chr(1) ~ chr(0x1f) $JSON_UNESCAPED_UNICODE ; Encode multibyte Unicode characters literally $JSON_UNESCAPED_SLASHES ; Don't escape / $JSON_HEX_TAG ; All < and > are converted to \u003C and \u003E $JSON_HEX_AMP ; All &amp;amp;amp;s are converted to \u0026 $JSON_HEX_APOS ; All ' are converted to \u0027 $JSON_HEX_QUOT ; All " are converted to \u0022 $JSON_PRETTY_PRINT ; Use whitespace in returned data to format it $JSON_STRICT_PRINT ; Make sure returned JSON string is RFC4627 compliant $JSON_UNQUOTED_STRING ; Output unquoted string if possible (conflicting with $JSMN_STRICT_PRINT) Most encoding option have the same means like PHP's json_enocde() function. When $JSON_PRETTY_PRINT is set, output format can be change by other 4 parameters ($Indent, $ArraySep, $ObjectSep, and $ColonSep). Because these 4 output format parameters will be checked inside Jsmn_Encode() function, returned string will be always accepted by Jsmn_Decode(). $JSON_UNQUOTED_STRING can be used to output unquoted string that also accetped by Jsmn_Decode(). $JSON_STRICT_PRINT is used to check output format setting and avoid non-standard JSON output. So this option is conflicting with $JSON_UNQUOTED_STRING. Get and Put Functions Json_Put(ByRef $Var, $Notation, $Data, $CheckExists = False) Json_Get(ByRef $Var, $Notation) These functions helps user to access object or array more easily. Both dot notation and square bracket notation can be supported. Json_Put() by default will create non-exists objects and arrays. For example: Local $Obj Json_Put($Obj, ".foo", "foo") Json_Put($Obj, ".bar[0]", "bar") Json_Put($Obj, ".test[1].foo.bar[2].foo.bar", "Test") Local $Test = Json_Get($Obj, '["test"][1]["foo"]["bar"][2]["foo"]["bar"]') ; "Test" Object Help Functions Json_ObjCreate() Json_ObjPut(ByRef $Object, $Key, $Value) Json_ObjGet(ByRef $Object, $Key) Json_ObjDelete(ByRef $Object, $Key) Json_ObjExists(ByRef $Object, $Key) Json_ObjGetCount(ByRef $Object) Json_ObjGetKeys(ByRef $Object) Json_ObjClear(ByRef $Object) These functions are just warps of "Scripting.Dictionary" COM object. You can use these functions if you are not already familiar with it. == Update 2013/05/19 == * Add Jsmn_Encode() option "$JSMN_UNESCAPED_ASCII". Now the default output of Json_Encode() is exactly the same as PHP's json_encode() function (for example, chr(1) will be encoded into u0001). $JSON_UNESCAPED_ASCII ; Don't escape ascii charcters between chr(1) ~ chr(0x1f) == Update 2015/01/08 == * Rename the library from jsmn.au3 to json.au3. All function names are changed, too. * Add Json_Put() and Json_Get() * Add Null support * Using BinaryCall.au3 to loading the machine code. == Update 2018/01/13== (Jos) * Add JsonDump() to list all Json Keys and their values to easily figure out what they are. == Update 2018/10/01== (Jos) * Fixed JsonDump() some fields and values were not showing as discussed here - tnx @TheXman . == Update 2018/10/01b== (Jos) * Added Json_ObjGetItems, Tidied source and fixed au3check warnings - tnx @TheXman . == Update 2018/10/28== (Jos) * Added declaration for $value to avoid au3check warning - tnx @DerPensionist == Update 2018/12/16== (Jos) * Added another declaration for $value to avoid au3check warning and updated the version at the top - tnx @maniootek == Update 2018/12/29== (Jos) * Changed Json_ObjGet() and Json_ObjExists() to allow for multilevel object in string. == Update 2019/01/17== (Jos) * Added support for DOT notation in JSON functions. == Update 2019/07/15== (Jos) * Added support for reading keys with a dot inside when using a dot as separator (updated) == Update 2021/11/18== (TheXman) * Update details in below post: == Update 2021/11/20== (TheXman) * Minor RegEx update, no change to the functionality or result._Json(2021.11.20).zip1 point
-
Just too monstrous for me to appreciate the finer workings of what parses through your mind.1 point
-
Can I make a window interface with buttons using Autoit?
seadoggie01 reacted to ViciousXUSMC for a topic
Koda Form Designer makes it pretty easy to build basic GUI's I use it all the time. Nothing super pretty, but always pretty functional1 point -
Query Builder tool
Earthshine reacted to jchd for a topic
From what I understand from the OP's posts, he wants to create an SQL[ite] query builder allowing SQL-illiterate users to click on GUI components to assemble a valid SQL query to perform the operation(s) expected. More or less generic SQL builder are available, payware or freeware, but this isn't a simple task. In fact, beyond very simple queries, things turn out to be very complex and if you insist on efficiency, then you need some level of IA.1 point -
This is a new version of the server/client example above based on the FakeObj object. Again, FakeObj is passed to the client through a ROT-object. Here, FakeObj can handle strings, doubles, integers and arrays. Server.au3: #AutoIt3Wrapper_Au3Check_Parameters=-d -w- 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #AutoIt3Wrapper_UseX64=Y Opt( "MustDeclareVars", 1 ) #include <Array.au3> #include "AccVars.au3" #include "IRunningObjectTable.au3" Global $oError = ObjEvent("AutoIt.Error", "_ErrFunc") Example() Func Example() ConsoleWrite( "Code running on server ..." & @CRLF ) Local $tFakeObj, $oFakeObj $oFakeObj = _ObjectFromTag("__MyInterface_", "Data hresult(variant)", $tFakeObj) $oFakeObj.Data("Test string from Server .....") $oFakeObj.Data( 123.123 ) $oFakeObj.Data( 123 ) Local $aArray = [ 123, 123.123, "Server test string" ] $oFakeObj.Data( $aArray ) ; Create a default ROT-object (Dictionary object) Local $sDataTransferObject, $oDataTransferObject $oDataTransferObject = ROT_CreateDefaultObject( $sDataTransferObject ) ; Create Dictionary object Local $oDict = ObjCreate( "Scripting.Dictionary" ) $oDict.Item( "$oFakeObj" ) = $oFakeObj ; Add Dictionary object to ROT-object $oDataTransferObject.Add( "$oDict", $oDict ) ; Start the client script in a new process ConsoleWrite( @CRLF & "Code running on Client ..." & @CRLF ) RunWait( @AutoItExe & " /AutoIt3ExecuteScript Client.au3" & " " & $sDataTransferObject ) EndFunc Func __MyInterface_QueryInterface($pSelf, $pRIID, $pObj) Local $tStruct = DllStructCreate("ptr", $pObj) DllStructSetData($tStruct, 1, $pSelf) Return 0 ; $S_OK #forceref $pRIID EndFunc Func __MyInterface_AddRef($pSelf) Return 1 #forceref $pSelf EndFunc Func __MyInterface_Release($pSelf) Return 1 #forceref $pSelf EndFunc Func __MyInterface_Data($pSelf, $pVariant) ConsoleWrite( @CRLF & "$pVar = " & $pVariant & @CRLF ) Local $tVariant = DllStructCreate( $tagVARIANT, $pVariant ) Local $sAlign1 = " " & ( @AutoItX64 ? " " : "" ) Local $iVariantType = DllStructGetData( $tVariant, "vt" ) ConsoleWrite( "Type = 0x" & Hex( $iVariantType, 4 ) & " " & $sAlign1 ) ; 4 word elements before the data element = 8 bytes Local $pData = $pVariant + 8, $tPtr, $pPtr Switch $iVariantType Case $VT_I4 ; 4 bytes signed integer ConsoleWrite( "(VT_I4, 4 bytes signed integer)" & @CRLF ) ; The data element contains the integer in the 4 first bytes Local $tInt = DllStructCreate( "int", $pData ) Local $iInt = DllStructGetData( $tInt, 1 ) ConsoleWrite( "data = " & $iInt & @CRLF ) Case $VT_R8 ; 8 bytes double ConsoleWrite( "(VT_R8, 8 bytes double)" & @CRLF ) ; The data element contains the double in the 8 first bytes ; That's the entire data element on 32 bit and half the data element on 64 bit Local $tFlt = DllStructCreate( "double", $pData ) Local $fFlt = DllStructGetData( $tFlt, 1 ) ConsoleWrite( "data = " & $fFlt & @CRLF ) Case $VT_BSTR ; Basic string ConsoleWrite( "(VT_BSTR, basic string)" & @CRLF ) ; The data element contains a pointer to the BSTR $tPtr = DllStructCreate( "ptr", $pData ) $pPtr = DllStructGetData( $tPtr, 1 ) ConsoleWrite( "pBSTR = " & $pPtr & " (BSTR pointer)" & @CRLF ) ; The BSTR must be read with a proper BSTR-function (see Variant.au3) Local $sStr = SysReadString( $pPtr ) ConsoleWrite( "data = " & $sStr & @CRLF ) Case $VT_ARRAY + $VT_VARIANT ; Array of variants ConsoleWrite( "(VT_ARRAY+VT_VARIANT, array of variants, safearray)" & @CRLF ) ; The data element contains a pointer to the safearray in the 4/8 first bytes $tPtr = DllStructCreate( "ptr", $pData ) $pPtr = DllStructGetData( $tPtr, 1 ) ConsoleWrite( "data = " & $pPtr & " (pointer to safearray)" & @CRLF ) ; Print safearray data to console ConsoleWrite( @CRLF & "Safearray data:" & @CRLF ) PrintSafeArray1D( $pPtr ) ; Convert safearray to AutoIt array through internal COM conversions ; Display the AutoIt array with _ArrayDisplay( $aArray ) ConsoleWrite( @CRLF & "Convert safearray to AutoIt array" & @CRLF ) Local $aArray SafeArrayLock( $pPtr ) AccessVariables02( AccVars_SafeArrayToArray, $pPtr, $aArray ) SafeArrayUnlock( $pPtr ) ConsoleWrite( "_ArrayDisplay( <AutoIt array> ) ..." & @CRLF ) _ArrayDisplay( $aArray ) Case Else ConsoleWrite( "Variant type = " & DllStructGetData( $tVariant, "vt" ) & @CRLF ) ConsoleWrite( "Unhandled variant type" & @CRLF ) EndSwitch Return 0 ; $S_OK #forceref $pSelf EndFunc ; #FUNCTION# ============================================================================= ; Name...........: _ObjectFromTag ; ======================================================================================== Func _ObjectFromTag($sFunctionPrefix, $tagInterface, ByRef $tInterface, $fPrint = False, $bIsUnknown = Default, $sIID = "{00000000-0000-0000-C000-000000000046}") ; last param is IID_IUnknown by default If $bIsUnknown = Default Then $bIsUnknown = True Local $sInterface = $tagInterface ; copy interface description Local $tagIUnknown = "QueryInterface hresult(ptr;ptr*);" & _ "AddRef dword();" & _ "Release dword();" ; Adding IUnknown methods If $bIsUnknown Then $tagInterface = $tagIUnknown & $tagInterface ; Below line is really simple even though it looks super complex. It's just written weird to fit in one line, not to steal your attention Local $aMethods = StringSplit(StringReplace(StringReplace(StringReplace(StringReplace(StringTrimRight(StringReplace(StringRegExpReplace(StringRegExpReplace($tagInterface, "\w+\*", "ptr"), "\h*(\w+)\h*(\w+\*?)\h*(\((.*?)\))\h*(;|;*\z)", "$1\|$2;$4" & @LF), ";" & @LF, @LF), 1), "object", "idispatch"), "hresult", "long"), "bstr", "ptr"), "variant", "ptr"), @LF, 3) Local $iUbound = UBound($aMethods) Local $sMethod, $aSplit, $sNamePart, $aTagPart, $sTagPart, $sRet, $sParams, $hCallback ; Allocation $tInterface = DllStructCreate("int RefCount;int Size;ptr Object;ptr Methods[" & $iUbound & "];int_ptr Callbacks[" & $iUbound & "];ulong_ptr Slots[16]") ; 16 pointer sized elements more to create space for possible private props If @error Then Return SetError(1, 0, 0) For $i = 0 To $iUbound - 1 $aSplit = StringSplit($aMethods[$i], "|", 2) If UBound($aSplit) <> 2 Then ReDim $aSplit[2] $sNamePart = $aSplit[0] $sTagPart = $aSplit[1] $sMethod = $sFunctionPrefix & $sNamePart If $fPrint Then Local $iPar = StringInStr($sTagPart, ";", 2), $t If $iPar Then $t = "Ret: " & StringLeft($sTagPart, $iPar - 1) & " " & _ "Par: " & StringRight($sTagPart, StringLen($sTagPart) - $iPar) Else $t = "Ret: " & $sTagPart EndIf Local $s = "Func " & $sMethod & _ "( $pSelf ) ; " & $t & @CRLF & _ "EndFunc" & @CRLF ConsoleWrite($s) EndIf $aTagPart = StringSplit($sTagPart, ";", 2) $sRet = $aTagPart[0] $sParams = StringReplace($sTagPart, $sRet, "", 1) $sParams = "ptr" & $sParams $hCallback = DllCallbackRegister($sMethod, $sRet, $sParams) If @error Then ConsoleWrite('! ' & @error & ' ' & $sMethod & @CRLF & @CRLF) EndIf DllStructSetData($tInterface, "Methods", DllCallbackGetPtr($hCallback), $i + 1) ; save callback pointer DllStructSetData($tInterface, "Callbacks", $hCallback, $i + 1) ; save callback handle Next DllStructSetData($tInterface, "RefCount", 1) ; initial ref count is 1 DllStructSetData($tInterface, "Size", $iUbound) ; number of interface methods DllStructSetData($tInterface, "Object", DllStructGetPtr($tInterface, "Methods")) ; Interface method pointers Return ObjCreateInterface(DllStructGetPtr($tInterface, "Object"), $sIID, $sInterface, $bIsUnknown) ; pointer that's wrapped into object EndFunc ;==>ObjectFromTag Func _ErrFunc() ConsoleWrite("! COM Error ! Number: 0x" & Hex($oError.number, 8) & " ScriptLine: " & $oError.scriptline & " - " & $oError.windescription & @CRLF) Return EndFunc ;==>_ErrFunc Func PrintSafeArray1D( $pSafeArray ) If Not IsPtr( $pSafeArray ) Then Return SetError(1,0,0) If Not SafeArrayGetDim( $pSafeArray ) = 1 Then Return SetError(2,0,0) Local $tSafeArray = DllStructCreate( $tagSAFEARRAY, $pSafeArray ) Local $iElemSize = DllStructGetData( $tSAFEARRAY, "cbElements" ) Local $iUBound, $pSafeArrayData, $vt, $data SafeArrayGetUBound( $pSafeArray, 1, $iUBound ) SafeArrayAccessData( $pSafeArray, $pSafeArrayData ) For $i = 0 To $iUBound $vt = DllStructGetData( DllStructCreate( "word", $pSafeArrayData ), 1 ) Switch $vt Case $VT_I4 ; 4 bytes signed integer $data = DllStructGetData( DllStructCreate( "int", $pSafeArrayData + 8 ), 1 ) Case $VT_R8 ; 8 bytes double $data = DllStructGetData( DllStructCreate( "double", $pSafeArrayData + 8 ), 1 ) Case $VT_BSTR ; Basic string $data = SysReadString( DllStructGetData( DllStructCreate( "ptr", $pSafeArrayData + 8 ), 1 ) ) Case Else $data = "" EndSwitch ConsoleWrite( $data & @CRLF ) $pSafeArrayData += $iElemSize Next SafeArrayUnaccessData( $pSafeArray ) EndFunc Func AccVars_SafeArrayToArray( $pvSafeArray, $pArray ) ; <<<< On function entry the native AutoIt array is converted to a safearray contained in a variant >>>> ; --- Get safearray information --- ; $pvSafeArray is a variant that contains a pointer Local $pSafeArray = DllStructGetData( DllStructCreate( "ptr", $pvSafeArray + 8 ), 1 ) ; Array type Local $iVarType SafeArrayGetVartype( $pSafeArray, $iVarType ) Switch $iVarType Case $VT_I2, $VT_I4 ; Signed integers Case $VT_R4, $VT_R8 ; 4/8 bytes floats Case $VT_BSTR ; Basic string Case $VT_BOOL ; Boolean Case $VT_UI4, $VT_UI8 ; 4/8 bytes unsigned integers Case $VT_VARIANT ; Variant Case Else Return SetError(1,0,0) EndSwitch ; --- Set $pArray to match an array --- ; Set vt element to $VT_ARRAY + $iVarType DllStructSetData( DllStructCreate( "word", $pArray ), 1, $VT_ARRAY + $iVarType ) ; Set data element to safearray pointer DllStructSetData( DllStructCreate( "ptr", $pArray + 8 ), 1, $pSafeArray ) ; <<<< On function exit the safearray contained in a variant is converted to a native AutoIt array >>>> EndFunc Client.au3: #AutoIt3Wrapper_Au3Check_Parameters=-d -w- 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #AutoIt3Wrapper_UseX64=Y Opt( "MustDeclareVars", 1 ) Example() Func Example() ; Get default ROT-object (Dictionary object) Local $oDataTransferObject = ObjGet( $CmdLine[1] ) ; Get Dictionary object from ROT-object Local $oDict = $oDataTransferObject.Item( "$oDict" ) Local $oFakeObj = $oDict.Item( "$oFakeObj" ) $oFakeObj.Data("Test string from Client .....") $oFakeObj.Data( 123.123 ) $oFakeObj.Data( 123 ) Local $aArray = [ 123, 123.123, "Client test string" ] $oFakeObj.Data( $aArray ) EndFunc Run Server.au3. Output in SciTE console: Code running on server ... $pVar = 0x000000000045ED30 Type = 0x0008 (VT_BSTR, basic string) pBSTR = 0x0000000000928EE8 (BSTR pointer) data = Test string from Server ..... $pVar = 0x000000000045ED30 Type = 0x0005 (VT_R8, 8 bytes double) data = 123.123 $pVar = 0x000000000045ED30 Type = 0x0003 (VT_I4, 4 bytes signed integer) data = 123 $pVar = 0x000000000045ED30 Type = 0x200C (VT_ARRAY+VT_VARIANT, array of variants, safearray) data = 0x000000000095C7B0 (pointer to safearray) Safearray data: 123 123.123 Server test string Convert safearray to AutoIt array _ArrayDisplay( <AutoIt array> ) ... Code running on Client ... $pVar = 0x000000000045E520 Type = 0x0008 (VT_BSTR, basic string) pBSTR = 0x0000000000926908 (BSTR pointer) data = Test string from Client ..... $pVar = 0x000000000045E520 Type = 0x0005 (VT_R8, 8 bytes double) data = 123.123 $pVar = 0x000000000045E520 Type = 0x0003 (VT_I4, 4 bytes signed integer) data = 123 $pVar = 0x000000000045E520 Type = 0x200C (VT_ARRAY+VT_VARIANT, array of variants, safearray) data = 0x000000000095E8F0 (pointer to safearray) Safearray data: 123 123.123 Client test string Convert safearray to AutoIt array _ArrayDisplay( <AutoIt array> ) ... All code in the 7z-file. FakeObj2.7z1 point
-
Seems like your CSS is wrong for locating the frameset. Once you resolve that, there are commands for switching context so that you can access the frame's contents. You need to use _WD_Window with the correct parameters or you can use the helper functions _WD_FrameEnter and _WD_FrameLeave. P.S. You can't use the $sStartNodeID parameter of _WD_FindElement to access a frame's contents.1 point