Jump to content

Recommended Posts

Posted (edited)

The idea is to be able to share information in the forum when a struct data needs to be shared among us.
As an example, lets say that we wanna share what comes out of $tagOSVERSIONINFOEX. We could just run:

#include <WinAPIMisc.au3>
#include <WinAPIDiag.au3>
#include <Debug.au3>
#include <Sqlite.au3>
Exit GetOs()
Func GetOs()
    Local $tOSVERSIONINFOEX = DllStructCreate($tagOSVERSIONINFOEX)
    DllStructSetData($tOSVERSIONINFOEX, 1, DllStructGetSize($tOSVERSIONINFOEX))

    Local $aCall = DllCall('kernel32.dll', 'bool', 'GetVersionExW', 'struct*', $tOSVERSIONINFOEX)
    If @error Or Not $aCall[0] Then Return SetError(@error, @extended, 0)

    Local $aArray = _WinAPI_DisplayStruct_mod($tOSVERSIONINFOEX, $tagOSVERSIONINFOEX, '', 0, 0, 0, True, 0, 1)

    Local $sText = _SQLite_Display2DResult($aArray, 0, True)
    ConsoleWrite(@CRLF & $sText & @CRLF & @CRLF)

    ; for those outside the editor
    Local $iW = 600, $iH = 300, $hGui = GUICreate(@ScriptName, $iW, $iH)
    GUISetFont(10, 400, 0, "Terminal")
    Local $idEdit = GUICtrlCreateEdit($sText, 0, 0, $iW, $iH)
    GUISetState()
    While GUIGetMsg() <> -3
    WEnd
    GUIDelete($hGui)
EndFunc   ;==>GetOs
... ...

and share the text that comes out:

-   -                  0x0125DC18  <struct>     0    -     
 1   OSVersionInfoSize  0           DWORD        4    284   
 2   MajorVersion       4           DWORD        4    10    
 3   MinorVersion       8           DWORD        4    0     
 4   BuildNumber        12          DWORD        4    22631 
 5   PlatformId         16          DWORD        4    2     
 6   CSDVersion         20          WCHAR[128]   256        
 7   ServicePackMajor   276         USHORT       2    0     
 8   ServicePackMinor   278         USHORT       2    0     
 9   SuiteMask          280         USHORT       2    256   
 10  ProductType        282         BYTE         1    1     
 11  Reserved           283         BYTE         1    -     
 -   -                  0x0125DD34  <endstruct>  284  -

So the mod. I made to _WinAPI_DisplayStruct() is here ( with the complete running example from above )

Spoiler
#include <WinAPIMisc.au3>
#include <WinAPIDiag.au3>
#include <Debug.au3>
#include <Sqlite.au3>
Exit GetOs()
Func GetOs()
    Local $tOSVERSIONINFOEX = DllStructCreate($tagOSVERSIONINFOEX)
    DllStructSetData($tOSVERSIONINFOEX, 1, DllStructGetSize($tOSVERSIONINFOEX))

    Local $aCall = DllCall('kernel32.dll', 'bool', 'GetVersionExW', 'struct*', $tOSVERSIONINFOEX)
    If @error Or Not $aCall[0] Then Return SetError(@error, @extended, 0)

    Local $aArray = _WinAPI_DisplayStruct_mod($tOSVERSIONINFOEX, $tagOSVERSIONINFOEX, '', 0, 0, 0, True, 0, 1)

    Local $sText = _SQLite_Display2DResult($aArray, 0, True)
    ConsoleWrite(@CRLF & $sText & @CRLF & @CRLF)

    ; for those outside the editor
    Local $iW = 600, $iH = 300, $hGui = GUICreate(@ScriptName, $iW, $iH)
    GUISetFont(10, 400, 0, "Terminal")
    Local $idEdit = GUICtrlCreateEdit($sText, 0, 0, $iW, $iH)
    GUISetState()
    While GUIGetMsg() <> -3
    WEnd
    GUIDelete($hGui)
EndFunc   ;==>GetOs

Func __WinAPI_DisplayStruct_GetArray()
    Local $sTitle = "[TITLE:Structure: ListView Display;CLASS:AutoIt v3 GUI;]"
    Local $iItemCount = ControlListView($sTitle, "", "[CLASS:SysListView32; INSTANCE:1]", "GetItemCount")
    Local $iSubItemCount = ControlListView($sTitle, "", "[CLASS:SysListView32; INSTANCE:1]", "GetSubItemCount")
    Local $aArray[$iItemCount][$iSubItemCount]
    For $n = 0 To UBound($aArray, 1) - 1
        For $m = 0 To UBound($aArray, 2) - 1
            $aArray[$n][$m] = ControlListView($sTitle, "", "[CLASS:SysListView32; INSTANCE:1]", "GetText", $n, $m)
        Next
    Next
    Return $aArray
EndFunc   ;==>__WinAPI_DisplayStruct_GetArray

; #FUNCTION# ====================================================================================================================
; Author.........: Yashied
; Modified.......: jpm, "argumentum's mod to return an array"
; ===============================================================================================================================
Func _WinAPI_DisplayStruct_mod($tStruct, $sStruct = '', $sTitle = '', $iItem = 0, $iSubItem = 0, $iFlags = 0, $bTop = True, $hParent = 0, $iRetArray = 0)
    If Not StringStripWS($sTitle, $STR_STRIPLEADING + $STR_STRIPTRAILING) Then
        $sTitle = 'Structure: ListView Display'
    EndIf
    $sStruct = StringRegExpReplace(StringStripWS($sStruct, $STR_STRIPLEADING + $STR_STRIPTRAILING + $STR_STRIPSPACES), ';+\Z', '')
    Local $pData, $aArray
    If IsDllStruct($tStruct) Then
        $pData = DllStructGetPtr($tStruct)
        If Not $sStruct Then
            $sStruct = 'byte[' & DllStructGetSize($tStruct) & ']'
            $iFlags = BitOR($iFlags, 64)
        EndIf
    Else
        $pData = $tStruct
        If Not $sStruct Then Return SetError(10, 0, 0)
    EndIf
    Local $tData = DllStructCreate($sStruct, $pData)

    Local $iData = DllStructGetSize($tData)
    If (Not BitAND($iFlags, 512)) And (_WinAPI_IsBadReadPtr($pData, $iData)) Then
        If Not BitAND($iFlags, 256) Then
            MsgBox($MB_SYSTEMMODAL, $sTitle, 'The memory range allocated to a given structure could not be read.' & _
                    @CRLF & @CRLF & Ptr($pData) & ' - ' & Ptr($pData + $iData - 1) & _
                    @CRLF & @CRLF & 'Press OK to exit.')
            Exit -1073741819
        EndIf
        Return SetError(15, 0, 0)
    EndIf

    Local $sOpt1 = Opt('GUIDataSeparatorChar', '|')
    Local $iOpt2 = Opt('GUIOnEventMode', 0)
    Local $iOpt3 = Opt('GUICloseOnESC', 1)

    If $hParent Then
        GUISetState(@SW_DISABLE, $hParent)
    EndIf
    Local $iStyle = 0x00000001
    If $bTop Then
        $iStyle = BitOR($iStyle, 0x00000008)
    EndIf
    $__g_hFRDlg = GUICreate($sTitle, 570, 620, -1, -1, 0x80C70000, $iStyle, $hParent)
    Local $idLV = GUICtrlCreateListView('#|Member|Offset|Type|Size|Value', 0, 0, 570, 620, 0x0000800D, ((_WinAPI_GetVersion() < 6.0) ? 0x00010031 : 0x00010030))
    Local $hLV = GUICtrlGetHandle($idLV)
    If _WinAPI_GetVersion() >= 6.0 Then
        _WinAPI_SetWindowTheme($hLV, 'Explorer')
    EndIf
    GUICtrlSetResizing(-1, 0x0066)
    GUICtrlSetFont(-1, 8.5, 400, 0, 'Tahoma')
    GUICtrlSetState(-1, 0x0100)
    Local $aVal[101] = [0]
    If Not BitAND($iFlags, 1) Then
        __Inc($aVal)
        $aVal[$aVal[0]] = ''
        GUICtrlCreateListViewItem('-|-|' & $pData & '|<struct>|0|-', $idLV)
        GUICtrlSetColor(-1, 0x9C9C9C)
    EndIf
    Local $aData = StringSplit($sStruct, ';')
    Local $aItem, $vItem, $sItem, $iMode, $iIndex, $iCount = 0, $iPrev = 0
    Local $aSel[2] = [0, 0]
    Local $aType[28][2] = _
            [['BYTE', 1], _
            ['BOOLEAN', 1], _
            ['CHAR', 1], _
            ['WCHAR', 2], _
            ['short', 2], _
            ['USHORT', 2], _
            ['WORD', 2], _
            ['int', 4], _
            ['long', 4], _
            ['BOOL', 4], _
            ['UINT', 4], _
            ['ULONG', 4], _
            ['DWORD', 4], _
            ['INT64', 8], _
            ['UINT64', 8], _
            ['ptr', (@AutoItX64 ? 8 : 4)], _
            ['HWND', (@AutoItX64 ? 8 : 4)], _
            ['HANDLE', (@AutoItX64 ? 8 : 4)], _
            ['float', 4], _
            ['double', 8], _
            ['INT_PTR', (@AutoItX64 ? 8 : 4)], _
            ['LONG_PTR', (@AutoItX64 ? 8 : 4)], _
            ['LRESULT', (@AutoItX64 ? 8 : 4)], _
            ['LPARAM', (@AutoItX64 ? 8 : 4)], _
            ['UINT_PTR', (@AutoItX64 ? 8 : 4)], _
            ['ULONG_PTR', (@AutoItX64 ? 8 : 4)], _
            ['DWORD_PTR', (@AutoItX64 ? 8 : 4)], _
            ['WPARAM', (@AutoItX64 ? 8 : 4)]]

    For $i = 1 To $aData[0]
        $aItem = StringSplit(StringStripWS($aData[$i], $STR_STRIPLEADING + $STR_STRIPTRAILING), ' ')
        Switch $aItem[1]
            Case 'ALIGN', 'STRUCT', 'ENDSTRUCT'
                ContinueLoop
            Case Else

        EndSwitch
        $iCount += 1
        $iMode = 1
        $sItem = $iCount & '|'
        If $aItem[0] > 1 Then
            $vItem = StringRegExpReplace($aItem[2], '\[.*\Z', '')
            $sItem &= $vItem & '|'
            If (Not BitAND($iFlags, 16)) And (Not StringCompare(StringRegExpReplace($vItem, '[0-9]+\Z', ''), 'RESERVED')) Then
                $iMode = 0
            EndIf
            If Not IsString($iItem) Then
                $vItem = $iCount
            EndIf
            $iIndex = 2
        Else
            If Not BitAND($iFlags, 4) Then
                $sItem &= '<unnamed>|'
            Else
                $sItem &= '|'
            EndIf
            If Not IsString($iItem) Then
                $vItem = $iCount
            Else
                $vItem = 0
            EndIf
            $iIndex = 1
        EndIf
        If (Not $aSel[0]) And ($vItem) And ($iItem) And ($vItem = $iItem) Then
            $aSel[0] = $iCount
        EndIf
        Local $iOffset = Number(DllStructGetPtr($tData, $iCount) - $pData)
        $iIndex = StringRegExp($aItem[$iIndex], '\[(\d+)\]', $STR_REGEXPARRAYGLOBALMATCH)
        Local $iSize
        Do
            ReDim $aItem[3]
            $vItem = StringRegExpReplace($aItem[1], '\[.*\Z', '')
            For $j = 0 To UBound($aType) - 1
                If Not StringCompare($aType[$j][0], $vItem) Then
                    $aItem[1] = $aType[$j][0]
                    $aItem[2] = $aType[$j][1]
                    $iSize = $aItem[2]
                    ExitLoop 2
                EndIf
            Next
            $aItem[1] = '?'
            $aItem[2] = '?'
            $iSize = 0
        Until 1
        $sItem &= $iOffset & '|'
        If (IsArray($iIndex)) And ($iIndex[0] > '1') Then
            If $iSize Then
                $aItem[2] = $aItem[2] * $iIndex[0]
            EndIf
            Do
                Switch $aItem[1]
                    Case 'BYTE', 'BOOLEAN'
                        If Not BitAND($iFlags, 64) Then
                            ContinueCase
                        EndIf
                    Case 'CHAR', 'WCHAR'
                        $sItem &= $aItem[1] & '[' & $iIndex[0] & ']|' & $aItem[2] & '|'
                        $iIndex = 0
                        ExitLoop
                    Case Else

                EndSwitch
                If ($iSize) And ($iMode) Then
                    $sItem &= $aItem[1] & '[' & $iIndex[0] & ']|' & $aItem[2] & ' (' & $iSize & ')' & '|'
                Else
                    $sItem &= $aItem[1] & '[' & $iIndex[0] & ']|' & $aItem[2] & '|'
                EndIf
                If $iMode Then
                    $iIndex = $iIndex[0]
                Else
                    $iIndex = 0
                EndIf
            Until 1
        Else
            $sItem &= $aItem[1] & '|' & $aItem[2] & '|'
            $iIndex = 0
        EndIf
        If (Not BitAND($iFlags, 2)) And ($iPrev) And ($iOffset > $iPrev) Then
            __Inc($aVal)
            $aVal[$aVal[0]] = ''
            GUICtrlCreateListViewItem('-|-|-|<alignment>|' & ($iOffset - $iPrev) & '|-', $idLV)
            GUICtrlSetColor(-1, 0xFF0000)
        EndIf
        If $iSize Then
            $iPrev = $iOffset + $aItem[2]
        Else
            $iPrev = 0
        EndIf
        Local $idLVItem, $idInit
        If $iIndex Then
            Local $sPattern = '[%0' & StringLen($iIndex) & 'd] '
            For $j = 1 To $iIndex
                __Inc($aVal)
                $aVal[$aVal[0]] = DllStructGetData($tData, $iCount, $j)
                If BitAND($iFlags, 128) Then
                    $aVal[$aVal[0]] = __WinAPIDiag_Hex($aVal[$aVal[0]], $aItem[1])
                EndIf
                $idLVItem = GUICtrlCreateListViewItem($sItem & StringFormat($sPattern, $j) & $aVal[$aVal[0]], $idLV)
                If ($aSel[0] = $iCount) And (Not $aSel[1]) Then
                    If ($iSubItem < 1) Or ($iSubItem > $iIndex) Or ($iSubItem = $j) Then
                        $aSel[1] = $idLVItem
                    EndIf
                EndIf
                If (Not $idInit) And ($iCount = 1) Then
                    $idInit = $idLVItem
                EndIf
                If Not BitAND($iFlags, 8) Then
                    GUICtrlSetBkColor(-1, 0xF5F5F5)
                EndIf
                If $iSize Then
                    $sItem = '-|-|' & ($iOffset + $j * $iSize) & '|-|-|'
                Else
                    GUICtrlSetColor(-1, 0xFF8800)
                    $sItem = '-|-|-|-|-|'
                EndIf
            Next
        Else
            __Inc($aVal)
            If $iMode Then
                $aVal[$aVal[0]] = DllStructGetData($tData, $iCount)
                If BitAND($iFlags, 128) Then
                    $aVal[$aVal[0]] = __WinAPIDiag_Hex($aVal[$aVal[0]], $aItem[1])
                EndIf
                $idLVItem = GUICtrlCreateListViewItem($sItem & $aVal[$aVal[0]], $idLV)
            Else
                $aVal[$aVal[0]] = ''
                $idLVItem = GUICtrlCreateListViewItem($sItem & '-', $idLV)
            EndIf
            If ($aSel[0] = $iCount) And (Not $aSel[1]) Then
                $aSel[1] = $idLVItem
            EndIf
            If (Not $idInit) And ($iCount = 1) Then
                $idInit = $idLVItem
            EndIf
            If Not $iSize Then
                GUICtrlSetColor(-1, 0xFF8800)
            EndIf
        EndIf
        If (Not BitAND($iFlags, 2)) And (Not $iSize) Then
            __Inc($aVal)
            $aVal[$aVal[0]] = ''
            GUICtrlCreateListViewItem('-|-|-|<alignment>|?|-', $idLV)
            GUICtrlSetColor(-1, 0xFF8800)
        EndIf
    Next
    If (Not BitAND($iFlags, 2)) And ($iPrev) And ($iData > $iPrev) Then
        __Inc($aVal)
        $aVal[$aVal[0]] = ''
        GUICtrlCreateListViewItem('-|-|-|<alignment>|' & ($iData - $iPrev) & '|-', $idLV)
        GUICtrlSetColor(-1, 0xFF0000)
    EndIf
    If Not BitAND($iFlags, 1) Then
        __Inc($aVal)
        $aVal[$aVal[0]] = ''
        GUICtrlCreateListViewItem('-|-|' & ($pData + $iData - 0) & '|<endstruct>|' & $iData & '|-', $idLV)
        GUICtrlSetColor(-1, 0x9C9C9C)
    EndIf
    If $aSel[1] Then
        GUICtrlSetState($aSel[1], 0x0100)
    Else
        GUICtrlSetState($idInit, 0x0100)
    EndIf
    Local $idDummy = GUICtrlCreateDummy()
    Local $aWidth[6] = [30, 130, 76, 100, 50, 167]
    For $i = 0 To UBound($aWidth) - 1
        GUICtrlSendMsg($idLV, 0x101E, $i, $aWidth[$i])
    Next
    Local $tParam = DllStructCreate('ptr;uint')
    DllStructSetData($tParam, 1, $hLV)
    If Not BitAND($iFlags, 32) Then
        DllStructSetData($tParam, 2, $idDummy)
    Else
        DllStructSetData($tParam, 2, 0)
    EndIf
    $__g_hFRDll = DllCallbackRegister('__DlgSubclassProc', 'lresult', 'hwnd;uint;wparam;lparam;uint;ptr')
    Local $pDll = DllCallbackGetPtr($__g_hFRDll)
    If _WinAPI_SetWindowSubclass($__g_hFRDlg, $pDll, 1000, DllStructGetPtr($tParam)) Then
        OnAutoItExitRegister('__WinAPIDiag_Quit')
    Else
        DllCallbackFree($__g_hFRDll)
        $__g_hFRDll = 0
    EndIf
    If $iRetArray Then ; mod
        $aArray = __WinAPI_DisplayStruct_GetArray()
    Else
        GUISetState()
        While 1
            Switch GUIGetMsg()
                Case 0
                    ContinueLoop
                Case -3
                    ExitLoop
                Case $idDummy
                    $iIndex = GUICtrlRead($idDummy)
                    If ($iIndex >= 0) And ($iIndex < $aVal[0]) Then
                        ClipPut($aVal[$iIndex + 1])
                    EndIf
            EndSwitch
        WEnd
    EndIf
    If $__g_hFRDll Then
        OnAutoItExitUnRegister('__WinAPIDiag_Quit')
    EndIf
    __WinAPIDiag_Quit()
    If $hParent Then
        GUISetState(@SW_ENABLE, $hParent)
    EndIf
    GUIDelete($__g_hFRDlg)
    Opt('GUIDataSeparatorChar', $sOpt1)
    Opt('GUIOnEventMode', $iOpt2)
    Opt('GUICloseOnESC', $iOpt3)

    Return ($iRetArray ? $aArray : 1)
EndFunc   ;==>_WinAPI_DisplayStruct_mod

 

This way is easier to share such.
I know this is a lazy way to do it but, is a fast mod. and does what is needed to get the data as text.

Edited by argumentum

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...