My best example is: The need to dynamically populate a ListView with elements from a 2 dimensional comma separated variable (CSV) file.
Looking at the AHK ListView documentation this does not appear to be possible. My meager attempts to program around or through this apparent limitation failed. The solution was in a post in the Archived Forums (https://autohotkey.com/board/topic/9730 ... omsearch=1). There are several other posts that might get you to the solution.
It turns out that LV_Add() is a "variadic" function. Although LV_Add() is documented as LV_Add([Options, Field1, Field2, ...]) the correct documentation is LV_Add([Options, Field*]) where the asterisk after Field denotes Field to be a variadic parameter and LV_Add() to be a variadic function. In this case Field becomes a variable array of sequential ListView row entries (e.g Field1, Field2, ...). It appears that LV_Insert and LV_Modify are also variadic functions.
In the above post, Jackie Sztuk-Blackholyman provided a simple script to show how to use a variadic parameter to add rows of elements to a ListView. (Thanks Jackie.) I have slightly modified that script to make the code sequence easier to read while adding an extra row and an extra column.
Code: Select all
Gui,Add,ListView,,ColTitle1|ColTitle2|ColTitle3|ColTitle4
args := {}
;BUILD AND ADD DATA ROW 1
args[1] := "A"
args[2] := "B"
args[3] := "C"
args[4] := "D"
LV_Add("",args*)
args := {}
;BUILD AND ADD DATA ROW 2
args[1] := "E"
args[2] := "F"
args[3] := "G"
args[4] := "H"
LV_Add("",args*)
args=
Gui,Show
Return
Esc::
GuiEscape:
GuiClose:
ExitApp
1. I pull the elements into an Array[row,col]=element.
2. I use 1 Loop to build the Column/TitleString (CTString) from the first row of elements. CTString is used by GUI,Add,Listview,,CTString to build ListView.
3. I use 2 nested Loops to read elements by row and column from the Array[row,col]=element into the variadic parameter args* and then use LV_Add("",args*) to add the list of elements one line at a time into ListView.
Code: Select all
Array := {}
Array[1,1] := "ColTitle1"
Array[1,2] := "ColTitle2"
Array[1,3] := "ColTitle3"
Array[1,4] := "ColTitle4"
Array[2,1] := "A"
Array[2,2] := "B"
Array[2,3] := "C"
Array[2,4] := "D"
Array[3,1] := "E"
Array[3,2] := "F"
Array[3,3] := "G"
Array[3,4] := "H"
MaxRow := 3
MaxCol := 4
;BUILD CTSring (COLUMN TITLE STRING) FROM Array[1,..]
CTString := ""
Loop, %MaxCol%
{
ColIndex := A_Index
CTString .= Array[1,ColIndex] . "|"
}
CTString := SubStr(CTString, 1, (StrLen(CTString)-1)) ; REMOVE LAST "|"
;USE CTSString TO BUILD ListView
Gui,Add,ListView,,%CTString%
;BUILD args[ColIndex] (i.e. args*) FROM Array[Row2..,Col1..]
MaxRow := MaxRow -1 ;REDUCE MaxRow BY 1 TO ACCOUNT FOR COLTITLE ROW
Loop, %MaxRow%
{
args := {}
RowIndex := A_Index + 1 ;INCREASE RowIndex BY 1 TO ACCOUNT FOR COLTITLE ROW
Loop, %MaxCol%
{
ColIndex := A_Index
args[ColIndex] := Array[RowIndex,ColIndex]
}
LV_Add("",args*)
args =
}
Gui,Show
Return
Esc::
GuiEscape:
GuiClose:
ExitApp
Code: Select all
DataString =
(
ColTitle1, ColTitle2, ColTitle3, ColTitle4
A,B,C,D
E,F,G,H
)
;BUILD ARRAY[Row,Column] FROM DataString
Array := {}
MaxRow := 0
MaxCol := 0
Loop, parse, DataString, `n ;PARSE DataString AT NEW LINES TO GET RowString
{
RowIndex := A_Index
RowString := A_LoopField
Loop, parse, RowString, CSV ;PARSE RowString AT COMMAS TO GET Elements
{
ColIndex := A_Index
Element := A_LoopField
Array[RowIndex,ColIndex] := Element ;BUILD Array[row,col] FROM Elements
}
If (ColIndex > MaxCol) ;IF ColIndex > MaxCol THEN UPDATE MaxCol
MaxCol := ColIndex
}
MaxRow := RowIndex
;BUILD CTSring (COLUMN TITLE STRING) FROM Array[1,..]
CTString := ""
Loop, %MaxCol%
{
ColIndex := A_Index
CTString .= Array[1,ColIndex] . "|"
}
CTString := SubStr(CTString, 1, (StrLen(CTString)-1)) ;REMOVE LAST "|"
;USE CTSString TO BUILD ListView
Gui,Add,ListView,,%CTString%
CTString =
;BUILD args[ColIndex] FROM Array[Row2..,Col1..]
MaxRow := MaxRow -1 ;REDUCE MaxRow BY 1 TO ACCOUNT FOR COLTITLE ROW
Loop, %MaxRow%
{
args := {}
RowIndex := A_Index + 1 ; INCREASE RowIndex BY 1 TO ACCOUNT FOR COLTITLE ROW
Loop, %MaxCol%
{
ColIndex := A_Index
args[ColIndex] := Array[RowIndex,ColIndex]
}
;ADD ROW TO ListView USING args*
LV_Add("",args*)
}
args =
Array =
Gui,Show
Return
Esc::
GuiEscape:
GuiClose:
ExitApp
The documentation regarding variadic functions is remarkably sparse given the power of the feature. What documentation there is can be found under Variadic Functions and Variadic Function Calls (https://autohotkey.com/docs/Functions.htm#Variadic). It consists of 2 paragraphs, 10 Notes, and 1 crude example.
If the last parameter in a function definition is followed by an asterisk (*) the function is considered to be variadic and may receive a variable number of parameters.
I hope you find these examples helpful.