StungStang Posted April 6, 2011 Share Posted April 6, 2011 (edited) Hi to all, my question is not about an issue...but i want to know if there are a metods to improve the Adding Item to listview. I've about 7000 item to add in a listview...but it take about 30 second! This is an example : _GUICtrlListView_BeginUpdate($hListView) _GUICtrlListView_DeleteAllItems($hListView) For $i = 1 to 7000 GUICtrlCreateListViewItem($Line[$i], $ListView) next _GUICtrlListView_EndUpdate($ListView) It's very slow...there are improvment for that? Hi! Edited April 6, 2011 by StungStang Link to comment Share on other sites More sharing options...
Mat Posted April 6, 2011 Share Posted April 6, 2011 The only thing I can think of is of is to use a virtual listview (read through the MSDN page here). It looks as though you already have the lines in an array so it should be easy AutoIt Project Listing Link to comment Share on other sites More sharing options...
StungStang Posted April 6, 2011 Author Share Posted April 6, 2011 Yes i have already the lines in an array... I see the MSDN page...but sincerly i can't understand too much...al the example is not written in autoit (ofc), it's hard to understand... Can you help me with it? hi! Link to comment Share on other sites More sharing options...
StungStang Posted April 7, 2011 Author Share Posted April 7, 2011 Up Link to comment Share on other sites More sharing options...
AutoBert Posted April 7, 2011 Share Posted April 7, 2011 Yes i have already the lines in an array...Then you can use _GUICtrlListView_AddArray. This is the fastest way. Link to comment Share on other sites More sharing options...
ReFran Posted April 7, 2011 Share Posted April 7, 2011 perhabs: _GUICtrlListView_AddArray do what you want. best regards, Reinhard Link to comment Share on other sites More sharing options...
BrewManNH Posted April 7, 2011 Share Posted April 7, 2011 I'm not sure how much data is in each line, but I added a list of 7000 dummy lines (each line held approximately 26 characters) to a Listview from an array in about .06 seconds using your code above. I can't see how you are getting 30 seconds to do the same thing unless your computer is extremely slow. Also, using _GUICtrlListView_AddArray it took about 10 times LONGER than looping through the array using the exact same data to create the listview. If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator Link to comment Share on other sites More sharing options...
StungStang Posted April 7, 2011 Author Share Posted April 7, 2011 (edited) Im using a pentium 4 with 2 Gb of ram with win xp pro sp3, not too much slow... My listview iteam line is formed like that : Radio Name|Streaming Link|Web Site|Genre|Country I grab the info from a sql database...the search time is about 3 second...stamp time is about 30 second! This is the piece of code that create listview item GUICtrlListView_BeginUpdate($hListView) _GUICtrlListView_DeleteAllItems($hListView) Local $hQuery, $aRow, $aNames _SQLite_Query(-1, "SELECT * FROM Data WHERE Radio LIKE '%" & $sText & "%';", $hQuery) While _SQLite_FetchData($hQuery, $aRow, False, False) = $SQLITE_OK $Line = $aRow[0] & "|" & $aRow[1] & "|" & $aRow[2] & "|" & $aRow[3] & "|" & $aRow[4] GUICtrlCreateListViewItem($Line, $ListView) WEnd _GUICtrlListView_EndUpdate($hListView) How you do that in 6 second?...What kind of pc you have? Hi Edited April 7, 2011 by StungStang Link to comment Share on other sites More sharing options...
BrewManNH Posted April 7, 2011 Share Posted April 7, 2011 That's hardly the same code as you posted in the first post. Here you're pulling the information from a SQL database, manipulating that information to format it the way you wanted, and then adding it to the listview. As I don't know much if anything about SQL queries, I don't know what information you're getting. It's not the code adding the information to the LV that's taking so much time, it's the data manipulation. Because if you had a 7000 line array with all of the information already in it, it would take very little time to create the LV from it. If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator Link to comment Share on other sites More sharing options...
StungStang Posted April 7, 2011 Author Share Posted April 7, 2011 Im getting an info like that : Radiname|Streaminglink|Website|Genre|Country To grab the info the application take about 3 second...to populate the listview it take 28 second! Too much... :/ Have you some trick?...What about this "virtual listview"? Hi! Link to comment Share on other sites More sharing options...
Mat Posted April 7, 2011 Share Posted April 7, 2011 Bingo: AutoIt Project Listing Link to comment Share on other sites More sharing options...
StungStang Posted April 7, 2011 Author Share Posted April 7, 2011 (edited) It's look like an faster array display function... I have to use a listview...with that i can read the listview selected item, that contain the info for reproducing my preferite radio with bass.dll Thank's again for your help Edited April 7, 2011 by StungStang Link to comment Share on other sites More sharing options...
Mat Posted April 7, 2011 Share Posted April 7, 2011 It is a faster _ArrayDisplay function (which uses a listview btw), but it makes it faster by using a virtual listview. The source code is rather cryptic thanks to the person deciding he could make it faster by using values rather than constants, so it will take some work. Unfortunately for you I'm writing exams soon, so I don't have much time to write out a full example for you. However, you now have a method you can try to implement which already has an example (albeit not that nice to look at) in AutoIt, so I think you could at least make a considerable start in getting some code together. Take a few days and I would try and tidy up the faster _ArrayDisplay, you can then take that and change it to better suite your needs. Once you have a basic example that is legible then the solution will either become clear or you will be able to get more specific help from us. On an interesting aside (don't even think about this yet) for future reference, once you have the virtual list view sorted then look up the notification codes in place to deal with cache. It may be you can speed up loading of the data from the database (a perfect example of when caching like this is suitable) so that you only load items you need. I wouldn't worry about that until you have the listview working though. AutoIt Project Listing Link to comment Share on other sites More sharing options...
AutoBert Posted April 8, 2011 Share Posted April 8, 2011 Hello, try _SQLite_GetTable2d instead of _SQLite_Query:Local $aResult, $iRows, $iColumns _GUICtrlListView_BeginUpdate($hListView) _GUICtrlListView_DeleteAllItems($hListView) Local $hQuery, $aRow, $aNames $iRval = _SQLite_GetTable2d(-1, "SELECT * FROM Data WHERE Radio LIKE '%" & $sText & "%';", $aResult, $iRows, $iColumns) _ArrayDelete($aResult,0) ;delete columnnames If $iRval = $SQLITE_OK Then _GUICtrlListView_AddArray($aResult) _GUICtrlListView_EndUpdate($hListView) mfg autoBert Link to comment Share on other sites More sharing options...
StungStang Posted April 8, 2011 Author Share Posted April 8, 2011 (edited) Hello, try _SQLite_GetTable2d instead of _SQLite_Query:Local $aResult, $iRows, $iColumns _GUICtrlListView_BeginUpdate($hListView) _GUICtrlListView_DeleteAllItems($hListView) Local $hQuery, $aRow, $aNames $iRval = _SQLite_GetTable2d(-1, "SELECT * FROM Data WHERE Radio LIKE '%" & $sText & "%';", $aResult, $iRows, $iColumns) _ArrayDelete($aResult,0) ;delete columnnames If $iRval = $SQLITE_OK Then _GUICtrlListView_AddArray($aResult) _GUICtrlListView_EndUpdate($hListView) mfg autoBert Good improvement...passed to 30 second in 9 second...other trick or is the best that can do ?... What about a virtual listview?...Anyone have an example ? Hi Edited April 8, 2011 by StungStang Link to comment Share on other sites More sharing options...
Mat Posted April 8, 2011 Share Posted April 8, 2011 You have an example. The faster version of _ArrayDisplay uses a virtual listview. AutoIt Project Listing Link to comment Share on other sites More sharing options...
AutoBert Posted April 8, 2011 Share Posted April 8, 2011 Good improvement...passed to 30 second in 9 second...The better result (21 second) is ca. 80% the faster way to get the data in SQLite so i cann't believeTo grab the info the application take about 3 second...to populate the listview it take 28 second!Too much... :/mfg autoBert Link to comment Share on other sites More sharing options...
StungStang Posted April 9, 2011 Author Share Posted April 9, 2011 You have an example. The faster version of _ArrayDisplay uses a virtual listview.It's true...but sincerly i dont know how to create a virtual listview No too much example here... Link to comment Share on other sites More sharing options...
BrewManNH Posted April 10, 2011 Share Posted April 10, 2011 Considering the fact that you can populate a listview with 7000 rows in WELL under .1 second by looping through an array, just exactly how much faster do you need it to be? If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator Link to comment Share on other sites More sharing options...
Mat Posted April 10, 2011 Share Posted April 10, 2011 Ok. This is the last time I'm going to point you to the same piece of code. The main file for the faster _ArrayDisplay took me 2mins to edit to get the following, and even most of that was just to take out an include so you'd have one file you could copy, paste and run. Bear in mind that this code is designed to suite all kinds of arrays. You could make it faster by making certain assumptions, like the dimensions of the array, and how many columns you need, that you don't want to sort... There are so many ways you can get a bit more speed out of this. And then there is what I said about caching and the database in an earlier post. Thats the right way to do this. expandcollapse popup; _ArrayDisplayVS.au3 ;~ #AutoIt3Wrapper_AU3Check_Parameters= -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 #include <GuiListView.au3> #include <GuiEdit.au3> #include <string.au3> ;#include <_ArrayDisplaySort.au3> ;~ #include <StringSplit.au3> ;~ #include <_ArraySortClib2SetV.au3> Global $iEndVPrev, $iToVPrev, $aArrayIndexV[1], $iStartcolV, $slider1V, $iStartVPrev, $iFromVPrev Global $tTextBufferV, $iCaseV, $avArrayV, $s_LISTVIEWSortOrderV, $iUBoundV, $iColV, $sSeparatorV, $imaskV, $iNumRowsV;, $iTimerProgressV Global $vDescendingV[1], $arArAscV[1], $i_LISTVIEWPrevcolumnV = -1, $ar_LISTVIEWArrayV[1], $hGUI, $hListView, $iStartV, $iEndV;, $arArDescV2V[1] Global $maxlenV, $tTextPtrV, $iNotSortedV, $iToV, $iFromV, $avTempV[1][1], $iColumnCountV, $iColumnToDisplayV, $iRowV, $tNMLVDISPINFOV Global $iTimeSPlitDataV, $iTimeSetDataV, $iTimeStartDataV, $iTimeStartCacheV, $iTimeRemCacheV, $iTimeStartMaskV, $iColWidth Global Const $WM_HSCROLL = 0x0114 Global $hMsvcrtV, $sStrCmpV, $tFloatCmpV, $pCmpV, $tIndexerV, $tagSourceV, $tSourceV, $pSourceV, $procStrCmpV ;============================================================================================================================== Local $aItems[7000] For $i = 0 To 6999 $aItems[$i] = "Item: " & $i Next _ArrayDisplaySortV($aItems) ;============================================================================================================================== Func _ArrayDisplaySortV(Const ByRef $avArrayVF, $sTitle = "Array: ListView Display", $iItemLimit = 0, $iOptions = 0, $sSeparatorVF = "", $sReplace = "") #Region const Local Const $_ARRAYUUCONSTANT_GUI_EVENT_CLOSE = -3 Local Const $_ARRAYUUCONSTANT_LVM_GETITEMCOUNT = (0x1000 + 4) Local Const $_ARRAYUUCONSTANT_LVM_GETITEMSTATE = (0x1000 + 44) Local Const $LVM_SETCOLUMNWIDTHU = (0x1000 + 30) Local Const $LVSCWU_AUTOSIZE = -1 Local Const $LVSCWU_AUTOSIZE_USEHEADER = -2 ;===========================================added rjc ;;virtual lv style Local Const $LVS_OWNERDATA = 0x1000 Local Const $_ARRAYCONSTANT_GUI_DOCKBORDERS = 0x66 Local Const $_ARRAYCONSTANT_GUI_DOCKBOTTOM = 0x40 Local Const $_ARRAYCONSTANT_GUI_DOCKHEIGHT = 0x0200 Local Const $_ARRAYCONSTANT_GUI_DOCKLEFT = 0x2 Local Const $_ARRAYCONSTANT_GUI_DOCKRIGHT = 0x4 Local Const $_ARRAYCONSTANT_GUI_EVENT_CLOSE = -3 Local Const $_ARRAYCONSTANT_LVIF_PARAM = 0x4 Local Const $_ARRAYCONSTANT_LVIF_TEXT = 0x1 Local Const $_ARRAYCONSTANT_LVM_GETITEMCOUNT = (0x1000 + 4) Local Const $_ARRAYCONSTANT_LVM_GETITEMSTATE = (0x1000 + 44) Local Const $_ARRAYCONSTANT_LVM_INSERTITEMA = (0x1000 + 7) Local Const $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE = (0x1000 + 54) Local Const $_ARRAYCONSTANT_LVM_SETITEMA = (0x1000 + 6) Local Const $_ARRAYCONSTANT_LVS_EX_FULLROWSELECT = 0x20 Local Const $_ARRAYCONSTANT_LVS_EX_GRIDLINES = 0x1 Local Const $_ARRAYCONSTANT_LVS_SHOWSELALWAYS = 0x8 Local Const $_ARRAYCONSTANT_WS_EX_CLIENTEDGE = 0x0200 Local Const $_ARRAYCONSTANT_WS_MAXIMIZEBOX = 0x00010000 Local Const $_ARRAYCONSTANT_WS_MINIMIZEBOX = 0x00020000 Local Const $_ARRAYCONSTANT_WS_SIZEBOX = 0x00040000 Local Const $_ARRAYCONSTANT_LVN_GETDISPINFO = -177 Local Const $_ARRAYCONSTANT_tagLVITEM = "int Mask;int Item;int SubItem;int State;int StateMask;ptr Text;int TextMax;int Image;int Param;int Indent;int GroupID;int Columns;ptr pColumns" #EndRegion const #Region first Local $sTextBuff = "char[261]" If Execute("@Unicode") Then $sTextBuff = "w" & $sTextBuff $tTextBufferV = DllStructCreate($sTextBuff) $maxlenV = DllStructGetSize($tTextBufferV) If Execute("@Unicode") Then $maxlenV = $maxlenV / 2 $tTextPtrV = DllStructGetPtr($tTextBufferV) Local $sBlank = "" Local $sCol0 = "", $vTmp, $iNumItems, $iBuffer = 2048000;,64;;$sSeparatorV3, $sSeparatorV2 = $sSeparatorV, Local $timerstamp1 = TimerInit(), $aItem, $i_ColWidth, $i_OrderColumn;, $timerstampprep = TimerInit() Local $iTranspose = BitAND($iOptions, 1), $iSort = BitAND($iOptions, 2) ;~ ReDim $ar_LISTVIEWArrayV[4000] $iCaseV = BitAND($iOptions, 4) $sSeparatorV = $sSeparatorVF $iDelimited = BitAND($iOptions, 8) Local $iReplaceTrue = BitAND($iOptions, 16) Local $iColUnLimited = BitAND($iOptions, 32) ; so 32 sets unlimited cols in Virtual If Not IsArray($avArrayVF) And IsString($avArrayVF) Then $avArrayV = StringSplit(StringStripCR($avArrayVF), @LF) ;~ $iDelimited = 1 Else $avArrayV = $avArrayVF EndIf If Not IsArray($avArrayV) Then Return SetError(1, 0, 0) ; Dimension checking Local $iDimension = UBound($avArrayV, 0), $iSubItems = UBound($avArrayV, 2), $arTitle[1], $sTempHeader = 'Row' ;, $iUBoundV = UBound($avArrayV, 1) If $iDimension > 2 Then Return SetError(2, 0, 0) If $iDelimited And $iDimension > 1 Then $iDelimited = 0 ;===========================================added rjc $arTitle = StringSplit($sTitle, "|") If (UBound($arTitle) > 2 Or $iDelimited) And $iDimension = 1 Then $iSubItems = UBound($arTitle) $iDelimited = 1 $ar_LISTVIEWArrayV = $avArrayV EndIf ; Separator handling If $iDelimited Then $iTranspose = 0 Local $arSeps = StringSplit(",|;", "") $iSort = 1 If $sSeparatorVF = "" Then For $i = 1 To UBound($arSeps) - 1 If StringInStr($avArrayV[0] & $avArrayV[1] & $avArrayV[UBound($avArrayV) - 1], $arSeps[$i]) Then $sSeparatorV = $arSeps[$i] ExitLoop EndIf Next EndIf If $iDelimited And $sSeparatorV <> "" Then $sReplace = $sSeparatorV EndIf If $iSort Then If $sSeparatorV = "" Then $sSeparatorV = "," ;~ $sBlank = " " ;~ $sSeparatorV2 = $sBlank & $sSeparatorV $sReplace = $sSeparatorV EndIf If $sSeparatorV = "" Then $sSeparatorV = Chr(1) If $sReplace == "" Then $sReplace = Chr(1); Then $chr = 1 EndIf If $sReplace == "" Then $sReplace = "&" ;===========================================added rjc If $sTitle = -1 Or $sTitle = "" Then $sTitle = "ListView array 1D and 2D Display" If StringInStr($sTitle, "|") Then; then check if there are header cols too; $arTitle = StringSplit($sTitle, "|") $sTitle = StringReplace($arTitle[1], $sSeparatorV, $sReplace, 0, 1);$arTitle[1] If $arTitle[2] = "" Then $sCol0 = "col 0" $sTempHeader &= $sSeparatorV & StringReplace($arTitle[2], $sSeparatorV, $sReplace, 0, 1) & $sCol0;$arTitle[2] Else $sTempHeader &= $sSeparatorV & "Col 0" EndIf ; Separator handling If $sSeparatorV = "" Then $sSeparatorV = Chr(1) If $sReplace == "" Then $sReplace = Chr(1); Then $chr = 1 EndIf If $sReplace == "" Then $sReplace = "&" ;===========================================added rjc If $sSeparatorV <> $sReplace Or $iReplaceTrue Then ;ConsoleWrite("$iReplaceTrue=" & $iReplaceTrue & @LF) ;~ ConsoleWrite("$sSeparatorV=" & $sSeparatorV & @LF) ;ConsoleWrite("==================================$sReplace=" & $sReplace & @LF) If $iDimension = 2 Then ReDim $avArrayV[$iUBoundV][$iSubItems] For $i = 0 To $iUBoundV - 1 For $j = 0 To $iSubItems - 1 $avArrayV[$i][$j] = StringReplace($avArrayV[$i][$j], $sSeparatorV, $sReplace, 0, 1);replace seaparator Next Next ElseIf $iDimension = 1 Then ReDim $avArrayV[$iUBoundV] For $i = 0 To $iUBoundV - 1 $avArrayV[$i] = StringReplace($avArrayV[$i], $sSeparatorV, $sReplace, 0, 1) ;replace seaparator Next EndIf Else ;~ $avArrayV = $avArrayVF If $iDelimited Then $iSubItems = UBound($arTitle) - 2 $iDelimited = 1 ;~ Local $ar_LISTVIEWArrayV = $avArrayV ;~ For $i = 0 To $iUBoundV - 1 ;~ $vTmp = StringLen($avArrayV[$i]) ;~ If $vTmp > $iBuffer Then $iBuffer = $vTmp ;~ Next EndIf EndIf ReDim $vDescendingV[$iSubItems + 2] ;ConsoleWrite("$iSubItems=" & $iSubItems & @LF) ;~ ;===========================================added rjc If $iDelimited And $iTranspose = 1 Then $iTranspose = 0 $sTitle = "** WARNING ** no transpose for delimited string array: " & $sTitle EndIf ; Hard limits Local $iLVIAddUDFThreshold = 4000, $iColVLimit, $iWidth = @DesktopWidth * 2 / 3, $iHeight = @DesktopHeight * 2 / 3;, $sSeparatorV = $sBlank & $sSeparatorV, $sSeparatorV3 If $iItemLimit > 40 Then $iLVIAddUDFThreshold = $iItemLimit $iColVLimit = $iLVIAddUDFThreshold ;~ If Not $iColUnLimited Then $iColVLimit = 5 ;~ $iColVLimit = 5 If $iItemLimit = 1 Or $iItemLimit < 0 Or $iItemLimit = Default Then $iItemLimit = $iLVIAddUDFThreshold ; Declare/define variables Local $sHeader ;= "Row" ;, $avArrayV[1];, $ar_LISTVIEWArrayV$i, $j, $arSelItems, ; Swap dimensions if transposing If $iTranspose Then Local $iTmp = $iUBoundV $iUBoundV = $iSubItems $iSubItems = $iTmp EndIf ; Set limits for dimensions If Not $iUBoundV Then $iUBoundV = 1 If Not $iSubItems Then $iSubItems = 1 ;===========================================added rjc If $iSubItems > $iColVLimit Then $iSubItems = $iColVLimit $sTitle = "** WARNING ** $iColVLimit maximum 4000: " & $sTitle EndIf ;===========================================added rjc If $iItemLimit < 1 Then $iItemLimit = $iUBoundV If $iUBoundV > $iItemLimit Then $iUBoundV = $iItemLimit ;===========================================added ult If $iLVIAddUDFThreshold > $iUBoundV - 1 Then $iLVIAddUDFThreshold = $iUBoundV - 1 ;===========================================added ult ; Convert array into text for listview ReDim $ar_LISTVIEWArrayV[$iUBoundV] Local $iArrayType = $iDimension + 2 * $iTranspose - 1, $sTxt;, $iTemp=1;, $sExec1 = '"', $sExec2 = '"',$avArrayVText[$iUBoundV + 1] ; Set header up;; make LV header ;===========================================added rjc StringReplace($ar_LISTVIEWArrayV[UBound($ar_LISTVIEWArrayV) - 1], $sSeparatorV, $sSeparatorV) Local $FirstPipes = @extended, $uboundary = $iSubItems - 1, $iMaxPipes = $FirstPipes, $sStrRep ;ConsoleWrite("$iMaxPipes=" & $iMaxPipes & @LF) If $iDelimited Then $uboundary = $iMaxPipes $iSubItems = $uboundary + 1 $avArrayV = $ar_LISTVIEWArrayV $avArrayV[0] = $ar_LISTVIEWArrayV[0] ReDim $arArAscV[$iSubItems + 1] Else ReDim $arArAscV[2] ;for 1D If $iDimension = 2 Then ReDim $arArAscV[UBound($avArrayV, 2) + 1] EndIf ;===========================================added rjc If Not $iDelimited And $iDimension = 1 And Not $iTranspose And Not $iSort Then $uboundary = 0 EndIf If $uboundary > $iColVLimit - 1 Then $uboundary = $iColVLimit - 1 If $uboundary > 4 Then $uboundary = 4 For $i = 1 To $uboundary If $i < UBound($arTitle) - 2 Then $sTempHeader &= $sSeparatorV & StringReplace($arTitle[$i + 2], $sSeparatorV, $sBlank & $sReplace, 0, 1);arTitle[$i + 2] Else $sTempHeader &= $sSeparatorV & "Col " & $i EndIf Next ; Set header up If $iSort Then $sHeader = "Row" & $sSeparatorV & $sHeader $sHeader = $sTempHeader & $sBlank Local $iOnEventMode = Opt("GUIOnEventMode", 0), $sDataSeparatorChar = Opt("GUIDataSeparatorChar", $sSeparatorV) ;ConsoleWrite("$sHeader=" & $sHeader & @LF) ;~ If $iColVLimit > 5 Then $iColVLimit = 5 ;~ If ($iSubItems > 5 And Not $iColUnLimited) Or $iDelimited Then ;10 Then ;~ $iSubItems = 5 ;~ _ArrayDisplaySort($avArrayVF, $sTitle & $sHeader, $iItemLimit, $iOptions, $sSeparatorV, $sReplace) ;~ Return ;~ EndIf ;=========================================== #EndRegion first #Region second Local $iHt = 30 If $iSubItems <= 5 Then $iHt = 0 ; Set interface up $hGUI = GUICreate($sTitle, $iWidth, $iHeight + $iHt, Default, Default, BitOR($_ARRAYCONSTANT_WS_SIZEBOX, $_ARRAYCONSTANT_WS_MINIMIZEBOX, $_ARRAYCONSTANT_WS_MAXIMIZEBOX)) Local $aiGUISize = WinGetClientSize($hGUI), $iGUIwidth = $aiGUISize[0] $hListView = GUICtrlCreateListView($sHeader, 0, 0, $aiGUISize[0], $aiGUISize[1] - 26 - 2 * $iHt, $_ARRAYCONSTANT_LVS_SHOWSELALWAYS + $LVS_OWNERDATA) Local $hCopy = GUICtrlCreateButton("Copy Selected", 3, $aiGUISize[1] - 23, 100, 20) Local $hClose = GUICtrlCreateButton("Close", 200, $aiGUISize[1] - 23, 100, 20) ;~ Local $aiGUISize = WinGetClientSize($hGUI), $iGUIwidth = $aiGUISize[0] $iColWidth = $aiGUISize[0] / 9 ;1280,@DesktopWidth ;~ Local $hRefresh = GUICtrlCreateButton("Refresh", 400, $aiGUISize[1] - 23, 100, 20) ;ConsoleWrite("$iSubItems=" & $iSubItems & @LF) If $iSubItems > 5 Then $slider1V = GUICtrlCreateSlider(3, $aiGUISize[1] - 23 - 30, $aiGUISize[0] - 6, 40) GUICtrlSetLimit(-1, UBound($avArrayV, 2) - 5, 0) ; change min/max value EndIf GUICtrlSetResizing($hListView, $_ARRAYCONSTANT_GUI_DOCKBORDERS) ;~ GUICtrlSetResizing($slider1V, $_ARRAYCONSTANT_GUI_DOCKBORDERS) ;~ GUICtrlSetResizing($hCopy, $_ARRAYCONSTANT_GUI_DOCKBORDERS) ;~ GUICtrlSetResizing($hClose, $_ARRAYCONSTANT_GUI_DOCKBORDERS) GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE, $_ARRAYCONSTANT_LVS_EX_GRIDLINES, $_ARRAYCONSTANT_LVS_EX_GRIDLINES) GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE, $_ARRAYCONSTANT_LVS_EX_FULLROWSELECT, $_ARRAYCONSTANT_LVS_EX_FULLROWSELECT) GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE, $_ARRAYCONSTANT_WS_EX_CLIENTEDGE, $_ARRAYCONSTANT_WS_EX_CLIENTEDGE) GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_DOUBLEBUFFER, $LVS_EX_DOUBLEBUFFER) ; ================================================================================================================ For $i = 0 To $iColVLimit ;;fix columns width GUICtrlSendMsg($hListView, 0x101E, $i, $iColWidth) ;;LVM_SETCOLUMNWIDTH = 0x101E Next ;===========================================added rjc ; ensure column width narrow enough to avoid crash with many columns GUICtrlSendMsg($hListView, $LVM_SETCOLUMNWIDTHU, $iSubItems, $LVSCWU_AUTOSIZE_USEHEADER) ; ================================================================================================================ ;~ ConsoleWrite("$iUBoundV=" &$iUBoundV& @LF) GUICtrlSendMsg($hListView, $LVM_SETITEMCOUNT, $iUBoundV, 0) ;;set total item count - necessary for virtual lv ;~ GUIRegisterMsg($WM_HSCROLL, "WM_HVSCROLL") Local $wProcNew If $iDimension = 1 And Not $iDelimited Then $wProcNew = DllCallbackRegister("_ArrayUDF_WM_NOTIFYSort1D", "ptr", "hwnd;uint;long;ptr") ;;register new window proc ;ConsoleWrite("will sort with _ArrayUDF_WM_NOTIFYSort1D " & @LF) ElseIf $iDimension = 1 Then $wProcNew = DllCallbackRegister("_ArrayUDF_WM_NOTIFYSort2", "ptr", "hwnd;uint;long;ptr") ;;register new window proc ;ConsoleWrite("will sort with _ArrayUDF_WM_NOTIFYSort2 " & @LF) ElseIf $iDimension = 2 Then $wProcNew = DllCallbackRegister("_ArrayUDF_WM_NOTIFYVir2D", "ptr", "hwnd;uint;long;ptr") ;;register new window proc ;ConsoleWrite("will not sort with _ArrayUDF_WM_NOTIFYVir2D " & @LF) EndIf Local $wProcOld = _ArrayUDF_WinSubclassV($hGUI, DllCallbackGetPtr($wProcNew)) ;;sublass gui Assign('ArrayUDF_wProcOld', $wProcOld, 2) ;; $ArrayUDF_wProcOld = global keeper of old windowproc ptr ;===========================================added rjc ; Show dialog GUISetState(@SW_SHOW, $hGUI) ConsoleWrite($sTitle & " MineV Total Time=" & Round(TimerDiff($timerstamp1)) & "" & @TAB & " msec" & @LF) ;===========================================avbs code for QuickSort If $iSort And $iDelimited Then Local $timerstamp11 = TimerInit() If $iDelimited Then ConsoleWrite("$iDelimited=" & $iDelimited & @LF) Local $timerstamp12 = TimerInit() For $i = 0 To UBound($ar_LISTVIEWArrayV) - 1 StringReplace($ar_LISTVIEWArrayV[$i], $sSeparatorV, $sSeparatorV) If @extended > $iMaxPipes Then $iMaxPipes = @extended Next $uboundary = $iMaxPipes $iSubItems = $uboundary + 1 If $iMaxPipes > $FirstPipes Then For $i = 1 To $iMaxPipes - $FirstPipes $sStrRep &= " " & $sSeparatorV & " " Next EndIf ConsoleWrite($sTitle & " $iMaxPipes Time=" & Round(TimerDiff($timerstamp12)) & "" & @TAB & " msec" & @LF) EndIf EndIf #EndRegion second If $iSort Or $iDelimited Then Local $timerstamp11 = TimerInit(), $iGuessNumeric If $iDimension = 1 And Not $iDelimited Then $iGuessNumeric = IsNumber($avArrayV[0]) And IsNumber($avArrayV[1]) And IsNumber($avArrayV[UBound($avArrayV) - 1]) ConsoleWrite($sTitle & "$iGuessNumeric=" & $iGuessNumeric & @LF) _GUICtrlListView_BeginUpdate($hListView) ReDim $aArrayIndexV[UBound($avArrayV)] For $i = 0 To UBound($avArrayV) - 1 $aArrayIndexV[$i] = $i Next $arArAscV[0] = $aArrayIndexV DllCallbackFree($wProcNew) If $iDimension = 1 And Not $iDelimited Then $wProcNew = DllCallbackRegister("_ArrayUDF_WM_NOTIFYSort1D", "ptr", "hwnd;uint;long;ptr") ;;register new window proc ConsoleWrite("will NOW sort with _ArrayUDF_WM_NOTIFYSort1D " & @LF) Else $wProcNew = DllCallbackRegister("_ArrayUDF_WM_NOTIFYSort2", "ptr", "hwnd;uint;long;ptr") ;;register new window proc ConsoleWrite("will NOW sort with _ArrayUDF_WM_NOTIFYSort2 " & @LF) EndIf _GUICtrlListView_EndUpdate($hListView) Local $timerstamp11 = TimerInit(), $iGuessNumeric ;_ArraySortClibSet3(ByRef $Array, $iMode = 1, $fDescend = False, $iStart = 0, $iEnd = 0, $iColumn = 0, $iWidth = 128) Local $aIndex = _ArraySortClibIndex3($avArrayV, 1, False, 0, UBound($avArrayV) - 1, 0) ;~ DllCall('kernel32.dll', 'hwnd', 'FreeLibrary', 'hwnd', $hMsvcrtV) $arArAscV[1] = $aIndex ConsoleWrite($sTitle & "_ArraySortClibIndex3 Time=" & Round(TimerDiff($timerstamp11)) & "" & @TAB & " msec" & @LF) $s_LISTVIEWSortOrderV = "DESC" EndIf Local $iCountLoops = 0 While 1 ;~ if $iSliderOn then ;~ ;~ EndIf Switch GUIGetMsg() Case $_ARRAYUUCONSTANT_GUI_EVENT_CLOSE, $hClose ExitLoop Case $hCopy Local $sClip = "" ; Get selected indices [ _GUICtrlListView_GetSelectedIndices($hListView, True) ] Local $aiCurItems[1] = [0] For $i = 0 To GUICtrlSendMsg($hListView, $_ARRAYUUCONSTANT_LVM_GETITEMCOUNT, 0, 0) If GUICtrlSendMsg($hListView, $_ARRAYUUCONSTANT_LVM_GETITEMSTATE, $i, 0x2) Then $aiCurItems[0] += 1 ReDim $aiCurItems[$aiCurItems[0] + 1] $aiCurItems[$aiCurItems[0]] = $i EndIf Next ; Generate clipboard text If Not $aiCurItems[0] Then For $i = 0 To $iUBoundV - 1 $sClip &= $ar_LISTVIEWArrayV[$i] & @CRLF Next Else For $i = 1 To UBound($aiCurItems) - 1 $sClip &= $ar_LISTVIEWArrayV[$aiCurItems[$i]] & @CRLF Next EndIf ClipPut($sClip) ;~ Case Else ;~ $iCountLoops += 1 ;~ If Int($iCountLoops / 5) >= 1 Then ;~ $iCountLoops = 0 ;~ ConsoleWrite("ListView Check" & @LF) ;~ EndIf EndSwitch WEnd GUIDelete($hGUI) ReDim $arArAscV[1] $s_LISTVIEWSortOrderV = "" $i_LISTVIEWPrevcolumnV = -1 ;~ ReDim $arArDescV2V[1] If IsString($ar_LISTVIEWArrayV) Then $ar_LISTVIEWArrayV = StringSplit("", "|") ;~ _ArrayDisplaySortV($ar_LISTVIEWArrayV, "$ar_LISTVIEWArrayV at exit") ReDim $ar_LISTVIEWArrayV[1] ReDim $avArrayV[1] DllCall('kernel32.dll', 'hwnd', 'FreeLibrary', 'hwnd', $hMsvcrtV) Opt("GUIOnEventMode", $iOnEventMode) Opt("GUIDataSeparatorChar", $sDataSeparatorChar) Return 1 EndFunc ;==>_ArrayDisplaySortV Func _ArrayUDF_WM_NOTIFYSort2($hWnd, $Msg, $wParam, $LParam) Local $iTimer = TimerInit() Local $wProcOld = Eval('ArrayUDF_wProcOld'), $i, $j, $ii, $jj, $text, $textlen, $maxlen, $a_Rowa2, $iRef ;;$WM_NOTIFY = 0x004E Switch $Msg Case 0x004E ;and the rest of it Local $tNMHDR = DllStructCreate("hwnd hwndfrom;int idfrom;int code", $LParam) Local $hWndFrom = DllStructGetData($tNMHDR, "hwndfrom"), $iCode = DllStructGetData($tNMHDR, "code") $iTimeStartDataV += TimerDiff($iTimer) If $iNotSortedV Then $iNotSortedV = ($s_LISTVIEWSortOrderV == "") ;; the following is not very good, better would be have listview handle available in global scope. If ControlGetHandle($hWnd, "", "[Class:SysListView32;Instance:1]") = $hWndFrom Then Switch $iCode Case $LVN_COLUMNCLICK $iNotSortedV = ($s_LISTVIEWSortOrderV == ""); Or ($s_LISTVIEWSortOrderV == "Ready") If $iNotSortedV Then MsgBox(64, "Warning", "Not Ready to sort, please wait", 1) ContinueCase EndIf $tNMLISTVIEW = DllStructCreate("hwnd hwndfrom;int idfrom;int code;" & _ "int item;int subitem", $LParam) $iColV = DllStructGetData($tNMLISTVIEW, "subitem") $iStartcolV = GUICtrlRead($slider1V) ConsoleWrite("$iStartcolV=" & $iStartcolV & @LF) If $iColV Then $iColV += $iStartcolV ConsoleWrite("$iColV=" & $iColV & @LF) ;=========================================== $timer = TimerInit() _Sort($iColV) ConsoleWrite("_Sort in _ArrayUDF_WM_NOTIFYSort2=" & Round(TimerDiff($timer), 2) & " msecs" & @LF) Case -150, -177 ;;$LVN_GETDISPINFOA = -150, $LVN_GETDISPINFOW = -177 ;;give requested items one by one (kinda slow if a lot of items are visible at the same time) $tNMLVDISPINFOV = DllStructCreate("hwnd hwndfrom;int idfrom;int code;" & _ "uint mask;int item;int subitem;uint state;uint statemask;ptr text;int textmax;int;dword lparam;int;uint[5]", $LParam) If BitAND(DllStructGetData($tNMLVDISPINFOV, "mask"), $LVIF_TEXT) Then $i = Dec(Hex(DllStructGetData($tNMLVDISPINFOV, "item"))) $j = DllStructGetData($tNMLVDISPINFOV, "subitem") If $j Then $j += $iStartcolV $iRowV = $i $iColumnToDisplayV = $j Local $iTimer = TimerInit() If $i_LISTVIEWPrevcolumnV = $iColV And $s_LISTVIEWSortOrderV == "DESC" Then $i = $iUBoundV - $i - 1 ;================================================================ Select Case $j = 0 And $iNotSortedV; $text = "[" & $i & "]" Case $j <> 0 And $iNotSortedV; $text = $avArrayV[$i][$j - 1] Case $j = 0 And Not $iNotSortedV And Not $iColV;sorted on Colzero $text = "[" & $i & "]" Case $j <> 0 And Not $iNotSortedV And Not $iColV;sorted on Colzero $text = $avArrayV[$i][$j - 1] ;================================================================ Case $j = 0 And Not $iNotSortedV And $iColV; ;~ $i = $i * 2 + 2 ;~ $text = "[" & DllStructGetData($tSourceV, $i, 2) & "]" $text = "[" & $aArrayIndexV[$i] & "]" ;~ $text = $aArrayIndexV[$i];$aArrayIndexV Case $j <> 0 And Not $iNotSortedV And $iColV; ;~ $i = $i * 2 + 2 ;~ $iRef = DllStructGetData($tSourceV, $i, 2) ;~ $text = $avArrayV[$iRef][$j - 1] $text = $avArrayV[$aArrayIndexV[$i]][$j - 1];$aArrayIndexV ;================================================================ EndSelect $iTimeSPlitDataV += TimerDiff($iTimer) ;================================================================ Local $iTimer = TimerInit() $textlen = StringLen($text) If $textlen > $maxlenV - 1 Then $text = StringLeft($text, $maxlenV - 1) DllStructSetData($tTextBufferV, 1, $text) DllStructSetData($tNMLVDISPINFOV, "textmax", $textlen) DllStructSetData($tNMLVDISPINFOV, "text", $tTextPtrV) $iTimeSetDataV += TimerDiff($iTimer) EndIf ; Case - 113 ;$LVN_OCACHEHINT = -113 ;~ $iNotSortedV = ($s_LISTVIEWSortOrderV == "") Return ; *************************************************************************** ;;cache data to make it faster. not quite sure how it works ;~ Case - 113 ;$LVN_OCACHEHINT = -113 ;~ ;;cache data to make it faster. not quite sure how it works ;~ Local $iTimer = TimerInit() ;~ Local $tNMLVCACHEHINT = DllStructCreate("hwnd hwndfrom;int idfrom;int code;" & _ ;~ "int from;int to", $lParam) ;~ $iFromVPrev = $iFromV ;~ $iFromV = DllStructGetData($tNMLVCACHEHINT, "from") ;~ _GUICtrlListView_EnsureVisible($hListView, $iFromV) ;~ $iRowV = $iFromV ;~ $iToV = DllStructGetData($tNMLVCACHEHINT, "to") ;~ ConsoleWrite('- chache: from ' & $iFromV & ' to ' & $iToV & @CRLF) EndSwitch EndIf Case $WM_HSCROLL ;WM_HSCROLL function ;~ Switch $LParam ;~ Case GUICtrlGetHandle($slider1V) If $LParam = GUICtrlGetHandle($slider1V) Then $iStartcolV = GUICtrlRead($slider1V) ConsoleWrite("$iStartcolV=" & $iStartcolV & @LF) For $i = 1 To 5 _GUICtrlListView_SetColumn($hListView, $i, "Col" & $iStartcolV + $i - 1) Next Local $iTop = _GUICtrlListView_GetTopIndex($hListView) ConsoleWrite("$iTop=" & $iTop & @LF) ConsoleWrite("$iFromV=" & $iFromV & @LF) GUICtrlSendMsg($hListView, $LVM_SETITEMCOUNT, $iUBoundV, 0) ;~ _GUICtrlListView_EnsureVisible($hListView, $iTop) _GUICtrlListView_EnsureVisible($hListView, $iFromV) ;~ sleep(5000) EndIf ;~ EndSwitch EndSwitch ;~ Return CallWindowProc(old) ;~ If $Msg <> 0x004E Then Return _ArrayUDF_CallWndProcV($wProcOld, $hWnd, $Msg, $wParam, $LParam) ;;pass the unhandled messages to default WindowProc Return _ArrayUDF_CallWndProcV($wProcOld, $hWnd, $Msg, $wParam, $LParam) EndFunc ;==>_ArrayUDF_WM_NOTIFYSort2 Func _ArrayUDF_WM_NOTIFYVir2D($hWnd, $Msg, $wParam, $LParam) Local $wProcOld = Eval('ArrayUDF_wProcOld'), $i, $j, $text, $textlen, $maxlen, $a_Rowa2;;$WM_NOTIFY = 0x004E If $Msg <> 0x004E Then Return _ArrayUDF_CallWndProcV($wProcOld, $hWnd, $Msg, $wParam, $LParam) Local $tNMHDR = DllStructCreate("hwnd hwndfrom;int idfrom;int code", $LParam) Local $hWndFrom = DllStructGetData($tNMHDR, "hwndfrom"), $iCode = DllStructGetData($tNMHDR, "code") ;; the following is not very good, better would be have listview handle available in global scope. If ControlGetHandle($hWnd, "", "[Class:SysListView32;Instance:1]") = $hWndFrom Then Switch $iCode Case $LVN_COLUMNCLICK If $iNotSortedV Then MsgBox(64, "Warning", "Not Ready to sort, please wait", 1) ContinueCase EndIf $tNMLISTVIEW = DllStructCreate("hwnd hwndfrom;int idfrom;int code;" & _ "int item;int subitem", $LParam) $iColV = DllStructGetData($tNMLISTVIEW, "subitem") ;=========================================== ;~ _GUICtrlListView_BeginUpdate($hWndFrom) $timer = TimerInit() _Sort($iColV) ConsoleWrite("_Sort in _ArrayUDF_WM_NOTIFYVir2D=" & Round(TimerDiff($timer), 2) & " msecs" & @LF) ;~ _GUICtrlListView_EndUpdate($hWndFrom) Case -150, -177 ;;$LVN_GETDISPINFOA = -150, $LVN_GETDISPINFOW = -177 ;;give requested items one by one (kinda slow if a lot of items are visible at the same time) $tNMLVDISPINFOV = DllStructCreate("hwnd hwndfrom;int idfrom;int code;" & _ "uint mask;int item;int subitem;uint state;uint statemask;ptr text;int textmax;int;dword lparam;int;uint[5]", $LParam) If BitAND(DllStructGetData($tNMLVDISPINFOV, "mask"), $LVIF_TEXT) Then $i = Dec(Hex(DllStructGetData($tNMLVDISPINFOV, "item"))) $j = DllStructGetData($tNMLVDISPINFOV, "subitem") ;================================================================ If $j >= $iStartV And $j <= $iEndV Then If $j = 0 Then $text = "[" & $i & "]" Else $text = $avArrayV[$i][$j - 1] EndIf ;================================================================ $textlen = StringLen($text) If $textlen > $maxlenV - 1 Then $text = StringLeft($text, $maxlenV - 1) DllStructSetData($tTextBufferV, 1, $text) DllStructSetData($tNMLVDISPINFOV, "textmax", $textlen) DllStructSetData($tNMLVDISPINFOV, "text", $tTextPtrV) EndIf EndIf EndSwitch EndIf ;;pass the unhandled messages to default WindowProc Return _ArrayUDF_CallWndProcV($wProcOld, $hWnd, $Msg, $wParam, $LParam) EndFunc ;==>_ArrayUDF_WM_NOTIFYVir2D Func _ArrayUDF_WM_NOTIFYSort1D($hWnd, $Msg, $wParam, $LParam) Local $wProcOld = Eval('ArrayUDF_wProcOld'), $i, $j, $text, $textlen, $maxlen, $a_Rowa2;;$WM_NOTIFY = 0x004E If $Msg <> 0x004E Then Return _ArrayUDF_CallWndProcV($wProcOld, $hWnd, $Msg, $wParam, $LParam) Local $tNMHDR = DllStructCreate("hwnd hwndfrom;int idfrom;int code", $LParam) Local $hWndFrom = DllStructGetData($tNMHDR, "hwndfrom"), $iCode = DllStructGetData($tNMHDR, "code") If $iNotSortedV Then $iNotSortedV = ($s_LISTVIEWSortOrderV == "") ;; the following is not very good, better would be have listview handle available in global scope. If ControlGetHandle($hWnd, "", "[Class:SysListView32;Instance:1]") = $hWndFrom Then Switch $iCode Case $LVN_COLUMNCLICK ;~ Local $iNotSortedV = ($s_LISTVIEWSortOrderV == ""); Or ($s_LISTVIEWSortOrderV == "Ready") If $iNotSortedV Then MsgBox(64, "Warning", "Not Ready to sort, please wait", 1) ContinueCase EndIf $tNMLISTVIEW = DllStructCreate("hwnd hwndfrom;int idfrom;int code;" & _ "int item;int subitem", $LParam) $iColV = DllStructGetData($tNMLISTVIEW, "subitem") ;=========================================== _GUICtrlListView_BeginUpdate($hWndFrom) $timer = TimerInit() If $i_LISTVIEWPrevcolumnV <> $iColV Then $s_LISTVIEWSortOrderV = "DESC" If $i_LISTVIEWPrevcolumnV = $iColV And $s_LISTVIEWSortOrderV == "DESC" Then ; ConsoleWrite('_ArrayReverse $s_LISTVIEWSortOrderV=' & $s_LISTVIEWSortOrderV & @CRLF) $s_LISTVIEWSortOrderV = "ASC" Else If ($i_LISTVIEWPrevcolumnV <> $iColV Or Not $s_LISTVIEWSortOrderV) And _ Not IsArray($arArAscV[$iColV]) And $iColV Then Local $iGuessNumeric = IsNumber($avArrayV[0]) And IsNumber($avArrayV[1]) And IsNumber($avArrayV[UBound($avArrayV) - 1]) Local $timerstamp13 = TimerInit() ConsoleWrite("$avArrayV[ubound($avArrayV)-1]=" & $avArrayV[UBound($avArrayV) - 1] & @LF) $arArAscV[$iColV] = $avArrayV ElseIf ($i_LISTVIEWPrevcolumnV <> $iColV Or Not $s_LISTVIEWSortOrderV) Or $iColV = 0 Then $avArrayV = $arArAscV[$iColV] EndIf $i_LISTVIEWPrevcolumnV = $iColV $s_LISTVIEWSortOrderV = "DESC" EndIf ConsoleWrite("Sort " & Round(TimerDiff($timer), 2) & " msecs" & @LF) _GUICtrlListView_EndUpdate($hWndFrom) Case -150, -177 ;;$LVN_GETDISPINFOA = -150, $LVN_GETDISPINFOW = -177 ;;give requested items one by one (kinda slow if a lot of items are visible at the same time) $tNMLVDISPINFOV = DllStructCreate("hwnd hwndfrom;int idfrom;int code;" & _ "uint mask;int item;int subitem;uint state;uint statemask;ptr text;int textmax;int;dword lparam;int;uint[5]", $LParam) If BitAND(DllStructGetData($tNMLVDISPINFOV, "mask"), $LVIF_TEXT) Then $i = Dec(Hex(DllStructGetData($tNMLVDISPINFOV, "item"))) $j = DllStructGetData($tNMLVDISPINFOV, "subitem") ;================================================================ ;~ If $j >= $iStartV And $j <= $iEndV Then ;~ Local $iNotSortedV = ($s_LISTVIEWSortOrderV == ""); Or ($s_LISTVIEWSortOrderV == "Ready") Local $sTemp1, $aTmp, $iRef; = StringSplit($ar_LISTVIEWArrayV[UBound($avArrayV) - 1], $sSeparatorV, 1) Local $a = $i If $i_LISTVIEWPrevcolumnV == $iColV And $s_LISTVIEWSortOrderV == "DESC" Then $a = $iUBoundV - $i - 1 Select Case $j = 0 And $iNotSortedV; $text = "[" & $a & "]" Case $j <> 0 And $iNotSortedV; $text = $avArrayV[$a] Case $j = 0 And Not $iNotSortedV And Not $iColV;sorted $text = "[" & $a & "]" Case $j <> 0 And Not $iNotSortedV And Not $iColV;;sorted $text = $avArrayV[$a] Case $j = 0 And Not $iNotSortedV And $iColV;;sorted ;~ $a = $a * 2 + 2 ;~ $text = "[" & DllStructGetData($tSourceV, $a, 2) & "]" $text = "[" & $aArrayIndexV[$a] & "]" Case $j <> 0 And Not $iNotSortedV And $iColV;;sorted ;~ $a = $a * 2 + 2 ;~ $iRef = DllStructGetData($tSourceV, $a, 2) ;~ $text = $avArrayV[$iRef] $text = $avArrayV[$aArrayIndexV[$a]];[$j - 1];$aArrayIndexV EndSelect $textlen = StringLen($text) If $textlen > $maxlenV - 1 Then $text = StringLeft($text, $maxlenV - 1) DllStructSetData($tTextBufferV, 1, $text) DllStructSetData($tNMLVDISPINFOV, "textmax", $textlen) DllStructSetData($tNMLVDISPINFOV, "text", $tTextPtrV) ;~ EndIf ;~ ElseIf BitAND(DllStructGetData($tNMLVDISPINFOV, "mask"), $LVIF_STATE) Then ;;meh. although the selected items array filling could be implemented here, so there wouldn't be no need ;;to loop through entire thing again when "Copy Selected" button is clicked EndIf EndSwitch EndIf ;;pass the unhandled messages to default WindowProc Return _ArrayUDF_CallWndProcV($wProcOld, $hWnd, $Msg, $wParam, $LParam) EndFunc ;==>_ArrayUDF_WM_NOTIFYSort1D Func _Sort($i_OrderColumn) ;===================================================================================================================== _GUICtrlListView_BeginUpdate($hListView) $timer = TimerInit() If $i_LISTVIEWPrevcolumnV <> $i_OrderColumn Then $s_LISTVIEWSortOrderV = "DESC" If $i_LISTVIEWPrevcolumnV = $i_OrderColumn And $s_LISTVIEWSortOrderV == "DESC" Then ; ConsoleWrite('_ArrayReverse $s_LISTVIEWSortOrderV=' & $s_LISTVIEWSortOrderV & @CRLF) $s_LISTVIEWSortOrderV = "ASC" Else If ($i_LISTVIEWPrevcolumnV <> $i_OrderColumn Or Not $s_LISTVIEWSortOrderV) And _ Not IsArray($arArAscV[$i_OrderColumn]) And $i_OrderColumn Then $aArrayIndexV = _ArraySortClibIndex3($avArrayV, 1, False, 0, UBound($avArrayV) - 1, $i_OrderColumn - 1) ;~ _ArraySortClibSet3($avArrayV, 1, False, 0, UBound($avArrayV) - 1, $i_OrderColumn - 1) Local $timerstamp13 = TimerInit() $arArAscV[$i_OrderColumn] = $aArrayIndexV ConsoleWrite("_ArraySortClibIndex3 Sort on $i_OrderColumn=" & $i_OrderColumn & @LF) ElseIf ($i_LISTVIEWPrevcolumnV <> $i_OrderColumn Or Not $s_LISTVIEWSortOrderV) Or $i_OrderColumn < 2 Then $aArrayIndexV = $arArAscV[$i_OrderColumn]; = $aArrayIndexV ConsoleWrite('- Get prev Array Index $s_LISTVIEWSortOrderV=' & $s_LISTVIEWSortOrderV & @CRLF) EndIf $i_LISTVIEWPrevcolumnV = $i_OrderColumn $s_LISTVIEWSortOrderV = "DESC" EndIf ConsoleWrite("Sort func" & Round(TimerDiff($timer), 2) & " msecs" & @LF) _GUICtrlListView_EndUpdate($hListView) ;===================================================================================================================== EndFunc ;==>_Sort Func _ArrayUDF_WinSubclassV($hWnd, $lpNewWindowProc) ;#define GWL_WNDPROC (-4) Local $aTmp, $sFunc = "SetWindowLong" If Execute("@Unicode") Then $sFunc &= "W" $aTmp = DllCall("user32.dll", "ptr", $sFunc, "hwnd", $hWnd, "int", -4, "ptr", $lpNewWindowProc) If @error Then Return SetError(1, 0, 0) If $aTmp[0] = 0 Then Return SetError(1, 0, 0) Return $aTmp[0] EndFunc ;==>_ArrayUDF_WinSubclassV Func _ArrayUDF_CallWndProcV($lpPrevWndFunc, $hWnd, $Msg, $wParam, $LParam) Local $aRet = DllCall('user32.dll', 'uint', 'CallWindowProc', 'ptr', $lpPrevWndFunc, 'hwnd', $hWnd, 'uint', $Msg, 'wparam', $wParam, 'lparam', $LParam) ;~ If @error Then Return 0 Return $aRet[0] EndFunc ;==>_ArrayUDF_CallWndProcV Func _ArraySortClibIndex3(ByRef $Array, $iMode = 1, $fDescend = False, $iStart = 0, $iEnd = 0, $iColumn = 0, $iWidth = 128) Local $iArrayDims = UBound($Array, 0), $aIndex[1] If @error Or $iArrayDims > 2 Then Return SetError(1, 0, 0) Local $iArraySize = UBound($Array, 1), $iColumnMax = UBound($Array, 2) If $iArraySize < 2 Then Return 0 If $iEnd < 1 Or $iEnd > $iArraySize - 1 Then $iEnd = $iArraySize - 1 If ($iEnd - $iStart < 2) Then Return SetError(2, 0, 0) If $iArrayDims = 2 Then If ($iColumnMax - $iColumn < 0) Then Return SetError(2, 0, 0) EndIf If $iWidth < 1 Then Return SetError(2, 0, 0) $iWidth = Ceiling($iWidth / 8) * 8 Local $sMem, $tSourceV, $pSourceV, $i, $j, $iCount, $fNumeric, $fCase, $aRet, $hMsvcrtV, $sStrCmpV, $tFloatCmpV, $pCmpV, $tIndexerV Switch $iMode Case 0 $fNumeric = True Case 1 $fCase = False Case 2 $fCase = True Case Else Return SetError(2, 0, 0) EndSwitch ;; initialize sorting proc If $fNumeric Then $tFloatCmpV = DllStructCreate("byte[36]") DllStructSetData($tFloatCmpV, 1, Binary("0x8B4C24048B542408DD01DC1ADFE0F6C440750D80E441740433C048C333C040C333C0C3")) $pCmpV = DllStructGetPtr($tFloatCmpV) Else $sStrCmpV = "_strcmpi" ;case insensitive If $fCase Then $sStrCmpV = "strcmp" ;case sensitive $aRet = DllCall('kernel32.dll', 'hwnd', 'LoadLibraryA', 'str', 'msvcrt.dll') $hMsvcrtV = $aRet[0] $aRet = DllCall('kernel32.dll', 'ptr', 'GetProcAddress', 'ptr', $hMsvcrtV, 'str', $sStrCmpV) DllCall('kernel32.dll', 'hwnd', 'FreeLibrary', 'hwnd', $hMsvcrtV) If $aRet[0] = 0 Then Return -1 $pCmpV = $aRet[0] EndIf ;; initialize memory $sMem = "" If $fNumeric Then For $i = 1 To $iArraySize $sMem &= "double;int[4];" Next $iWidth = 24 Else For $i = 1 To $iArraySize $sMem &= "char[" & $iWidth & "];int[4];" Next $iWidth += 16 EndIf $sMem = StringTrimRight($sMem, 1) $tSourceV = DllStructCreate($sMem) ;; fill memory If $iArrayDims = 1 Then For $i = 0 To $iArraySize - 1 DllStructSetData($tSourceV, $i * 2 + 1, $Array[$i]) Next Else For $i = 0 To $iArraySize - 1 DllStructSetData($tSourceV, $i * 2 + 1, $Array[$i][$iColumn]) Next EndIf ;; enumerate elements $tIndexerV = DllStructCreate("byte[32]") DllStructSetData($tIndexerV, 1, Binary("0x33C08B7424048B4C2408037424108B5C240C890603F3403BC17CF7C3")) DllCall('user32.dll', 'uint', 'CallWindowProc', 'ptr', DllStructGetPtr($tIndexerV), 'ptr', DllStructGetPtr($tSourceV, 2), 'int', $iArraySize, 'int', $iWidth, 'int', 4) $pSourceV = DllStructGetPtr($tSourceV, $iStart * 2 + 1) ;;pointer to search starting element $iCount = $iEnd - $iStart + 1 ;;count of elements to search ;;sort DllCall('msvcrt.dll', 'none:cdecl', 'qsort', 'ptr', $pSourceV, 'int', $iCount, 'int', $iWidth, 'ptr', $pCmpV) ;; read back the result ReDim $aIndex[UBound($Array)] For $i = $iStart To $iEnd $aIndex[$i] = DllStructGetData($tSourceV, $i * 2 + 2, 2) Next Return $aIndex EndFunc ;==>_ArraySortClibIndex3 AutoIt Project Listing Link to comment Share on other sites More sharing options...
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