При создании GUIListView сделать стандартными средствами так, чтобы выравнивание заголовка отличалось от выравнивания содержимого невозможно.
(Сразу хочу предупредить - далее в тексте не рассматривается выравнивание заголовка по центру. То есть для выравнивания по центру дальнейшие высказывания где-то рабочие, где-то не рабочие, в где-то необходима доработка).
А зачастую необходимо в разных колонках сделать выравнивание к разным краям (текстовую информацию к левому краю, числовую - к правому).
Можно сделать выравнивание одновременно и заголовка и содержимого. Но лично мне не нравится полученный таким образом вид таблицы (хочется как проводнике Windows - все заголовки прижаты к левому краю)
Выравнивание можно выполнить тремя функциями.
В варианте 1 параметром является идентификатор элемента GUIListView (($ListView1), в двух других параметром является дескриптор GUIHeader (_GUICtrlListView_GetHeader($ListView1)). То есть теоретически в первом варианте устанавливаем параметры таблицы, а в оставшихся изменяем параметры заголовка таблицы. Но по факту все варианты изменяют одновременно и выравнивание заголовка и выравнивание записей в таблице.
Если колонка не будет изменять свою ширину, то есть простейший способ сделать выравнивание заголовка - просто добавить необходимое количество пробелов.
Также есть простой, но не очень элегантный способ выравнивания заголовка влево даже при изменяющемся размере ширины колонки. Просто добавляем большое количество пробелов справа от текста заголовка.
В результате получаем в изображении текста заголовка три точечки (которые указывают что при текущей ширине колонки показан не весь текст заголовка)

И, наконец, самый сложный вариант. Динамически, в зависимости от размера ширины колонки, формируем текст заголовка добавляя пробелы.
В общем виде
Пример
(Сразу хочу предупредить - далее в тексте не рассматривается выравнивание заголовка по центру. То есть для выравнивания по центру дальнейшие высказывания где-то рабочие, где-то не рабочие, в где-то необходима доработка).
А зачастую необходимо в разных колонках сделать выравнивание к разным краям (текстовую информацию к левому краю, числовую - к правому).
Можно сделать выравнивание одновременно и заголовка и содержимого. Но лично мне не нравится полученный таким образом вид таблицы (хочется как проводнике Windows - все заголовки прижаты к левому краю)

Выравнивание можно выполнить тремя функциями.
Код:
;вариант 1
_GUICtrlListView_JustifyColumn($ListView1, 1, 1)
;вариант 2
_GUICtrlHeader_SetItemFormat(_GUICtrlListView_GetHeader($ListView1), 1, BitOR($HDF_RIGHT, $HDF_STRING)) ;
;вариант 3 (примечание - по факту функция _GUICtrlHeader_SetItemAlign вызывает _GUICtrlHeader_SetItemFormat)
_GUICtrlHeader_SetItemAlign(_GUICtrlListView_GetHeader($ListView1), 1, 1)
В варианте 1 параметром является идентификатор элемента GUIListView (($ListView1), в двух других параметром является дескриптор GUIHeader (_GUICtrlListView_GetHeader($ListView1)). То есть теоретически в первом варианте устанавливаем параметры таблицы, а в оставшихся изменяем параметры заголовка таблицы. Но по факту все варианты изменяют одновременно и выравнивание заголовка и выравнивание записей в таблице.
Если колонка не будет изменять свою ширину, то есть простейший способ сделать выравнивание заголовка - просто добавить необходимое количество пробелов.
Код:
;в колонке Размер сделаем выравнивание по правому краю, а заголовок, при подборе нужного количества пробелов, будет прижат к левому краю
;работает если ширина колонки Размер не будет изменяться
$ListView1 = GUICtrlCreateListView("Файл|Размер|Дата", 0, 20, 600, 200) ; строка для наглядности
$ListView1 = GUICtrlCreateListView("Файл|Размер |Дата", 0, 20, 600, 200)
Также есть простой, но не очень элегантный способ выравнивания заголовка влево даже при изменяющемся размере ширины колонки. Просто добавляем большое количество пробелов справа от текста заголовка.
Код:
$ListView1 = GUICtrlCreateListView("Файл|Размер" & StringFormat("%200s", " ") & "|Дата", 0, 20, 600, 200) ;после слова Размер добавлено 200 пробелов
В результате получаем в изображении текста заголовка три точечки (которые указывают что при текущей ширине колонки показан не весь текст заголовка)

И, наконец, самый сложный вариант. Динамически, в зависимости от размера ширины колонки, формируем текст заголовка добавляя пробелы.
В общем виде
Код:
;$hHead - дескриптор заголовка в котором изменяется текст заголовка
;$iColumnIndex - индекс колонки в которой изменяется текст заголовка
;$iItemWidth - текущая ширина колонки
Func GetHeaderText($hHead, $iColumnIndex, $iItemWidth=0)
If Not $iItemWidth Then
$iItemWidth = _GUICtrlHeader_GetItemWidth($hHead, $iColumnIndex)
EndIf
$iZazor = 12 ;такой должна быть разница между шириной заголовка и шириной столбца (постоянная величина или зависит от конкретного компьютера - не проверял)
$sHeaderText = StringStripWS(_GUICtrlHeader_GetItemText($hHead, $iColumnIndex), 1 + 2) ;минус пробелы в начале и конце
$iHeaderTextWidth = GetStringDimensions($hHead, $sHeaderText)[0]
If $iHeaderTextWidth < ($iItemWidth - $iZazor) Then
$nWidth1space = GetStringDimensions($hHead," ")[0] / 10 ;может пробел ВСЕГДА помещается в целое число пикселей - не проверял
$iKolSpace = Floor(($iItemWidth - $iZazor - $iHeaderTextWidth) / $nWidth1space)
$sHeaderTextNew = $sHeaderText & StringFormat("%" & $iKolSpace & "s", "")
Else
$sHeaderTextNew = $sHeaderText
EndIf
Return $sHeaderTextNew
EndFunc
;из описания _WinAPI_GetTextExtentPoint32
Func GetStringDimensions($hWnd, $sText)
Local $hDC = _WinAPI_GetDC($hWnd) ; Возвращает дескриптор контекста устройства указанного окна.
Local $hFont = _SendMessage($hWnd, $WM_GETFONT) ; Возвращает дескриптор шрифта, используемого для создания текста.
Local $hSelectObject = _WinAPI_SelectObject($hDC, $hFont) ; Выбирает объект в указанном контекст устройстве.
Local $tSIZE = _WinAPI_GetTextExtentPoint32($hDC, $sText) ; Вычисляет ширину и высоту указанной строки.
_WinAPI_SelectObject($hDC, $hSelectObject)
_WinAPI_ReleaseDC($hWnd, $hDC) ; Освобождает контекст устройства
Local $aReturn[2] = [DllStructGetData($tSIZE, 1), DllStructGetData($tSIZE, 2)] ; Объявляет массив с шириной и высотой строки.
Return $aReturn
EndFunc ;==>GetStringDimensions
Пример
Код:
#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <WindowsConstants.au3>
#include <File.au3>
#include <GuiListView.au3>
;#include <GuiHeader.au3>
;#include <Array.au3>
#include <WinAPIConv.au3>
#include <WinAPI.au3>
$Form1 = GUICreate("Form1", 550, 250, 500,-1, $WS_THICKFRAME)
$ListView1 = GUICtrlCreateListView("Файл|Размер|Дата", 0, 20, 600, 200, -1, $LVS_EX_GRIDLINES + $LVS_EX_HEADERDRAGDROP + $LVS_EX_FULLROWSELECT) ;
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 0, 300)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 1, 100)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 2, 120)
_GUICtrlListView_JustifyColumn($ListView1, 1, 1) ;в колонке с индексом 1 выравнивание по правому краю
Global $hHeader = _GUICtrlListView_GetHeader($ListView1)
Global $aColumnContr[2] = [1, 0] ;индекс колонки заголовок которой перемещаем и ширина колонки до изменения
_GUICtrlHeader_SetItemText($hHeader, $aColumnContr[0], GetHeaderText($hHeader, $aColumnContr[0]))
;заполняем таблицу (достаточно небольшого количества элементов)
$aFiles = _FileListToArray(@WindowsDir & "\System32", '*', 1, 1)
#include <Math.au3>
$iMax = _Min ( 7, $aFiles[0] )
For $i = 1 To $iMax
FileToGUIListView($aFiles[$i], $ListView1)
Next
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState(@SW_SHOW)
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
EndSwitch
WEnd
;На основании хелпера по _GUICtrlHeader_Create (в т.ч. русскоязычного)
;Отслеживание сообщений что "что атрибуты пункта Header изменились" и на основании этого добавляем
;необходимое количество пробелов в текст заголовка
Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
#forceref $hWnd, $iMsg, $wParam
Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
Local $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
Local $iCode = DllStructGetData($tNMHDR, "Code")
Switch $hWndFrom
Case $hHeader ;уведомление о событиях связанных с заголовками $ListView1
Switch $iCode
#cs
;Уведомление высылается элементом Header родительскому окну о том, что атрибуты пункта Header собираются измениться
Case $HDN_ITEMCHANGING, $HDN_ITEMCHANGINGW ; Notifies a header control's parent window that the attributes of a header item are about to change
_WM_NOTIFY_DebugEvent("$HDN_ITEMCHANGING", $tagNMHEADER, $lParam, "IDFrom,,Item,Button") ;#include <Extras\WM_NOTIFY.au3>
Return False ; To allow the changes
; Return True ; To prevent them
#ce
; Уведомление высылается элементом Header родительскому окну о том, что атрибуты пункта Header изменились
Case $HDN_ITEMCHANGED, $HDN_ITEMCHANGEDW ; Notifies a header control's parent window that the attributes of a header item have changed
;_WM_NOTIFY_DebugEvent("$HDN_ITEMCHANGED", $tagNMHEADER, $lParam, "IDFrom,,Item,Button");#include <Extras\WM_NOTIFY.au3>
; no return value
$tNMHEADER = DllStructCreate($tagNMHEADER, $lParam)
If DllStructGetData($tNMHEADER, "Item") = $aColumnContr[0] Then ;изменяется контролируемая нами колонка
$iHeaderItemWidth = _GUICtrlHeader_GetItemWidth($hHeader, $aColumnContr[0])
If $iHeaderItemWidth <> $aColumnContr[1] Then ;меняем только если ширина колонки изменилась
$aColumnContr[1] = $iHeaderItemWidth
_GUICtrlHeader_SetItemText($hHeader, $aColumnContr[0], GetHeaderText($hHeader, $aColumnContr[0], $iHeaderItemWidth))
EndIf
EndIf
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_NOTIFY
Func GetHeaderText($hHead, $iColumnIndex, $iItemWidth=0)
If Not $iItemWidth Then
$iItemWidth = _GUICtrlHeader_GetItemWidth($hHead, $iColumnIndex)
EndIf
$iZazor = 12 ;такой должна быть разница между шириной заголовка и шириной столбца (постоянная величина или зависит от конкретного компьютера - не проверял)
$sHeaderText = StringStripWS(_GUICtrlHeader_GetItemText($hHead, $iColumnIndex), 1 + 2) ;минус пробелы в начале и конце
$iHeaderTextWidth = GetStringDimensions($hHead, $sHeaderText)[0]
If $iHeaderTextWidth < ($iItemWidth - $iZazor) Then
$nWidth1space = GetStringDimensions($hHead," ")[0] / 10 ;может пробел ВСЕГДА помещается в целое число пикселей - не проверял
$iKolSpace = Floor(($iItemWidth - $iZazor - $iHeaderTextWidth) / $nWidth1space)
$sHeaderTextNew = $sHeaderText & StringFormat("%" & $iKolSpace & "s", "")
Else
$sHeaderTextNew = $sHeaderText
EndIf
Return $sHeaderTextNew
EndFunc
;из описания _WinAPI_GetTextExtentPoint32
Func GetStringDimensions($hWnd, $sText)
Local $hDC = _WinAPI_GetDC($hWnd) ; Возвращает дескриптор контекста устройства указанного окна.
Local $hFont = _SendMessage($hWnd, $WM_GETFONT) ; Возвращает дескриптор шрифта, используемого для создания текста.
Local $hSelectObject = _WinAPI_SelectObject($hDC, $hFont) ; Выбирает объект в указанном контекст устройстве.
Local $tSIZE = _WinAPI_GetTextExtentPoint32($hDC, $sText) ; Вычисляет ширину и высоту указанной строки.
_WinAPI_SelectObject($hDC, $hSelectObject)
_WinAPI_ReleaseDC($hWnd, $hDC) ; Освобождает контекст устройства
Local $aReturn[2] = [DllStructGetData($tSIZE, 1), DllStructGetData($tSIZE, 2)] ; Объявляет массив с шириной и высотой строки.
Return $aReturn
EndFunc ;==>GetStringDimensions
Func FileToGUIListView($FullFileName, $pListView)
$t = FileGetTime($FullFileName)
$FileDateTime = $t[2] & '.' & $t[1] & '.' & $t[0] & " " & $t[3] & ':' & $t[4] & ':' & $t[5]
$sSize = _WinAPI_StrFormatKBSize(FileGetSize($FullFileName))
GUICtrlCreateListViewItem($FullFileName & "|" & $sSize & "|" & $FileDateTime, $pListView)
EndFunc