Аналогичная функция от guinness, к сожалению, никуда не годится (в отличие от его _GUICtrlListView_SaveHTML), поэтому решил полностью переписать свой прежний вариант (который использовал в DllViewer) и сделать его универcальным, а не только под задачи моей программы. Может, кому то пригодится, как мне пригодилась _SaveHTML от guinness.
На выходе имеем строку, которую можно сохранить в файл или вставить в буфер обмена, а затем в текстовый редактор. Визуально текст будет выглядеть так:
Как указано в шапке функции, вариант с передачей массива заранее определенных максимальных значений длины строк пунктов работает быстрее (в 1.5 -2 раза), так как скрипту не нужно полностью перебирать весь список (для определения указанных значений это, как вы понимаете, единственный способ).
Разница становится заметна на списках с более 1000-2000 строк. На списки в 100-200 строк дополнительный перебор оказывает минимальное по времени влияние.
Код:
#include <GuiListView.au3>
; #FUNCTION# =========================================================================================================
; Name...........: _SaveListAsTxt()
; Description ...: Saves the contents of the list ListView as a text table with formatting
; Syntax.........: _SaveListAsTxt($hListView [, $aArrayMax [, $sHorSepHeader [, $sColumnSep [, $sRowSep [, $sAddingStr [,$CountSpace]]]]]])
; Parameters ....: $hListView - Handle or identifier the ListView.
; $aArrayMax - [Optional] Аn array of maximum lengths of rows in each column. [Default = -1]
; $sHorSepHeader - [Optional] Symbol for horizontal divider title. [Default = '=']
; $sColumnSep - [Optional] Delimiter character for the header rows of columns. [Default = '|']
; $sRowSep - [Optional] Delimiter character for the rows of columns [Default = '|']
; $sAddingStr - [Optional] Аppend the number of rows and the timestamp or not. [Default = 1]
; $CountSpace - [Optional] Number of spaces between lines. [Default = 1]
; Return values .: Success - Formatted text.
; Failure - Empty string.
; Author ........: Erlik (aka Garry Galler)
; Modified.......:
; Remarks........: With an array of predefined values of maximum lengths of rows in each column
; function works almost twice as fast.
; Example........: None
;=====================================================================================================================
Func _SaveListAsTxt($hListView, $aArrayMax =-1, $sHorSepHeader = '=', $sColumnSep = '|', $sRowSep = '|', $sAddingStr = 1, $CountSpace = 1)
;Local $hTimer = TimerInit()
Local $iLV_ItemCount,$iLV_ColumnCount,$aLV_TextColumn, $aLV_TextRows, $sHeader='',$sFormatText,$iWidthHeader=0, $sLine='',$iLenRow
$iLV_ItemCount = _GUICtrlListView_GetItemCount($hListView) ; GUICtrlSendMsg($ListView, $LVM_GETITEMCOUNT, 0, 0)
$iLV_ColumnCount = _GUICtrlListView_GetColumnCount($hListView) ;_SendMessage(GUICtrlSendMsg($ListView, $LVM_GETHEADER, 0, 0), 0x1200)
If $iLV_ItemCount <= 0 Then Return ''
; преобразуем коды символов, если передана не строка
If IsInt($sHorSepHeader) Then $sHorSepHeader = Chr($sHorSepHeader)
If IsInt($sColumnSep) Then $sColumnSep = Chr($sColumnSep)
If IsInt($sRowSep) Then $sRowSep = Chr($sRowSep)
Local $aDataColumns[$iLV_ColumnCount][3]
For $i = 0 To $iLV_ColumnCount-1
$aLV_TextColumn = _GUICtrlListView_GetColumn($hListView,$i)
$aDataColumns[$i][0] = $aLV_TextColumn[5] ; текст заголовка колонки
$aDataColumns[$i][1] = StringLen($aLV_TextColumn[5]) ; длина текста заголовка колонки
$aDataColumns[$i][2] = StringLen($aLV_TextColumn[5]) ; максимальная длина текста в строке пункта колонки, начальное значение - длина текста заголовка колонки
Next
; если был передан массив максимальных значений длин текста пунктов колонок, то используем эти значения
If Ubound($aArrayMax)>= $iLV_ColumnCount Then
For $i=0 To $iLV_ColumnCount-1
If $aArrayMax[$i]> $aDataColumns[$i][1] Then $aDataColumns[$i][2]=$aArrayMax[$i]
Next
; иначе вычисляем максимальные значения перебором всего списка
Else
For $iLV_IndexItem = 0 To $iLV_ItemCount -1
$aLV_TextRows = _GUICtrlListView_GetItemTextArray($hListView, $iLV_IndexItem)
If Not IsArray($aLV_TextRows) Then ContinueLoop
For $i = 0 To $aLV_TextRows[0]-1
$iLenRow = StringLen($aLV_TextRows[$i+1])
If $iLenRow > $aDataColumns[$i][2] Then
$aDataColumns[$i][2]= $iLenRow
EndIf
Next
Next
EndIf
For $i=0 To $iLV_ColumnCount-1
$sHeader &= StringFormat('%-' & ($aDataColumns[$i][2]+$CountSpace) & 's', $aDataColumns[$i][0]) & $sColumnSep
Next
$iWidthHeader = StringLen($sHeader)
For $i = 1 To $iWidthHeader
$sLine &= $sHorSepHeader
Next
$sFormatText &= $sLine & @CRLF
$sFormatText &= $sHeader & @CRLF
$sFormatText &= $sLine & @CRLF
For $iLV_IndexItem = 0 To $iLV_ItemCount -1
$aLV_TextRows = _GUICtrlListView_GetItemTextArray($hListView, $iLV_IndexItem)
If Not IsArray($aLV_TextRows) Then ContinueLoop
For $i = 0 To $aLV_TextRows[0]-1
$sFormatText&=StringFormat('%-' & $aDataColumns[$i][2] + $CountSpace & 's',$aLV_TextRows[$i+1]) & $sRowSep
Next
$sFormatText &= @CRLF
Next
$sFormatText &= $sLine & @CRLF
; добавляем в конец таблицы число строк и дату\время
If $sAddingStr Then
Local $sStr1 = 'Total count: ' & $iLV_ItemCount
Local $sStr2 = 'TimeStamp: ' & @MDAY & '.' & @MON & '.' & @YEAR & ' ' & @HOUR & '.' & @MIN
Local $iMaxWidth = $iWidthHeader-Stringlen($sStr2)
$sFormatText &= StringFormat('%-' & $iMaxWidth & 's', $sStr1) & $sStr2 & @CRLF & $sLine
EndIf
;ConsoleWrite('_SaveListAsTxt:' & TimerDiff($hTimer) & @CR)
Return $sFormatText
EndFunc
На выходе имеем строку, которую можно сохранить в файл или вставить в буфер обмена, а затем в текстовый редактор. Визуально текст будет выглядеть так:
Код:
========================================================================================
Имя функции |Адрес |Относительный адрес |Путь |
========================================================================================
D2D1ConvertColorSpace |0x1020DB46 |0x0020DB46 |C:\Windows\system32\d2d1.dll |
D2D1CreateDevice |0x1020DC29 |0x0020DC29 |C:\Windows\system32\d2d1.dll |
D2D1CreateDeviceContext |0x1020DD4F |0x0020DD4F |C:\Windows\system32\d2d1.dll |
D2D1SinCos |0x1020DEC2 |0x0020DEC2 |C:\Windows\system32\d2d1.dll |
D2D1Tan |0x1020DF27 |0x0020DF27 |C:\Windows\system32\d2d1.dll |
D2D1Vec3Length |0x1020DF6A |0x0020DF6A |C:\Windows\system32\d2d1.dll |
D2D1CreateFactory |0x1020E11E |0x0020E11E |C:\Windows\system32\d2d1.dll |
D2D1MakeRotateMatrix |0x102153A1 |0x002153A1 |C:\Windows\system32\d2d1.dll |
D2D1MakeSkewMatrix |0x102153E6 |0x002153E6 |C:\Windows\system32\d2d1.dll |
D2D1IsMatrixInvertible |0x10215433 |0x00215433 |C:\Windows\system32\d2d1.dll |
D2D1InvertMatrix |0x102154AC |0x002154AC |C:\Windows\system32\d2d1.dll |
========================================================================================
Total count: 11 TimeStamp: 02.03.2014 17.30
========================================================================================
Код:
;Вызывать либо так:
Local $sText = _SaveListAsTxt($ListView)
;либо так:
Local $aTest[4]=[70,10,10,70] ; массив на четыре колонки - каждое значение максимальная длина строки текста в колонке.
Local $sText = _SaveListAsTxt($ListView,$aTest[4])
Как указано в шапке функции, вариант с передачей массива заранее определенных максимальных значений длины строк пунктов работает быстрее (в 1.5 -2 раза), так как скрипту не нужно полностью перебирать весь список (для определения указанных значений это, как вы понимаете, единственный способ).
Разница становится заметна на списках с более 1000-2000 строк. На списки в 100-200 строк дополнительный перебор оказывает минимальное по времени влияние.