Jump to content
c.haslam

Structure: Differentiating between Hwnd and Ptr

Recommended Posts

c.haslam

jchd posted VarTypeDump(). It has something like:

$data = DllStructGetData($vVar, $nbElem)
.
.
$type = VarGetType($data)
Switch $type
.
.
    Case "Ptr"
.
.
       $elem = "ptr"
       ; alias: hwnd, handle

I have found that a hwnd or handle can be detected by:

$elem = IsHwnd($data) ? 'handle' : 'ptr'
  • jchd did not differentiate between Hwnd and Ptr. Is that because differentiating may fail?
  • Are Hwnd and Handle the same for both 32-bit and 64-bit AutoIt? The Help for DllStructCreate(0 lists both, with identical descriptions. In 32-bit AutoIt, the length of both is 4.
Edited by c.haslam

Spoiler

CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard

 

Share this post


Link to post
Share on other sites
jchd

You're seing an old version. Probably my fault as it's quite possible that I never updated the various places where I posted the code. Again it was only for example, not really intended as a clean and stable UDF for public consumption.

Here's what I currently have.

#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_Compile_Both=n
;~ #AutoIt3Wrapper_UseX64=y
#AutoIt3Wrapper_Run_AU3Check=n
#AutoIt3Wrapper_Version=B       ; beta 3.3.15.0 or greater is mandatory

#include-once

#include <AutoItConstants.au3>
#include <String.au3>
#include <Math.au3>

Global Const $_TAB = '      '
Global $_DumpStr, $_DumpBin

; user-callable function, so that noone messes with __VarDump indentation
; $vVar is the variable to be dumped
; $iLimit is the max number of entries of an array dimension, map or DllStruct array element to be displayed in full
Func _VarDump(ByRef $vVar, $iLimit = 20, $bFullStr = 0, $bFullBin = 0)
    If $iLimit < 3 Then $iLimit = 0
    $_DumpStr = ($bFullStr ? __DumpFullStr : __DumpStr)
    $_DumpBin = ($bFullBin ? __DumpFullBin : __DumpBin)
    Return (__VarDump($vVar, $iLimit))
EndFunc   ;==>_VarDump


Func __VarDump(ByRef $vVar, $iLimit, $sIndent = '', $sMore = '')
    Local $ret, $len, $ptr, $tmp

    Switch VarGetType($vVar)

        Case "String"
            $len = StringLen($vVar)
            Return 'String       (' & $len & ") " & $_DumpStr($vVar)

        Case "Double"
            Return 'Double       ' & $vVar & (IsInt($vVar) ? '.0' : '')

        Case "Int32", "Int64"
            Return VarGetType($vVar) & '        ' & $vVar

        Case "Array"
            Local $iDimensions = UBound($vVar, 0)
            Local $iCells = 1
            $ret = 'Array'
            $iDimensions -= 1
            For $i = 0 To $iDimensions
                $ret &= '[' & UBound($vVar, $i + 1) & ']'
                $iCells *= UBound($vVar, $i + 1)
            Next
            $sMore = _StringRepeat(' ', StringLen($ret) - 1)
            If $iCells = 0 Then
                Return $ret & $_TAB & '  (array is empty)'
            Else
                Return $ret & @CRLF & __VarDumpArray($vVar, $iLimit, $sIndent, $sMore)
            EndIf

        Case "Binary"
            $len = BinaryLen($vVar)
            $ret = 'Binary       (' & BinaryLen($vVar) & ') '
            Return ($ret & $_DumpBin($vVar))

        Case "Bool"
            Return 'Boolean      ' & $vVar

        Case "Keyword"
            Return ('Keyword      ' & ($vVar = Null ? 'Null' : ($vVar = Default ? 'Default' : 'Other keyword')))

        Case "Ptr"
            Return (IsHWnd($vVar) ? 'HWnd         ' : 'Pointer      ' & $vVar)

        Case "Object"
            $tmp = 'Object' & @LF & $sMore & $sIndent & '    Name:             ' & ObjName($vVar, $OBJ_NAME)
            $ret = ObjName($vVar, $OBJ_STRING)
            If Not @error Then $tmp &= @LF & $sMore & $sIndent & '    Description:      ' & $ret
            $ret = ObjName($vVar, $OBJ_PROGID)
            If Not @error Then $tmp &= @LF & $sMore & $sIndent & '    ProgID:           ' & $ret
            $ret = ObjName($vVar, $OBJ_FILE)
            If Not @error Then $tmp &= @LF & $sMore & $sIndent & '    Associated file:  ' & $ret
            $ret = ObjName($vVar, $OBJ_MODULE)
            If Not @error Then $tmp &= @LF & $sMore & $sIndent & '    Owner/marshaller: ' & $ret
            $ret = ObjName($vVar, $OBJ_CLSID)
            If Not @error Then $tmp &= @LF & $sMore & $sIndent & '    CLSID:            ' & $ret
            $ret = ObjName($vVar, $OBJ_IID)
            If Not @error Then $tmp &= @LF & $sMore & $sIndent & '    InterfaceID:      ' & $ret
            Return $tmp

        Case "Function", "UserFunction"
            Return StringFormat('%-13s', VarGetType($vVar)) & FuncName($vVar)

        Case "DllStruct"
            $len = DllStructGetSize($vVar)
            $ptr = DllStructGetPtr($vVar)
            $ret = 'Struct       (' & $len & ') @:' & Hex($ptr) & ' (structure alignment is unknown)' & @CRLF
            Local $nbElem = 1, $idx, $incr, $data, $type, $indent = $sIndent & $_TAB, $oldvalue, $readvalue, $elem
            While 1
                $data = DllStructGetData($vVar, $nbElem)
                If @error = 2 Then ExitLoop
                $type = VarGetType($data)
                $idx = 1
                $incr = 0
                ; determine max index of element
                While 1
                    DllStructGetData($vVar, $nbElem, 2 * $idx)
                    If @error = 3 Then ExitLoop
                    $incr = $idx
                    $idx *= 2
                WEnd
                ; index is in [$idx, (2 * $idx) - 1]
                $idx += $incr
                Do
                    DllStructGetData($vVar, $nbElem, $idx)
                    If @error = 3 Then
                        ; approach is asymetric (upper bound is too big)
                        $idx -= ($incr = 1) ? 1 : $incr / 2
                    Else
                        $idx += Int($incr / 2)
                    EndIf
                    $incr = Int($incr / 2)
                Until $incr = 0
                Switch $type
                    Case "Int32", "Int64"
                        $ret &= $indent
                        $data = DllStructGetData($vVar, $nbElem, 1)
                        DllStructSetData($vVar, $nbElem, 0x7777666655554433, 1)
                        $readvalue = DllStructGetData($vVar, $nbElem, 1)
                        Switch $readvalue
                            Case 0x7777666655554433
                                $elem = "int64"
                                ; alias: uint64
                                ; alias: int_ptr(x64), long_ptr(x64), lresult(x64), lparam(x64)
                                ; alias: uint_ptr(x64), ulong_ptr(x64), dword_ptr(x64), wparam(x64)
                            Case 0x55554433
                                DllStructSetData($vVar, $nbElem, 0x88887777, 1)
                                $readvalue = DllStructGetData($vVar, $nbElem, 1)
                                $elem = ($readvalue > 0 ? "uint" : "int")
                                ; int aliases: long, bool, int_ptr(x86), long_ptr(x86), lresult(x86), lparam(x86);
                                ; uint aliases: ulong, dword, uint_ptr(x86), ulong_ptr(x86), dword_ptr(x86), wparam(x86)
                            Case 0x4433
                                DllStructSetData($vVar, $nbElem, 0x8888, 1)
                                $readvalue = DllStructGetData($vVar, $nbElem, 1)
                                $elem = ($readvalue > 0 ? "ushort" : "short")
                                ; ushort alias: word
                            Case 0x33
                                $elem = "byte"
                                ; alias: ubyte
                        EndSwitch
                        DllStructSetData($vVar, $nbElem, $data, 1)
                        If $idx = 1 Then
                            $ret &= StringFormat('%-' & 9 + StringLen($len) & 's ', $elem) & $data & @CRLF
                        Else
                            $ret &= $elem & "[" & $idx & "]" & @CRLF
                            For $i = 1 To $idx
                                If $iLimit And $idx > $iLimit And $i > $iLimit Then
                                    $ret &= $indent & StringFormat('%-' & 9 + StringLen($len) & 's ', '') & '... there are ' & $idx - $iLimit & ' more ' & $elem & ' in this array' & @CRLF
                                    ExitLoop
                                Else
                                    $ret &= $indent & StringFormat('%-' & 9 + StringLen($len) & 's ', '') & DllStructGetData($vVar, $nbElem, $i) & @CRLF
                                EndIf
                            Next
                        EndIf
                    Case "String"
                        $oldvalue = DllStructGetData($vVar, $nbElem, 1)
                        DllStructSetData($vVar, $nbElem, ChrW(0x2573), 1)
                        $readvalue = DllStructGetData($vVar, $nbElem, 1)
                        DllStructSetData($vVar, $nbElem, $oldvalue, 1)
                        $elem = ($readvalue = ChrW(0x2573) ? "wchar" : "char")
                        If $idx > 1 Then $elem &= "[" & $idx & "]"
                        $ret &= $indent & StringFormat('%-' & 9 + StringLen($len) & 's ', $elem) & $_DumpStr($data) & @CRLF
                    Case "Binary"
                        Local $blen = BinaryLen($data)
                        $elem = "byte"
                        If $idx > 1 Then $elem &= "[" & $idx & "]"
                        $ret &= $indent & StringFormat('%-' & 9 + StringLen($len) & 's ', $elem) & $_DumpBin($data) & @CRLF
                    Case "Ptr"
                        $ret &= $indent
                        $elem = "ptr"
                        ; alias: hwnd, handle
                        If $idx = 1 Then
                            $ret &= StringFormat('%-' & 9 + StringLen($len) & 's ', $elem) & $data & @CRLF
                        Else
                            $ret &= $elem & "[" & $idx & "]" & @CRLF
                            For $i = 1 To $idx
                                $ret &= $indent & StringFormat('%-' & 9 + StringLen($len) & 's ', '') & DllStructGetData($vVar, $nbElem, $i) & @CRLF
                            Next
                        EndIf
                    Case "Double"
                        $ret &= $indent
                        $oldvalue = DllStructGetData($vVar, $nbElem, 1)
                        DllStructSetData($vVar, $nbElem, 10 ^ - 15, 1)
                        $readvalue = DllStructGetData($vVar, $nbElem, 1)
                        DllStructSetData($vVar, $nbElem, $oldvalue, 1)
                        $elem = ($readvalue = 10 ^ - 15 ? "double" : "float")
                        If $idx = 1 Then
                            $ret &= StringFormat('%-' & 9 + StringLen($len) & 's ', $elem) & $data & (IsInt($data) ? '.0' : '') & @CRLF
                        Else
                            $ret &= $elem & "[" & $idx & "]" & @CRLF
                            For $i = 1 To $idx
                                If $iLimit And $idx > $iLimit And $i > $iLimit Then
                                    $ret &= $indent & StringFormat('%-' & 9 + StringLen($len) & 's ', '') & '... there are ' & $idx - $iLimit & ' more ' & $elem & ' in this array' & @CRLF
                                    ExitLoop
                                Else
                                    $ret &= $indent & StringFormat('%-' & 9 + StringLen($len) & 's %s', '', DllStructGetData($vVar, $nbElem, $i)) & (IsInt(DllStructGetData($vVar, $nbElem, $i)) ? '.0' : '') & @CRLF
                                EndIf
                            Next
                        EndIf
                EndSwitch
                $nbElem += 1
            WEnd
            Return StringTrimRight($ret, 2)

        Case "Map"
            Local $iCells = UBound($vVar)
            $ret = 'Map[' & $iCells & ']'
            If $iCells = 0 Then
                Return $ret & $_TAB & '  (map is empty)'
            Else
                Return $ret & @CRLF & __VarDumpMap($vVar, $iLimit, $sIndent, '    ')
            EndIf

        Case Else
            Return StringFormat('%-13s', VarGetType($vVar)) & $vVar

    EndSwitch
EndFunc   ;==>__VarDump


Func __VarDumpArray(ByRef $aArray, $iLimit, $sIndent = $_TAB, $sMore = '')
    Local $sDump, $sArrayFetch, $sArrayRead, $iDone = 0, $iElements = 1
    Local $iDimensions = UBound($aArray, 0)
    Local $aUBounds[$iDimensions]
    Local $aIndices[$iDimensions]
    $iDimensions -= 1
    For $i = 0 To $iDimensions
        $aUBounds[$i] = UBound($aArray, $i + 1) - 1
        $iElements *= $aUBounds[$i] + 1
        $aIndices[$i] = 0
    Next
    $sIndent &= $_TAB
    While $iDone < ($iLimit ? _Min($iLimit, $iElements) : $iElements)
        $sArrayFetch = ''
        For $i = 0 To $iDimensions
            $sArrayFetch &= '[' & $aIndices[$i] & ']'
        Next
        $sArrayRead = Execute('$aArray' & $sArrayFetch)
        $sDump &= $sIndent & $sArrayFetch & ' => ' & __VarDump($sArrayRead, $iLimit, $sIndent, $sMore) & @CRLF
        $iDone += 1
        If $iLimit And $iDone = $iLimit Then
            $sDump &= $sIndent & '... there are ' & $iElements - $iDone & ' more elements in this array' & @CRLF
            ExitLoop
        EndIf

        For $i = $iDimensions To 0 Step -1
            $aIndices[$i] += 1
            If $aIndices[$i] > $aUBounds[$i] Then
                $aIndices[$i] = 0
            Else
                ExitLoop
            EndIf
        Next
    WEnd
    Return (StringTrimRight($sDump, 2))
EndFunc   ;==>__VarDumpArray


Func __VarDumpMap(ByRef $mMap, $iLimit, $sIndent = $_TAB, $sMore = '')
    Local $i = 0, $sDump
    $sIndent &= $_TAB
    For $key In MapKeys($mMap)
        $sDump &= $sIndent & StringFormat('%-16s => ', _
                "[" & (IsString($key) ? __DumpStr($key) : $key) & "]")
        $sDump &= __VarDump($mMap[$key], $iLimit, $sIndent, $sMore) & @CRLF
        If $iLimit And $i = $iLimit - 1 Then
            $sDump &= $sIndent & '... there are ' & UBound($mMap) - $i - 1 & ' more elements in this map' & @CRLF
            ExitLoop
        EndIf
        $i += 1
    Next
    Return (StringTrimRight($sDump, 2))
EndFunc   ;==>__VarDumpMap


Func __DumpStr($vVar)
    Local $len = StringLen($vVar)
    $vVar = Execute("'" & StringRegExpReplace(StringReplace($vVar, "'", "''"), "([\p{Cc}])", "<0x' & Hex(AscW('$1'), 2) & '>") & "'")
    Return "'" & (($len <= 64) ? $vVar : StringMid($vVar, 1, 32) & ' ... ' & StringTrimLeft(StringMid($vVar, $len - 31, 32), 2)) & "'"
EndFunc   ;==>__DumpStr


Func __DumpBin(ByRef $vVar)
    Local $len = BinaryLen($vVar)
    Return (($len <= 32) ? $vVar : BinaryMid($vVar, 1, 16) & ' ... ' & StringTrimLeft(BinaryMid($vVar, $len - 15, 16), 2))
EndFunc   ;==>__DumpBin


Func __DumpFullStr(ByRef $vVar)
    $vVar = Execute("'" & StringRegExpReplace(StringReplace($vVar, "'", "''"), "([\p{Cc}])", "<0x' & Hex(AscW('$1'), 2) & '>") & "'")
    Return "'" & $vVar & "'"
EndFunc   ;==>__DumpFullStr


Func __DumpFullBin(ByRef $vVar)
    Return $vVar
EndFunc   ;==>__DumpFullBin


Func _VarCmp(ByRef $vVar1, ByRef $vVar2, $iMethod = 1)
    If $iMethod = Default Then $iMethod = 1
    Local $dim = UBound($vVar1, $UBOUND_DIMENSIONS)
    If $dim <> UBound($vVar2, $UBOUND_DIMENSIONS) Then Return SetError(1, 0, '')
    Local $err = 0
    If $dim = 0 Then
        If BitAND($iMethod, 1) And $vVar1 <> $vVar2 Then $err = 4
        If BitAND($iMethod, 2) And Not ($vVar1 == $vVar2) Then $err += 8
        If BitAND($iMethod, 4) And VarGetType($vVar1) <> VarGetType($vVar2) Then $err += 16
        If BitAND($iMethod, 8) And _VarDump($vVar1) <> _VarDump($vVar2) Then $err += 32
        If $err Then Return SetError($err, 0, '')
    EndIf
    Local $iElems = 1
    For $i = 1 To $dim
        If UBound($vVar1, $i) <> UBound($vVar2, $i) Then Return SetError(2, 0, $i)
        $iElems *= UBound($vVar1, $i)
    Next
    Local $idx, $n, $v1, $v2
    For $i = 0 To $iElems - 1
        $idx = ''
        $n = $i
        For $j = 1 To $dim
            $n = Mod($n, UBound($vVar1, $j))
            $idx = '[' & $n & ']' & $idx
            $n = Int($i / UBound($vVar1, $j))
        Next
        $v1 = Execute('$vVar1' & $idx)
        $v2 = Execute('$vVar2' & $idx)
        If BitAND($iMethod, 1) And $v1 <> $v2 Then $err = 4
        If BitAND($iMethod, 2) And Not ($v1 == $v2) Then $err += 8
        If BitAND($iMethod, 4) And VarGetType($v1) <> VarGetType($v2) Then $err += 16
        If BitAND($iMethod, 8) And _VarDump($v1) <> _VarDump($v2) Then $err += 32
        If $err Then Return SetError($err, 0, $idx)
    Next
    Return SetError(0, 0, '')
EndFunc   ;==>_VarCmp


; Unicode-aware ConsoleWrite
Func _ConsoleWrite($s)
    ConsoleWrite(BinaryToString(StringToBinary($s, 4), 1))
EndFunc   ;==>_ConsoleWrite


#cs

    ; Example use

    Local $tTest = DllStructCreate("byte;byte[3];char;char[3];wchar;wchar[3];short;short[3];ushort;ushort[3];int;int[3];uint;uint[3];int64;int64[3];uint64;uint64[3];float;float[3];double;double[3];handle;handle[3];boolean;bool;hwnd;handle;int_ptr;long_ptr;lresult;lparam;uint_ptr;ulong_ptr;dword_ptr;wparam")
    DllStructSetData($tTest, 2, '€')
    DllStructSetData($tTest, 6, '€')
    _ConsoleWrite('Test structure types' & @LF & _VarDump($tTest) & @LF & @LF)

    Local $struct = DllStructCreate("char[3];handle[3];uint[35];byte[128];wchar[190000]; double[3];int64[3];char[3];float;double;byte;byte;short;ushort;int;uint;char")
    DllStructSetData($struct, 1, 'sos')
    DllStructSetData($struct, 2, Ptr(123456789))
    DllStructSetData($struct, 3, 8, 1)
    DllStructSetData($struct, 3, 0x87654321, 2)
    DllStructSetData($struct, 3, 256, 5)
    DllStructSetData($struct, 4, Binary('sos'))
    DllStructSetData($struct, 5, 'gno' & @CRLF & 'j''i' & @TAB & 'o')
    DllStructSetData($struct, 6, 3.1415926, 2)
    DllStructSetData($struct, 7, 17, 1)
    DllStructSetData($struct, 7, -1, 2)
    DllStructSetData($struct, 8, 'end')
    DllStructSetData($struct, 9, 2.7182818284590452353602874713527)
    DllStructSetData($struct, 10, 2.7182818284590452353602874713527)
    DllStructSetData($struct, 11, 107)
    DllStructSetData($struct, 12, -108)
    DllStructSetData($struct, 13, 109)
    DllStructSetData($struct, 14, 110)
    DllStructSetData($struct, 15, 111)
    DllStructSetData($struct, 16, 112)


    Local $f = _VarDump

    Local $c[2][0]
    Local $e = [[Null, Default], [__DumpStr, MsgBox]]
    Local Enum $p = 33333333333333
    Opt("WinTitleMatchMode", 2)
    Local $a[3][4] = [ _
    [$c, $e, ObjCreate("shell.application"), WinGetHandle("Dump.au3")], _
    ['zzz', 1/3, True, 0x123456], _
    [$struct, 93, Null, $p] _
    ]

    _ConsoleWrite('Test example of moderate complexity' & @LF & $f($a) & @LF)


    ;~ ; _VarCmp() test

    Local $a = [['', 0x123456], [1, "A", -2.0]], $b = [[0, Ptr(0x123456)], ["1", "a", -2]]
    Local $ret = _VarCmp($a, $b)
    ConsoleWrite("Method 1 : " & @error & ', ' & @extended  & ', ' & $ret & @LF)
    $ret = _VarCmp($a, $b, 2)
    ConsoleWrite("Method 2 : " & @error & ', ' & @extended  & ', ' & $ret & @LF)
    $ret = _VarCmp($a, $b, 4)
    ConsoleWrite("Method 4 : " & @error & ', ' & @extended  & ', ' & $ret & @LF)
    $ret = _VarCmp($a, $b, 8)
    ConsoleWrite("Method 8 : " & @error & ', ' & @extended  & ', ' & $ret & @LF)
    $ret = _VarCmp($a, $b, 15)
    ConsoleWrite("Method 15 : " & @error & ', ' & @extended  & ', ' & $ret & @LF)

    Local $m[], $n[]
    $m[25] = ObjCreate("shell.application")
    $n["grhjiop jpgr 25"] = ObjCreate("shell.application")
    $m["tghjnio"] = $n
    ConsoleWrite(_VarDump($m) & @LF)

#ce

 


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 here
RegExp tutorial: enough to get started
PCRE 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)

Share this post


Link to post
Share on other sites
c.haslam

jchd,

Most interesting! Thank you

It appears to me that you do not distinguish among types of pointer.

  • I would think that a hwnd is a handle of a window while handle is a non-window handle.
  • And then there are non-hwnd, non-handle pointers.
  • AutoIt cannot distinguish between hwnd and handle. Am I correct?

I also see that Map is back. I do not see it in the 3.3.15.0 History/Changelog. Anyway, welcome back, Map!


Spoiler

CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard

 

Share this post


Link to post
Share on other sites
jchd
11 hours ago, c.haslam said:

AutoIt cannot distinguish between hwnd and handle. Am I correct?

Yes IFAICT. All else is a 32- or 64-bit pointer, also AFAIK.

The term handle is widely used, as in "file handle". In fact I regard them as either an opaque reference (loose term) to an object (loose term) or a simple index in a table of known existing "things". Similarly, the term "pointer" is also vague, as in "file pointer". It's OS business not mine.

OTOH a memory pointer is a direct link to something in memory, hence much more fragile in the sense that basing a DllStruct on a random pointer then reading/writing there is most likely going to cause a program crash. Operating a window/control/file function on a random handle is harmless, just issues an non-fatal error.

A variable dump is mainly meant to display its actual content, interpretation of this content being left to the developper. Decorating this content with some user-friendly display is a comfortable luxury, compared to getting a Mb of monolithic hex core dump (like those I was taking hours to dissect in the early mainframe era). Regard _VarDump as a halfway between viewing a full PDF in some hex editor and viewing it thru a PDF display program.


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 here
RegExp tutorial: enough to get started
PCRE 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)

Share this post


Link to post
Share on other sites
c.haslam
6 hours ago, jchd said:

Regard _VarDump as a halfway between viewing a full PDF in some hex editor and viewing it thru a PDF display program.

 Understood. My objective is somewhat different from yours. When this all started, I already had my cDebug dumping array and nested arrays working AOK, to the Console. I then had trouble with DLL calls in GDI Plus. So I started to add structures to cDebug, helped greatly by your VarDump(). I am now working on comparison of user-specified tag and detected tag.

I remember dissecting hex core dumps a mainframe. I started programming for the IBM 650 mainframe, with 4K 36-bit words of drum memory.


Spoiler

CDebug Dumps values of variables including arrays and DLL structs, to a GUI, to the Console, and to the Clipboard

 

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now

×