Что нового

[Элементы GUI] Как у ListView узнать статус свёрнутости группы?

Sergy

Новичок
Сообщения
24
Репутация
1
Сделал ListView с группами. Групп вполне может быть пару сотен по 10-100 элементов в группе. Для удобства сделал группы сворачиваемыми. Наткнулся на одну проблему - как узнать в каком состоянии группа сейчас? Collapsed или нет? При помощи _GUICtrlListView_SetGroupInfo можно указать, свёрнута группа или нет, думалось, что _GUICtrlListView_GetGroupInfo должна давать узнать текущее состояние свёрнутости, ан нет, такую информацию не предоставляет :(

Прикладываю пример ListView. Как сделать, что бы при нажатии на обновить ($hButton_Refresh) просто выводились статусы развёрнутости первых пяти групп?

Код:
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>

Global $hListView_Result
Global $hForm_ZaprosGUI

Global $aReqestsArray [200][2]
For $iI = 0 To UBound($aReqestsArray)-1
	$aReqestsArray[$iI][0] = $iI
	$aReqestsArray[$iI][1] = 'Группа '&$iI
Next

Global $aArray[200][6]	; тестовый массивчик
For $iI = 0 To UBound($aArray)-1
	$aArray[$iI][0] = $iI
	$aArray[$iI][1] = 'тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест '
	$aArray[$iI][2] = 'просто текст просто текст просто текст просто текст просто текст просто текст просто текст просто текст '
	$aArray[$iI][3] = '100'
	$aArray[$iI][4] = 99
	$aArray[$iI][5] = 'проверка'
Next

Example()
Exit


Func Example()


	$hForm_ZaprosGUI = GUICreate("ListView Redraw Items", 700, 600)
	$hListView_Result = GUICtrlCreateListView("", 2, 70, 670, 500)
	$hButton_Refresh = GUICtrlCreateButton("Обновить", 2, 2, 75, 25)
	Dim $hForm_ZaprosGUI_AccelTable[1][2] = [["{F5}", $hButton_Refresh]]
	GUISetAccelerators($hForm_ZaprosGUI_AccelTable)

	$LV = _GUICtrlListView_AddColumn($hListView_Result, "колонка 1")
	_GUICtrlListView_AddColumn($hListView_Result, "колонка 2", 200)
	_GUICtrlListView_AddColumn($hListView_Result, "колонка 3", 300)
	_GUICtrlListView_AddColumn($hListView_Result, "колонка 4")
	_GUICtrlListView_AddColumn($hListView_Result, "колонка 5", 100)
	_GUICtrlListView_AddColumn($hListView_Result, "колонка 6", 50)
    _GUICtrlListView_SetItemCount($hListView_Result, 60000)

	RefreshLV()

	GUISetState(@SW_SHOW)

	While 1
		$nMsg = GUIGetMsg()
		Switch $nMsg
			Case $GUI_EVENT_CLOSE
				GUIDelete()
				ExitLoop
			Case $hButton_Refresh
				For $i = 0 to 4
					ConsoleWrite('Статус группы '&$i&': '& _MyListViewGroupGetCollapse($hListView_Result, $i) &@CRLF)
				Next
;~ 				RefreshLV()
		EndSwitch
	WEnd
	GUIDelete()
EndFunc   ;==>Example

Func RefreshLV()

	_GUICtrlListView_BeginUpdate($hListView_Result)

	_GUICtrlListView_DeleteAllItems ( $hListView_Result )
	_GUICtrlListView_RemoveAllGroups ( $hListView_Result )

    For $iI = 0 To UBound($aArray)-1
        _GUICtrlListView_AddItem($hListView_Result, $aArray[$iI][0], $iI)
		For $iJ = 1 To UBound($aArray, 2)-1
			_GUICtrlListView_AddSubItem($hListView_Result, $iI, $aArray[$iI][$iJ], $iJ, $iJ )
		Next
    Next

	; создадим группы
	For $i=0 To UBound($aReqestsArray)-1
		_GUICtrlListView_InsertGroup ($hListView_Result, -1, $i,        $aReqestsArray[$i][1])
		_GUICtrlListView_SetGroupInfo($hListView_Result, $i, $i+1& '. '&$aReqestsArray[$i][1], 0, $LVGS_COLLAPSIBLE)	; Сделаем группы раскрывающимися
	Next

	; разнесём результаты по группам
	For $i=0 To UBound($aArray)-1
		if $i > UBound ($aReqestsArray)-1 Then ExitLoop
		_GUICtrlListView_SetItemGroupID($hListView_Result, $i, $aArray[$i][0])
	Next

	; разрешаем групповой просмотр
	_GUICtrlListView_EnableGroupView($hListView_Result, True)

	_GUICtrlListView_EndUpdate($hListView_Result)

;~ 	; Redraw items
	_GUICtrlListView_RedrawItems($hListView_Result, 0, 9)

EndFunc ;==> Refresh

Func _MyListViewGroupGetCollapse($hLVname, $hLVGroupIndex)
;~ 	$aInfo = _GUICtrlListView_GetGroupInfoByIndex ($hLVname, $hLVGroupIndex)
;~ 	ConsoleWrite ("Text: " & $aInfo[0] & @TAB& " Group ID: " & $aInfo[2]& @TAB) ;&@CRLF)
	
	; как узнать в каком состоянии группа сейчас? Collapsed или нет?
	
	Return 1
EndFunc ;==> _MyListViewGroupGetCollapse
 
Автор
S

Sergy

Новичок
Сообщения
24
Репутация
1
Вот здесь умеют отслеживать момент сворачивания/раpворачивания группы при помощи WM_NOTIFY. Не пойму, как можно это переделать на простую функцию считывания текущего статуса развёрнутости. Или без WM_NOTIFY никак и надо городить постоянное отслеживание переключения состояний?




Добавлено:
Сообщение автоматически объединено:

На основе той темы c WM_NOTIFY сделал вариант с отслеживанием изменений состояния развёрнутости групп. Код не вычищенный, главное, что сейчас при нажатии на "Обновить" листвью чистится и перерисовывается заново. Т.е. если после нажатия обновить ничего визуально не поменялось - значит состояние восстановлено верно :smile:

Код:
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>

#include <GuiImageList.au3>
#include <WindowsConstants.au3>
#include <MsgBoxConstants.au3>



Global $hListView_Result
Global $hForm_ZaprosGUI
Global $BeginUpdate = 0	; Индикатор процесса перерисовки ListView

Global $idListview, $hWndListView
Global Const $LVN_GROUPINFO = ($LVN_FIRST - 88)
Global Const $tagNMLVGROUP = $tagNMHDR & ";int iGroupId;uint iNewState;uint iOldState"
;                                                            $LVGS_flags    $LVGS_flags


Global $aReqestsArray [200][3]
For $iI = 0 To UBound($aReqestsArray)-1
	$aReqestsArray[$iI][0] = $iI +1
	$aReqestsArray[$iI][1] = 'Группа '&$iI +1
	$aReqestsArray[$iI][2] = 0
Next

Global $aArray[200][6]	; тестовый массивчик
For $iI = 0 To UBound($aArray)-1
	$aArray[$iI][0] = $iI
	$aArray[$iI][1] = 'тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест '
	$aArray[$iI][2] = 'просто текст просто текст просто текст просто текст просто текст просто текст просто текст просто текст '
	$aArray[$iI][3] = '100'
	$aArray[$iI][4] = 99
	$aArray[$iI][5] = 'проверка'
Next

Example()
Exit


Func Example()


	$hForm_ZaprosGUI = GUICreate("ListView Redraw Items", 700, 600)
	$hListView_Result = GUICtrlCreateListView("", 2, 70, 670, 500)
	$hButton_Refresh = GUICtrlCreateButton("Обновить", 2, 2, 75, 25)
	Dim $hForm_ZaprosGUI_AccelTable[1][2] = [["{F5}", $hButton_Refresh]]
	GUISetAccelerators($hForm_ZaprosGUI_AccelTable)

	$LV = _GUICtrlListView_AddColumn($hListView_Result, "колонка 1")
	_GUICtrlListView_AddColumn($hListView_Result, "колонка 2", 200)
	_GUICtrlListView_AddColumn($hListView_Result, "колонка 3", 300)
	_GUICtrlListView_AddColumn($hListView_Result, "колонка 4")
	_GUICtrlListView_AddColumn($hListView_Result, "колонка 5", 100)
	_GUICtrlListView_AddColumn($hListView_Result, "колонка 6", 50)
    _GUICtrlListView_SetItemCount($hListView_Result, 60000)

	RefreshLV()

	GUISetState(@SW_SHOW)

	$hWndListView = GUICtrlGetHandle($hListView_Result)
    GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

	While 1
		$nMsg = GUIGetMsg()
		Switch $nMsg
			Case $GUI_EVENT_CLOSE
				GUIDelete()
				ExitLoop
			Case $hButton_Refresh
				RefreshLV()
		EndSwitch
	WEnd
	GUIDelete()
EndFunc   ;==>Example

Func RefreshLV()

	$BeginUpdate = 1
	_GUICtrlListView_BeginUpdate($hListView_Result)

	_GUICtrlListView_DeleteAllItems ( $hListView_Result )
	_GUICtrlListView_RemoveAllGroups ( $hListView_Result )

    For $iI = 0 To UBound($aArray)-1
        _GUICtrlListView_AddItem($hListView_Result, $aArray[$iI][0], $iI)
		For $iJ = 1 To UBound($aArray, 2)-1
			_GUICtrlListView_AddSubItem($hListView_Result, $iI, $aArray[$iI][$iJ], $iJ, $iJ )
		Next
    Next

	; создадим группы
	For $i=0 To UBound($aReqestsArray)-1
		_GUICtrlListView_InsertGroup ($hListView_Result, -1, $i,        $aReqestsArray[$i][1])
		_GUICtrlListView_SetGroupInfo($hListView_Result, $i, $i+1& '. '&$aReqestsArray[$i][1], 0, $LVGS_COLLAPSIBLE)	; Сделаем группы раскрывающимися
		; свернём группу, если нужно
		If $aReqestsArray[$i][2] = 1 Then
	 		_GUICtrlListView_SetGroupInfo($hListView_Result, $i, $i+1& '. '&$aReqestsArray[$i][1], 0, $LVGS_COLLAPSIBLE+$LVGS_COLLAPSED )	; Свернём группу
		EndIf
	Next

	; разнесём результаты по группам
	For $i=0 To UBound($aArray)-1
		if $i > UBound ($aReqestsArray)-1 Then ExitLoop
		_GUICtrlListView_SetItemGroupID($hListView_Result, $i, $aArray[$i][0])
	Next

	; разрешаем групповой просмотр
	_GUICtrlListView_EnableGroupView($hListView_Result, True)

	_GUICtrlListView_EndUpdate($hListView_Result)

;~ 	; Redraw items
	_GUICtrlListView_RedrawItems($hListView_Result, 0, 9)
	$BeginUpdate = 0
EndFunc ;==> Refresh


Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
;~     #forceref $hWnd, $iMsg, $wParam
    Local $tInfo, $tNMHDR = DllStructCreate($tagNMHDR, $lParam), $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    Local $iIDFrom = DllStructGetData($tNMHDR, "IDFrom"), $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hWndListView
            Switch $iCode

                Case $LVN_GROUPINFO ; A Group was clicked
					If $BeginUpdate = 0 Then	; приостанавливаем обработку во время перерисовки ListView
						$tInfo = DllStructCreate($tagNMLVGROUP, $lParam)
						Local $Collapsed = False
						If DllStructGetData($tInfo, "iNewState") > DllStructGetData($tInfo, "iOldState") Then
							$Collapsed = True
							$aReqestsArray[DllStructGetData($tInfo, "iGroupId")][2] = 1		; в третьей колонке храним статус свёрнутости группы
						Else
							$aReqestsArray[DllStructGetData($tInfo, "iGroupId")][2] = 0
						EndIf
;~ 						ConsoleWrite("-------"& @CRLF&$hWndFrom&" -->IsCollapsed: " & $Collapsed & " GroupId: " & DllStructGetData($tInfo, "iGroupId") & @CRLF					) 
					EndIf
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY


Если у кого-нибудь есть более изящное решение или замечания по усовершенствованию этого кода, буду рад увидеть.
 

InnI

AutoIT Гуру
Сообщения
4,782
Репутация
1,377
Sergy
В GuiListView.au3 есть недокументированная функция
Код:
For $i = 0 to 4
    ConsoleWrite('Статус группы ' & $i & ': ' & _GUICtrlListView_GetGroupState($hListView_Result, $i, $LVGS_COLLAPSED) & @CRLF)
Next
 
Автор
S

Sergy

Новичок
Сообщения
24
Репутация
1
Спасибо! Я знал что тут должно быть простое решение.
 
Верх