Sign in to follow this  
Followers 0
Ascend4nt

_DLLStructDisplay - Show Struct in ListView

14 posts in this topic

#1 ·  Posted (edited)

_DLLStructDisplay

Posted Image

While working on debugging a project a while back, I was looking for better ways to debug the code. And voila, here it is.

Anyway, this function displays the contents of your DLLStruct's in a ListView format (placing the items in an array and utilizing _ArrayDisplay).

IMPORTANT: You must supply the string EXACTLY as it was used to set up the structure (although you can add descriptions after the datatypes if they aren't already there). The string requirement might seem like one more extra step, but without it the function wouldn't work (and you're debugging would be much harder).

The code is smart enough to split items into subitems (based on [#]'s found), and will display the description with {sub item #x}).

Also - the behaviour with GINORMOUS pieces of data is unknown - this is best used with smaller structures!

NOTE: One thing you might notice about structures is alignment has alot to do with where items are placed in the structure. The default is '8', which means that everything is aligned on a boundary equally divisible by itself (char being 1 byte is aligned anywhere, int's being 4 bytes, are aligned on offsets divisible by 4, double's and int64's both are aligned on offsets equally divisible by 8)

HOWEVER: a prefix of 'align ##' can change this behavior so that the data can be 'misaligned' so to speak, to the specified alignment # (see AutoIT Help info for DLLStructCreate)

Update Log:

5/27/2011: Small fixes, ability to use multiple 'align' directives

Fixed: initial 'align (##);' check code failed in certain circumstances (align on its own, spaces after #)

Fixed: 'char' & 'byte' can now be part of description of all array objects

Added/Fixed: 'align (##);' can now appear anywhere in a structure, now properly handled (extra ones are reported in display)

5/26/2011: Updated to new structure alignment directives (as of AutoIt v3.3.7.2beta)

Added: Structure size information, End-of-Structure Padding Info

Added: Struct/EndStruct support, these show up in list with C-style curly braces { };

3/18/2010: Updated to all new supported types as of AutoIT v3.3.6.0

Added: Index, Offset, Size Columns, Base Pointer & Alignment Type info (in Title Bar and in 'Offset' column)

Fixed: subitem listings, items with labels, alignment override being read as a type, subitem offsets, fixed case-sensitivity

Adjusted: stripped unnecessary whitespace, added options to display Strings (char[#]/wchar[#]) and Binary string data (ubyte[#],byte[#]) as one concatenated string

Download the ZIP Here

Ascend4nt's AutoIT Code License agreement:

While I provide this source code freely, if you do use the code in your projects, all I ask is that:

  • If you provide source, keep the header as I have put it, OR, if you expand it, then at least acknowledge me as the original author, and any other authors I credit
  • If the program is released, acknowledge me in your credits (it doesn't have to state which functions came from me, though again if the source is provided - see #1)
  • The source on it's own (as opposed to part of a project) can not be posted unless a link to the page(s) where the code were retrieved from is provided and a message stating that the latest updates will be available on the page(s) linked to.
  • Pieces of the code can however be discussed on the threads where Ascend4nt has posted the code without worrying about further linking.
Edited by Ascend4nt

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Heh I made something similar for a long time ago, forgot to post it :(

Anyways, it looks good & useful. However my thoughts:

  • Using for example "align 2;" should not show up as a data type
  • Possible trailing and leading spaces should be removed, it looks funny in the listview.
  • Definitely needs to display the pointer to the struct somewhere, this will serve as a double purpose since it will display '0' of the struct is invalid
  • Maybe show arrays of type byte/char/wchar in binary/string in a single listview element?
Other than that it works fine >_<

Edit:

To calculate correct offset you can use DllStructGetPtr() with the element paramater. Array elements will always be placed next to eachother in the array.

Edited by monoceres

Broken link? PM me and I'll send you the file!

Share this post


Link to post
Share on other sites

Excellent learning tool.

I must say thank you, I have learned a lot from your code over the months.

I now understand things I never even learnt.

Share this post


Link to post
Share on other sites

@Monoceres: Thanks for the ideas - I will implement some of them, maybe some as bool parameters. As for calculating the offset, I had tried to use an element index, but then found out there's only a pointer to the element (so pointers to individual items in [#] can't be gotten).

I'm going to just use a type-size translation array or even a string with StringRegExp to see which would be faster to get the actual size of each item (hmm..gotta take into account size differences with @AutoItX64)

@dmob: Thanks for the compliment >_< , I'm glad I've been of help.

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Updated! Hopefully this satisfies the needs of most. (This also fixes some issues). Changes (since last time):

Fixes:

  • Fixed items with label descriptions
  • Fixed alignment-override being read as a data-type
  • Fixed subitem offset info
Additions:

  • Added DLL Struct 'Base pointer' info (in Title bar & 'Offset' column description)
  • Added Alignment info (in Title bar & 'Offset' column description)
  • Stripped whitespace from Struct Type/descriptions (except where needed for Labels and subitem info)
  • Added parameter option to display multi-character strings (char[#]/wchar[#]) as one concatenated string (default behavior)
  • Added parameter option to display multi-byte Binary strings (ubyte[#],byte[#]) as one concatenated string (not default behavior)
  • *edit* Also added 'Size' column (which is also properly adjusted for x86 or x64 mode)
Anyways, have a look. Hopefully this should make everyone happy. >_<

Edited by Ascend4nt

Share this post


Link to post
Share on other sites

Okay, last change (I hope!). I've added an 'Index' column, because those sub-items can make it a bit confusing if you're trying to remember which index to use as the base index into the Structure. (the sub-item # is the sub-index)

Th-th-th-thats all >_<

Share this post


Link to post
Share on other sites

Excellent! Very useful thing.

Was missing it and also was too lazy to write it and I knew some day someone would and I'll just say thanks.

So, thanks.

Btw, I see you don't use Opt("MustDeclareVars", 1). Everyone should. And tidy.exe, and #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 4 -w 5 -w 6 and ...actually nothing more >_<


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

Excellent! Very useful thing.

Was missing it and also was too lazy to write it and I knew some day someone would and I'll just say thanks.

So, thanks.

You're welcome :( Now someone should create a tool to test, mess around with, and create your own DLLStructs.

:( erm, hey, why are you looking at me. I'm not a GUI guy da*it!

*walks off mumbling about too many projects on my mind* >_<

Share this post


Link to post
Share on other sites

I'm back. Code has been updated, latest edit:

*edits: 3/18/2010: Updated to all new supported types as of AutoIT v3.3.6.0

Share this post


Link to post
Share on other sites

New updates (works with latest beta changes!):

5/26/2011: Updated to new structure alignment directives (as of AutoIt v3.3.7.2beta)

Added: Structure size information, End-of-Structure Padding Info

Added: Struct/EndStruct support, these show up in list with C-style curly braces { };

Share this post


Link to post
Share on other sites

Updated again. Didn't know about the ability to use multiple 'align' directives in a structure, now I do! So here's a version that works with those structures (plus a bugfix or 2):

5/27/2011: Small fixes, ability to use multiple 'align' directives

Fixed: initial 'align (##);' check code failed in certain circumstances (align on its own, spaces after #)

Fixed: 'char' & 'byte' can now be part of description of all array objects

Added/Fixed: 'align (##);' can now appear anywhere in a structure, now properly handled (extra ones are reported in display)

Share this post


Link to post
Share on other sites

I have changed for my personal use:

113 ; $aStDisplay[0][0]="Index"
114 ; $aStDisplay[0][1]="DLL Struct Type + Description (optional)"
115 ; $aStDisplay[0][2]="Value"
116 ; $aStDisplay[0][3]="Offset [Base Ptr="&$iBaseAddress&", Alignment="&$iAlign&" [Base], Size="&$iStrSize&']'
117 ; $aStDisplay[0][4]="Size [Total="&$iStrSize&']'
118
119 $iDispIndex=0
...
224  _ArrayDisplay($aStDisplay,"DLLStruct"&$sStructName&" Contents [Base Ptr="&$iBaseAddress&", Alignment="&$iAlign&", Size="&$iStrSize&']',-1,0,"","|", _
225  "Row|Index|DLL Struct Type + Description (optional)|Value|Offset [Base Ptr="&$iBaseAddress&", Alignment="&$iAlign&" [Base], Size="&$iStrSize&"]|Size [Total="&$iStrSize&']')

AutoIt-Syntaxsheme for Proton & Phase5 * Firefox Addons by me (resizable Textarea 0.1d) (docked JS-Console 0.1.1)

Share this post


Link to post
Share on other sites

Return=False
@Error=0

@Extended=0

using it to read $tSTARTUPINFO struct from the RunBiinary UDF from trancexx

 


What is what? What is what.

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
Sign in to follow this  
Followers 0

  • Similar Content

    • careca
      By careca
      Hi, having an issue with an application i did, seems to crash randomly, and can take hours to do so.
      Simply says in the error msgbox:
      AutoIt Error
      Line 16392 (whatevermyapppath.exe)
      Error: The requested action with this object has failed.
       
      Recent changes to the script include this:
       
      ObjGet("winmgmts:\\localhost\root\CIMV2") $oSelect_active_network_cards = $objWMIService.ExecQuery('SELECT ProductName FROM Win32_NetworkAdapter WHERE NetConnectionStatus = 2 OR NetConnectionStatus = 9', "WQL") For $oSelect_active_network_card In $oSelect_active_network_cards $Adapter = $oSelect_active_network_card.ProductName Next Is the only thing i can see that can be related to an "object"
      This lines run only once at the top of the script.
      When i run the script itself and wait for a crash, it doesn't, or at least yet i didn't.
      What do you think this error could be?
      UPDATE: Runing the script eventually output this:
      "C:\script.au3" (894) : ==> The requested action with this object has failed.:
      $oNetwork_cards = $objWMIService.ExecQuery('SELECT BytesReceivedPerSec, BytesSentPerSec FROM Win32_PerfFormattedData_Tcpip_NetworkInterface WHERE name LIKE "' & $Adapter & '"', "WQL")
      $oNetwork_cards = $objWMIService^ ERROR
    • nacerbaaziz
      By nacerbaaziz
      Hi dear
      I have a question
      about the display language of the system
      How can I get the current display language and how can I change it by autoit
      Of course, if this is possible
      Greetings to all and hope you help me
    • Stormgrade
      By Stormgrade
      Hello,
      I want to use the "_ChangeScreenResEx()" UDF for changing my display settings from 1680*1050 to 1280*800.
      When I use it the display change to 1280*800 but with Intel Drivers, Scaling option change : Maintain display Scaling become Center Image.

      Here my Main program
      #include <.\_ChangeResolutionEx.au3> Global $Config = @ScriptDir & "\ChangeResolution.ini" Global $aSection = IniReadSectionNames($Config) Global $Moniteur,$Largeur,$Hauteur,$Profondeur,$Refresh for $i = 1 to $aSection[0] Step 1 $Moniteur = Number($i) $Largeur = Number(IniRead($Config,$i,"Width","1680")) $Hauteur = Number(IniRead($Config,$i,"Height","1050")) $Profondeur = Number(IniRead($Config,$i,"Bits","32")) $Refresh = Number(IniRead($Config,$i,"Refresh","60")) _ChangeScreenResEx($Moniteur,$Largeur,$Hauteur,$Profondeur,$Refresh) Sleep(1000) Next  _ChangeScreenResEx()
      #include-once ;=============================================================================== ; Function Name: _ChangeScreenResEx() ; Description: Changes the current screen geometry, colour and refresh rate. ; Version: 1.0.0.0 ; Parameter(s): $i_DisplayNum - Display to change, starting at 1 ; $i_Width - Width of the desktop screen in pixels. (horizontal resolution) ; $i_Height - Height of the desktop screen in pixels. (vertical resolution) ; $i_BitsPP - Depth of the desktop screen in bits per pixel. ; $i_RefreshRate - Refresh rate of the desktop screen in hertz. ; Requirement(s): AutoIt Beta > 3.1 ; Return Value(s): On Success - Screen is adjusted, @ERROR = 0 ; On Failure - sets @ERROR = 1 ; Forum(s): ; Author(s): Original code - psandu.ro, PartyPooper ; Modifications - bobchernow ;=============================================================================== Func _ChangeScreenResEx($i_DisplayNum = 1, $i_Width = @DesktopWidth, $i_Height = @DesktopHeight, $i_BitsPP = @DesktopDepth, $i_RefreshRate = @DesktopRefresh) Local Const $DM_PELSWIDTH = 0x00080000 Local Const $DM_PELSHEIGHT = 0x00100000 Local Const $DM_BITSPERPEL = 0x00040000 Local Const $DM_DISPLAYFREQUENCY = 0x00400000 Local Const $CDS_TEST = 0x00000002 Local Const $CDS_UPDATEREGISTRY = 0x00000001 Local Const $DISP_CHANGE_RESTART = 1 Local Const $DISP_CHANGE_SUCCESSFUL = 0 Local Const $HWND_BROADCAST = 0xffff Local Const $WM_DISPLAYCHANGE = 0x007E If $i_Width = "" Or $i_Width = -1 Then $i_Width = @DesktopWidth; default to current setting If $i_Height = "" Or $i_Height = -1 Then $i_Height = @DesktopHeight; default to current setting If $i_BitsPP = "" Or $i_BitsPP = -1 Then $i_BitsPP = @DesktopDepth; default to current setting If $i_RefreshRate = "" Or $i_RefreshRate = -1 Then $i_RefreshRate = @DesktopRefresh; default to current setting Local $DEVMODE = DllStructCreate("byte[32];int[10];byte[32];int[6]") Local $s_Display $s_Display = "\\.\Display" & $i_DisplayNum Local $B = DllCall("user32.dll", "int", "EnumDisplaySettings", "ptr", 0, "int", 0, "ptr", DllStructGetPtr($DEVMODE)) If @error Then $B = 0 SetError(1) Return $B Else $B = $B[0] EndIf If $B <> 0 Then DllStructSetData($DEVMODE, 2, BitOR($DM_PELSWIDTH, $DM_PELSHEIGHT, $DM_BITSPERPEL, $DM_DISPLAYFREQUENCY), 5) DllStructSetData($DEVMODE, 4, $i_Width, 2) DllStructSetData($DEVMODE, 4, $i_Height, 3) DllStructSetData($DEVMODE, 4, $i_BitsPP, 1) DllStructSetData($DEVMODE, 4, $i_RefreshRate, 5) $B = DllCall("user32.dll", "int", "ChangeDisplaySettingsEx","str", $s_Display, "ptr", DllStructGetPtr($DEVMODE), "hwnd", 0, "dword", $CDS_TEST, "lparam", 0) If @error Then $B = -1 Else $B = $B[0] EndIf Select Case $B = $DISP_CHANGE_RESTART $DEVMODE = "" Return 2 Case $B = $DISP_CHANGE_SUCCESSFUL DllCall("user32.dll", "int", "ChangeDisplaySettingsEx","str", $s_Display, "ptr", DllStructGetPtr($DEVMODE), "hwnd", 0, "dword", $CDS_UPDATEREGISTRY, "lparam", 0) DllCall("user32.dll", "int", "SendMessage", "hwnd", $HWND_BROADCAST, "int", $WM_DISPLAYCHANGE, _ "int", $i_BitsPP, "int", $i_Height * 2 ^ 16 + $i_Width) $DEVMODE = "" Return 1 Case Else $DEVMODE = "" SetError(1) Return $B EndSelect EndIf EndFunc;==>_ChangeScreenResEx Any idea how to get around this problem ?
      thanks for your answer.
    • Leo1906
      By Leo1906
      Hello Guys,
      once aggain I need your help on a DLL Topic
      I need to pass arguments to my function via a structure, because I am limited to only one argument that can be passed.
      But I don't think that thats so important.
      So here's my approach:
      C++ Code (just the important part):
      extern "C" { struct ParamStruct { const char* test1; const char* test2; const char* test3; int size; }; int testFunc(struct ParamStruct * params) { return params->size; } } And thats how I try to call the function using Autoit:
      Local $struct = "struct;char shapefile[128];char output[128];char filename[128];int size;endstruct" Local $tTest = DllStructCreate($struct) DllStructSetData($tTest, "test1", "Bla") DllStructSetData($tTest, "test2", "BlaBla") DllStructSetData($tTest, "test3", "BlaBlaBla") DllStructSetData($tTest, "size", 40) $dll = DLLOpen("myDLL.dll") $ret = DllCall($dll, "int:cdecl", "testFunc", "STRUCT*", DllStructGetPtr($tTest)) MsgBox(0, 0, $ret[0]) DllClose($dll) Just for testing I want the function to just return the integer value in the struct.
      But this aint working. I tested many things, but still I'm not able to get it running. I even don't know if the mistakes are in the C++ code or the Autoit code or both .. I'm not that skilled at C++ and also not that skilled at Autoit DLLCalls :-/
      I would really appreciate some help!
      Kind regards,
      leo
    • FrancescoDiMuro
      By FrancescoDiMuro
      Hi guys! How are you? Hope you're fine
      I'm trying to use SQLite for managing some data, and, I would like to display my "retrieved" data, but I'm trying to do a select from 2 table, and seems to not work properly...
      What I'd like to do is retrieve data from 2 tables and display in a listview...
      I tried with:
      Local $aRisultato, $iRighe, $iColonne, $iRVal $iRval = _SQLite_GetTable2d($hDatabase, "SELECT * FROM Magazzino_Rockwell, Magazzino_Siemens;", $aRisultato, $iRighe, $iColonne) If $iRVal = $SQLITE_OK Then ;_SQLite_Display2DResult($aRisultato) _ArrayDisplay($aRisultato) EndIf ... but it displays a single record 41 times, and it does this thing for every record in the database...
      What do you need to help me?
      Thanks  

      EDIT:
      Managed with a double If and double query like this:
       
      $iRval = _SQLite_GetTable2d($hDatabase, "SELECT * FROM Magazzino_Rockwell;", $aRisultato, $iRighe, $iColonne) If $iRVal = $SQLITE_OK Then Local $aRisultatoRockwell = $aRisultato $iRval = _SQLite_GetTable2d($hDatabase, "SELECT * FROM Magazzino_Siemens;", $aRisultato, $iRighe, $iColonne) If $iRVal = $SQLITE_OK Then _ArrayConcatenate($aRisultato, $aRisultatoRockwell) Local $i, $sRiga, $s_LV_Item For $i = 1 To Ubound($aRisultato) - 1 $sRiga = $aRisultato[$i][0] & "|" & _ $aRisultato[$i][1] & "|" & _ $aRisultato[$i][2] & "|" & _ $aRisultato[$i][3] & "|" & _ $aRisultato[$i][4] & "|" & _ $aRisultato[$i][5] & "|" & _ $aRisultato[$i][6] & "|" & _ $aRisultato[$i][7] & "|" & _ $aRisultato[$i][8] & "|" & _ $aRisultato[$i][9] & "|" & _ $aRisultato[$i][10] & "|" & _ $aRisultato[$i][11] $s_LV_Item = GUICtrlCreateListViewItem($sRiga, $lv_Lista) Next And so, the listview is created
      If anyone has another more efficient way, I'm here Thanks guys