I tried to convert this into a TreeView version, but failed. I was hoping to get lucky with the DecodeInteger and EncodeInteger and WM_NOTIFY functions, which are beyond my programming understanding.
If anyone wants to take a shot at converting those to treeview versions, or explain why this couldn't work with treeview, here's my version fwiw. It doesn't work in that nothing happens, no color change:
-I changed the LV functions in the original script to their respective TV counterparts.
-I used tree branch ItemID instead of listview row number; I left in a message box that states those ID just to see that script runs through them.
-The sample tree is from the help file's example, except I set the root directory to A_ScriptDir to keep the build process short -> you need folders in there though.
-The background starts as white with black foreground (text?), and if the script worked those colors would be reversed when a branch was double-clicked.
Code:
Code:
/* struct NMHDR {
HWND hwndFrom; uint4 0
UINT idFrom; uint4 4
UINT code; uint4 8
} 12
*/
/* struct NMCUSTOMDRAW {
NMHDR hdr; 12 0
DWORD dwDrawStage; uint4 12
HDC hdc; uint4 16
RECT rc; 16 20
DWORD_PTR dwItemSpec; uint4 36
UINT uItemState; uint4 40
LPARAM lItemlParam; int4 44
} 48
*/
/* struct NMLVCUSTOMDRAW {
NMCUSTOMDRAW nmcd; 48 0
COLORREF clrText; uint4 48
COLORREF clrTextBk; uint4 52
#if (_WIN32_IE >= 0x0400)
int iSubItem; int4 56
#endif
#if (_WIN32_IE >= 0x560)
DWORD dwItemType; uint4 60
COLORREF clrFace; uint4 64
int iIconEffect; int4 68
int iIconPhase; int4 72
int iPartId; int4 76
int iStateId: int4 80
RECT rcText; 16 84
UINT uAlign; uint4 100
#endif
} 104
*/
TreeRoot := A_ScriptDir
;TreeRoot := A_AppData
Gui, +LastFound
;Gui, Add, ListView, x5 y5 w200 h200 vLV_Sample, index|day
Gui, Add, TreeView, x5 y5 w200 h200 vMyTree gMyTree
AddSubFoldersToTree(TreeRoot)
Gui, Show,, %TreeRoot% ; Display the source directory (TreeRoot) in the title bar.
TV_ColorInitiate() ; (Gui_Number, Control) - defaults to: (1, SysListView321)
TV_ColorChange()
Loop, % TV_GetCount()
{
treeIndex := TV_GetNext(treeIndex)
treeIndices .= treeIndex "`n"
If (treeIndex == 0)
Break
TV_ColorChange(treeIndex, "0x000000", "0xFFFFFF")
}
Return
GuiClose:
GuiEscape:
Exitapp
MyTree:
If (A_GuiEvent == "S") ; i.e. do nothing extra on "select new tree item" events.
return
treeIndices =
Loop, % TV_GetCount()
{
treeIndex := TV_GetNext(treeIndex)
treeIndices .= treeIndex "`n"
If (treeIndex == 0)
Break
TV_ColorChange(treeIndex, "0xFFFFFF", "0x000000")
}
Msgbox, TV_ColorChange (reversal) was applied to following branches (item IDs):`n%treeIndices%
Return
TV_ColorInitiate(Gui_Number=1, Control="") ; initiate treeview color change procedure
{
global hw_TV_ColorChange
If Control =
Control := "SysTreeView321"
Gui, %Gui_Number%:+Lastfound
Gui_ID := WinExist()
ControlGet, hw_TV_ColorChange, HWND,, %Control%, ahk_id %Gui_ID%
OnMessage( 0x4E, "WM_NOTIFY" )
}
TV_ColorChange(treeIndex="", TextColor="", BackColor="") ; change specific line's color or reset all lines
{
global
If treeIndex =
{
Loop, % TV_GetCount()
{
treeIndex := TV_GetNext(treeIndex)
If (treeIndex == 0) ; root
Break
TV_ColorChange(treeIndex,TextColor,BackColor)
}
}
Else
{
Line_Color_%treeIndex%_Text := TextColor
Line_Color_%treeIndex%_Back := BackColor
WinSet, Redraw,, ahk_id %hw_TV_ColorChange%
}
}
WM_NOTIFY( p_w, p_l, p_m )
{
local draw_stage, Current_Line, treeIndex
if ( DecodeInteger( "uint4", p_l, 0 ) = hw_TV_ColorChange )
{
if ( DecodeInteger( "int4", p_l, 8 ) = -12 )
{ ; NM_CUSTOMDRAW
draw_stage := DecodeInteger( "uint4", p_l, 12 )
if ( draw_stage = 1 ) ; CDDS_PREPAINT
return, 0x20 ; CDRF_NOTIFYITEMDRAW
else if ( draw_stage = 0x10000|1 )
{ ; CDDS_ITEM
Current_Line := DecodeInteger( "uint4", p_l, 36 )+1
TV_GetText(Current_Line,treeIndex)
If (Line_Color_%treeIndex%_Text != "")
{
EncodeInteger( Line_Color_%treeIndex%_Text, 4, p_l, 48 ) ; foreground
EncodeInteger( Line_Color_%treeIndex%_Back, 4, p_l, 52 ) ; background
}
}
}
}
}
DecodeInteger( p_type, p_address, p_offset, p_hex = true )
{
old_FormatInteger := A_FormatInteger
ifEqual, p_hex, 1, SetFormat, Integer, hex
else, SetFormat, Integer, dec
StringRight, size, p_type, 1
loop, %size%
value += *( ( p_address+p_offset )+( A_Index-1 ) ) << ( 8*( A_Index-1 ) )
if ( size <= 4 and InStr( p_type, "u" ) != 1 and *( p_address+p_offset+( size-1 ) ) & 0x80 )
value := -( ( ~value+1 ) & ( ( 2**( 8*size ) )-1 ) )
SetFormat, Integer, %old_FormatInteger%
return, value
}
EncodeInteger( p_value, p_size, p_address, p_offset )
{
loop, %p_size%
DllCall( "RtlFillMemory", "uint", p_address+p_offset+A_Index-1, "uint", 1, "uchar", p_value >> ( 8*( A_Index-1 ) ) )
}
AddSubFoldersToTree(Folder, ParentItemID = 0)
{
; This function adds to the TreeView all subfolders in the specified folder.
; It also calls itself recursively to gather nested folders to any depth.
Loop %Folder%\*.*, 2 ; Retrieve all of Folder's sub-folders.
AddSubFoldersToTree(A_LoopFileFullPath, TV_Add(A_LoopFileName, ParentItemID))
}