- Сообщения
- 8,673
- Репутация
- 2,486
lorents [?]
Свёртывание/развёртывание вроде работает корректно, также как и подборка размера элементов.
Новая проблема назрела - прокрутка элементов при большом списке, придётся делать ручную синхронизацию...
Вот что пока получилось:будет время посмотрите
Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <FontConstants.au3>
#include <GUIListView.au3>
#include <GUITreeView.au3>
#include <WinAPI.au3>
Global $i_TLV_Changing = False
Global $a_TLV_Data[1][1]
Global $h_TLV_Font = _WinAPI_CreateFont(14, 6, 0, 0, 0, False, False, False)
$hGUI = GUICreate("TreeListView Test", 400, 300)
$anTLV = _GUICtrlTreeListView_Create($hGUI, 10, 10, 380, 280)
For $i = 1 To 4 ;5
$anTLV_Item = _GUICtrlTreeListView_AddItem($anTLV, "My Folder " & $i & "|Folder|" & Round(Random(1, 5), 1) & " mb")
$anTLV_SubItem1 = _GUICtrlTreeListView_AddItem($anTLV, "My Script " & $i & ".au3|File|" & Round(Random(1, 5), 1) & " kb", $anTLV_Item[0])
$anTLV_SubItem2 = _GUICtrlTreeListView_AddItem($anTLV, "My File " & $i & ".txt|File|" & Round(Random(1, 5), 1) & " kb", $anTLV_Item[0])
_GUICtrlTreeListView_ExpandItem($anTLV, $anTLV_Item, True)
Next
GUISetState(@SW_SHOW, $hGUI)
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
EndSwitch
WEnd
Func _GUICtrlTreeListView_Create($hWnd, $iLeft, $iTop, $iWidth, $iHeight)
Local $anTLV[2]
$anTLV[0] = GUICtrlCreateTreeView($iLeft + 5, $iTop + 25, ($iWidth / 2) + 10, $iHeight - 45, BitOr($GUI_SS_DEFAULT_TREEVIEW, $TVS_HASLINES));, $TVS_SINGLEEXPAND))
$anTLV[1] = GUICtrlCreateListView("Name|Type|Size", $iLeft, $iTop, $iWidth, $iHeight, BitOr($GUI_SS_DEFAULT_LISTVIEW, $WS_CLIPSIBLINGS, $LVS_NOSORTHEADER))
__GUICtrlTreeListView_SetFont($anTLV[1], $h_TLV_Font)
GUIRegisterMsg($WM_NOTIFY, "__GUICtrlTreeListView_WM_NOTIFY")
Return $anTLV
EndFunc
Func _GUICtrlTreeListView_AddItem($anTLV, $sItemText, $nTVCtrl = -1)
Local $anTLV_Item[2], $iItem, $aTVPos
$i_TLV_Changing = True
If $nTVCtrl = -1 Then
$nTVCtrl = $anTLV[0]
EndIf
$anTLV_Item[0] = GUICtrlCreateTreeViewItem(StringRegExpReplace($sItemText, '^(.*?)\|.*', '\1'), $nTVCtrl)
$anTLV_Item[1] = GUICtrlCreateListViewItem($sItemText, $anTLV[1])
$aTVPos = WinGetPos(GUICtrlGetHandle($anTLV[0]))
If UBound($aTVPos) > 2 Then
_GUICtrlListView_SetColumnWidth($anTLV[1], 0, $aTVPos[2] + 10)
EndIf
For $i = 1 To _GUICtrlListView_GetColumnCount($anTLV[1])-1
_GUICtrlListView_SetColumnWidth($anTLV[1], $i, -1)
Next
$a_TLV_Data[0][0] += 1
ReDim $a_TLV_Data[$a_TLV_Data[0][0] + 1][6]
$a_TLV_Data[$a_TLV_Data[0][0]][0] = $anTLV[0] ;TreeView ID
$a_TLV_Data[$a_TLV_Data[0][0]][1] = $anTLV[1] ;ListView ID
$a_TLV_Data[$a_TLV_Data[0][0]][2] = $anTLV_Item[0] ;Added TV Item ID
$a_TLV_Data[$a_TLV_Data[0][0]][3] = $anTLV_Item[1] ;Added LV Item ID
$a_TLV_Data[$a_TLV_Data[0][0]][4] = $sItemText ;LV Item Text (including SubItems delimited with |)
$a_TLV_Data[$a_TLV_Data[0][0]][5] = $nTVCtrl ;TV Item Parent ID
$i_TLV_Changing = False
Return $anTLV_Item
EndFunc
Func _GUICtrlTreeListView_ExpandItem($anTLV, $nTVCtrl, $bExpand)
$i_TLV_Changing = True
_GUICtrlTreeView_Expand($anTLV[0], $nTVCtrl[0], $bExpand)
$i_TLV_Changing = False
EndFunc
Func __GUICtrlTreeListView_WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hTreeView, $hListView, $hLVHeader
If $i_TLV_Changing Then
Return $GUI_RUNDEFMSG
EndIf
$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
$iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
$iCode = DllStructGetData($tNMHDR, "Code")
For $i = 1 To $a_TLV_Data[0][0]
$hTreeView = GUICtrlGetHandle($a_TLV_Data[$i][0])
$hListView = GUICtrlGetHandle($a_TLV_Data[$i][1])
$hLVHeader = _GUICtrlListView_GetHeader($hListView)
Switch $hWndFrom
Case $hLVHeader
Switch $iCode
Case $HDN_ITEMCHANGING, $HDN_ITEMCHANGINGW
Return 1
EndSwitch
ExitLoop
Case $hListView
Switch $iCode
Case $LVN_ITEMCHANGING, $LVN_BEGINDRAG, $LVN_MARQUEEBEGIN
Return 1
EndSwitch
ExitLoop
Case $hTreeView
Switch $iCode
Case $TVN_ITEMEXPANDINGA, $TVN_ITEMEXPANDINGW
Local $tPOINT = DllStructCreate("int X;int Y")
DllStructSetData($tPOINT, "X", MouseGetPos(0))
DllStructSetData($tPOINT, "Y", MouseGetPos(1))
_WinAPI_ScreenToClient($hTreeView, $tPOINT)
Local $iX = DllStructGetData($tPOINT, "X")
Local $iY = DllStructGetData($tPOINT, "Y")
Local $hTVItem = _GUICtrlTreeView_HitTestItem($hTreeView, $iX, $iY)
Local $aLVItem = _GUICtrlListView_HitTest($hListView, $iX, $iY)
If $hTVItem <> 0 Then
Local $iTVItemIndx = _GUICtrlTreeView_Index($hTreeView, $hTVItem) ;$aLVItem[0]
Local $iTVItemID = _GUICtrlTreeView_GetItemParam($hTreeView, $hTVItem) ;$aLVItem[0]
For $j = 1 To $a_TLV_Data[0][0]
If $iTVItemID = $a_TLV_Data[$j][2] Then
Local $iChilds = _GUICtrlTreeView_GetChildCount($hTreeView, $hTVItem)
If _GUICtrlTreeView_GetExpanded($hTreeView, $hTVItem) Then
;~ _GUICtrlListView_DeleteAllItems($hListView)
;~
;~ For $x = 1 To $a_TLV_Data[0][0]
;~ If $a_TLV_Data[$x][5] <> $iTVItemID Then
;~ $a_TLV_Data[$x][3] = GUICtrlCreateListViewItem($a_TLV_Data[$x][4], $a_TLV_Data[$i][1])
;~ EndIf
;~ Next
For $x = $j + $iChilds To $j + 1 Step -1
;_GUICtrlListView_DeleteItem($hListView, $x - 1)
GUICtrlDelete($a_TLV_Data[$x][3])
$a_TLV_Data[$x][3] = 0
Next
Else
_GUICtrlListView_DeleteAllItems($hListView)
For $x = 1 To $a_TLV_Data[0][0]
$hParent = _GUICtrlTreeView_GetParentHandle($a_TLV_Data[$i][0], $a_TLV_Data[$x][2])
;It's a child item, it's not hitted parent item (expanded), and the parent of this item is expanded
If $hParent And $hParent <> $hTVItem And Not _GUICtrlTreeView_GetExpanded($a_TLV_Data[$i][0], $hParent) Then
ContinueLoop
EndIf
;Otherwise we create the item (it's visible) and reset the LV Item ID
$a_TLV_Data[$x][3] = GUICtrlCreateListViewItem($a_TLV_Data[$x][4], $a_TLV_Data[$i][1])
Next
;~ For $x = $j + 1 To $j + $iChilds
;~ $a_TLV_Data[$x][3] = _GUICtrlListView_InsertItem($hListView, $a_TLV_Data[$x][4], $x - 1)
;~
;~ $aText = StringSplit($a_TLV_Data[$x][4], '|')
;~
;~ For $iSubItem = 1 To $aText[0]
;~ _GUICtrlListView_SetItemText($hListView, $x - 1, $aText[$iSubItem], $iSubItem - 1)
;~ Next
;~ Next
EndIf
ExitLoop
EndIf
Next
EndIf
EndSwitch
ExitLoop
EndSwitch
Next
Return $GUI_RUNDEFMSG
EndFunc
; =========================================================================================
; Name...........: _GUICtrlListView_SetFont
; Description ...: Set font for a list-view controls items and header text
; Syntax.........: _GUICtrlListView_SetFont($hWnd, $hFontLV, $hFontHD = 0)
; Parameters ....: $hWnd - Handle to the control
; $hFontLV - Handle to font
; $hFontHD - Handle to header font (Optional)
; Return values .: Success - True
; Failure - False
; Author ........: rover
; Remarks .......: Use optional header font parameter for a different font/size of header
; =========================================================================================
Func __GUICtrlTreeListView_SetFont($hWnd, $hFontLV, $hFontHD = 0)
If $Debug_LV Then __UDF_ValidateClassName($hWnd, $__LISTVIEWCONSTANT_ClassName)
If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)
Local $aReturn, $hHeader, $hDLL
$hHeader = HWnd(_GUICtrlListView_GetHeader($hWnd)) ; get handle to header control
If Not IsHWnd($hWnd) Or Not IsPtr($hFontLV) Or Not IsHWnd($hHeader) Then Return SetError(1, 0, False)
_SendMessage($hWnd, $__LISTVIEWCONSTANT_WM_SETREDRAW, 0) ; disable repainting
$hDLL = DllOpen("UxTheme.dll")
; turn off theme for header control to enable header autosizing
$aReturn = DllCall($hDLL, "int", "SetWindowTheme", "hwnd", $hHeader, "wstr", "", "wstr", "")
If @error Or $aReturn[0] Then
DllClose($hDLL)
Return SetError(2, 0, False)
EndIf
If IsPtr($hFontHD) Then ; set font for items and if available separate font for header
_SendMessage($hWnd, $__LISTVIEWCONSTANT_WM_SETFONT, $hFontLV, True, 0, "hwnd")
_SendMessage($hHeader, $__LISTVIEWCONSTANT_WM_SETFONT, $hFontHD, True, 0, "hwnd")
Else ; set same font for header and items
; resizing header down to a smaller font size causes listview repaint problems, so repainting is enabled
_SendMessage($hWnd, $__LISTVIEWCONSTANT_WM_SETREDRAW, 1) ; enable repainting
_SendMessage($hWnd, $__LISTVIEWCONSTANT_WM_SETFONT, $hFontLV, True, 0, "hwnd")
EndIf
; restore control theme painting
$aReturn = DllCall($hDLL, "int", "SetWindowTheme", "hwnd", $hHeader, "ptr", 0, "ptr", 0)
If @error Or $aReturn[0] Then
DllClose($hDLL)
Return SetError(3, 0, False)
EndIf
DllClose($hDLL)
_SendMessage($hWnd, $__LISTVIEWCONSTANT_WM_SETREDRAW, 1) ; enable repainting
_WinAPI_RedrawWindow($hWnd, 0, 0, $RDW_INVALIDATE)
Return SetError(0, 0, $aReturn[0] <> 1)
EndFunc
Свёртывание/развёртывание вроде работает корректно, также как и подборка размера элементов.
Новая проблема назрела - прокрутка элементов при большом списке, придётся делать ручную синхронизацию...