LarsJ Posted February 11, 2016 Author Posted February 11, 2016 (edited) Here you are: expandcollapse popup#include <GUIConstantsEx.au3> #include <EditConstants.au3> #include <WindowsConstants.au3> #include <GuiListView.au3> #include <SQLite.au3> #include <Timers.au3> #include <Array.au3> Opt( "MustDeclareVars", 1 ) Global Const $tagNMLVCACHEHINT = $tagNMHDR & ";int iFrom;int iTo" Global $TableName, $hListView, $hListView2, $hInput, $idInputChange Example() Func Example() _SQLite_Startup() If @error Then Exit MsgBox(16, "Error SQLite", "SQLite.dll") $TableName = 'table1' Local $sFileDB = @ScriptDir & '\Data.db', $iRows=100000 If Not FileExists($sFileDB) Then Local $hStarttime=_Timer_Init(), $Line='tuysdufysdfsduyfiusydfisdyfiusfdsdf', $sData Local $sExec = 'BEGIN; Create Table table1 ([ID] INTEGER PRIMARY KEY AUTOINCREMENT, [f_1] TEXT,[f_2] TEXT,[f_3] TEXT,[f_4] TEXT,[f_5] TEXT );' ConsoleWrite( @CRLF & 'Create database ... : ' ) ; Create string For $i=0 To $iRows-1 $sData=StringMid($Line,Random(5,25,1)) $sExec &= 'INSERT INTO '&$TableName&' (f_1,f_2,f_3,f_4,f_5) VALUES ("' & $sData&'","'&$sData&'","'&$sData&'","'&$sData&'","'&$sData& '");' Next $sExec &= 'COMMIT;' ; Create Table Local $hDB = _SQLite_Open($sFileDB), $hStarttime=_Timer_Init() _SQLite_Exec( -1, "PRAGMA synchronous = OFF;" ) _SQLite_Exec($hDB, $sExec) _SQLite_Close($hDB) ConsoleWrite( _Timer_Diff($hStarttime) / 1000 & @CRLF ) EndIf _SQLite_Open($sFileDB) _SQLite_Exec( -1, "ATTACH DATABASE ':memory:' AS DisplayMemDb;" ) _SQLite_Exec( -1, "CREATE TABLE DisplayMemDb.SearchRes AS SELECT * FROM " & $TableName & " WHERE UPPER(ID) like UPPER('5555%');" ) #cs Local $aMyResult, $iMyRows, $iMyColumns, $aRow _SQLite_GetTable2d( -1, "SELECT rowid,* FROM DisplayMemDb.SearchRes;", $aMyResult, $iMyRows, $iMyColumns ) _SQLite_QuerySingleRow( -1, "SELECT COUNT(*) FROM DisplayMemDb.SearchRes;", $aRow ) ; Item count If IsArray( $aRow ) Then ConsoleWrite( "$iRows = " & $aRow[0] & @CRLF ) _ArrayDisplay( $aMyResult ) #ce Local $Form1 = GUICreate("Form1", 803, 457, -1, -1) Local $idListView = GUICtrlCreateListView("", 8, 24, 785, 383, BitOR($LVS_OWNERDATA,$LVS_SHOWSELALWAYS)) _GUICtrlListView_SetExtendedListViewStyle(-1, BitOR($LVS_EX_DOUBLEBUFFER, $LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT)) _GUICtrlListView_AddColumn( $idListView, "Column1", 50 ) _GUICtrlListView_AddColumn( $idListView, "Column2", 100 ) _GUICtrlListView_AddColumn( $idListView, "Column3", 100 ) _GUICtrlListView_AddColumn( $idListView, "Column4", 100 ) _GUICtrlListView_AddColumn( $idListView, "Column5", 100 ) _GUICtrlListView_AddColumn( $idListView, "Column6", 100 ) $hListView = GUICtrlGetHandle( $idListView ) Local $idListView2 = GUICtrlCreateListView("", 8, 24, 785, 383, BitOR($LVS_OWNERDATA,$LVS_SHOWSELALWAYS)) _GUICtrlListView_SetExtendedListViewStyle(-1, BitOR($LVS_EX_DOUBLEBUFFER, $LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT)) _GUICtrlListView_AddColumn( $idListView2, "Column1", 50 ) _GUICtrlListView_AddColumn( $idListView2, "Column2", 50 ) _GUICtrlListView_AddColumn( $idListView2, "Column3", 100 ) _GUICtrlListView_AddColumn( $idListView2, "Column4", 100 ) _GUICtrlListView_AddColumn( $idListView2, "Column5", 100 ) _GUICtrlListView_AddColumn( $idListView2, "Column6", 100 ) _GUICtrlListView_AddColumn( $idListView2, "Column7", 100 ) $hListView2 = GUICtrlGetHandle( $idListView2 ) GUICtrlSetState( $idListView2, $GUI_HIDE ) Local $idInput = GUICtrlCreateInput("", 8, 416, 249, 21) GUICtrlSetState(-1,$GUI_FOCUS) $hInput = GUICtrlGetHandle( $idInput ) $idInputChange = GUICtrlCreateDummy() GUIRegisterMsg( $WM_COMMAND, "WM_COMMAND" ) GUISetState() GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" ) GUICtrlSendMsg( $idListView, $LVM_SETITEMCOUNT, $iRows, 0 ) Local $bFirst = True While 1 Switch GUIGetMsg() Case $idInputChange Local $sInput = GUICtrlRead( $idInput ) ; Get control data If $sInput Then If $bFirst Then GUICtrlSetState( $idListView, $GUI_HIDE ) GUICtrlSetState( $idListView2, $GUI_SHOW ) $bFirst = False EndIf Local $aRow _SQLite_Exec( -1, "DROP TABLE DisplayMemDb.SearchRes;" ) _SQLite_Exec( -1, 'CREATE TABLE DisplayMemDb.SearchRes AS SELECT * FROM ' & $TableName & ' WHERE UPPER(ID) like UPPER("'&$sInput&'%");' ) _SQLite_QuerySingleRow( -1, "SELECT COUNT(*) FROM DisplayMemDb.SearchRes;", $aRow ) ; Item count GUICtrlSendMsg( $idListView2, $LVM_SETITEMCOUNT, Int($aRow[0]), 0 ) Else GUICtrlSetState( $idListView2, $GUI_HIDE ) GUICtrlSetState( $idListView, $GUI_SHOW ) $bFirst = True EndIf Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd GUIDelete( $Form1 ) Exit EndFunc ; Change $hInput Func WM_COMMAND( $hWnd, $iMsg, $wParam, $lParam ) Local $hWndFrom = $lParam Local $iCode = BitShift( $wParam, 16 ) ; High word Switch $hWndFrom ; Input Case $hInput Switch $iCode Case $EN_CHANGE GUICtrlSendToDummy( $idInputChange ) ; => Case $idInputChange EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam ) Local Static $tText = DllStructCreate( "wchar[100]" ) Local Static $pText = DllStructGetPtr( $tText ) Local Static $aResult, $iRows, $iFrom Local $tNMHDR, $hWndFrom, $iCode $tNMHDR = DllStructCreate( $tagNMHDR, $lParam ) $hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) ) $iCode = DllStructGetData( $tNMHDR, "Code" ) Switch $hWndFrom Case $hListView Switch $iCode Case $LVN_GETDISPINFOW Local $tNMLVDISPINFO = DllStructCreate( $tagNMLVDISPINFO, $lParam ) If BitAND( DllStructGetData( $tNMLVDISPINFO, "Mask" ), $LVIF_TEXT ) Then Local $iIndex = DllStructGetData($tNMLVDISPINFO, "item") - $iFrom + 1 ; number row Local $nCol = DllStructGetData($tNMLVDISPINFO, "subitem") ; number column If $iIndex > 0 And $iIndex < $iRows + 1 Then Local $sItem = $aResult[$iIndex][$nCol] DllStructSetData( $tText, 1, $sItem ) DllStructSetData( $tNMLVDISPINFO, "Text", $pText ) DllStructSetData( $tNMLVDISPINFO, "TextMax", StringLen( $sItem ) ) EndIf EndIf Case $LVN_ODCACHEHINT Local $tNMLVCACHEHINT = DllStructCreate( $tagNMLVCACHEHINT, $lParam ), $iColumns $iFrom = DllStructGetData( $tNMLVCACHEHINT, "iFrom" ) _SQLite_GetTable2d( -1, "SELECT * FROM " & $TableName & " WHERE ID BETWEEN " & $iFrom + 1 & " And " & DllStructGetData( $tNMLVCACHEHINT, "iTo" ) + 1 & ";", $aResult, $iRows, $iColumns ) EndSwitch Case $hListView2 Switch $iCode Case $LVN_GETDISPINFOW Local $tNMLVDISPINFO = DllStructCreate( $tagNMLVDISPINFO, $lParam ) If BitAND( DllStructGetData( $tNMLVDISPINFO, "Mask" ), $LVIF_TEXT ) Then Local $iIndex = DllStructGetData($tNMLVDISPINFO, "item") - $iFrom + 1 ; number row Local $nCol = DllStructGetData($tNMLVDISPINFO, "subitem") ; number column If $iIndex > 0 And $iIndex < $iRows + 1 Then Local $sItem = $aResult[$iIndex][$nCol] DllStructSetData( $tText, 1, $sItem ) DllStructSetData( $tNMLVDISPINFO, "Text", $pText ) DllStructSetData( $tNMLVDISPINFO, "TextMax", StringLen( $sItem ) ) EndIf EndIf Case $LVN_ODCACHEHINT Local $tNMLVCACHEHINT = DllStructCreate( $tagNMLVCACHEHINT, $lParam ), $iColumns $iFrom = DllStructGetData( $tNMLVCACHEHINT, "iFrom" ) _SQLite_GetTable2d( -1, "SELECT rowid,* FROM DisplayMemDb.SearchRes WHERE rowid BETWEEN " & $iFrom + 1 & " And " & DllStructGetData( $tNMLVCACHEHINT, "iTo" ) + 1 & ";", $aResult, $iRows, $iColumns ) EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc The example shows a way to implement a search box. You can search for numbers in the first column: 1 - 100000. As soon as you enter a number into the search box the listview is replaced with a new listview with an additional column. Column 1 is the row numbers. Columns 2-7 are the result of the search. If you search for the number 1001 the result is the numbers 1001 and 10010 - 10019. A total of 11 rows. Edited October 16, 2016 by LarsJ Explanation below code Controls,  File Explorer,  ROT objects,  UI Automation,  Windows Message MonitorCompiled code: Accessing AutoIt variables,  DotNet.au3 UDF,  Using C# and VB codeShell menus: The Context menu,  The Favorites menu. Shell related: Control Panel,  System Image ListsGraphics related: Rubik's Cube,  OpenGL without external libraries,  Navigating in an image,  Non-rectangular selectionsListView controls: Colors and fonts,  Multi-line header,  Multi-line items,  Checkboxes and icons,  Incremental searchListView controls: Virtual ListViews,  Editing cells,  Data display functions
LarsJ Posted February 12, 2016 Author Posted February 12, 2016 pvnn, You are welcome.  There is one more major issue in the code in posts 34 and 35: There is not defined a primary key in the database table. The lack of a primary key has serious performance implications when there are more than 62 rows for each treeview item. This is evident in the code in post 35 with 6200 rows for each treeview item. If you select a row in the listview, navigating with the arrow keys is extremely slow. In the examples below the name-field is set as primary key, and the performance is much, much better. Especially the JOIN clause in the SQL SELECT statement for $LVN_ODCACHEHINT events performs significantly better when a primary key is defined. This is a copy of the code from post 35, and a primary key is added to the SSDB table (delete a previous database before you run the code): expandcollapse popup#include <GuiListView.au3> #include <GUIConstantsEx.au3> #include <ListViewConstants.au3> #include <TreeViewConstants.au3> #include <WindowsConstants.au3> #include <GuiTreeView.au3> #include <SQLite.au3> #include <Math.au3> Global Const $tagNMLVCACHEHINT = $tagNMHDR & ";int iFrom;int iTo" Global $aListView, $hListView, $TreeView_SelTitle ConsoleWrite( "Initializing database ..." & @CRLF ) DBInit() Opt("GUIOnEventMode", 1) #Region ### START Koda GUI section ### Form= Global $Form1 = GUICreate("Form1", 881, 516, -1, -1) GUISetOnEvent($GUI_EVENT_CLOSE, "Form1Close") Global $TreeView = GUICtrlCreateTreeView(8, 16, 319, 489, BitOR($GUI_SS_DEFAULT_TREEVIEW,$TVS_FULLROWSELECT,$WS_HSCROLL,$WS_VSCROLL,$WS_BORDER), BitOR($WS_EX_CLIENTEDGE,$WS_EX_STATICEDGE)) Global $TreeView_Root_1 = GUICtrlCreateTreeViewItem("root - 1", $TreeView) GUICtrlSetOnEvent(-1, "TreeView1Click") Global $TreeView_1 = GUICtrlCreateTreeViewItem("111", $TreeView_Root_1) GUICtrlSetOnEvent(-1, "TreeView1Click") Global $TreeView_2 = GUICtrlCreateTreeViewItem("222", $TreeView_Root_1) GUICtrlSetOnEvent(-1, "TreeView1Click") Global $TreeView_3 = GUICtrlCreateTreeViewItem("333", $TreeView_Root_1) GUICtrlSetOnEvent(-1, "TreeView1Click") Global $TreeView_Root_2 = GUICtrlCreateTreeViewItem("root - 2", $TreeView) GUICtrlSetOnEvent(-1, "TreeView1Click") Global $TreeView_4 = GUICtrlCreateTreeViewItem("444", $TreeView_Root_2) GUICtrlSetOnEvent(-1, "TreeView1Click") Global $TreeView_5 = GUICtrlCreateTreeViewItem("555", $TreeView_Root_2) GUICtrlSetOnEvent(-1, "TreeView1Click") ;Global $ListView = GUICtrlCreateListView("Rowid|Name|Time|Category", 336, 16, 538, 486, BitOR($GUI_SS_DEFAULT_LISTVIEW,$LVS_ALIGNLEFT,$WS_HSCROLL,$WS_VSCROLL,$WS_BORDER), BitOR($WS_EX_CLIENTEDGE,$WS_EX_STATICEDGE,$LVS_EX_FULLROWSELECT)) Global $ListView = GUICtrlCreateListView("Rowid|Name|Time|Category", 336, 16, 538, 486, $LVS_OWNERDATA, BitOR($WS_EX_CLIENTEDGE,$WS_EX_STATICEDGE)) ; $LVS_OWNERDATA must be included for a virtual listview _GUICtrlListView_SetExtendedListViewStyle( $ListView, $LVS_EX_DOUBLEBUFFER+$LVS_EX_FULLROWSELECT ) GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 0, 100) GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 1, 200) GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 2, 88) GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 3, 112) GUICtrlSetOnEvent(-1, "ListViewClick") GUIRegisterMsg($WM_NOTIFY, "LWS_WM_NOTIFY") GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### $hListView = GUICtrlGetHandle($ListView) _GUICtrlTreeView_Expand($TreeView, $TreeView_Root_1, True) While 1 Sleep(100) WEnd Func Form1Close() GUIRegisterMsg( $WM_NOTIFY, "" ) ; Exit EndFunc ;========================================================================================== Func ListViewClick() EndFunc ;========================================================================================== Func TreeView1Click() Local $sQuery, $aResult, $iRows, $iColumns Static Local $TreeView_SelTitlePRE = "" If $TreeView_SelTitlePRE == "" Then $TreeView_Selected = _GUICtrlTreeView_GetFirstChild($TreeView, $TreeView_Root_1) _GUICtrlTreeView_ClickItem($TreeView, $TreeView_Selected, "left") Else $TreeView_Selected = _GUICtrlTreeView_GetSelection($TreeView) EndIf $TreeView_SelTitle = _GUICtrlTreeView_GetText($TreeView, $TreeView_Selected) If $TreeView_SelTitle == $TreeView_SelTitlePRE Then Return Else $TreeView_SelTitlePRE = $TreeView_SelTitle EndIf ConsoleWrite($TreeView_SelTitle & @CRLF) $sQuery = "SELECT count(Title) FROM SSDB WHERE Title IS '" & $TreeView_SelTitle & "'" _SQLite_GetTable(-1, $sQuery, $aResult, $iRows, $iColumns) ;GUICtrlSendMsg( $hListView, $LVM_SETITEMCOUNT, $aResult[2], 0 ) ConsoleWrite("Rows = " & $aResult[2] & @CRLF) _SQLite_Exec( -1, "DROP VIEW DisplayView;" ) _SQLite_Exec( -1, "DROP TABLE DisplayMemDb.RowRelation;" ) _SQLite_Exec( -1, "CREATE TEMP VIEW DisplayView AS SELECT Name,Time,Category FROM SSDB WHERE Title IS '" & $TreeView_SelTitle & "';" ) _SQLite_Exec( -1, "CREATE TABLE DisplayMemDb.RowRelation AS SELECT Name FROM DisplayView;" ) GUICtrlSendMsg( $ListView, $LVM_SETITEMCOUNT, Int($aResult[2]), 0 ) ; GUICtrlSendMsg works with control IDs only, $aResult[2] (string) must be an integer EndFunc ;========================================================================================== Func DBInit() Local $aResult, $iRows, $iColumns ;------------------------------------------------------------------------------------------ Local $sPathTo_SSDB = @ScriptDir & "\SSDB.sqlite" Local $sPathTo_SQLiteDLL = @ScriptDir & "\sqlite3.dll" Global $sSqlBuild_Table = "(Title, Name, Time, Category, column_05, column_06, column_07, column_08)" ;------------------------------------------------------------------------------------------ _SQLite_Startup($sPathTo_SQLiteDLL) If FileExists($sPathTo_SSDB) Then $hSSDB = _SQLite_Open($sPathTo_SSDB) Else $hSSDB = _SQLite_Open($sPathTo_SSDB) ;------------------------------------------------------------------------------------------ _SQLite_Exec($hSSDB, "CREATE TABLE IF NOT EXISTS SSDB (Title, Name PRIMARY KEY, Time, Category, column_05, column_06, column_07, column_08);") ;------------------------------------------------------------------------------------------ $sQuery = "" For $i = 1 To 5 $sQuery &= 'INSERT INTO SSDB ' & $sSqlBuild_Table & ' VALUES ' $sTitle = String($i) & String($i) & String($i) If $i = 1 Then For $j = 0 To 6200 $sQuery &= "('" & StringRegExpReplace($sTitle, "'", "''") & "'" $sQuery &= ",'" & StringRegExpReplace($sTitle & "_" & $j, "'", "''") & "'" $sQuery &= ",'" & StringRegExpReplace("12345", "'", "''") & "'" $sQuery &= ",'" & StringRegExpReplace("123", "'", "''") & "'" $sQuery &= ",'','','','')," Next Else For $j = 0 To 6200 $sQuery &= "('" & StringRegExpReplace($sTitle, "'", "''") & "'" $sQuery &= ",'" & StringRegExpReplace($sTitle & "_" & $j, "'", "''") & "'" $sQuery &= ",'" & StringRegExpReplace("12345", "'", "''") & "'" $sQuery &= ",'" & StringRegExpReplace("123", "'", "''") & "'" $sQuery &= ",'','','','')," Next EndIf $sQuery &= "('" & StringRegExpReplace($sTitle, "'", "''") & "'" $sQuery &= ",'" & StringRegExpReplace($sTitle & "_" & $j, "'", "''") & "'" $sQuery &= ",'" & StringRegExpReplace("12345", "'", "''") & "'" $sQuery &= ",'" & StringRegExpReplace("123", "'", "''") & "'" $sQuery &= ",'','','','');" Next If Not (_SQLite_Exec(-1, $sQuery) = $SQLITE_OK) Then Return SetError(2) EndIf _SQLite_Exec( -1, "ATTACH DATABASE ':memory:' AS DisplayMemDb;" ) ; <<<<<<<<<<<<<<<<<<< _SQLite_Exec( -1, "CREATE TEMP VIEW DisplayView AS SELECT Name,Time,Category FROM SSDB WHERE Title IS '111';" ) _SQLite_Exec( -1, "CREATE TABLE DisplayMemDb.RowRelation AS SELECT Name FROM DisplayView;" ) EndFunc ;========================================================================================== Func LWS_WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam ) Local Static $tText = DllStructCreate( "wchar[512]" ) Local Static $pText = DllStructGetPtr( $tText ) Local Static $aResult, $iRows, $iFrom Local $tNMHDR, $hWndFrom, $iCode, $tInfo, $VKey $tNMHDR = DllStructCreate( $tagNMHDR, $lParam ) $hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) ) $iCode = DllStructGetData( $tNMHDR, "Code" ) Switch $hWndFrom Case $hListView Switch $iCode Case $NM_CUSTOMDRAW Local $tNMLVCUSTOMDRAW = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam) Local $dwDrawStage = DllStructGetData($tNMLVCUSTOMDRAW, "dwDrawStage") Local $dwItemSpec = DllStructGetData($tNMLVCUSTOMDRAW, "dwItemSpec") Switch $dwDrawStage ; Holds a value that specifies the drawing stage Case $CDDS_PREPAINT ; Before the paint cycle begins Return $CDRF_NOTIFYITEMDRAW ; Notify the parent window of any item-related drawing operations Case $CDDS_ITEMPREPAINT ; Before painting an item If Mod( $dwItemSpec, 2 ) = 0 Then DllStructSetData( $tNMLVCUSTOMDRAW, "ClrTextBk", 0xFFFFFF ) Else DllStructSetData( $tNMLVCUSTOMDRAW, "ClrTextBk", 0xF8FFF8 ) EndIf Return $CDRF_NEWFONT ; $CDRF_NEWFONT must be returned after changing font or colors EndSwitch Case $LVN_GETDISPINFOW Local $tNMLVDISPINFO = DllStructCreate( $tagNMLVDISPINFO, $lParam ) If BitAND( DllStructGetData( $tNMLVDISPINFO, "Mask" ), $LVIF_TEXT ) Then Local $iIndex = DllStructGetData( $tNMLVDISPINFO, "Item" ) - $iFrom + 1 If $iIndex > 0 And $iIndex < $iRows + 1 Then Local $sItem = $aResult[$iIndex][DllStructGetData($tNMLVDISPINFO,"SubItem")] DllStructSetData( $tText, 1, $sItem ) DllStructSetData( $tNMLVDISPINFO, "Text", $pText ) DllStructSetData( $tNMLVDISPINFO, "TextMax", StringLen( $sItem ) ) EndIf EndIf Case $LVN_ODCACHEHINT Local $tNMLVCACHEHINT = DllStructCreate( $tagNMLVCACHEHINT, $lParam ), $iColumns $iFrom = DllStructGetData( $tNMLVCACHEHINT, "iFrom" ) ;Local $sSQL = "SELECT Name,Time,Category FROM SSDB WHERE Title IS '" & $TreeView_SelTitle & "' AND item_id >= " & $iFrom & " AND item_id <= " & DllStructGetData( $tNMLVCACHEHINT, "iTo" ) & ";" Local $sSQL = "SELECT RowRelation.rowid,DisplayView.Name,Time,Category FROM DisplayView INNER JOIN RowRelation ON DisplayView.Name = RowRelation.Name WHERE RowRelation.rowid BETWEEN " & $iFrom + 1 & " And " & DllStructGetData( $tNMLVCACHEHINT, "iTo" ) + 1 & ";" _SQLite_GetTable2d( -1, $sSQL, $aResult, $iRows, $iColumns ) EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc  The importance of a primary key is demonstrated in the example below where a much larger table is created. These For loops are used to create the table: For $i = 1 To 5 $sQuery &= 'INSERT INTO SSDB ' & $sSqlBuild_Table & ' VALUES ' $sTitle = String($i) & String($i) & String($i) If $i = 1 Then For $j = 0 To 620000 $sQuery &= "('" & StringRegExpReplace($sTitle, "'", "''") & "'" $sQuery &= ",'" & StringRegExpReplace($sTitle & "_" & $j, "'", "''") & "'" $sQuery &= ",'" & StringRegExpReplace("12345", "'", "''") & "'" $sQuery &= ",'" & StringRegExpReplace("123", "'", "''") & "'" $sQuery &= ",'','','','')," Next Else For $j = 0 To 62000 $sQuery &= "('" & StringRegExpReplace($sTitle, "'", "''") & "'" $sQuery &= ",'" & StringRegExpReplace($sTitle & "_" & $j, "'", "''") & "'" $sQuery &= ",'" & StringRegExpReplace("12345", "'", "''") & "'" $sQuery &= ",'" & StringRegExpReplace("123", "'", "''") & "'" $sQuery &= ",'','','','')," Next EndIf $sQuery &= "('" & StringRegExpReplace($sTitle, "'", "''") & "'" $sQuery &= ",'" & StringRegExpReplace($sTitle & "_" & $j, "'", "''") & "'" $sQuery &= ",'" & StringRegExpReplace("12345", "'", "''") & "'" $sQuery &= ",'" & StringRegExpReplace("123", "'", "''") & "'" $sQuery &= ",'','','','');" Next Note the first loop that creates 620,000 rows. It takes a minute to create the database. It uses 48 MB of disk space. It contains a total of 868,010 rows. When you click the 111-item (620,000 rows) in the treeview it takes a second to fill the listview. Even on my old Windows XP these 620,000 rows are flying over the screen. Both using the mouse and the keyboard. Full code (delete the small database before you create the large one): expandcollapse popup#include <GuiListView.au3> #include <GUIConstantsEx.au3> #include <ListViewConstants.au3> #include <TreeViewConstants.au3> #include <WindowsConstants.au3> #include <GuiTreeView.au3> #include <SQLite.au3> #include <Math.au3> Global Const $tagNMLVCACHEHINT = $tagNMHDR & ";int iFrom;int iTo" Global $aListView, $hListView, $TreeView_SelTitle ConsoleWrite( "Initializing database ..." & @CRLF ) DBInit() Opt("GUIOnEventMode", 1) #Region ### START Koda GUI section ### Form= Global $Form1 = GUICreate("Form1", 881, 516, -1, -1) GUISetOnEvent($GUI_EVENT_CLOSE, "Form1Close") Global $TreeView = GUICtrlCreateTreeView(8, 16, 319, 489, BitOR($GUI_SS_DEFAULT_TREEVIEW,$TVS_FULLROWSELECT,$WS_HSCROLL,$WS_VSCROLL,$WS_BORDER), BitOR($WS_EX_CLIENTEDGE,$WS_EX_STATICEDGE)) Global $TreeView_Root_1 = GUICtrlCreateTreeViewItem("root - 1", $TreeView) GUICtrlSetOnEvent(-1, "TreeView1Click") Global $TreeView_1 = GUICtrlCreateTreeViewItem("111", $TreeView_Root_1) GUICtrlSetOnEvent(-1, "TreeView1Click") Global $TreeView_2 = GUICtrlCreateTreeViewItem("222", $TreeView_Root_1) GUICtrlSetOnEvent(-1, "TreeView1Click") Global $TreeView_3 = GUICtrlCreateTreeViewItem("333", $TreeView_Root_1) GUICtrlSetOnEvent(-1, "TreeView1Click") Global $TreeView_Root_2 = GUICtrlCreateTreeViewItem("root - 2", $TreeView) GUICtrlSetOnEvent(-1, "TreeView1Click") Global $TreeView_4 = GUICtrlCreateTreeViewItem("444", $TreeView_Root_2) GUICtrlSetOnEvent(-1, "TreeView1Click") Global $TreeView_5 = GUICtrlCreateTreeViewItem("555", $TreeView_Root_2) GUICtrlSetOnEvent(-1, "TreeView1Click") ;Global $ListView = GUICtrlCreateListView("Rowid|Name|Time|Category", 336, 16, 538, 486, BitOR($GUI_SS_DEFAULT_LISTVIEW,$LVS_ALIGNLEFT,$WS_HSCROLL,$WS_VSCROLL,$WS_BORDER), BitOR($WS_EX_CLIENTEDGE,$WS_EX_STATICEDGE,$LVS_EX_FULLROWSELECT)) Global $ListView = GUICtrlCreateListView("Rowid|Name|Time|Category", 336, 16, 538, 486, $LVS_OWNERDATA, BitOR($WS_EX_CLIENTEDGE,$WS_EX_STATICEDGE)) ; $LVS_OWNERDATA must be included for a virtual listview _GUICtrlListView_SetExtendedListViewStyle( $ListView, $LVS_EX_DOUBLEBUFFER+$LVS_EX_FULLROWSELECT ) GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 0, 100) GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 1, 200) GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 2, 88) GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 3, 112) GUICtrlSetOnEvent(-1, "ListViewClick") GUIRegisterMsg($WM_NOTIFY, "LWS_WM_NOTIFY") GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### $hListView = GUICtrlGetHandle($ListView) _GUICtrlTreeView_Expand($TreeView, $TreeView_Root_1, True) While 1 Sleep(100) WEnd Func Form1Close() GUIRegisterMsg( $WM_NOTIFY, "" ) ; Exit EndFunc ;========================================================================================== Func ListViewClick() EndFunc ;========================================================================================== Func TreeView1Click() Local $sQuery, $aResult, $iRows, $iColumns Static Local $TreeView_SelTitlePRE = "" If $TreeView_SelTitlePRE == "" Then $TreeView_Selected = _GUICtrlTreeView_GetFirstChild($TreeView, $TreeView_Root_1) _GUICtrlTreeView_ClickItem($TreeView, $TreeView_Selected, "left") Else $TreeView_Selected = _GUICtrlTreeView_GetSelection($TreeView) EndIf $TreeView_SelTitle = _GUICtrlTreeView_GetText($TreeView, $TreeView_Selected) If $TreeView_SelTitle == $TreeView_SelTitlePRE Then Return Else $TreeView_SelTitlePRE = $TreeView_SelTitle EndIf ConsoleWrite($TreeView_SelTitle & @CRLF) $sQuery = "SELECT count(Title) FROM SSDB WHERE Title IS '" & $TreeView_SelTitle & "'" _SQLite_GetTable(-1, $sQuery, $aResult, $iRows, $iColumns) ;GUICtrlSendMsg( $hListView, $LVM_SETITEMCOUNT, $aResult[2], 0 ) ConsoleWrite("Rows = " & $aResult[2] & @CRLF) _SQLite_Exec( -1, "DROP VIEW DisplayView;" ) _SQLite_Exec( -1, "DROP TABLE DisplayMemDb.RowRelation;" ) _SQLite_Exec( -1, "CREATE TEMP VIEW DisplayView AS SELECT Name,Time,Category FROM SSDB WHERE Title IS '" & $TreeView_SelTitle & "';" ) _SQLite_Exec( -1, "CREATE TABLE DisplayMemDb.RowRelation AS SELECT Name FROM DisplayView;" ) GUICtrlSendMsg( $ListView, $LVM_SETITEMCOUNT, Int($aResult[2]), 0 ) ; GUICtrlSendMsg works with control IDs only, $aResult[2] (string) must be an integer EndFunc ;========================================================================================== Func DBInit() Local $aResult, $iRows, $iColumns ;------------------------------------------------------------------------------------------ Local $sPathTo_SSDB = @ScriptDir & "\SSDB.sqlite" Local $sPathTo_SQLiteDLL = @ScriptDir & "\sqlite3.dll" Global $sSqlBuild_Table = "(Title, Name, Time, Category, column_05, column_06, column_07, column_08)" ;------------------------------------------------------------------------------------------ _SQLite_Startup($sPathTo_SQLiteDLL) If FileExists($sPathTo_SSDB) Then $hSSDB = _SQLite_Open($sPathTo_SSDB) Else $hSSDB = _SQLite_Open($sPathTo_SSDB) ;------------------------------------------------------------------------------------------ _SQLite_Exec($hSSDB, "CREATE TABLE IF NOT EXISTS SSDB (Title, Name PRIMARY KEY, Time, Category, column_05, column_06, column_07, column_08);") ;------------------------------------------------------------------------------------------ $sQuery = "" For $i = 1 To 5 $sQuery &= 'INSERT INTO SSDB ' & $sSqlBuild_Table & ' VALUES ' $sTitle = String($i) & String($i) & String($i) If $i = 1 Then For $j = 0 To 620000 $sQuery &= "('" & StringRegExpReplace($sTitle, "'", "''") & "'" $sQuery &= ",'" & StringRegExpReplace($sTitle & "_" & $j, "'", "''") & "'" $sQuery &= ",'" & StringRegExpReplace("12345", "'", "''") & "'" $sQuery &= ",'" & StringRegExpReplace("123", "'", "''") & "'" $sQuery &= ",'','','','')," Next Else For $j = 0 To 62000 $sQuery &= "('" & StringRegExpReplace($sTitle, "'", "''") & "'" $sQuery &= ",'" & StringRegExpReplace($sTitle & "_" & $j, "'", "''") & "'" $sQuery &= ",'" & StringRegExpReplace("12345", "'", "''") & "'" $sQuery &= ",'" & StringRegExpReplace("123", "'", "''") & "'" $sQuery &= ",'','','','')," Next EndIf $sQuery &= "('" & StringRegExpReplace($sTitle, "'", "''") & "'" $sQuery &= ",'" & StringRegExpReplace($sTitle & "_" & $j, "'", "''") & "'" $sQuery &= ",'" & StringRegExpReplace("12345", "'", "''") & "'" $sQuery &= ",'" & StringRegExpReplace("123", "'", "''") & "'" $sQuery &= ",'','','','');" Next If Not (_SQLite_Exec(-1, $sQuery) = $SQLITE_OK) Then Return SetError(2) EndIf _SQLite_Exec( -1, "ATTACH DATABASE ':memory:' AS DisplayMemDb;" ) ; <<<<<<<<<<<<<<<<<<< _SQLite_Exec( -1, "CREATE TEMP VIEW DisplayView AS SELECT Name,Time,Category FROM SSDB WHERE Title IS '111';" ) _SQLite_Exec( -1, "CREATE TABLE DisplayMemDb.RowRelation AS SELECT Name FROM DisplayView;" ) EndFunc ;========================================================================================== Func LWS_WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam ) Local Static $tText = DllStructCreate( "wchar[512]" ) Local Static $pText = DllStructGetPtr( $tText ) Local Static $aResult, $iRows, $iFrom Local $tNMHDR, $hWndFrom, $iCode, $tInfo, $VKey $tNMHDR = DllStructCreate( $tagNMHDR, $lParam ) $hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) ) $iCode = DllStructGetData( $tNMHDR, "Code" ) Switch $hWndFrom Case $hListView Switch $iCode Case $NM_CUSTOMDRAW Local $tNMLVCUSTOMDRAW = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam) Local $dwDrawStage = DllStructGetData($tNMLVCUSTOMDRAW, "dwDrawStage") Local $dwItemSpec = DllStructGetData($tNMLVCUSTOMDRAW, "dwItemSpec") Switch $dwDrawStage ; Holds a value that specifies the drawing stage Case $CDDS_PREPAINT ; Before the paint cycle begins Return $CDRF_NOTIFYITEMDRAW ; Notify the parent window of any item-related drawing operations Case $CDDS_ITEMPREPAINT ; Before painting an item If Mod( $dwItemSpec, 2 ) = 0 Then DllStructSetData( $tNMLVCUSTOMDRAW, "ClrTextBk", 0xFFFFFF ) Else DllStructSetData( $tNMLVCUSTOMDRAW, "ClrTextBk", 0xF8FFF8 ) EndIf Return $CDRF_NEWFONT ; $CDRF_NEWFONT must be returned after changing font or colors EndSwitch Case $LVN_GETDISPINFOW Local $tNMLVDISPINFO = DllStructCreate( $tagNMLVDISPINFO, $lParam ) If BitAND( DllStructGetData( $tNMLVDISPINFO, "Mask" ), $LVIF_TEXT ) Then Local $iIndex = DllStructGetData( $tNMLVDISPINFO, "Item" ) - $iFrom + 1 If $iIndex > 0 And $iIndex < $iRows + 1 Then Local $sItem = $aResult[$iIndex][DllStructGetData($tNMLVDISPINFO,"SubItem")] DllStructSetData( $tText, 1, $sItem ) DllStructSetData( $tNMLVDISPINFO, "Text", $pText ) DllStructSetData( $tNMLVDISPINFO, "TextMax", StringLen( $sItem ) ) EndIf EndIf Case $LVN_ODCACHEHINT Local $tNMLVCACHEHINT = DllStructCreate( $tagNMLVCACHEHINT, $lParam ), $iColumns $iFrom = DllStructGetData( $tNMLVCACHEHINT, "iFrom" ) ;Local $sSQL = "SELECT Name,Time,Category FROM SSDB WHERE Title IS '" & $TreeView_SelTitle & "' AND item_id >= " & $iFrom & " AND item_id <= " & DllStructGetData( $tNMLVCACHEHINT, "iTo" ) & ";" Local $sSQL = "SELECT RowRelation.rowid,DisplayView.Name,Time,Category FROM DisplayView INNER JOIN RowRelation ON DisplayView.Name = RowRelation.Name WHERE RowRelation.rowid BETWEEN " & $iFrom + 1 & " And " & DllStructGetData( $tNMLVCACHEHINT, "iTo" ) + 1 & ";" _SQLite_GetTable2d( -1, $sSQL, $aResult, $iRows, $iColumns ) EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc  I have marked the code in post 35 as deprecated but left the code as it is. Then you can see what happens if you forget the primary key.  Take a look at the code in post 41. It's a small example (just 100,000 rows) that shows a way to implement a search box. Controls,  File Explorer,  ROT objects,  UI Automation,  Windows Message MonitorCompiled code: Accessing AutoIt variables,  DotNet.au3 UDF,  Using C# and VB codeShell menus: The Context menu,  The Favorites menu. Shell related: Control Panel,  System Image ListsGraphics related: Rubik's Cube,  OpenGL without external libraries,  Navigating in an image,  Non-rectangular selectionsListView controls: Colors and fonts,  Multi-line header,  Multi-line items,  Checkboxes and icons,  Incremental searchListView controls: Virtual ListViews,  Editing cells,  Data display functions
pvnn Posted February 17, 2016 Posted February 17, 2016 LarsJ, with SQLite all is clear. Both as a data source to use other databases: PostgreSQL or Oracle? What to use instead _SQLite_GetTable2d. Can you give a simple example? Thank you
LarsJ Posted February 18, 2016 Author Posted February 18, 2016 The easiest way to use AutoIt with other databases besides SQLite is using ADO. You can start by looking at the information in these links: AutoIt ADO Wiki, Connecting to a PostgreSQL database and ADO Programmer's Reference. In post 2 in second link you can find AdoSQL.au3 which contains the function _AdoSQL_GetData2d. I think this is the direct replacement of _SQLite_GetTable2d. To search the AutoIt forums you can Google in this way: oracle site:autoitscript.com If you have more questions related to ADO you'll get better answers in "AutoIt General Help and Support" forum. I'm not at all an ADO expert. argumentum 1 Controls,  File Explorer,  ROT objects,  UI Automation,  Windows Message MonitorCompiled code: Accessing AutoIt variables,  DotNet.au3 UDF,  Using C# and VB codeShell menus: The Context menu,  The Favorites menu. Shell related: Control Panel,  System Image ListsGraphics related: Rubik's Cube,  OpenGL without external libraries,  Navigating in an image,  Non-rectangular selectionsListView controls: Colors and fonts,  Multi-line header,  Multi-line items,  Checkboxes and icons,  Incremental searchListView controls: Virtual ListViews,  Editing cells,  Data display functions
pvnn Posted February 25, 2016 Posted February 25, 2016 LarsJ thank you for Links. Excellent library AdoSQL.au3. I was able to create a Virtual ListView as a data source PostgreSQL and Oracle Thank you very much for your help
Terenz Posted October 8, 2016 Posted October 8, 2016 (edited) On 12/2/2016 at 4:36 PM, LarsJ said: You are welcome Hi Lars, When you have time i'd like to see an edited example of "LvVirtArraySort" with checkboxes, if is possible. I have study the example on my own, many things are clear but others not: 1) Is possible to sort "Column 0" based on array[x][y]? On the example "LvVirtArrayIcons" the checkbox was stored on the array ( $aItems[$iItem][10] ) and i don't have understood if is possible also with "LvVirtArraySort" when you click on the column since you are sorting before the click, example make an order for checkbox checked-unchecked. 2) Is possible to avoid index 0 of the array when sorting leaving the first row untouched? I have check it out "SortNumbers" and "SortStrings" but is overclomplex for me, editing things like $i = 0 or $j = 0 don't give the expected result. Thanks in advance Edited October 8, 2016 by Terenz Nothing is so strong as gentleness. Nothing is so gentle as real strength Â
LarsJ Posted October 10, 2016 Author Posted October 10, 2016 (edited) Terenz, Here is an example of LvVirtArraySort with checkboxes. The rows are sorted according to checked state and column. Picture to the left. I'm not quite sure if that's what you mean with point 1. If I've misunderstood it, you have to add a new post. In the next example the first row is left unsorted. It's always the first row. To keep code simple I've removed the tab control and some of the functionality of the buttons in the listview header. The sorting is only in the ascending order with respect to the columns. Now that I've found out how to do it, I'll add the functionality of the header buttons again. I might manage to make a new example till tomorrow. Virtual ListViews.7z Edited October 10, 2016 by LarsJ Terenz and Danyfirex 2 Controls,  File Explorer,  ROT objects,  UI Automation,  Windows Message MonitorCompiled code: Accessing AutoIt variables,  DotNet.au3 UDF,  Using C# and VB codeShell menus: The Context menu,  The Favorites menu. Shell related: Control Panel,  System Image ListsGraphics related: Rubik's Cube,  OpenGL without external libraries,  Navigating in an image,  Non-rectangular selectionsListView controls: Colors and fonts,  Multi-line header,  Multi-line items,  Checkboxes and icons,  Incremental searchListView controls: Virtual ListViews,  Editing cells,  Data display functions
Terenz Posted October 10, 2016 Posted October 10, 2016 (edited) I'm not sure about the choice to sort only the flagged item, in my mind was more simple. First column with checkbox, ascending sort by checked item-unchecked item and descending sort by unchecked item-checked item, value sorted by actual order like if was sorted by strings sort also the checked item in that order. Other columns must be independent by the checked state so we don't loose the descending order, if i want to sort by "Intergers" clicking on the column i want to sort everything not only the item i have selected. I'm not saying you did it wrong or anything like that lol I only had a different idea in mind about the checkbox and sorting, maybe i'm totally astray since i'm treat the checkbox column like any other column. EDIT: Some images just for be clear, i have forget the static first row. P.S I prefer the simplest example without button-tabs etc. more readable, without ternary is better but is just my little opinion since i never use it. Edited October 10, 2016 by Terenz Nothing is so strong as gentleness. Nothing is so gentle as real strength Â
LarsJ Posted October 12, 2016 Author Posted October 12, 2016 (edited) This seems to be a relatively simple sorting. You just sort the rows by one column at a time in ascending order. Only the subitems in this specific column are used for the sorting. The column with the checkboxes does not contain any text values. This column is sorted by the checked state. You can implement such a sorting in a normal listview if you create your own sorting function. You don't need a virtual listview for that. Or will the listview contain a large number of rows? And then you want to use a virtual listview of performance reasons. How many rows and columns do you expect the listview will contain? What is the data source for the listview? Where do you get the data from? I've added the checkboxes to an otherwise empty column and created a sorting function for it. I've set some of the checkboxes to the checked state in advance. Virtual ListViews.7z The Ternary operator is almost twice as fast as an If...Else...EndIf block. It's very useful in loops and in fast repeated calls of for example VM_Message handler functions. Edited October 12, 2016 by LarsJ Terenz 1 Controls,  File Explorer,  ROT objects,  UI Automation,  Windows Message MonitorCompiled code: Accessing AutoIt variables,  DotNet.au3 UDF,  Using C# and VB codeShell menus: The Context menu,  The Favorites menu. Shell related: Control Panel,  System Image ListsGraphics related: Rubik's Cube,  OpenGL without external libraries,  Navigating in an image,  Non-rectangular selectionsListView controls: Colors and fonts,  Multi-line header,  Multi-line items,  Checkboxes and icons,  Incremental searchListView controls: Virtual ListViews,  Editing cells,  Data display functions
Terenz Posted October 12, 2016 Posted October 12, 2016 (edited) My listview has huge number of rows and at least 10 column ( and the array with information is 15! ) is a sort of database of people with personal information and contacts for this reason i'm using the virtual listview. I'll let you know about your example at time i'm testing it, thanks again. EDIT: Tested, you can add also: 1) The descending sorting 2) Static first row Thanks Edited October 12, 2016 by Terenz Nothing is so strong as gentleness. Nothing is so gentle as real strength Â
LarsJ Posted October 13, 2016 Author Posted October 13, 2016 (edited) Descending sort order and this static row: Virtual ListViews.7z Since the structures are only being used for sorting, you can achieve a performance gain by replacing structures with arrays after the sorting. Then you can use arrays in the WM_NOTIFY function instead of structures. An array lookup is at least twice as fast as a structure lookup. The more columns you have, the bigger the performance gain will be. Also the SortChecks function will probably be twice as fast. But you'll need a little bit of logic to handle the static row. Edited October 13, 2016 by LarsJ Terenz 1 Controls,  File Explorer,  ROT objects,  UI Automation,  Windows Message MonitorCompiled code: Accessing AutoIt variables,  DotNet.au3 UDF,  Using C# and VB codeShell menus: The Context menu,  The Favorites menu. Shell related: Control Panel,  System Image ListsGraphics related: Rubik's Cube,  OpenGL without external libraries,  Navigating in an image,  Non-rectangular selectionsListView controls: Colors and fonts,  Multi-line header,  Multi-line items,  Checkboxes and icons,  Incremental searchListView controls: Virtual ListViews,  Editing cells,  Data display functions
Terenz Posted October 14, 2016 Posted October 14, 2016 Thank you so much. If the structure are used only for sorting, we can't sort directly the array and the show the result in the listview? Maybe require more time sorting an array? Structure are a mystery to me, with array after many years i can unravel, more or less Nothing is so strong as gentleness. Nothing is so gentle as real strength Â
Terenz Posted October 16, 2016 Posted October 16, 2016 (edited) On 13/10/2016 at 1:40 PM, LarsJ said: Descending sort order and this static row: Lars a problem with the first static row. I'd like to see the checkbox on the first line ( it have a function ) but if i'll change: $aItems[$iRows-1][0] = 8192 ; Check mark, 0 = Empty, 4096 = Unchecked, 8192 = Checked The first row will be involved in the checkbox sorting. Can you resolve please? Thanks EDIT: I think i have resolved by myself, if i have other issue i'll report. Edited October 16, 2016 by Terenz Nothing is so strong as gentleness. Nothing is so gentle as real strength Â
LarsJ Posted October 17, 2016 Author Posted October 17, 2016 Sorting. You can test how long it takes to sort the array by a column. If it doesn't take too long, you can sort the array directly. You must re-sort the array when you click a sort button in the listview header. One way to get around all the sorting issues, is to store the array in a database.   Cleanup in first post. Added list of examples. Controls,  File Explorer,  ROT objects,  UI Automation,  Windows Message MonitorCompiled code: Accessing AutoIt variables,  DotNet.au3 UDF,  Using C# and VB codeShell menus: The Context menu,  The Favorites menu. Shell related: Control Panel,  System Image ListsGraphics related: Rubik's Cube,  OpenGL without external libraries,  Navigating in an image,  Non-rectangular selectionsListView controls: Colors and fonts,  Multi-line header,  Multi-line items,  Checkboxes and icons,  Incremental searchListView controls: Virtual ListViews,  Editing cells,  Data display functions
LarsJ Posted December 15, 2016 Author Posted December 15, 2016 (edited) In this example a CSV-file with 100,000 rows and 10 columns is data source for a virtual listview. Run LvVirtCSVfileCreate.au3 to create the CSV-file. It takes a few seconds. Run LvVirtCSVfile.au3 to display the CSV-file in the listview. The listview shows up instantly. The CSV-file is loaded into a 1D-array with FileReadToArray. The caching mechanism (see first post) of the virtual listview is used to split the items (rows) into 10 subitems (columns) and store the subitems in a display array. The listview is filled with data from the display array through $LVN_GETDISPINFOW notifications. expandcollapse popup#include <GUIConstants.au3> #include <WindowsConstants.au3> #include <GuiListView.au3> Opt( "MustDeclareVars", 1 ) Global $hLV, $aItems Example() Func Example() ; Create GUI GUICreate( "Virtual ListViews", 880, 400 ) ; Create ListView Local $idLV = GUICtrlCreateListView( "", 10, 10, 880-20, 400-20, $LVS_OWNERDATA, BitOR( $WS_EX_CLIENTEDGE, $LVS_EX_DOUBLEBUFFER, $LVS_EX_FULLROWSELECT ) ) $hLV = GUICtrlGetHandle( $idLV ) ; Virtual listview Reduces flicker _GUICtrlListView_AddColumn( $hLV, "Col0", 100 ) _GUICtrlListView_AddColumn( $hLV, "Col1", 100 ) _GUICtrlListView_AddColumn( $hLV, "Col2", 100 ) For $i = 3 To 9 _GUICtrlListView_AddColumn( $hLV, "Col" & $i, 75 ) Next ; WM_NOTIFY message handler GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" ) GUISetState( @SW_SHOW ) ; Load data from CSV-file $aItems = FileReadToArray( "LvVirtCSVfile.csv" ) GUICtrlSendMsg( $idLV, $LVM_SETITEMCOUNT, UBound( $aItems ), 0 ) ; Message loop While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd GUIDelete() EndFunc Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam ) Static $tagNMLVCACHEHINT = $tagNMHDR & ";int iFrom;int iTo" Static $tText = DllStructCreate( "wchar[50]" ) Static $pText = DllStructGetPtr( $tText ) Static $aDisplay[100][10], $iRows, $iFrom Local $tNMHDR = DllStructCreate( $tagNMHDR, $lParam ) Local $hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) ) Local $iCode = DllStructGetData( $tNMHDR, "Code" ) Switch $hWndFrom Case $hLV Switch $iCode Case $LVN_GETDISPINFOW Local $tNMLVDISPINFO = DllStructCreate( $tagNMLVDISPINFO, $lParam ) If BitAND( DllStructGetData( $tNMLVDISPINFO, "Mask" ), $LVIF_TEXT ) Then Local $iIndex = DllStructGetData( $tNMLVDISPINFO, "Item" ) - $iFrom If $iIndex >= 0 And $iIndex < $iRows Then Local $sItem = $aDisplay[$iIndex][DllStructGetData($tNMLVDISPINFO,"SubItem")] DllStructSetData( $tText, 1, $sItem ) DllStructSetData( $tNMLVDISPINFO, "Text", $pText ) DllStructSetData( $tNMLVDISPINFO, "TextMax", StringLen( $sItem ) ) EndIf EndIf Case $LVN_ODCACHEHINT Local $tNMLVCACHEHINT = DllStructCreate( $tagNMLVCACHEHINT, $lParam ) Local $iTo = DllStructGetData( $tNMLVCACHEHINT, "iTo" ), $aSubItems $iFrom = DllStructGetData( $tNMLVCACHEHINT, "iFrom" ) $iRows = 0 For $i = $iFrom To $iTo $aSubItems = StringSplit( $aItems[$i], ",", 2 ) ; 2 = $STR_NOCOUNT For $j = 0 To 9 $aDisplay[$iRows][$j] = $aSubItems[$j] Next $iRows += 1 Next EndSwitch EndSwitch Return $GUI_RUNDEFMSG #forceref $hWnd, $iMsg, $wParam EndFunc The two scripts are included in the zip: CSVfile.7z Edited December 15, 2016 by LarsJ Controls,  File Explorer,  ROT objects,  UI Automation,  Windows Message MonitorCompiled code: Accessing AutoIt variables,  DotNet.au3 UDF,  Using C# and VB codeShell menus: The Context menu,  The Favorites menu. Shell related: Control Panel,  System Image ListsGraphics related: Rubik's Cube,  OpenGL without external libraries,  Navigating in an image,  Non-rectangular selectionsListView controls: Colors and fonts,  Multi-line header,  Multi-line items,  Checkboxes and icons,  Incremental searchListView controls: Virtual ListViews,  Editing cells,  Data display functions
Adrian123 Posted March 26, 2017 Posted March 26, 2017 Hi thank You for your work I'm trying to implement here https://www.autoitscript.com/forum/topic/187651-virtual-listview-sqlite But I have some memory leaking an you please help me with an advice you seam to know winapi in depth Thanks Adrian  Â
Adrian123 Posted March 27, 2017 Posted March 27, 2017 Answered here : https://www.autoitscript.com/forum/topic/187651-virtual-listview-sqlite Thank You.
kklee69 Posted June 27, 2017 Posted June 27, 2017 (edited) Â Â CAN WE DOÂ Virtual listviews + 2 LINE TXTÂ IN LISTVIEW ?? PLEASE HELP ME Edited June 27, 2017 by kklee69
LarsJ Posted June 27, 2017 Author Posted June 27, 2017 Yes, You can use 2-line texts in a virtual listview. If you need more help than this, please be more specific. Controls,  File Explorer,  ROT objects,  UI Automation,  Windows Message MonitorCompiled code: Accessing AutoIt variables,  DotNet.au3 UDF,  Using C# and VB codeShell menus: The Context menu,  The Favorites menu. Shell related: Control Panel,  System Image ListsGraphics related: Rubik's Cube,  OpenGL without external libraries,  Navigating in an image,  Non-rectangular selectionsListView controls: Colors and fonts,  Multi-line header,  Multi-line items,  Checkboxes and icons,  Incremental searchListView controls: Virtual ListViews,  Editing cells,  Data display functions
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now