GUICtrlRegisterListViewSort
Регистрация пользовательской функции для внутренней сортировки ListView функцией обратного вызова.
GUICtrlRegisterListViewSort ( controlID, "function" )
Параметры
controlID | Идентификатор ListView, для которого должна выполниться функция. |
function |
Имя пользовательской функции, вызываемой, когда выполняется сортировка обратным вызовом. |
Возвращаемое значение
Успех: | Возвращает 1 |
Ошибка: | Возвращает 0 |
Примечания
!!! Чтобы функция была работоспособной, нужно определить максимум 4 параметра функции иначе функция не будет вызываться !!!Func MySortFunction($nListViewID, $LParam1, $LParam2, $nColumn)
; ...
EndFunc
; или
Func MySortFunction($nListViewID, $LParam1, $LParam2)
; ...
EndFunc
Позиция | Параметр | Описание |
---|---|---|
1 | controlID | Идентификатор ListView для которой используется возврат функции. |
2 | lParam1 | lParam значение первого пункта (по умолчанию идентификатор пункта). |
3 | lParam2 | lParam значение второго пункта (по умолчанию идентификатор пункта). |
4 | column | колонка, которая была нажата для сортировки (Номер первый колонки - 0). |
Возвращаемое значение | Описание |
---|---|
-1 | 1-ый пункт должен предшествовать 2-му. |
0 | Без изменений. |
1 | 1-ый пункт должен последовать за 2-ым. |
См. также
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