Автор Тема: _ArrayDisplayEx - расширение стандартной функции _ArrayDisplay  (Прочитано 10043 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Garrett [?]

  • Глобальный модератор
  • *
  • Сообщений: 3816
  • Репутация: 950
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.12.0
Работая с массивами, я  (думаю и не только я) пользуюсь функцией из UDF Array.au3 _ArrayDisplay. Она в удобной форме выводит содержимое массива, что порой бывает полезно.
Давно заметил, если мы имеем дело с добавлением в ячейку, массива или объекта (вложенность), то ячейка, содержащая в себе массив или объект, никак не отображается в списке, который выводит _ArrayDisplay.  Это IMHO не очень удобно в плане визуального представления. До определенного момента я мирился с этим, но как-то раз решил поправить ситуацию, и дописал в Array.au3 (стандартная поставка) пару строк, которые позволили мне видеть содержимое ячеек.
Привожу на ваш суд участок кода функции _ArrayDisplay,  который дополнит её вышеописанным свойством.

Пример:
Код: AutoIt [Выделить]
#include <IE.au3>
#include <Array.au3>
Dim $a[10] = [2,8,3,7,4,1,6,45,22,99]
Dim $b[1][2] = [["This!", 2]]
$a[2] = $b
$oIE = _IECreate('http://ya.ru')
$a[3] = $oIE
_ArrayDisplay($a, "Value of the array: $a")
_ArrayDisplay($a[2], "Value of the cell array $a[2]")
MsgBox(0, "Value of the cell array $a[3] "& ObjName($a[3]), "Locationurl: " & _IEPropertyGet($a[3], "locationurl"))


Исходный код:
(нажмите для показа/скрытия)

Код для замены:
(нажмите для показа/скрытия)

Внимание! Если вы решите модернизировать свою UDF выше описанным методом, не забудьте сделать резервную копию.

P.S. Если это окажется действительно полезным и удобным не только для меня, то наверно можно будет написать авторам UDF, чтобы они внесли изменения.
« Последнее редактирование: Июнь 01, 2011, 20:48:53 от Garrett »

Скорблю и помню.




Русское сообщество AutoIt


Оффлайн madmasles [?]

  • Глобальный модератор
  • *
  • Сообщений: 7790
  • Репутация: 2313
  • Пол: Мужской
  • Награды За модерирование форума
    • Награды
  • Версия AutoIt: 3.3.x.x
Garrett,
ИМХО, очень полезная вещь, спасибо.
:thanks:  :thumbs_up:

Может, пока лучше сделать это отдельной функцией, например, _ArrayDisplayEx() ?
« Последнее редактирование: Июнь 01, 2011, 14:06:19 от madmasles »

Оффлайн CreatoR [?]

  • Администратор
  • *
  • Сообщений: 7805
  • Репутация: 2279
  • Пол: Мужской
  • AutoIt is simple, subtle, elegant
    • CreatoR's Lab
    • Награды
  • Версия AutoIt: 3.3.10.2
Да, хорошая идея, я об этом тоже думал, правда больше в направлений отображения этих элементов.
Можно было бы ещё добавить кнопочку для просмотра массива, но вот как это совместить с отображением типа ячейки...


Добавлено: Июнь 01, 2011, 15:51:23
[?]
Цитировать
как это совместить с отображением типа ячейки
Вот так получилось:
Код: AutoIt [Выделить]
#include <Array.au3>

Dim $a[10] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Dim $b[1] = ["Is Test"]
Dim $c[1][2] = [["This!", $b]]

$a[7] = $c
$a[8] = DllStructCreate('int[2];')
$a[9] = ObjCreate("shell.application")
_ArrayDisplayEx($a, "Value of the array: $a")

Func _ArrayDisplayEx(Const ByRef $avArray, $sTitle = "Array: ListView Display", $iItemLimit = -1, $iTranspose = 0, $sSeparator = "", $sReplace = "|", $sHeader = "")
    If Not IsArray($avArray) Then Return SetError(1, 0, 0)
    ; Dimension checking
    Local $iDimension = UBound($avArray, 0), $iUBound = UBound($avArray, 1) - 1, $iSubMax = UBound($avArray, 2) - 1
    If $iDimension > 2 Then Return SetError(2, 0, 0)

    ; Separator handling
;~     If $sSeparator = "" Then $sSeparator = Chr(1)
    If $sSeparator = "" Then $sSeparator = Chr(124)

    ;  Check the separator to make sure it's not used literally in the array
    If _ArraySearch($avArray, $sSeparator, 0, 0, 0, 1) <> -1 Then
        For $x = 1 To 255
            If $x >= 32 And $x <= 127 Then ContinueLoop
            Local $sFind = _ArraySearch($avArray, Chr($x), 0, 0, 0, 1)
            If $sFind = -1 Then
                $sSeparator = Chr($x)
                ExitLoop
            EndIf
        Next
    EndIf

    ; Declare variables
    Local $vTmp, $iBuffer = 64
    Local $iColLimit = 250
    Local $iOnEventMode = Opt("GUIOnEventMode", 0), $sDataSeparatorChar = Opt("GUIDataSeparatorChar", $sSeparator)

    ; Swap dimensions if transposing
    If $iSubMax < 0 Then $iSubMax = 0
    If $iTranspose Then
        $vTmp = $iUBound
        $iUBound = $iSubMax
        $iSubMax = $vTmp
    EndIf

    ; Set limits for dimensions
    If $iSubMax > $iColLimit Then $iSubMax = $iColLimit
    If $iItemLimit < 1 Then $iItemLimit = $iUBound
    If $iUBound > $iItemLimit Then $iUBound = $iItemLimit

    ; Set header up
    If $sHeader = "" Then
        $sHeader = "Row  "  ; blanks added to adjust column size for big number of rows
        For $i = 0 To $iSubMax
            $sHeader &= $sSeparator & "Col " & $i
        Next
    EndIf

    ; Convert array into text for listview
    Local $avArrayText[$iUBound + 1]
    For $i = 0 To $iUBound
        $avArrayText[$i] = "[" & $i & "]"
        For $j = 0 To $iSubMax
            ; Get current item
            ; Visibility of an array or object in the list
            ; Editing: Garrett
            If $iDimension = 1 Then
                If $iTranspose Then                
                    $vTmp = $avArray[$j]                    
                Else                
                    $vTmp = $avArray[$i]                          
                EndIf
            Else
                If $iTranspose Then
                    $vTmp = $avArray[$j][$i]
                Else
                    $vTmp = $avArray[$i][$j]                          
                EndIf
            EndIf

            If IsArray($vTmp) Then
                $vTmp = '#Array(' & UBound($vTmp, 0) & '-D)'
            ElseIf IsObj($vTmp) Then
                $vTmp = '#Object(' & ObjName($vTmp) & ')'
            ElseIf IsDllStruct($vTmp) Then
                $vTmp = '#DllStruct(' & DllStructGetSize($vTmp) & ')'
            EndIf

            ; Add to text array
            $vTmp = StringReplace($vTmp, $sSeparator, $sReplace, 0, 1)
            $avArrayText[$i] &= $sSeparator & $vTmp

            ; Set max buffer size
            $vTmp = StringLen($vTmp)
            If $vTmp > $iBuffer Then $iBuffer = $vTmp
        Next
    Next

    ; GUI Constants
    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_DOCKSIZE = 768
    Local Const $_ARRAYCONSTANT_GUI_DOCKHCENTER = 8
    Local Const $_ARRAYCONSTANT_GUI_EVENT_CLOSE = -3
    Local Const $_ARRAYCONSTANT_LVIF_PARAM = 0x4
    Local Const $_ARRAYCONSTANT_LVIF_TEXT = 0x1
    Local Const $_ARRAYCONSTANT_LVM_GETCOLUMNWIDTH = (0x1000 + 29)
    Local Const $_ARRAYCONSTANT_LVM_GETITEMCOUNT = (0x1000 + 4)
    Local Const $_ARRAYCONSTANT_LVM_GETITEMSTATE = (0x1000 + 44)
    Local Const $_ARRAYCONSTANT_LVM_INSERTITEMW = (0x1000 + 77)
    Local Const $_ARRAYCONSTANT_LVM_SETEXTENDEDLISTVIEWSTYLE = (0x1000 + 54)
    Local Const $_ARRAYCONSTANT_LVM_SETITEMW = (0x1000 + 76)
    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_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"

    Local $iAddMask = BitOR($_ARRAYCONSTANT_LVIF_TEXT, $_ARRAYCONSTANT_LVIF_PARAM)
    Local $tBuffer = DllStructCreate("wchar Text[" & $iBuffer & "]"), $pBuffer = DllStructGetPtr($tBuffer)
    Local $tItem = DllStructCreate($_ARRAYCONSTANT_tagLVITEM), $pItem = DllStructGetPtr($tItem)
    DllStructSetData($tItem, "Param", 0)
    DllStructSetData($tItem, "Text", $pBuffer)
    DllStructSetData($tItem, "TextMax", $iBuffer)

    ; Set interface up
    Local $iWidth = 640, $iHeight = 480
    Local $hGUI = GUICreate($sTitle, $iWidth, $iHeight, Default, Default, BitOR($_ARRAYCONSTANT_WS_SIZEBOX, $_ARRAYCONSTANT_WS_MINIMIZEBOX, $_ARRAYCONSTANT_WS_MAXIMIZEBOX))
    Local $aiGUISize = WinGetClientSize($hGUI)
    Local $hListView = GUICtrlCreateListView($sHeader, 0, 0, $aiGUISize[0], $aiGUISize[1] - 26, $_ARRAYCONSTANT_LVS_SHOWSELALWAYS)
    Local $hCopy = GUICtrlCreateButton("Copy Selected", ($aiGUISize[0] / 2) - 120, $aiGUISize[1] - 23, 100, 20)
    Local $hDisplay = GUICtrlCreateButton("Display SubArray", ($aiGUISize[0] / 2) + 20, $aiGUISize[1] - 23, 100, 20)
    GUICtrlSetResizing($hListView, $_ARRAYCONSTANT_GUI_DOCKBORDERS)
    GUICtrlSetResizing($hCopy, $_ARRAYCONSTANT_GUI_DOCKHCENTER + $_ARRAYCONSTANT_GUI_DOCKBOTTOM + $_ARRAYCONSTANT_GUI_DOCKSIZE)
    GUICtrlSetResizing($hDisplay, $_ARRAYCONSTANT_GUI_DOCKHCENTER + $_ARRAYCONSTANT_GUI_DOCKBOTTOM + $_ARRAYCONSTANT_GUI_DOCKSIZE)
    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)

    ; Fill listview
    Local $aItem
    For $i = 0 To $iUBound
        If GUICtrlCreateListViewItem($avArrayText[$i], $hListView) = 0 Then
            ; use GUICtrlSendMsg() to overcome AutoIt limitation
            $aItem = StringSplit($avArrayText[$i], $sSeparator)
            DllStructSetData($tBuffer, "Text", $aItem[1])

            ; Add listview item
            DllStructSetData($tItem, "Item", $i)
            DllStructSetData($tItem, "SubItem", 0)
            DllStructSetData($tItem, "Mask", $iAddMask)
            GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_INSERTITEMW, 0, $pItem)

            ; Set listview subitem text
            DllStructSetData($tItem, "Mask", $_ARRAYCONSTANT_LVIF_TEXT)
            For $j = 2 To $aItem[0]
                DllStructSetData($tBuffer, "Text", $aItem[$j])
                DllStructSetData($tItem, "SubItem", $j - 1)
                GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_SETITEMW, 0, $pItem)
            Next
        EndIf
    Next

    ; adjust window width
    $iWidth = 0
    For $i = 0 To $iSubMax + 1
        $iWidth += GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_GETCOLUMNWIDTH, $i, 0)
    Next
    If $iWidth < 250 Then $iWidth = 230
    $iWidth += 20

    If $iWidth > @DesktopWidth Then $iWidth = @DesktopWidth - 100

    WinMove($hGUI, "", (@DesktopWidth - $iWidth)/2, Default, $iWidth)

    ; Show dialog
    GUISetState(@SW_SHOW, $hGUI)

    While 1
        Switch GUIGetMsg()
            Case $_ARRAYCONSTANT_GUI_EVENT_CLOSE
                ExitLoop
            Case $hCopy
                Local $sClip = ""

                ; Get selected indices [ _GUICtrlListView_GetSelectedIndices($hListView, True) ]
                Local $aiCurItems[1] = [0]
               
                For $i = 0 To GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_GETITEMCOUNT, 0, 0)
                    If GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_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 $sItem In $avArrayText
                        $sClip &= $sItem & @CRLF
                    Next
                Else
                    For $i = 1 To UBound($aiCurItems) - 1
                        $sClip &= $avArrayText[$aiCurItems[$i]] & @CRLF
                    Next
                EndIf
               
                ClipPut($sClip)
            Case $hDisplay
                Local $iSelItem = -1
               
                For $i = 0 To GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_GETITEMCOUNT, 0, 0)
                    If GUICtrlSendMsg($hListView, $_ARRAYCONSTANT_LVM_GETITEMSTATE, $i, 0x2) Then
                        $iSelItem = $i
                        ExitLoop
                    EndIf
                Next
               
                If $iSelItem <> -1 Then
                    GUISetState(@SW_DISABLE, $hGUI)
                   
                    If $iDimension = 1 Then
                        If IsArray($avArray[$iSelItem]) Then
                            _ArrayDisplayEx($avArray[$iSelItem], "SubArray[" & $iSelItem & "]")
                        EndIf
                    Else
                        For $j = 0 To $iSubMax
                            If IsArray($avArray[$iSelItem][$j]) Then
                                _ArrayDisplayEx($avArray[$iSelItem][$j], "SubArray[" & $iSelItem & "][" & $j & "]")
                            EndIf
                        Next
                    EndIf
                   
                    GUISetState(@SW_ENABLE, $hGUI)
                    WinActivate($hGUI)
                EndIf
        EndSwitch
    WEnd
   
    GUIDelete($hGUI)

    Opt("GUIOnEventMode", $iOnEventMode)
    Opt("GUIDataSeparatorChar", $sDataSeparatorChar)

    Return 1
EndFunc


Я также немного поправил вывод типа данных, теперь также отображает тип структуры + сократил немного код.
« Последнее редактирование: Июнь 01, 2011, 15:57:02 от CreatoR, Причина: Объединение сообщений »


Правила, Поиск, Супер тема


AutoIt is simple, subtle, elegant.


«Не оказываю тех. поддержку через ПМ/ICQ, и по электронной почте - для этого есть форум. (C)»
«Законы Мэрфи неоспоримы!»


Мои работы

Оффлайн Garrett [?]

  • Глобальный модератор
  • *
  • Сообщений: 3816

  • Автор темы
  • Репутация: 950
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.12.0
madmasles  [?]
Цитировать
Может, пока лучше сделать это отдельной функцией, например, _ArrayDisplayEx() ?

Да конечно, вы правы.
Да я так сказать это для себя делал, и поэтому просто модифицировал свою стандартную UDF, а тут решил опробовать бету версию, последнюю, и пустые ячейки как-то резко бросились в глаза.  :)
Пришлось перекидывать модифицированную UDF. Ну и грешным делом подумал, а почему бы не  выложить в народ, может ещё кому-нибудь сгодится!

CreatoR  [?]
Цитировать
Можно было бы ещё добавить кнопочку для просмотра массива
Думал об этом, но потом как-то забросил эту идею, честно говоря, мне было лень, так как функция уже была написана, а пустые ячейки просто раздражали ;D

Цитировать
Вот так получилось:

Шикарно! :beer:
Добавляю её себе в LED.au3 ( Library on Every Day )! Есть у меня такая, для ежедневного пользования, сразу подгружается в шаблон нового документа наряду с другими часто используемыми UDF. В ней у меня разного рода, часто используемые функции,  как собственные, так и заимствованные у других авторов.

 
Цитировать
Я также немного поправил вывод типа данных, теперь также отображает тип структуры + сократил немного код.
На счёт структур не задумывался, пока не приходилось их в массив добавлять, но полагаю, может пригодиться. Кстати к #DllStruct тоже можно "подцепить" кнопочку, для отображения по индексу содержимого полей структуры.

P.S. Раз уж "родилась" _ArrayDisplayEx я немного изменил название темы, если никто не против?!
« Последнее редактирование: Август 07, 2011, 15:18:18 от Garrett »

Русское сообщество AutoIt

Re: Доработка визуализации функции _ArrayDisplay
« Ответ #3 Отправлен: Июнь 01, 2011, 20:44:21 »

Онлайн Alofa [?]

  • Скриптер
  • ****
  • Сообщений: 1076
  • Репутация: 146
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.12.0
Для Autoit v3.3.8.1
(нажмите для показа/скрытия)

Для Autoit v3.3.12.0
(нажмите для показа/скрытия)

Для Autoit v3.3.14.2 - v3.3.15.0
(нажмите для показа/скрытия)

Русское сообщество AutoIt

Re: _ArrayDisplayEx - расширение стандартной функции _ArrayDisplay
« Ответ #4 Отправлен: Октябрь 24, 2016, 02:41:58 »

 

Похожие темы

  Тема / Автор Ответов Последний ответ
219 Ответов
172244 Просмотров
Последний ответ Март 31, 2017, 18:42:53
от MRGYV
2 Ответов
3840 Просмотров
Последний ответ Сентябрь 28, 2009, 10:03:15
от BrAWo
2 Ответов
3093 Просмотров
Последний ответ Сентябрь 06, 2010, 17:47:37
от assch
30 Ответов
7675 Просмотров
Последний ответ Февраль 26, 2012, 21:57:07
от CreatoR
5 Ответов
1865 Просмотров
Последний ответ Январь 21, 2014, 00:53:56
от AZJIO
7 Ответов
2092 Просмотров
Последний ответ Февраль 03, 2015, 22:10:56
от madmasles
8 Ответов
2612 Просмотров
Последний ответ Май 27, 2015, 20:26:03
от AZJIO
2 Ответов
1178 Просмотров
Последний ответ Ноябрь 05, 2015, 12:25:38
от ВиталийВВ
2 Ответов
1086 Просмотров
Последний ответ Июль 30, 2016, 10:36:00
от AZJIO
1 Ответов
1336 Просмотров
Последний ответ Сентябрь 09, 2016, 21:11:14
от Dessan