AZJIO

_ArrayDisplay for 3.3.8.1

Dec 22nd, 2013
482
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Func _ArrayDisplay(Const ByRef $avArray, $sTitle = Default, $sArray_Range = -1, $iFlags = Default, $vUser_Separator = Default, $sReplace = "|", $sHeader = Default)
  2.     #forceref $sReplace
  3.  
  4.     Local Const $_ARRAYCONSTANT_MB_SYSTEMMODAL = 4096
  5.     Local Const $_ARRAYCONSTANT_MB_ICONINFORMATION = 64
  6.     Local Const $_ARRAYCONSTANT_MB_ICONERROR = 16
  7.     Local Const $_ARRAYCONSTANT_MB_YESNO = 4
  8.     Local Const $_ARRAYCONSTANT_IDYES = 6
  9.  
  10.     ; Default values
  11.     If $sTitle = Default Then $sTitle = "ArrayDisplay"
  12.     If $sArray_Range = -1 Then $sArray_Range = ""
  13.     If $iFlags = Default Then $iFlags = 0
  14.     If $vUser_Separator = Default Then $vUser_Separator = ""
  15.     If $sHeader = Default Then $sHeader = ""
  16.     Local $iMax_ColWidth = 350
  17.  
  18.     ; Check valid array
  19.     Local $sMsg = "", $iRet
  20.     If IsArray($avArray) Then
  21.         ; Dimension checking
  22.         Local $iDimension = UBound($avArray, 0), $iRowCount = UBound($avArray, 1), $iColCount = UBound($avArray, 2)
  23.         If $iDimension > 2 Then
  24.             $sMsg = "Larger than 2D array passed to function"
  25.             $iRet = 2
  26.         EndIf
  27.     Else
  28.         $sMsg = "No array variable passed to function"
  29.         $iRet = 1
  30.     EndIf
  31.     If $sMsg Then
  32.         If BitAND($iFlags, 8) And MsgBox($_ARRAYCONSTANT_MB_SYSTEMMODAL + $_ARRAYCONSTANT_MB_ICONERROR + $_ARRAYCONSTANT_MB_YESNO, _
  33.                 "ArrayDisplay Error: " & $sTitle, $sMsg & @CRLF & @CRLF & "Exit the script?") = $_ARRAYCONSTANT_IDYES Then
  34.             Exit
  35.         Else
  36.             Return SetError($iRet, 0, "")
  37.         EndIf
  38.     EndIf
  39.  
  40.     ; Check for transpose and column align
  41.     Local $iTranspose = BitAND($iFlags, 1)
  42.     Local $iColAlign = BitAND($iFlags, 6) ; 0 = Left (default); 2 = Right; 4 = Center
  43.  
  44.     ; Determine copy separator
  45.     Local $iCW_ColWidth = Number($vUser_Separator)
  46.  
  47.     ; Add dimensions to title
  48.     Local $sDisplayTitle = "[" & $iRowCount & "]"
  49.     If $iDimension = 2 Then
  50.         $sDisplayTitle &= "[" & $iColCount & "]"
  51.     EndIf
  52.     If $iTranspose Then $sDisplayTitle &= " Transposed"
  53.     If $sTitle Then $sDisplayTitle &= " - " & $sTitle
  54.  
  55.     ; Separator handling
  56.     Local $sAD_Separator = ChrW(0xFAB1)
  57.     ; Set separator to use in this UDF and store existing one
  58.     Local $sCurr_Separator = Opt("GUIDataSeparatorChar", $sAD_Separator)
  59.     ; Set default user separator if required
  60.     If $vUser_Separator = "" Then $vUser_Separator = $sCurr_Separator
  61.  
  62.     ; Declare variables
  63.     Local $vTmp, $iRowLimit = 65526, $iColLimit = 250 ; Row = 64k control limit minus 4 buttons; Column - arbitrary limit
  64.  
  65.     ; Swap dimensions if transposing
  66.     If $iColCount < 0 Then $iColCount = 0
  67.     If $iTranspose Then
  68.         $vTmp = $iRowCount
  69.         $iRowCount = $iColCount
  70.         $iColCount = $vTmp
  71.     EndIf
  72.  
  73.     ; Set display limits for dimensions
  74.     Local $iItem_Start = 0, $iItem_End = $iRowCount - 1, $iSubItem_Start = 0, $iSubItem_End = $iColCount - 1, $avDimSplit, $avRangeSplit
  75.     ; Adjust for 1D array
  76.     If $iDimension = 1 Then
  77.         If $iTranspose Then
  78.             $iItem_End = 0
  79.         Else
  80.             $iSubItem_End = 0
  81.         EndIf
  82.     EndIf
  83.     ; Check for range set
  84.     If $sArray_Range Then
  85.         ; Force trailing | if required
  86.         $iItem_End = Number($sArray_Range)
  87.         ; Check valid ranges
  88.         ; Swap if tranposing
  89.         If $iTranspose Then
  90.             $vTmp = $iItem_Start
  91.             $iItem_Start = $iSubItem_Start
  92.             $iSubItem_Start = $vTmp
  93.             $vTmp = $iItem_End
  94.             $iItem_End = $iSubItem_End
  95.             $iSubItem_End = $vTmp
  96.         EndIf
  97.         If $iItem_Start < 0 Then $iItem_Start = 0
  98.         If $iSubItem_Start < 0 Then $iSubItem_Start = 0
  99.         If $iItem_End > $iRowCount - 1 Then $iItem_End = $iRowCount - 1
  100.         If $iSubItem_End > $iColCount - 1 Then $iSubItem_End = $iColCount - 1
  101.     EndIf
  102.  
  103.     ; Check if array will be truncated
  104.     $sMsg = ""
  105.     If $iItem_End - $iItem_Start > $iRowLimit Then
  106.         $sMsg = "Array truncated - maximum " & $iRowLimit & " rows will be displayed"
  107.         $iItem_End = $iItem_Start + $iRowLimit - 1
  108.     EndIf
  109.     If $iSubItem_End - $iSubItem_Start > $iColLimit Then
  110.         If $sMsg Then $sMsg &= @CRLF & @CRLF
  111.         $sMsg &= "Array truncated - maximum " & $iColLimit & " columns will be displayed"
  112.         $iSubItem_End = $iSubItem_Start + $iColLimit - 1
  113.     EndIf
  114.  
  115.     If $sHeader = "" Then $sHeader = "Row"
  116.     ; Split custom header on separator
  117.     $aHeader = StringSplit($sHeader, $sCurr_Separator) ; No count element
  118.     $sHeader = ""
  119.     If $aHeader[0] > $iColCount + 1 Then
  120.         For $i = $iSubItem_Start To $iSubItem_End + 1
  121.             $sHeader &= $sAD_Separator & $aHeader[$i + 1]
  122.         Next
  123.     Else
  124.         For $i = $iSubItem_Start + 1 To $aHeader[0]
  125.             $sHeader &= $sAD_Separator & $aHeader[$i]
  126.         Next
  127.         For $i = $aHeader[0] - 1 To $iSubItem_End
  128.             $sHeader &= $sAD_Separator & "Col " & $i
  129.         Next
  130.     EndIf
  131.     $sHeader = StringTrimLeft($sHeader, 1)
  132.  
  133.     ; Convert array into ListViewItem compatible lines
  134.     Local $avArrayText[$iItem_End - $iItem_Start + 1]
  135.     For $i = $iItem_Start To $iItem_End
  136.         $avArrayText[$i - $iItem_Start] = "[" & $i & "]"
  137.         For $j = $iSubItem_Start To $iSubItem_End
  138.             ; Get current item
  139.             If $iDimension = 1 Then
  140.                 If $iTranspose Then
  141.                     $vTmp = $avArray[$j]
  142.                 Else
  143.                     $vTmp = $avArray[$i]
  144.                 EndIf
  145.             Else
  146.                 If $iTranspose Then
  147.                     $vTmp = $avArray[$j][$i]
  148.                 Else
  149.                     $vTmp = $avArray[$i][$j]
  150.                 EndIf
  151.             EndIf
  152.             $avArrayText[$i - $iItem_Start] &= $sAD_Separator & $vTmp
  153.         Next
  154.     Next
  155.  
  156.     ; GUI Constants
  157.     Local Const $_ARRAYCONSTANT_GUI_DOCKBOTTOM = 64
  158.     Local Const $_ARRAYCONSTANT_GUI_DOCKBORDERS = 102
  159.     Local Const $_ARRAYCONSTANT_GUI_DOCKHEIGHT = 512
  160.     Local Const $_ARRAYCONSTANT_GUI_DOCKLEFT = 2
  161.     Local Const $_ARRAYCONSTANT_GUI_DOCKRIGHT = 4
  162.     Local Const $_ARRAYCONSTANT_GUI_EVENT_CLOSE = -3
  163.     Local Const $_ARRAYCONSTANT_GUI_FOCUS = 256
  164.     Local Const $_ARRAYCONSTANT_GUI_BKCOLOR_LV_ALTERNATE = 0xFE000000
  165.     Local Const $_ARRAYCONSTANT_LVM_GETITEMRECT = (0x1000 + 14)
  166.     Local Const $_ARRAYCONSTANT_LVM_GETCOLUMNWIDTH = (0x1000 + 29)
  167.     Local Const $_ARRAYCONSTANT_LVM_SETCOLUMNWIDTH = (0x1000 + 30)
  168.     Local Const $_ARRAYCONSTANT_LVM_GETITEMSTATE = (0x1000 + 44)
  169.     Local Const $_ARRAYCONSTANT_LVM_GETSELECTEDCOUNT = (0x1000 + 50)
  170.     Local Const $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE = (0x1000 + 54)
  171.     Local Const $_ARRAYCONSTANT_LVS_EX_GRIDLINES = 0x1
  172.     Local Const $_ARRAYCONSTANT_LVIS_SELECTED = 0x2
  173.     Local Const $_ARRAYCONSTANT_LVS_SHOWSELALWAYS = 0x8
  174.     Local Const $_ARRAYCONSTANT_LVS_EX_FULLROWSELECT = 0x20
  175.     Local Const $_ARRAYCONSTANT_WS_EX_CLIENTEDGE = 0x0200
  176.     Local Const $_ARRAYCONSTANT_WS_MAXIMIZEBOX = 0x00010000
  177.     Local Const $_ARRAYCONSTANT_WS_MINIMIZEBOX = 0x00020000
  178.     Local Const $_ARRAYCONSTANT_WS_SIZEBOX = 0x00040000
  179.     Local Const $_ARRAYCONSTANT_WM_SETREDRAW = 11
  180.     Local Const $_ARRAYCONSTANT_LVSCW_AUTOSIZE = -1
  181.  
  182.     ; Create GUI
  183.     Local $iOrgWidth = 200, $iHeight = 200, $iMinSize = 250
  184.     Local $hGUI = GUICreate($sDisplayTitle, $iOrgWidth, $iHeight, Default, Default, BitOR($_ARRAYCONSTANT_WS_SIZEBOX, $_ARRAYCONSTANT_WS_MINIMIZEBOX, $_ARRAYCONSTANT_WS_MAXIMIZEBOX))
  185.     Local $aiGUISize = WinGetClientSize($hGUI)
  186.     Local $iButtonWidth = $aiGUISize[0] / 2
  187.     ; Create ListView
  188.     Local $cListView = GUICtrlCreateListView($sHeader, 0, 0, $aiGUISize[0], $aiGUISize[1] - 46, $_ARRAYCONSTANT_LVS_SHOWSELALWAYS)
  189.     GUICtrlSetBkColor($cListView, $_ARRAYCONSTANT_GUI_BKCOLOR_LV_ALTERNATE)
  190.     GUICtrlSendMsg($cListView, $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE, $_ARRAYCONSTANT_LVS_EX_GRIDLINES, $_ARRAYCONSTANT_LVS_EX_GRIDLINES)
  191.     GUICtrlSendMsg($cListView, $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE, $_ARRAYCONSTANT_LVS_EX_FULLROWSELECT, $_ARRAYCONSTANT_LVS_EX_FULLROWSELECT)
  192.     GUICtrlSendMsg($cListView, $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE, $_ARRAYCONSTANT_WS_EX_CLIENTEDGE, $_ARRAYCONSTANT_WS_EX_CLIENTEDGE)
  193.     ; Create buttons
  194.     Local $cCopy_ID = GUICtrlCreateButton("Copy Data && Hdr/Row", 0, $aiGUISize[1] - 43, $iButtonWidth, 20)
  195.     Local $cCopy_Data = GUICtrlCreateButton("Copy Data Only", $iButtonWidth, $aiGUISize[1] - 43, $iButtonWidth, 20)
  196.     Local $cExit_Script = GUICtrlCreateButton("Exit Script", $iButtonWidth, $aiGUISize[1] - 23, $iButtonWidth, 20)
  197.     ; Set resizing
  198.     GUICtrlSetResizing($cListView, $_ARRAYCONSTANT_GUI_DOCKBORDERS)
  199.     GUICtrlSetResizing($cCopy_ID, $_ARRAYCONSTANT_GUI_DOCKLEFT + $_ARRAYCONSTANT_GUI_DOCKBOTTOM + $_ARRAYCONSTANT_GUI_DOCKHEIGHT)
  200.     GUICtrlSetResizing($cCopy_Data, $_ARRAYCONSTANT_GUI_DOCKRIGHT + $_ARRAYCONSTANT_GUI_DOCKBOTTOM + $_ARRAYCONSTANT_GUI_DOCKHEIGHT)
  201.     GUICtrlSetResizing($cExit_Script, $_ARRAYCONSTANT_GUI_DOCKRIGHT + $_ARRAYCONSTANT_GUI_DOCKBOTTOM + $_ARRAYCONSTANT_GUI_DOCKHEIGHT)
  202.  
  203.     ; Start ListView update
  204.     GUICtrlSendMsg($cListView, $_ARRAYCONSTANT_WM_SETREDRAW, 0, 0)
  205.  
  206.     ; Fill listview
  207.     Local $cItem
  208.     For $i = 0 To UBound($avArrayText) - 1
  209.         $cItem = GUICtrlCreateListViewItem($avArrayText[$i], $cListView)
  210.     Next
  211.  
  212.     ; Align columns if required - $iColAlign = 2 for Right and 4 for Center
  213.     If $iColAlign Then
  214.         Local Const $_ARRAYCONSTANT_LVCF_FMT = 0x01
  215.         Local Const $_ARRAYCONSTANT_LVM_SETCOLUMNW = (0x1000 + 96)
  216.         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")
  217.         DllStructSetData($tColumn, "Mask", $_ARRAYCONSTANT_LVCF_FMT)
  218.         DllStructSetData($tColumn, "Fmt", $iColAlign / 2) ; Left = 0; Right = 1; Center = 2
  219.         Local $pColumn = DllStructGetPtr($tColumn)
  220.         ; Loop through columns
  221.         For $i = 1 To $iSubItem_End - $iSubItem_Start + 1
  222.             GUICtrlSendMsg($cListView, $_ARRAYCONSTANT_LVM_SETCOLUMNW, $i, $pColumn)
  223.         Next
  224.     EndIf
  225.  
  226.     ; End ListView update
  227.     GUICtrlSendMsg($cListView, $_ARRAYCONSTANT_WM_SETREDRAW, 1, 0)
  228.  
  229.     ; Allow for borders with and without vertical scrollbar
  230.     Local $iBorder = 45
  231.     If UBound($avArrayText) > 20 Then
  232.         $iBorder += 20
  233.     EndIf
  234.     ; Adjust dialog width
  235.     Local $iWidth = $iBorder, $iColWidth = 0, $aiColWidth[$iColCount + 2], $iMin_ColWidth = 50
  236.     ; Get required column widths to fit items
  237.     For $i = 0 To $iSubItem_End - $iSubItem_Start + 1
  238.         GUICtrlSendMsg($cListView, $_ARRAYCONSTANT_LVM_SETCOLUMNWIDTH, $i, $_ARRAYCONSTANT_LVSCW_AUTOSIZE)
  239.         $iColWidth = GUICtrlSendMsg($cListView, $_ARRAYCONSTANT_LVM_GETCOLUMNWIDTH, $i, 0)
  240.         ; Set minimum if required
  241.         If $iColWidth < $iMin_ColWidth Then
  242.             GUICtrlSendMsg($cListView, $_ARRAYCONSTANT_LVM_SETCOLUMNWIDTH, $i, $iMin_ColWidth)
  243.             $iColWidth = $iMin_ColWidth
  244.         EndIf
  245.         ; Add to total width
  246.         $iWidth += $iColWidth
  247.         ; Store  value
  248.         $aiColWidth[$i] = $iColWidth
  249.     Next
  250.     ; Now check max size
  251.     If $iWidth > @DesktopWidth - 100 Then
  252.         ; Apply max col width limit to reduce width
  253.         $iWidth = $iBorder
  254.         For $i = 0 To $iSubItem_End - $iSubItem_Start + 1
  255.             If $aiColWidth[$i] > $iMax_ColWidth Then
  256.                 ; Reset width
  257.                 GUICtrlSendMsg($cListView, $_ARRAYCONSTANT_LVM_SETCOLUMNWIDTH, $i, $iMax_ColWidth)
  258.                 $iWidth += $iMax_ColWidth
  259.             Else
  260.                 ; Retain width
  261.                 $iWidth += $aiColWidth[$i]
  262.             EndIf
  263.         Next
  264.     EndIf
  265.     ; Check max/min width
  266.     If $iWidth > @DesktopWidth - 100 Then
  267.         $iWidth = @DesktopWidth - 100
  268.     ElseIf $iWidth < $iMinSize Then
  269.         $iWidth = $iMinSize
  270.     EndIf
  271.  
  272.     ; Get row height
  273.     Local $tRect = DllStructCreate("struct; long Left;long Top;long Right;long Bottom; endstruct")
  274.     DllCall("user32.dll", "struct*", "SendMessageW", "hwnd", GUICtrlGetHandle($cListView), "uint", $_ARRAYCONSTANT_LVM_GETITEMRECT, "wparam", 0, "struct*", $tRect)
  275.     ; Set required GUI height
  276.     Local $aiWin_Pos = WinGetPos($hGUI)
  277.     Local $aiLV_Pos = ControlGetPos($hGUI, "", $cListView)
  278.     $iHeight = ((UBound($avArrayText) + 3) * (DllStructGetData($tRect, "Bottom") - DllStructGetData($tRect, "Top"))) + $aiWin_Pos[3] - $aiLV_Pos[3]
  279.     ; Check min/max height
  280.     If $iHeight > @DesktopHeight - 100 Then
  281.         $iHeight = @DesktopHeight - 100
  282.     ElseIf $iHeight < $iMinSize Then
  283.         $iHeight = $iMinSize
  284.     EndIf
  285.  
  286.     ; Display and resize dialog
  287.     GUISetState(@SW_HIDE, $hGUI)
  288.     WinMove($hGUI, "", (@DesktopWidth - $iWidth) / 2, (@DesktopHeight - $iHeight) / 2, $iWidth, $iHeight)
  289.     GUISetState(@SW_SHOW, $hGUI)
  290.  
  291.     ; Announce if array was truncated
  292.     If $sMsg Then
  293.         MsgBox($_ARRAYCONSTANT_MB_SYSTEMMODAL + $_ARRAYCONSTANT_MB_ICONINFORMATION, "Array truncated", $sMsg, 0, $hGUI)
  294.     EndIf
  295.  
  296.     ; Switch to GetMessage mode
  297.     Local $iOnEventMode = Opt("GUIOnEventMode", 0), $iMsg
  298.  
  299.     While 1
  300.  
  301.         $iMsg = GUIGetMsg() ; Variable needed to check which "Copy" button was pressed
  302.         Switch $iMsg
  303.             Case $_ARRAYCONSTANT_GUI_EVENT_CLOSE
  304.                 ExitLoop
  305.  
  306.             Case $cCopy_ID, $cCopy_Data
  307.                 ; Count selected rows
  308.                 Local $iSel_Count = GUICtrlSendMsg($cListView, $_ARRAYCONSTANT_LVM_GETSELECTEDCOUNT, 0, 0)
  309.                 ; Display splash dialog if required
  310.                 If Not ($iSel_Count) And (($iItem_End - $iItem_Start) * ($iSubItem_End - $iSubItem_Start) > 10000) Then
  311.                     SplashTextOn("ArrayDisplay", "Copying data" & @CRLF & @CRLF & "Please be patient", 300, 100)
  312.                 EndIf
  313.                 Local $sClip = "", $sItem, $aSplit
  314.                 ; Add items
  315.                 For $i = 0 To $iItem_End - $iItem_Start
  316.                     ; Skip if copying selected rows and item not selected
  317.                     If $iSel_Count And Not (GUICtrlSendMsg($cListView, $_ARRAYCONSTANT_LVM_GETITEMSTATE, $i, $_ARRAYCONSTANT_LVIS_SELECTED)) Then
  318.                         ContinueLoop
  319.                     EndIf
  320.                     $sItem = $avArrayText[$i]
  321.                     If $iMsg = $cCopy_Data Then
  322.                         ; Remove row ID if required
  323.                         $sItem = StringRegExpReplace($sItem, "^\[\d+\].(.*)$", "$1")
  324.                     EndIf
  325.                     If $iCW_ColWidth Then
  326.                         ; Expand columns
  327.                         $aSplit = StringSplit($sItem, $sAD_Separator)
  328.                         $sItem = ""
  329.                         For $j = 1 To $aSplit[0]
  330.                             $sItem &= StringFormat("%-" & $iCW_ColWidth + 1 & "s", StringLeft($aSplit[$j], $iCW_ColWidth))
  331.                         Next
  332.                     Else
  333.                         ; Use defined separator
  334.                         $sItem = StringReplace($sItem, $sAD_Separator, $vUser_Separator)
  335.                     EndIf
  336.                     $sClip &= $sItem & @CRLF
  337.                 Next
  338.                 ; Add header line if required
  339.                 If $iMsg = $cCopy_ID Then
  340.                     If $iCW_ColWidth Then
  341.                         $aSplit = StringSplit($sHeader, $sAD_Separator)
  342.                         $sItem = ""
  343.                         For $j = 1 To $aSplit[0]
  344.                             $sItem &= StringFormat("%-" & $iCW_ColWidth + 1 & "s", StringLeft($aSplit[$j], $iCW_ColWidth))
  345.                         Next
  346.                     Else
  347.                         $sItem = StringReplace($sHeader, $sAD_Separator, $vUser_Separator)
  348.                     EndIf
  349.                     $sClip = $sItem & @CRLF & $sClip
  350.                 EndIf
  351.                 ;Send to clipboard
  352.                 ClipPut($sClip)
  353.                 ; Remove splash if used
  354.                 SplashOff()
  355.                 ; Refocus ListView
  356.                 GUICtrlSetState($cListView, $_ARRAYCONSTANT_GUI_FOCUS)
  357.  
  358.             Case $cExit_Script
  359.                 Exit
  360.         EndSwitch
  361.     WEnd
  362.  
  363.     ; Clear up
  364.     GUIDelete($hGUI)
  365.     Opt("GUIOnEventMode", $iOnEventMode) ; Reset original GUI mode
  366.     Opt("GUIDataSeparatorChar", $sCurr_Separator) ; Reset original separator
  367.  
  368.     Return 1
  369.  
  370. EndFunc   ;==>_ArrayDisplay
RAW Paste Data