Jump to content

Get string from pointer to memory [Solved]


 Share

Recommended Posts

I am using _GuiCtrlTreeview_SetItemParam() to store a string associated with a treeview item. (I am not calling GuiCtrlCreateTreeViewItem partly because this function stores the control ID of the item there.) Because $iParam is an lparam, I actually call _WinAPI_CreateString() and then store the pointer it returns by calling _GuiCtrlTreeview_SetItemParam().

Now my question: in my case, _GuiCtrlTreeview_GetItemParam(0 returns a pointer. How can I get the string from the pointer?

Or is there a simpler way?

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

 

Link to comment
Share on other sites

Thanks, but ...

I will have many of strings of various lengths, and I don't want to have to track them, so how do I get the length of each string?

Spoiler

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

 

Link to comment
Share on other sites

you can try this:

$hDLL = DllOpen("c:\windows\system32\msvcrt.dll")

$aRet = DllCall($hDLL,"long","wcslen", "PTR", $StringWPTR)
$sString = DllStructGetData(DllStructCreate("WCHAR[" & $aRet[0] & "]",$pStringWPTR),1)

$aRet = DllCall($hDLL,"long","strlen", "PTR", $StringAPTR)
$sString = DllStructGetData(DllStructCreate("CHAR[" & $aRet[0] & "]",$pStringAPTR),1)

but string should be zero-terminated and MS VC libraries should be installed

Edited by Iczer
Link to comment
Share on other sites

I have found a solution. I will describe the relevant parts of the project -- for the benefit of others

I use Pegasus Mail and back up the settings and data daily: just the files that have changed, i.e. have the archive bit set. Pegasus organizes saved emails into what it calls "folders" (but which are actually files). The "folders' are organized into a tree structure.

Very occasionally a Pegasus "folder" disappears, and when it does, it needs to be retrieved from back ups. But to retrieve a "folder" one needs to know its filename, and the name of the file is FOL followed by seemingly random hex-looking digits.

Pegasus maintains a file, hierarch.pm. It is in CSV format and contains the tree structure including the name of the "folder" and the filename. It is, of course, flat,

My project is to show hierarch.pm in a treeview so the user can select a "folder" and have the script tell him the name of the corresponding file.

So the treeview needs a string to be associated with each "folder" item.

To do this, I avoided using GuiTreeviewCreateItem() so I, not calling this native AutoIt funcion, get to store the file name in the $iParam parameter of the treeview struct. So I created the treeview by calling _GuiCtrlTreeview_Add() and _GuiCtrlTreeview_AddChild().

I thought of calling _GuiCtrlTreeview_SetItemParam() to store the file name with each treeview item. But $iParam cannot be used directly to store a string.

In Structureconstants.au3, $iParam is a 4-byte integer. In 32-bit AutoIt, a pointer is also 4 bytes. I decided to try storing a pointer to a string there.

To allocate memory and get a pointer back, I call _WinAPI_CreateString(). To get the string back, I call PointerToStringW():

Func _PointerToStringW($ptr)
    Return DllStructGetData(DllStructCreate("wchar[" & _WinAPI_StringLenW($ptr) & "]", $ptr), 1)
EndFunc

To store the string with the treeview item, I coded;

$pStr = _WinAPI_CreateString(StringInStr($a20[$i][$kFull],':FOL') ? $a20[$i][$kFull] : '')
_GUICtrlTreeView_SetItemParam($g_hTV,$hItem,$pStr)

To retrieve a string I coded:

Local $ptr = _GUICtrlTreeView_GetItemParam($g_hTV,$hItem)
Local $s = _PointerToStringW($ptr)
.
.
.
Func _PointerToStringW($ptr)
    Return DllStructGetData(DllStructCreate("wchar[" & _WinAPI_StringLenW($ptr) & "]", $ptr), 1)
EndFunc

I also keep track of these pointers in an array, and when the script is ending I free the memory:

OnAutoItExitRegister('FreePointersToParamStrings')


Func FreePointersToParamStrings()
    For $i = 0 To $g_iqPointers
        _WinAPI_FreeMemory($g_pointers[$i])
    Next
EndFunc

This works in x86 AutoIt. It may not work in AutoIt x64.

Edited by c.haslam
Added retrieval code
Spoiler

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

 

Link to comment
Share on other sites

I have been looking at the Param element on Microsoft. I see there that it is an LPARAM. StructureConstants.au3 has:

Global Const $tagTVITEM = "struct;uint Mask;handle hItem;uint State;uint StateMask;ptr Text;int TextMax;int Image;int SelectedImage;" & _
        "int Children;lparam Param;endstruct"

_GuiCtrlTreeview_SetItemParam() creates a $tagTVITEMEX structure.

This suggest that the last parameter to _GuiCtrlTreeview_SetItemParam() and  _GuiCtrlTreeview_GetItemParam() should be a pointer ($pParam).

Did I find 2 bugs?

(The Help for $tagTVITEMEX has Param as a Param. BTW the Help for DllStructCreate las LPARAM amd WPARAM but not PARAM.)

Spoiler

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

 

Link to comment
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
 Share

  • Recently Browsing   0 members

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