#include-once #include #include #include #include ; #INDEX# ======================================================================================================================= ; Title .........: Internal UDF Library for AutoIt3 _ArrayDisplay() and _DebugArrayDisplay() ; AutoIt Version : 3.3.16.0 ; Description ...: Internal functions for the Array.au3 and Debug.au3 ; Author(s) .....: Melba23, jpm, LarsJ, pixelsearch ; Modified by ...: Nine ; =============================================================================================================================== #Region Global Variables and Constants ; #CONSTANTS# =================================================================================================================== Global Const $ADS_COLALIGNLEFT = 0 ; (default) Column text alignment - left Global Const $ADS_TRANSPOSE = 1 ; Transposes the array (2D only) Global Const $ADS_COLALIGNRIGHT = 2 ; Column text alignment - right Global Const $ADS_COLALIGNCENTER = 4 ; Column text alignment - center Global Const $ADS_VERBOSE = 8 ; Verbose - display MsgBox on error and splash screens during processing of large arrays Global Const $ADS_NOROW = 64 ; No 'Row' column displayed Global Const $ADS_CHECKERROR = 128 ; return if @error <> 0 Global Const $ADS_ROWPREFIX = "#" Global Const $ADS_NUMERICSORT = "*" Global Const $ADS_tagLVITEM = "struct;uint Mask;int Item;int SubItem;uint State;uint StateMask;ptr Text;int TextMax;int Image;lparam Param;" & _ "int Indent;int GroupID;uint Columns;ptr pColumns;ptr piColFmt;int iGroup;endstruct" Global Enum $eADS_List, $eADS_Transpose, $eADS_DisplayRow, $eADS_Array, $eADS_Index, $eADS_SortDir, $eADS_Header, $eADS_Start, _ $eADS_Numeric, $eADS_Dummy, $eADS_All ; =============================================================================================================================== ; #VARIABLES# =================================================================================================================== Global $_gADS_aData[1][$eADS_All] Global $_gADS_aIndex[1] ; =============================================================================================================================== #EndRegion Global Variables and Constants #Region Functions list ; #FUNCTIONS# =================================================================================================================== ; _ArrayDisplayEX (See Original _ArrayDisplay for parameters description) ; _DebugArrayDisplayEX (See Original _ArrayDisplay for parameters description) ; =============================================================================================================================== ; #INTERNAL_USE_ONLY# =========================================================================================================== ; __ArrayDisplay_ShareEX ; ___ADS_WM_NOTIFY ; __ADS_BaseIndex ; __ADS_SortIndex ; __ADS_GetSortColStruct ; __ADS_SortArrayStruct ; __ADS_CreateSubArray ; __ADS_HeaderSetItemFormat ; __ADS_GetItemText ; __ADS_GetItemTextStringSelected ; __ADS_JustifyColumn ; __ADS_CustomHeader ; =============================================================================================================================== #EndRegion Functions list Func _ArrayDisplayEX(Const ByRef $aArray, $sTitle = Default, $sArrayRange = Default, $iFlags = Default, $vUser_Separator = Default, $sHeader = Default, $iMax_ColWidth = Default) #forceref $vUser_Separator Local $iRet = __ArrayDisplay_ShareEX($aArray, 0, $sTitle, $sArrayRange, $iFlags, Default, $sHeader, $iMax_ColWidth, 0, False) Return SetError(@error, @extended, $iRet) EndFunc ;==>_ArrayDisplayEX Func _DebugArrayDisplayEX(Const ByRef $aArray, $sTitle = Default, $sArrayRange = Default, $iFlags = Default, $vUser_Separator = Default, $sHeader = Default, $iMax_ColWidth = Default, $hUser_Function = Default, Const $_iCallerScriptLineNumber = @ScriptLineNumber, Const $_iCallerError = @error, Const $_iCallerExtended = @extended) Local $iRet = __ArrayDisplay_ShareEX($aArray, 0, $sTitle, $sArrayRange, $iFlags, $vUser_Separator, $sHeader, $iMax_ColWidth, $hUser_Function, True, $_iCallerScriptLineNumber, $_iCallerError, $_iCallerExtended) Return SetError(@error, @extended, $iRet) EndFunc ;==>_DebugArrayDisplayEX Func __ArrayDisplay_ShareEX(Const ByRef $aArray, $iLevel, $sTitle = Default, $sArrayRange = Default, $iFlags = Default, $vUser_Separator = Default, $sHeader = Default, $iMax_ColWidth = Default, $hUser_Function = Default, $bDebug = True, Const $_iScriptLineNumber = @ScriptLineNumber, Const $_iCallerError = @error, Const $_iCallerExtended = @extended) Local $sMsgBoxTitle = (($bDebug) ? ("_DebugArrayDisplay") : ("_ArrayDisplay")) Local $iDimensions, $iItem_End, $iSubItem_Start, $iSubItem_End, $nRows, $nCols ; Default values If $sTitle = Default Then $sTitle = $sMsgBoxTitle If $sArrayRange = Default Then $sArrayRange = "" If $iFlags = Default Then $iFlags = 0 If $vUser_Separator = Default Then $vUser_Separator = "" If $sHeader = Default Then $sHeader = "" If $iMax_ColWidth = Default Then $iMax_ColWidth = 350 If $iMax_ColWidth > 4095 Then $iMax_ColWidth = 4095 ; needed as the structure inside the notify handler is declared as Static If $hUser_Function = Default Then $hUser_Function = 0 ; Check for transpose, column align, verbosity and "Row" column visibility $_gADS_aData[$iLevel][$eADS_Transpose] = BitAND($iFlags, $ADS_TRANSPOSE) Local $iColAlign = BitAND($iFlags, 6) ; 0 = Left (default); 2 = Right; 4 = Center Local $iVerbose = Int(BitAND($iFlags, $ADS_VERBOSE)) $_gADS_aData[$iLevel][$eADS_DisplayRow] = Int(BitAND($iFlags, $ADS_NOROW) = 0) ; Set lower button border Local $iButtonBorder = (($bDebug) ? (40) : (20)) #Region Check valid array Local $sMsg = "", $iRet = 1 If IsArray($aArray) Then $_gADS_aData[$iLevel][$eADS_Array] = $aArray $iDimensions = UBound($aArray, $UBOUND_DIMENSIONS) If $iDimensions = 1 Then $_gADS_aData[$iLevel][$eADS_Transpose] = 0 $nRows = UBound($aArray, $UBOUND_ROWS) $nCols = ($iDimensions = 2) ? UBound($aArray, $UBOUND_COLUMNS) : 1 ; Dimension checking If $iDimensions > 2 Then $sMsg = "Larger than 2D array passed to function" $iRet = 2 EndIf If $_iCallerError Then If $bDebug Then ; Call _DebugReport() if available If IsDeclared("__g_sReportCallBack_DebugReport_Debug") Then $sMsg = "@@ Debug( " & $_iScriptLineNumber & ") : @error = " & $_iCallerError & " in " & $sMsgBoxTitle & "( '" & $sTitle & "' )" Execute('$__g_sReportCallBack_DebugReport_Debug("' & $sMsg & '")') EndIf $iRet = 3 ElseIf BitAND($iFlags, $ADS_CHECKERROR) Then $sMsg = "@error = " & $_iCallerError & " when calling the function" If $_iScriptLineNumber > 0 Then $sMsg &= " at line " & $_iScriptLineNumber $iRet = 3 EndIf EndIf Else $sMsg = "No array variable passed to function" EndIf If $sMsg Then If $iVerbose And MsgBox($MB_SYSTEMMODAL + $MB_ICONERROR + $MB_YESNO, _ $sMsgBoxTitle & "() Error: " & $sTitle, $sMsg & @CRLF & @CRLF & "Exit the script?") = $IDYES Then Exit Else Return SetError($iRet, 0, 0) EndIf EndIf #EndRegion Check valid array #Region Check array range ; Determine copy separator Local $iCW_ColWidth = Number($vUser_Separator) ; Get current separator character Local $sCurr_Separator = Opt("GUIDataSeparatorChar") ; Set default user separator if required If $vUser_Separator = "" Then $vUser_Separator = $sCurr_Separator ; Declare variables $_gADS_aData[$iLevel][$eADS_Start] = 0 $iItem_End = $nRows - 1 $iSubItem_Start = 0 $iSubItem_End = (($iDimensions = 2) ? ($nCols - 1) : (0)) Local $avRangeSplit ; Check for range settings If $sArrayRange Then ; Split into separate dimension sections Local $vTmp, $aArray_Range = StringRegExp($sArrayRange & "||", "(?U)(.*)\|", $STR_REGEXPARRAYGLOBALMATCH) ; Rows range If $aArray_Range[0] Then $avRangeSplit = StringSplit($aArray_Range[0], ":") If @error Then $iItem_End = Number($aArray_Range[0]) Else $_gADS_aData[$iLevel][$eADS_Start] = Number($avRangeSplit[1]) If $avRangeSplit[2] <> "" Then $iItem_End = Number($avRangeSplit[2]) EndIf EndIf EndIf ; Check row bounds If $_gADS_aData[$iLevel][$eADS_Start] < 0 Then $_gADS_aData[$iLevel][$eADS_Start] = 0 If $iItem_End >= $nRows Then $iItem_End = $nRows - 1 If ($_gADS_aData[$iLevel][$eADS_Start] > $iItem_End) And ($iItem_End > 0) Then $vTmp = $_gADS_aData[$iLevel][$eADS_Start] $_gADS_aData[$iLevel][$eADS_Start] = $iItem_End $iItem_End = $vTmp EndIf ; Columns range If $iDimensions = 2 And $aArray_Range[1] Then $avRangeSplit = StringSplit($aArray_Range[1], ":") If @error Then $iSubItem_End = Number($aArray_Range[1]) Else $iSubItem_Start = Number($avRangeSplit[1]) If $avRangeSplit[2] <> "" Then $iSubItem_End = Number($avRangeSplit[2]) EndIf EndIf ; Check column bounds If $iSubItem_Start > $iSubItem_End Then $vTmp = $iSubItem_Start $iSubItem_Start = $iSubItem_End $iSubItem_End = $vTmp EndIf If $iSubItem_Start < 0 Then $iSubItem_Start = 0 If $iSubItem_End >= $nCols Then $iSubItem_End = $nCols - 1 EndIf EndIf ; Create data display Local $sDisplayData = "[" & $nRows & "]" If $iDimensions = 2 Then $sDisplayData &= " [" & $nCols & "]" EndIf ; Create tooltip data Local $sTipData = "" If $sArrayRange Then If $sTipData Then $sTipData &= " - " $sTipData &= "Range set " & $sArrayRange EndIf If $_gADS_aData[$iLevel][$eADS_Transpose] Then If $sTipData Then $sTipData &= " - " $sTipData &= "Transposed" EndIf If $sArrayRange Or $_gADS_aData[$iLevel][$eADS_Transpose] Then $_gADS_aData[$iLevel][$eADS_Array] = __ADS_CreateSubArray($_gADS_aData[$iLevel][$eADS_Array], $iDimensions, $_gADS_aData[$iLevel][$eADS_Start], $iItem_End, _ $iSubItem_Start, $iSubItem_End, $nRows, $nCols, $_gADS_aData[$iLevel][$eADS_Transpose]) EndIf #EndRegion Check array range #Region Generate Base Sort index __ADS_BaseIndex($_gADS_aData[$iLevel][$eADS_Index], $nRows, $nCols) $_gADS_aIndex[$iLevel] = ($_gADS_aData[$iLevel][$eADS_Index])[0] #EndRegion Generate Base Sort index #Region GUI and Listview generation $sHeader = __ADS_CustomHeader($_gADS_aData[$iLevel][$eADS_Header], $_gADS_aData[$iLevel][$eADS_Numeric], $sHeader, $sCurr_Separator, $iSubItem_Start, _ $iSubItem_End, $_gADS_aData[$iLevel][$eADS_Transpose], $nRows, $nCols, $_gADS_aData[$iLevel][$eADS_DisplayRow]) ; Display splash dialog if required If $iVerbose And ($nRows * $nCols) > 1000 Then SplashTextOn($sMsgBoxTitle, "Preparing display" & @CRLF & @CRLF & "Please be patient", 300, 100) EndIf ; GUI Constants Local Const $_ADS_GUI_DOCKBOTTOM = 64 Local Const $_ADS_GUI_DOCKBORDERS = 102 Local Const $_ADS_GUI_DOCKHEIGHT = 512 Local Const $_ADS_GUI_DOCKLEFT = 2 Local Const $_ADS_GUI_DOCKRIGHT = 4 Local Const $_ADS_GUI_DOCKHCENTER = 8 Local Const $_ADS_GUI_EVENT_CLOSE = -3 Local Const $_ADS_GUI_EVENT_ARRAY = 1 Local Const $_ADS_GUI_FOCUS = 256 Local Const $_ADS_SS_CENTER = 0x1 Local Const $_ADS_SS_CENTERIMAGE = 0x0200 Local Const $_ADS_LVM_GETITEMRECT = (0x1000 + 14) Local Const $_ADS_LVM_GETITEMSTATE = (0x1000 + 44) Local Const $_ADS_LVM_GETSELECTEDCOUNT = (0x1000 + 50) Local Const $_ADS_LVM_SETEXTENDEDLISTVIEWSTYLE = (0x1000 + 54) Local Const $_ADS_LVS_EX_GRIDLINES = 0x1 Local Const $_ADS_LVIS_SELECTED = 0x0002 Local Const $_ADS_LVS_SHOWSELALWAYS = 0x8 Local Const $_ADS_LVS_OWNERDATA = 0x1000 Local Const $_ADS_LVS_EX_FULLROWSELECT = 0x20 Local Const $_ADS_LVS_EX_DOUBLEBUFFER = 0x00010000 ; Paints via double-buffering, which reduces flicker Local Const $_ADS_WS_EX_CLIENTEDGE = 0x0200 Local Const $_ADS_WS_MAXIMIZEBOX = 0x00010000 Local Const $_ADS_WS_MINIMIZEBOX = 0x00020000 Local Const $_ADS_WS_SIZEBOX = 0x00040000 ; Set coord mode 1 Local $iCoordMode = Opt("GUICoordMode", 1) ; Create GUI Local $iOrgWidth = 210, $iHeight = 200, $iMinSize = 250 Local $hGUI = GUICreate($sTitle, $iOrgWidth, $iHeight, Default, Default, BitOR($_ADS_WS_SIZEBOX, $_ADS_WS_MINIMIZEBOX, $_ADS_WS_MAXIMIZEBOX)) Local $aiGUISize = WinGetClientSize($hGUI) ; Create ListView Local $idListView = GUICtrlCreateListView($sHeader, 0, 0, $aiGUISize[0], $aiGUISize[1] - $iButtonBorder, BitOR($_ADS_LVS_SHOWSELALWAYS, $_ADS_LVS_OWNERDATA)) $_gADS_aData[$iLevel][$eADS_List] = GUICtrlGetHandle($idListView) GUICtrlSendMsg($idListView, $_ADS_LVM_SETEXTENDEDLISTVIEWSTYLE, $_ADS_LVS_EX_GRIDLINES, $_ADS_LVS_EX_GRIDLINES) GUICtrlSendMsg($idListView, $_ADS_LVM_SETEXTENDEDLISTVIEWSTYLE, $_ADS_LVS_EX_FULLROWSELECT, $_ADS_LVS_EX_FULLROWSELECT) GUICtrlSendMsg($idListView, $_ADS_LVM_SETEXTENDEDLISTVIEWSTYLE, $_ADS_LVS_EX_DOUBLEBUFFER, $_ADS_LVS_EX_DOUBLEBUFFER) GUICtrlSendMsg($idListView, $_ADS_LVM_SETEXTENDEDLISTVIEWSTYLE, $_ADS_WS_EX_CLIENTEDGE, $_ADS_WS_EX_CLIENTEDGE) Local $hHeader = HWnd(GUICtrlSendMsg($idListView, (0x1000 + 31), 0, 0)) ; $LVM_GETHEADER _GUICtrlListView_GetHeader($idListView) ; Set resizing GUICtrlSetResizing($idListView, $_ADS_GUI_DOCKBORDERS) ; Fill listview Local $iColFill = $nCols + $_gADS_aData[$iLevel][$eADS_DisplayRow] ; Align columns if required - $iColAlign = 2 for Right and 4 for Center If $iColAlign Then ; Loop through columns For $i = 0 To $iColFill - 1 __ADS_JustifyColumn($idListView, $i, $iColAlign / 2) Next EndIf GUICtrlSendMsg($idListView, (0x1000 + 47), $nRows, 0) ; $LVM_SETITEMCOUNT ; Get row height Local $tRECT = DllStructCreate("struct; long Left;long Top;long Right;long Bottom; endstruct") ; $tagRECT DllCall("user32.dll", "struct*", "SendMessageW", "hwnd", $_gADS_aData[$iLevel][$eADS_List], "uint", $_ADS_LVM_GETITEMRECT, "wparam", 0, "struct*", $tRECT) ; Set required GUI height Local $aiWin_Pos = WinGetPos($hGUI) Local $aiLV_Pos = ControlGetPos($hGUI, "", $idListView) $iHeight = (($nRows + 3) * (DllStructGetData($tRECT, "Bottom") - DllStructGetData($tRECT, "Top"))) + $aiWin_Pos[3] - $aiLV_Pos[3] ; Check min/max height If $iHeight > @DesktopHeight - 100 Then $iHeight = @DesktopHeight - 100 ElseIf $iHeight < $iMinSize Then $iHeight = $iMinSize EndIf $_gADS_aData[$iLevel][$eADS_Dummy] = GUICtrlCreateDummy() If $iVerbose Then SplashOff() ; Sorting information $_gADS_aData[$iLevel][$eADS_SortDir] = 0x00000400 ; $HDF_SORTUP Local $iColumn = 0, $iColumnPrev = -1 If $_gADS_aData[$iLevel][$eADS_DisplayRow] Then $iColumnPrev = $iColumn __ADS_HeaderSetItemFormat($hHeader, $iColumn, 0x00004000 + $_gADS_aData[$iLevel][$eADS_SortDir] + $iColAlign / 2) ; $HDF_STRING EndIf #EndRegion GUI and Listview generation GUIRegisterMsg($WM_NOTIFY, __ADS_WM_NOTIFY) #Region Adjust dialog width Local $iWidth = 40, $iColWidth = 0, $aiColWidth[$iColFill], $iMin_ColWidth = 55 ; Get required column widths to fit items Local $iColWidthHeader For $i = 0 To $iColFill - 1 GUICtrlSendMsg($idListView, (0x1000 + 30), $i, -1) ; $LVM_SETCOLUMNWIDTH $LVSCW_AUTOSIZE $iColWidth = GUICtrlSendMsg($idListView, (0x1000 + 29), $i, 0) ; $LVM_GETCOLUMNWIDTH ; Check width of header if set If $sHeader <> "" Then If $iColWidth = 0 Then ExitLoop GUICtrlSendMsg($idListView, (0x1000 + 30), $i, -2) ; $LVM_SETCOLUMNWIDTH $LVSCW_AUTOSIZE_USEHEADER $iColWidthHeader = GUICtrlSendMsg($idListView, (0x1000 + 29), $i, 0) ; $GETCOLUMNWIDTH ; Set minimum if required If $iColWidth < $iMin_ColWidth And $iColWidthHeader < $iMin_ColWidth Then GUICtrlSendMsg($idListView, (0x1000 + 30), $i, $iMin_ColWidth) ; $LVM_SETCOLUMNWIDTH $iColWidth = $iMin_ColWidth ElseIf $iColWidthHeader < $iColWidth Then GUICtrlSendMsg($idListView, (0x1000 + 30), $i, $iColWidth) ; $LVM_SETCOLUMNWIDTH Else $iColWidth = $iColWidthHeader EndIf Else ; Set minimum if required If $iColWidth < $iMin_ColWidth Then GUICtrlSendMsg($idListView, (0x1000 + 30), $i, $iMin_ColWidth) ; $LVM_SETCOLUMNWIDTH $iColWidth = $iMin_ColWidth EndIf EndIf ; Add to total width $iWidth += $iColWidth ; Store value $aiColWidth[$i] = $iColWidth Next ; Now check max size If $iWidth > @DesktopWidth - 100 Then ; Apply max col width limit to reduce width $iWidth = 40 For $i = 0 To $iColFill - 1 If $aiColWidth[$i] > $iMax_ColWidth Then ; Reset width GUICtrlSendMsg($idListView, (0x1000 + 30), $i, $iMax_ColWidth) ; $LVM_SETCOLUMNWIDTH $iWidth += $iMax_ColWidth Else ; Retain width $iWidth += $aiColWidth[$i] EndIf Next EndIf ; Check max/min width If $iWidth > @DesktopWidth - 100 Then $iWidth = @DesktopWidth - 100 ElseIf $iWidth < $iMinSize Then $iWidth = $iMinSize EndIf #EndRegion Adjust dialog width ; Allow for borders with vertical scrollbar Local $iScrollBarSize = 0 If $iHeight = (@DesktopHeight - 100) Then $iScrollBarSize = 15 ; Resize dialog WinMove($hGUI, "", (@DesktopWidth - $iWidth + $iScrollBarSize) / 2, (@DesktopHeight - $iHeight) / 2, $iWidth + $iScrollBarSize, $iHeight) ; Resize ListView $aiGUISize = WinGetClientSize($hGUI) GUICtrlSetPos($idListView, 0, 0, $iWidth, $aiGUISize[1] - $iButtonBorder) #Region Create bottom infos Local $iButtonWidth_1 = $aiGUISize[0] / 2 Local $iButtonWidth_2 = $aiGUISize[0] / 3 Local $idCopy_ID = 9999, $idCopy_Data = 99999, $idData_Label = 99999, $idUser_Func = 99999, $idExit_Script = 99999 If $bDebug Then ; Create buttons $idCopy_ID = GUICtrlCreateButton("Copy Data && Hdr/Row", 0, $aiGUISize[1] - $iButtonBorder, $iButtonWidth_1, 20) $idCopy_Data = GUICtrlCreateButton("Copy Data Only", $iButtonWidth_1, $aiGUISize[1] - $iButtonBorder, $iButtonWidth_1, 20) Local $iButtonWidth_Var = $iButtonWidth_1 Local $iOffset = $iButtonWidth_1 If IsFunc($hUser_Function) Then ; Create UserFunc button if function passed $idUser_Func = GUICtrlCreateButton("Run User Func", $iButtonWidth_2, $aiGUISize[1] - 20, $iButtonWidth_2, 20) $iButtonWidth_Var = $iButtonWidth_2 $iOffset = $iButtonWidth_2 * 2 EndIf ; Create Exit button and data label $idExit_Script = GUICtrlCreateButton("Exit Script", $iOffset, $aiGUISize[1] - 20, $iButtonWidth_Var, 20) $idData_Label = GUICtrlCreateLabel($sDisplayData, 0, $aiGUISize[1] - 20, $iButtonWidth_Var, 18, BitOR($_ADS_SS_CENTER, $_ADS_SS_CENTERIMAGE)) Else $idData_Label = GUICtrlCreateLabel($sDisplayData, 0, $aiGUISize[1] - 20, $aiGUISize[0], 18, BitOR($_ADS_SS_CENTER, $_ADS_SS_CENTERIMAGE)) EndIf ; Change label colour and create tooltip if required If $_gADS_aData[$iLevel][$eADS_Transpose] Or $sArrayRange Then GUICtrlSetColor($idData_Label, 0xFF0000) GUICtrlSetTip($idData_Label, $sTipData) EndIf GUICtrlSetResizing($idCopy_ID, $_ADS_GUI_DOCKLEFT + $_ADS_GUI_DOCKBOTTOM + $_ADS_GUI_DOCKHEIGHT) GUICtrlSetResizing($idCopy_Data, $_ADS_GUI_DOCKRIGHT + $_ADS_GUI_DOCKBOTTOM + $_ADS_GUI_DOCKHEIGHT) GUICtrlSetResizing($idData_Label, $_ADS_GUI_DOCKLEFT + $_ADS_GUI_DOCKBOTTOM + $_ADS_GUI_DOCKHEIGHT) GUICtrlSetResizing($idUser_Func, $_ADS_GUI_DOCKHCENTER + $_ADS_GUI_DOCKBOTTOM + $_ADS_GUI_DOCKHEIGHT) GUICtrlSetResizing($idExit_Script, $_ADS_GUI_DOCKRIGHT + $_ADS_GUI_DOCKBOTTOM + $_ADS_GUI_DOCKHEIGHT) #EndRegion Create bottom infos ; Display dialog GUISetState(@SW_SHOW, $hGUI) #Region GUI Handling events ; Switch to GetMessage mode Local $iOnEventMode = Opt("GUIOnEventMode", 0), $aMsg, $vTemp While True $aMsg = GUIGetMsg($_ADS_GUI_EVENT_ARRAY) ; Variable needed to check which "Copy" button was pressed If $aMsg[1] = $hGUI Then Switch $aMsg[0] Case $_ADS_GUI_EVENT_CLOSE ExitLoop Case $idCopy_ID, $idCopy_Data ; Count selected rows Local $iSel_Count = GUICtrlSendMsg($idListView, $_ADS_LVM_GETSELECTEDCOUNT, 0, 0) ; Display splash dialog if required If $iVerbose And (Not $iSel_Count) And ($iItem_End - $_gADS_aData[$iLevel][$eADS_Start]) * ($iSubItem_End - $iSubItem_Start) > 10000 Then SplashTextOn($sMsgBoxTitle, "Copying data" & @CRLF & @CRLF & "Please be patient", 300, 100) EndIf ; Generate clipboard text Local $sClip = "", $sItem, $aSplit, $iFirstCol = 0 If $aMsg[0] = $idCopy_Data And $_gADS_aData[$iLevel][$eADS_DisplayRow] Then $iFirstCol = 1 ; Add items For $i = 0 To GUICtrlSendMsg($idListView, 0X1004, 0, 0) - 1 ; $LVM_GETITEMCOUNT ; Skip if copying selected rows and item not selected If $iSel_Count And Not (GUICtrlSendMsg($idListView, $_ADS_LVM_GETITEMSTATE, $i, $_ADS_LVIS_SELECTED) <> 0) Then ContinueLoop EndIf $sItem = __ADS_GetItemTextStringSelected($idListView, $i, $iFirstCol) If $aMsg[0] = $idCopy_ID And Not $_gADS_aData[$iLevel][$eADS_DisplayRow] Then ; Add row data $sItem = $ADS_ROWPREFIX & " " & ($i + $_gADS_aData[$iLevel][$eADS_Start]) & $sCurr_Separator & $sItem EndIf If $iCW_ColWidth Then ; Expand columns $aSplit = StringSplit($sItem, $sCurr_Separator) $sItem = "" For $j = 1 To $aSplit[0] $sItem &= StringFormat("%-" & $iCW_ColWidth + 1 & "s", StringLeft($aSplit[$j], $iCW_ColWidth)) Next Else ; Use defined separator $sItem = StringReplace($sItem, $sCurr_Separator, $vUser_Separator) EndIf $sClip &= $sItem & @CRLF Next $sItem = $sHeader ; Add header line if required If $aMsg[0] = $idCopy_ID Then $sItem = $sHeader If Not $_gADS_aData[$iLevel][$eADS_DisplayRow] Then ; Add "Row" to header $sItem = "Row" & $sCurr_Separator & $sItem EndIf If $iCW_ColWidth Then $aSplit = StringSplit($sItem, $sCurr_Separator) $sItem = "" For $j = 1 To $aSplit[0] $sItem &= StringFormat("%-" & $iCW_ColWidth + 1 & "s", StringLeft($aSplit[$j], $iCW_ColWidth)) Next Else $sItem = StringReplace($sItem, $sCurr_Separator, $vUser_Separator) EndIf $sClip = $sItem & @CRLF & $sClip EndIf ;Send to clipboard ClipPut($sClip) ; Remove splash if used SplashOff() ; Refocus ListView GUICtrlSetState($idListView, $_ADS_GUI_FOCUS) Case $idListView $iColumn = GUICtrlGetState($idListView) $vTemp = $iColumn + Not $_gADS_aData[$iLevel][$eADS_DisplayRow] If Not IsArray(($_gADS_aData[$iLevel][$eADS_Index])[$vTemp]) Then __ADS_SortIndex($_gADS_aData[$iLevel][$eADS_Array], $_gADS_aData[$iLevel][$eADS_Index], $vTemp, $nRows, _ $_gADS_aData[$iLevel][$eADS_Transpose], ($_gADS_aData[$iLevel][$eADS_Numeric])[$vTemp - 1]) EndIf If $iColumn <> $iColumnPrev Then __ADS_HeaderSetItemFormat($hHeader, $iColumnPrev, 0x00004000 + $iColAlign / 2) ; $HDF_STRING If $_gADS_aData[$iLevel][$eADS_DisplayRow] And $iColumn = 0 Then $_gADS_aIndex[$iLevel] = ($_gADS_aData[$iLevel][$eADS_Index])[0] Else $_gADS_aIndex[$iLevel] = ($_gADS_aData[$iLevel][$eADS_Index])[$vTemp] EndIf EndIf $_gADS_aData[$iLevel][$eADS_SortDir] = ($iColumn = $iColumnPrev) ? $_gADS_aData[$iLevel][$eADS_SortDir] = 0x00000400 ? 0x00000200 : 0x00000400 : 0x00000400 ; $HDF_SORTUP __ADS_HeaderSetItemFormat($hHeader, $iColumn, 0x00004000 + $_gADS_aData[$iLevel][$eADS_SortDir] + $iColAlign / 2) ; $HDF_STRING GUICtrlSendMsg($idListView, (0x1000 + 140), $iColumn, 0) ; $LVM_SETSELECTEDCOLUMN GUICtrlSendMsg($idListView, (0x1000 + 47), $nRows, 0) ; $LVM_SETITEMCOUNT $iColumnPrev = $iColumn Case $idUser_Func ; Get selected indices Local $aiSelItems[1] = [0] For $i = 0 To GUICtrlSendMsg($idListView, 0x1004, 0, 0) - 1 ; $LVM_GETITEMCOUNT If (GUICtrlSendMsg($idListView, $_ADS_LVM_GETITEMSTATE, $i, $_ADS_LVIS_SELECTED) <> 0) Then $aiSelItems[0] += 1 ReDim $aiSelItems[$aiSelItems[0] + 1] $aiSelItems[$aiSelItems[0]] = $i + $_gADS_aData[$iLevel][$eADS_Start] EndIf Next ; Pass array and selection to user function $hUser_Function($_gADS_aData[$iLevel][$eADS_Array], $aiSelItems) GUICtrlSetState($idListView, $_ADS_GUI_FOCUS) Case $_gADS_aData[$iLevel][$eADS_Dummy] ReDim $_gADS_aData[$iLevel + 2][$eADS_All] ReDim $_gADS_aIndex[$iLevel + 2] If $iDimensions = 1 Then $vTemp = GUICtrlRead($aMsg[0]) __ArrayDisplay_ShareEX(($_gADS_aData[$iLevel][$eADS_Array])[Number($vTemp)], $iLevel + 1, "Row " & $vTemp & " (" & $iLevel + 1 & ")", _ Default, Default, Default, Default, Default, Default, $bDebug) Else $vTemp = StringSplit(GUICtrlRead($aMsg[0]), "|", $STR_NOCOUNT) __ArrayDisplay_ShareEX(($_gADS_aData[$iLevel][$eADS_Array])[Number($vTemp[0])][Number($vTemp[1])], $iLevel + 1, "Row " & $vTemp[0] & " - Col " & $vTemp[1] & " (" & $iLevel + 1 & ")", _ Default, Default, Default, Default, Default, Default, $bDebug) EndIf ReDim $_gADS_aData[$iLevel + 1][$eADS_All] ReDim $_gADS_aIndex[$iLevel + 1] Case $idExit_Script ExitLoop EndSwitch EndIf WEnd #EndRegion GUI Handling events ; Release resources in case of big array used $_gADS_aIndex[$iLevel] = 0 For $i = 0 To $eADS_All - 1 $_gADS_aData[$iLevel][$i] = 0 Next GUIDelete($hGUI) If $aMsg[0] = $idExit_Script Then Exit Opt("GUICoordMode", $iCoordMode) ; Reset original Coord mode Opt("GUIOnEventMode", $iOnEventMode) ; Reset original GUI mode Return SetError($_iCallerError, $_iCallerExtended, 1) EndFunc ;==>__ArrayDisplay_ShareEX Func __ADS_WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) Local Static $tText = DllStructCreate("wchar[4096]"), $pText = DllStructGetPtr($tText) Local $tNMLVDISPINFO = DllStructCreate($tagNMLVDISPINFO, $lParam) Local $iLevel = -1 For $i = 0 To UBound($_gADS_aData) - 1 If $_gADS_aData[$i][$eADS_List] = DllStructGetData($tNMLVDISPINFO, "hWndFrom") Then $iLevel = $i ExitLoop EndIf Next If $iLevel < 0 Then Return $GUI_RUNDEFMSG Local $iDimensions = UBound($_gADS_aData[$iLevel][$eADS_Array], $UBOUND_DIMENSIONS) Local $nRows = UBound($_gADS_aData[$iLevel][$eADS_Array], $UBOUND_ROWS) Local $nCols = ($iDimensions = 2) ? UBound($_gADS_aData[$iLevel][$eADS_Array], $UBOUND_COLUMNS) : 1 Switch DllStructGetData($tNMLVDISPINFO, "Code") Case $NM_CLICK Local $tNMITEMACTIVATE = DllStructCreate($tagNMITEMACTIVATE, $lParam) Local $iItem = DllStructGetData($tNMITEMACTIVATE, "Index"), $iCol = DllStructGetData($tNMITEMACTIVATE, "SubItem") If $iItem < 0 Or $iCol < 0 Then Return $GUI_RUNDEFMSG Local $iRow = ($_gADS_aData[$iLevel][$eADS_SortDir] = 0x00000400) ? ($_gADS_aIndex[$iLevel])[$iItem] : ($_gADS_aIndex[$iLevel])[$nRows - 1 - $iItem] If $iCol Or Not $_gADS_aData[$iLevel][$eADS_DisplayRow] Then If $iDimensions = 1 And IsArray(($_gADS_aData[$iLevel][$eADS_Array])[$iRow]) Then GUICtrlSendToDummy($_gADS_aData[$iLevel][$eADS_Dummy], $iRow) ElseIf $iDimensions = 2 And IsArray(($_gADS_aData[$iLevel][$eADS_Array])[$iRow][$iCol - $_gADS_aData[$iLevel][$eADS_DisplayRow]]) Then GUICtrlSendToDummy($_gADS_aData[$iLevel][$eADS_Dummy], $iRow & "|" & ($iCol - $_gADS_aData[$iLevel][$eADS_DisplayRow])) EndIf EndIf Case $LVN_GETDISPINFOW Local $iItem = DllStructGetData($tNMLVDISPINFO, "Item") Local $iRow = ($_gADS_aData[$iLevel][$eADS_SortDir] = 0x00000400) ? ($_gADS_aIndex[$iLevel])[$iItem] : ($_gADS_aIndex[$iLevel])[$nRows - 1 - $iItem] Local $iCol = DllStructGetData($tNMLVDISPINFO, "SubItem") Local $sTemp If Not $_gADS_aData[$iLevel][$eADS_DisplayRow] Then If $iDimensions = 2 Then $sTemp = ($_gADS_aData[$iLevel][$eADS_Array])[$iRow][$iCol] Else $sTemp = ($_gADS_aData[$iLevel][$eADS_Array])[$iRow] EndIf Switch VarGetType($sTemp) Case "Array" $sTemp = "{Array}" Case "Map" $sTemp = "{Map}" EndSwitch If StringLen($sTemp) > 4095 Then $sTemp = StringLeft($sTemp, 4095) DllStructSetData($tText, 1, $sTemp) DllStructSetData($tNMLVDISPINFO, "Text", $pText) Else If $iCol = 0 Then If $_gADS_aData[$iLevel][$eADS_Transpose] Then Local $sCaptionCplt = "" If $iRow + $_gADS_aData[$iLevel][$eADS_Start] < UBound($_gADS_aData[$iLevel][$eADS_Header]) _ And StringStripWS(($_gADS_aData[$iLevel][$eADS_Header])[$iRow + $_gADS_aData[$iLevel][$eADS_Start]], 1 + 2) <> "" Then $sCaptionCplt = " (" & StringStripWS(($_gADS_aData[$iLevel][$eADS_Header])[$iRow + $_gADS_aData[$iLevel][$eADS_Start]], 1 + 2) ;If StringRight($sCaptionCplt, 1) = $ADS_NUMERICSORT Then $sCaptionCplt = StringTrimRight($sCaptionCplt, 1) $sCaptionCplt &= ")" EndIf DllStructSetData($tText, 1, "Col " & ($iRow + $_gADS_aData[$iLevel][$eADS_Start]) & $sCaptionCplt) Else DllStructSetData($tText, 1, $ADS_ROWPREFIX & " " & $iRow + $_gADS_aData[$iLevel][$eADS_Start]) EndIf DllStructSetData($tNMLVDISPINFO, "Text", $pText) Else If $iDimensions = 2 Then $sTemp = ($_gADS_aData[$iLevel][$eADS_Array])[$iRow][$iCol - 1] Else $sTemp = ($_gADS_aData[$iLevel][$eADS_Array])[$iRow] EndIf Switch VarGetType($sTemp) Case "Array" $sTemp = "{Array}" Case "Map" $sTemp = "{Map}" EndSwitch If StringLen($sTemp) > 4095 Then $sTemp = StringLeft($sTemp, 4095) DllStructSetData($tText, 1, $sTemp) DllStructSetData($tNMLVDISPINFO, "Text", $pText) EndIf EndIf EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>__ADS_WM_NOTIFY Func __ADS_BaseIndex(ByRef $aData, $nRows, $nCols) Dim $aData[$nCols + 1] Local $aArray[$nRows] For $i = 0 To $nRows - 1 $aArray[$i] = $i Next $aData[0] = $aArray EndFunc ;==>__ADS_BaseIndex Func __ADS_SortIndex(ByRef $aArray, ByRef $aData, $iCol, $nRows, $iTranspose, $iNumeric) Local Const $CURSOR_WAIT = 15 GUISetCursor($CURSOR_WAIT, $GUI_CURSOR_OVERRIDE) Local $aIndex[$nRows] Local $tIndex = __ADS_GetSortColStruct($aArray, $iCol - 1, $iTranspose, $iNumeric) For $i = 0 To $nRows - 1 $aIndex[$i] = DllStructGetData($tIndex, 1, $i + 1) Next $aData[$iCol] = $aIndex GUISetCursor() EndFunc ;==>__ADS_SortIndex Func __ADS_GetSortColStruct(Const ByRef $aArray, $iCol, $iTranspose, $iNumSort) Local $iDims = UBound($aArray, $UBOUND_DIMENSIONS) Local $nRows = UBound($aArray) Local $tIndex = DllStructCreate("uint[" & $nRows & "]") Local $pIndex = DllStructGetPtr($tIndex) Static $hDll = DllOpen("kernel32.dll") Static $hDllComp = DllOpen("shlwapi.dll") Local $lo, $hi, $mi, $r, $nVal1, $nVal2 ; Sorting by one column For $i = 1 To $nRows - 1 $lo = 0 $hi = $i - 1 Do $mi = Int(($lo + $hi) / 2) If $iNumSort Then ; Numeric sort If $iDims = 1 Then $nVal1 = Number($aArray[$i]) $nVal2 = Number($aArray[DllStructGetData($tIndex, 1, $mi + 1)]) Else $nVal1 = Number($aArray[$i][$iCol]) $nVal2 = Number($aArray[DllStructGetData($tIndex, 1, $mi + 1)][$iCol]) EndIf $r = $nVal1 < $nVal2 ? -1 : $nVal1 > $nVal2 ? 1 : 0 Else ; Natural sort If $iDims = 1 Then $r = DllCall($hDllComp, 'int', 'StrCmpLogicalW', 'wstr', $aArray[$i], 'wstr', $aArray[DllStructGetData($tIndex, 1, $mi + 1)])[0] Else $r = DllCall($hDllComp, 'int', 'StrCmpLogicalW', 'wstr', $aArray[$i][$iCol], 'wstr', $aArray[DllStructGetData($tIndex, 1, $mi + 1)][$iCol])[0] EndIf EndIf Switch $r Case -1 $hi = $mi - 1 Case 1 $lo = $mi + 1 Case 0 ExitLoop EndSwitch Until $lo > $hi DllCall($hDll, "none", "RtlMoveMemory", "struct*", $pIndex + ($mi + 1) * 4, "struct*", $pIndex + $mi * 4, "ulong_ptr", ($i - $mi) * 4) DllStructSetData($tIndex, 1, $i, $mi + 1 + ($lo = $mi + 1)) Next Return $tIndex EndFunc ;==>__ADS_GetSortColStruct Func __ADS_CreateSubArray(ByRef $aArray, $iDims, ByRef $iItem_Start, ByRef $iItem_End, ByRef $iSubItem_Start, ByRef $iSubItem_End, ByRef $nRows, ByRef $nCols, $iTranspose) ; the returned subarray is transposed $nRows = $iItem_End - $iItem_Start + 1 $nCols = $iSubItem_End - $iSubItem_Start + 1 Local $iRow = -1, $iCol, $iTemp, $aTemp If $iTranspose Then Dim $aTemp[$nCols][$nRows] For $i = $iItem_Start To $iItem_End $iRow += 1 $iCol = -1 For $j = $iSubItem_Start To $iSubItem_End $iCol += 1 $aTemp[$iCol][$iRow] = $aArray[$i][$j] Next Next $iTemp = $iItem_Start $iItem_Start = $iSubItem_Start $iSubItem_Start = $iTemp $iTemp = $iItem_End $iItem_End = $iSubItem_End $iSubItem_End = $iTemp $iTemp = $nRows $nRows = $nCols $nCols = $iTemp Else If $iDims = 1 Then Dim $aTemp[$nRows] For $i = $iItem_Start To $iItem_End $iRow += 1 $aTemp[$iRow] = $aArray[$i] Next Else Dim $aTemp[$nRows][$nCols] For $i = $iItem_Start To $iItem_End $iRow += 1 $iCol = -1 For $j = $iSubItem_Start To $iSubItem_End $iCol += 1 $aTemp[$iRow][$iCol] = $aArray[$i][$j] Next Next EndIf EndIf Return $aTemp EndFunc ;==>__ADS_CreateSubArray ; #DUPLICATED Functions to avoid big #include "GuiHeader.au3"# ================================================================== ; Functions have been simplified (unicode inprocess) according to __ADS_Share() needs Func __ADS_HeaderSetItemFormat($hWnd, $iIndex, $iFormat) Local Static $tHDItem = DllStructCreate("uint Mask;int XY;ptr Text;handle hBMP;int TextMax;int Fmt;lparam Param;int Image;int Order;uint Type;ptr pFilter;uint State") ; $tagHDITEM DllStructSetData($tHDItem, "Mask", 0x00000004) ; $HDI_FORMAT DllStructSetData($tHDItem, "Fmt", $iFormat) Local $aResult = DllCall("user32.dll", "lresult", "SendMessageW", "hwnd", $hWnd, "uint", 0x120C, "wparam", $iIndex, "struct*", $tHDItem) ; $HDM_SETITEMW Return $aResult[0] <> 0 EndFunc ;==>__ADS_HeaderSetItemFormat ; #DUPLICATED Functions to avoid big #include "GuiListView.au3"# ================================================================ ; Functions have been simplified (unicode inprocess) according to __ADS_Share() needs Func __ADS_GetItemText($idListView, $iIndex, $iSubItem = 0) Local $tBuffer = DllStructCreate("wchar Text[4096]") Local $pBuffer = DllStructGetPtr($tBuffer) Local $tItem = DllStructCreate($ADS_tagLVITEM) DllStructSetData($tItem, "SubItem", $iSubItem) DllStructSetData($tItem, "TextMax", 4096) DllStructSetData($tItem, "Text", $pBuffer) ;Global Const $LVM_GETITEMTEXTW = (0x1000 + 115) ; 0X1073 If IsHWnd($idListView) Then DllCall("user32.dll", "lresult", "SendMessageW", "hwnd", $idListView, "uint", 0x1073, "wparam", $iIndex, "struct*", $tItem) Else Local $pItem = DllStructGetPtr($tItem) GUICtrlSendMsg($idListView, 0x1073, $iIndex, $pItem) EndIf Return DllStructGetData($tBuffer, "Text") EndFunc ;==>__ADS_GetItemText Func __ADS_GetItemTextStringSelected($idListView, $iItem, $iFirstCol) Local $sRow = "", $sSeparatorChar = Opt('GUIDataSeparatorChar') Local $iSelected = $iItem ; get row ; GetColumnCount Local $hHeader = HWnd(GUICtrlSendMsg($idListView, 0x101F, 0, 0)) ; $LVM_GETHEADER Local $nCol = DllCall("user32.dll", "lresult", "SendMessageW", "hwnd", $hHeader, "uint", 0x1200, "wparam", 0, "lparam", 0)[0] ; $HDM_GETITEMCOUNT For $x = $iFirstCol To $nCol - 1 $sRow &= __ADS_GetItemText($idListView, $iSelected, $x) & $sSeparatorChar Next Return StringTrimRight($sRow, 1) EndFunc ;==>__ADS_GetItemTextStringSelected Func __ADS_JustifyColumn($idListView, $iIndex, $iAlign = -1) ;Local $aAlign[3] = [$LVCFMT_LEFT, $LVCFMT_RIGHT, $LVCFMT_CENTER] Local $tColumn = DllStructCreate("uint Mask;int Fmt;int CX;ptr Text;int TextMax;int SubItem;int Image;int Order;int cxMin;int cxDefault;int cxIdeal") ; $tagLVCOLUMN If $iAlign < 0 Or $iAlign > 2 Then $iAlign = 0 DllStructSetData($tColumn, "Mask", 0x01) ; $LVCF_FMT DllStructSetData($tColumn, "Fmt", $iAlign) Local $pColumn = DllStructGetPtr($tColumn) Local $iRet = GUICtrlSendMsg($idListView, 0x1060, $iIndex, $pColumn) ; $_ADS_LVM_SETCOLUMNW Return $iRet <> 0 EndFunc ;==>__ADS_JustifyColumn Func __ADS_CustomHeader(ByRef $aHeader, ByRef $aNumeric, $sHeader, $sCurr_Separator, $iSubItem_Start, $iSubItem_End, $iTranspose, $nRows, $nCols, $iDisplayRow) $aHeader = StringSplit($sHeader, $sCurr_Separator, $STR_NOCOUNT) If UBound($aHeader) = 0 Then Dim $aHeader[1] = [""] $sHeader = "Row" Local $iIndex = $iSubItem_Start If $iTranspose Then Dim $aNumeric[$nRows] ; All default headers $sHeader = "Row" For $j = 0 To $nCols - 1 $sHeader &= $sCurr_Separator & $ADS_ROWPREFIX & " " & $j + $iSubItem_Start Next Else ; Create custom header with available items Dim $aNumeric[$nCols] If $aHeader[0] Then ; Set as many as available For $iIndex = $iSubItem_Start To $iSubItem_End ; Check custom header available If $iIndex >= UBound($aHeader) Then ExitLoop If StringRight($aHeader[$iIndex], 1) = $ADS_NUMERICSORT Then $aHeader[$iIndex] = StringTrimRight($aHeader[$iIndex], 1) ; remove "*" from right $aNumeric[$iIndex - $iSubItem_Start] = 1 ; 1 (numeric sort) or empty (natural sort) EndIf $sHeader &= $sCurr_Separator & $aHeader[$iIndex] Next EndIf ; Add default headers to fill to end For $j = $iIndex To $iSubItem_End $sHeader &= $sCurr_Separator & "Col " & $j Next EndIf ; Remove "Row" header if not needed If Not $iDisplayRow Then $sHeader = StringTrimLeft($sHeader, 4) Return $sHeader EndFunc ;==>__ADS_CustomHeader