Jump to content

_GUICtrlListView_SetItem's $iParam parameter


Recommended Posts

I have

Local $idListview = GUICtrlCreateListView("",8,8,@DesktopWidth/2-16,@DesktopHeight-150,$LVS_SHOWSELALWAYS, _
        $LVS_EX_INFOTIP)
    Local $hListView = GUICtrlGetHandle($idListview)
    _GUICtrlListView_InsertColumn($hListview, 0, "Filename", 400)
    _GUICtrlListView_InsertColumn($hListview, 1, "Ext", 50)
    _GUICtrlListView_InsertColumn($hListview, 2, "Size",70)
    _GUICtrlListView_InsertColumn($hListview, 3, 'Date time',100)
    _GUICtrlListView_InsertColumn($hListview, 4, "Path", 385)
    _GUICtrlListView_InsertColumn($hListview, 5, "sizeInt", 0)
    _GUICtrlListView_JustifyColumn($hListview, $kSize,1)    ; right align

then further on

While True
        $sFnamExt = FileFindNextFile($iSrch)
        If @error Then
            ExitLoop
        EndIf
        $sAtts = FileGetAttrib($sPath&'\'&$sFnamExt)
        If StringInStr($sAtts,'D') Then
            If $sFnamExt<>'$RECYCLE.BIN' Then
                $sDirs &= '?'&$sPath&'\'&$sFnamExt
            EndIf
        Else
            $p = StringInStr($sFnamExt,'.',0,-1)    ; last
            If $p=0 Then
                $sFnam = $sFnamExt
                $sExt = ''
            Else
                $sFnam = StringLeft($sFnamExt,$p-1)
                $sExt = StringTrimLeft($sFnamExt,$p)
            EndIf
            _GUICtrlListView_AddItem($hListview,$sFnam,-1,_GUICtrlListView_GetItemCount($hListview)+1000)
            _GUICtrlListView_AddSubItem($hListview,$nItem,$sExt,$kExt)
            $nSize = FileGetSize($sPath&'\'&$sFnamExt)
            $sSize = AddThousandsSeparator($nsize)
            _GUICtrlListView_AddSubItem($hListview,$nItem,$sSize,$kSize)
            _GUICtrlListView_AddSubItem($hListview,$nItem,$nsize,$kSizeInt)
            $nTotBytes += $nSize
            $a1 = FileGetTime($sPath&'\'&$sFnamExt,$FT_MODIFIED,$FT_ARRAY)
            $t = $a1[0]&'-'&$a1[1]&'-'&$a1[2]&' '&$a1[3]&':'&$a1[4]
            _GUICtrlListView_AddSubItem($hListview,$nItem,$t,$kDateTime)
            _GUICtrlListView_AddSubItem($hListview,$nItem,$sPath,$kPath)
            If $gSQL Then
                $s = "Insert into tbl values ("&_SQLite_Escape($sFnam)&","&_SQLite_Escape($sExt)&",'"& _
                    $sSize&"','"& _
                    $t&"',"&_SQLite_Escape($sPath)&","&$nSize&")"
                _SQLite_Exec(-1,$s)
                If @error Then
                    MsgBox(0,@ScriptLineNumber,_SQLite_ErrMsg())
                EndIf

            EndIf
        EndIf
    WEnd
    FileClose($iSrch)

You will see that I heeded the advice in Help > _GUICtrlListView_AddItem: "As AutoIt uses the $iParam parameter to store the controlID of native-created ListView items, this value should be set sufficiently high for UDF-created items to avoid possible conflict with any existing controls - a starting value of 1000 is recommended."

(It's unfortunate that the Example does not heed this advice. OK, it doesn't need to because there are no other controls, but still --- it would help neophytes if it did. Also to me _GUICtrlListView_AddItem is not native because it is a UDF. Confused?)

My script then does a sort using SQLite, and updates the ListView:

Local $hQuery
    Local $colNames = ['fnam','ext','nsize','dateTime','path','SizeInt']
    Local $s =  "Select * FROM tbl ORDER BY "&$colNames[$ncol]&';'
    _SQLite_Query(-1,$s, $hQuery)
    If @error Then
        MsgBox(0,@ScriptLineNumber,_SQLite_ErrMsg())
    EndIf
    Local $aRow[$kSizeInt+1]
    Local $iItem=-1
    While _SQLite_FetchData($hQuery, $aRow, False, False) = $SQLITE_OK ; Read Out the next Row
        If @error Then
            MsgBox(0,@ScriptLineNumber,_SQLite_ErrMsg())
        EndIf
        $iItem += 1
        For $i = $kFnam To $kSizeInt
            _GUICtrlListView_SetItem($hListview,$aRow[$i],$iItem,$i,Default)
        Next
    WEnd

This works, but I had earlier coded

_GUICtrlListView_SetItem($hListview,$aRow[$i],$iItem,$i,Default,$iItem+1000)

because the same advice is in the Help for this function.

So my care in specifying $param back-fired! What am I not understanding?

The only difference in what works is that the $param parameter is defaulted.

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

When you add listview items with the native GUICtrlCreateListViewItem() the controlID (an integer in the range 3 - 65,535) is stored in ItemParam.

When you add listview items with _GUICtrlListView_-functions (UDF-functions) ItemParam is not used. You can use it to store your own information.

If you are adding listview items with GUICtrlCreateListViewItem(), you cannot use ItemParam for your own information. It's already used for controlID.

What information do you store in ItemParam in your example? What are you using the information for? If you do not need to store additional information, then there is no need to fill out ItemParam. Just leave it as default zero.

Offset of 1000 (or maybe 100,000 or maybe negative ItemParam values (If you are using negative ItemParam values use an offset of -20 to avoid conflicts with $GUI_EVENT_-constants.)) comes into play only if there is actually a need to save additional information in ItemParam.

In the example for _GUICtrlListView_AddItem(), there is no need to save additional information in ItemParam. Therefore, the value is not filled out and there is no need for any offset.

Native, built-in or internal functions are the functions stored in AutoIt3.exe and AutoIt3_x64.exe and coded in C++. Therefore, they are significantly faster than UDF functions.

Edited by LarsJ
Offset -20 for negative ItemParams
Link to comment
Share on other sites

I don't use $iParam, so I can remove this argument.

I think I am grasping the native and UDF families of functions for ListView. Please correct me if I am wrong.

Native functions

There seem to be:

  • GuiCtrlCreateListview - creates a listview control, including column headings, with styles and exstyles
  • GUICtrlCreateListViewItem - creates an item (row), including sub-items
  • GUICtrlRegisterListViewSort - sets sort order
  • GUICtrlSetData - updates text of item or sub-item
  • GuiCtrlRead - gets control ID of selected item; gets whether check box of an item is checked
  • GuiCtrlDelete - Deletes a listview; perhaps deletes a listview item
  • GuiCtrlGetState - Get number clicked column
  • GuiCtrlSetState - Checks/unchecks an item; de-selects an item; permits dragging an item; shows/hides an item
  • GUIDataSeparatorChar (Option).

UDF functions

If one needs more features than this, call the UDF functions, of which there are many. All of the above features are available in the UDF functions.

----------

I have figured out that ItemParm is a member of the LVITEM structure. The Help calls it $iParam.

Edited by c.haslam
typo
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

Consider a script that calls only UDFs for ListView. Does the warning that $iParam be no lower than 1000 still apply? If so, why?

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

The warning applies without exception as soon as you use $iParam. There is a reason why the warning is spread all over the listview section in the help file.

But if you add code to handle the situations where it's a problem that an $iParam value is matching a controlID, and you do that in both your own code and in the code in the UDF functions that you are using, then it's of course not a problem any more.

Link to comment
Share on other sites

Only for listviews with single selections (GUICtrlRead()). For listviews with multiple selections, you must use UDF functions. And there are no problems at all in using the UDF functions.

A general approach to listviews is to create listview and listview items with native functions due to speed and then use UDF functions for everything else.

If you want some really quick listviews (lightning fast), you need virtual listviews.

Link to comment
Share on other sites

I have been thinking about the remark about $iParam in the Help for many ListView UDFs.

I am wondering whether the following would cover the issue, and make it clear why for calls to functions with this parameter it should sometimes not be used. I suggest that I might not have gone astray here if the following were the remark:

If you call GUICtrlCreateListViewItem(), do not call _GuiListview...() functions with $iParam, but if you create listview items with _GUICtrlListView_AddItem(), you can call it with $iParam, being any integer value you wish. You would then be able to retrieve the value with _GUICtrlListView_GetItemParam(). GUICtrlCreateListViewItem(), (without $iParam), stores the listview-item control ID there.

Just a thought.

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

×
×
  • Create New...