Функция GUICtrlRegisterListViewSort

         Описание функции


GUICtrlRegisterListViewSort

Регистрация пользовательской функции для внутренней сортировки ListView функцией обратного вызова.

GUICtrlRegisterListViewSort ( controlID, "function" )

Параметры

controlID Идентификатор ListView, для которого должна выполниться функция.
function Имя пользовательской функции, вызываемой, когда выполняется сортировка обратным вызовом.

Возвращаемое значение

Успех:Возвращает 1
Ошибка:Возвращает 0

Примечания

!!! Чтобы функция была работоспособной, нужно определить максимум 4 параметра функции иначе функция не будет вызываться !!!
т.е:

Func MySortFunction($nListViewID, $LParam1, $LParam2, $nColumn)
; ...
EndFunc

; или

Func MySortFunction($nListViewID, $LParam1, $LParam2)
; ...
EndFunc



Когда функция вызывается, то 4 параметра принимают следующие значения:
ПозицияПараметрОписание
1controlIDИдентификатор ListView для которой используется возврат функции.
2lParam1lParam значение первого пункта (по умолчанию идентификатор пункта).
3lParam2lParam значение второго пункта (по умолчанию идентификатор пункта).
4columnколонка, которая была нажата для сортировки (Номер первый колонки - 0).

Следующие значения должны быть возвращены изменив поведение сортировки обратным вызовом:
Возвращаемое значениеОписание
-11-ый пункт должен предшествовать 2-му.
0Без изменений.
11-ый пункт должен последовать за 2-ым.

Смотрите также примеры сортировки с самосозданием пунктов GUI ListView.

См. также

GUICtrlCreateListView

Пример

#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>

Global $nCurCol = -1
Global $nSortDir = 1
Global $bSet = 0
Global $nCol = -1

Example1()
Example2()

; *******************************************************
; Пример 1 - сортировка 3-х различных колонок
; *******************************************************
Func Example1()
    Local $lv, $msg

    GUICreate("Тест 1", 300, 200)

    $lv = GUICtrlCreateListView("Колонка1|Кол2|Кол3", 10, 10, 280, 180)
    GUICtrlRegisterListViewSort(-1, "LVSort") ; Регистрация функции обратного вызова сортировки "LVSort"

    GUICtrlCreateListViewItem("ABC|666|10.05.2004", $lv)
    GUICtrlSetImage(-1, "shell32.dll", 7)
    GUICtrlCreateListViewItem("DEF|444|11.05.2005", $lv)
    GUICtrlSetImage(-1, "shell32.dll", 12)
    GUICtrlCreateListViewItem("CDE|444|12.05.2004", $lv)
    GUICtrlSetImage(-1, "shell32.dll", 3)

    GUISetState()

    While 1
        $msg = GUIGetMsg()
        Switch $msg
            Case $GUI_EVENT_CLOSE
                ExitLoop

            Case $lv
                $bSet = 0
                $nCurCol = $nCol
                GUICtrlSendMsg($lv, $LVM_SETSELECTEDCOLUMN, GUICtrlGetState($lv), 0)
                DllCall("user32.dll", "int", "InvalidateRect", "hwnd", GUICtrlGetHandle($lv), "int", 0, "int", 1)
        EndSwitch
    WEnd

    GUIDelete()
EndFunc

; Наша функция обратного вызова сортировки
Func LVSort($hWnd, $nItem1, $nItem2, $nColumn)
    Local $val1, $val2, $nResult

    ; Переключает направление сортировки (по убыванию или по возрастанию)
    If $nColumn = $nCurCol Then
        If Not $bSet Then
            $nSortDir = $nSortDir * - 1
            $bSet = 1
        EndIf
    Else
        $nSortDir = 1
    EndIf
    $nCol = $nColumn

    $val1 = GetSubItemText($hWnd, $nItem1, $nColumn)
    $val2 = GetSubItemText($hWnd, $nItem2, $nColumn)

    ; Если это 3-я колонка (отсчёт колонок от 0), тогда сравнение дат
    If $nColumn = 2 Then
        $val1 = StringRight($val1, 4) & StringMid($val1, 4, 2) & StringLeft($val1, 2)
        $val2 = StringRight($val2, 4) & StringMid($val2, 4, 2) & StringLeft($val2, 2)
    EndIf

    $nResult = 0 ; Не изменять позиции of item1 и item2

    If $val1 < $val2 Then
        $nResult = -1 ; Переместить item2 перед item1
    ElseIf $val1 > $val2 Then
        $nResult = 1 ; Переместить item2 после item1
    EndIf

    $nResult = $nResult * $nSortDir

    Return $nResult
EndFunc

; Возвращает текст пункта ListView указанной колонки
Func GetSubItemText($nCtrlID, $nItemID, $nColumn)
    Local $stLvfi = DllStructCreate("uint;ptr;int;int[2];int")
    Local $nIndex, $stBuffer, $stLvi, $sItemText

    DllStructSetData($stLvfi, 1, $LVFI_PARAM) ; Поиск пункта нашего сохранённого индекса
    DllStructSetData($stLvfi, 3, $nItemID)

    $stBuffer = DllStructCreate("char[260]")

    $nIndex = GUICtrlSendMsg($nCtrlID, $LVM_FINDITEM, -1, DllStructGetPtr($stLvfi));

    $stLvi = DllStructCreate("uint;int;int;uint;uint;ptr;int;int;int;int")

    DllStructSetData($stLvi, 1, $LVIF_TEXT)
    DllStructSetData($stLvi, 2, $nIndex)
    DllStructSetData($stLvi, 3, $nColumn)
    DllStructSetData($stLvi, 6, DllStructGetPtr($stBuffer))
    DllStructSetData($stLvi, 7, 260)

    GUICtrlSendMsg($nCtrlID, $LVM_GETITEMA, 0, DllStructGetPtr($stLvi));

    $sItemText = DllStructGetData($stBuffer, 1)

    $stLvi = 0
    $stLvfi = 0
    $stBuffer = 0

    Return $sItemText
EndFunc

; *******************************************************
; Пример 2 - сортировка с самосозданием пунктов функцией DllCall
; *******************************************************
Func Example2()
    Local $hGUI, $lv, $msg

    $nCurCol = -1
    $nSortDir = 1
    $bSet = 0
    $nCol = -1

    $hGUI = GUICreate("Тест 2", 300, 200)

    $lv = GUICtrlCreateListView("Колонка1|Кол2|Кол3", 10, 10, 280, 180)
    GUICtrlRegisterListViewSort(-1, "LVSort2") ; Регистрация функции обратного вызова сортировки "LVSort2"

    MyGUICtrlCreateListViewItem("ABC|666|10.05.2004", $lv, -1)
    MyGUICtrlCreateListViewItem("DEF|444|11.05.2005", $lv, -1)
    MyGUICtrlCreateListViewItem("CDE|444|12.05.2004", $lv, -1)

    GUISetState()

    While 1
        $msg = GUIGetMsg()
        Switch $msg
            Case $GUI_EVENT_CLOSE
                ExitLoop

            Case $lv
                $bSet = 0
                $nCurCol = $nCol
                GUICtrlSendMsg($lv, $LVM_SETSELECTEDCOLUMN, GUICtrlGetState($lv), 0)
                DllCall("user32.dll", "int", "InvalidateRect", "hwnd", ControlGetHandle($hGUI, "", $lv), "int", 0, "int", 1)
        EndSwitch
    WEnd
EndFunc

; Наша функция обратного вызова сортировки
Func LVSort2($hWnd, $nItem1, $nItem2, $nColumn)
    Local $val1, $val2, $nResult

    ; Переключает направление сортировки (по убыванию или по возрастанию)
    If $nColumn = $nCurCol Then
        If Not $bSet Then
            $nSortDir = $nSortDir * - 1
            $bSet = 1
        EndIf
    Else
        $nSortDir = 1
    EndIf
    $nCol = $nColumn

    $val1 = GetSubItemText($hWnd, $nItem1, $nColumn)
    $val2 = GetSubItemText($hWnd, $nItem2, $nColumn)

    ; Если это 3-я колонка (отсчёт колонок от 0), тогда сравнение дат
    If $nColumn = 2 Then
        $val1 = StringRight($val1, 4) & StringMid($val1, 4, 2) & StringLeft($val1, 2)
        $val2 = StringRight($val2, 4) & StringMid($val2, 4, 2) & StringLeft($val2, 2)
    EndIf

    $nResult = 0 ; Не изменять позиции of item1 и item2

    If $val1 < $val2 Then
        $nResult = -1 ; Переместить item2 перед item1
    ElseIf $val1 > $val2 Then
        $nResult = 1 ; Переместить item2 после item1
    EndIf

    $nResult = $nResult * $nSortDir

    Return $nResult
EndFunc

; Создаёт и вставляет пункт в ListView
Func MyGUICtrlCreateListViewItem($sText, $nCtrlID, $nIndex)
    Local $stLvItem = DllStructCreate("uint;int;int;uint;uint;ptr;int;int;int;int;")
    Local $stText = DllStructCreate("char[260]")
    Local $arText = StringSplit($sText, "|")

    If $nIndex = -1 Then $nIndex = GUICtrlSendMsg($nCtrlID, $LVM_GETITEMCOUNT, 0, 0)

    DllStructSetData($stText, 1, $arText[1]) ; Сохраняет текст пункта в структуру

    DllStructSetData($stLvItem, 1, BitOR($LVIF_TEXT, $LVIF_PARAM))
    DllStructSetData($stLvItem, 2, $nIndex)
    DllStructSetData($stLvItem, 6, DllStructGetPtr($stText))
    ; Устанавливает lParam структуры в индекс строки - уникальный в ListView
    DllStructSetData($stLvItem, 9, $nIndex)

    $nIndex = GUICtrlSendMsg($nCtrlID, $LVM_INSERTITEMA, 0, DllStructGetPtr($stLvItem))

    If $nIndex > -1 Then
        ; Вставляет остальную часть текста колонок
        For $i = 2 To $arText[0]
            DllStructSetData($stText, 1, $arText[$i])
            DllStructSetData($stLvItem, 3, $i - 1) ; Устанавливает индекс подпункта

            GUICtrlSendMsg($nCtrlID, $LVM_SETITEMTEXTA, $nIndex, DllStructGetPtr($stLvItem))
        Next
    EndIf

    $stText = 0
    $stLvItem = 0

    ; Изменяет ширину колонки в соответствии с текстом пункта
    For $i = 0 To 2
        GUICtrlSendMsg($nCtrlID, $LVM_SETCOLUMNWIDTH, $i, -1)
        GUICtrlSendMsg($nCtrlID, $LVM_SETCOLUMNWIDTH, $i, -2)
    Next
EndFunc