Looking for a way to step through ExplorerList elements I found this MS internal structure...
-----------------
Brad's VB-32 Programs & Samples
btmtz.mvps.org - TVItemData: Treeview item data (or how undocumented can you get?)
-----------------
Here some code to play with...
Code: Select all
;/ Some extra info on (Explorer)TreeGadgets
;/ sverson 2006-08-16 PB4 final
Structure TREE_ITEM ;/ MS internal TreeItem structure (see http://btmtz.mvps.org [TVITEM1Data])
hitemParent.l ;/ handle of the item's parent, can be 0 (root's parent is a dummy item, whose only valid member is the hitemChild, the root itself)
hitemNextSibling.l ;/ handle of the item's Next sibling, can be 0
hitemChild.l ;/ handle of the item's first child, can be 0
lpszText.l ;/ pointer to the item's text, allocated in DWORD chunks, can be LPSTR_TEXTCALLBACK, is Unicode on NT.
wState.w ;/ item's state flags, 1st byte is state, low nibble of 2nd byte is overlay image index, high nibble of 2nd byte is state image index
wImage.w ;/ normal icon imagelist index, can be I_IMAGECALLBACK (&HFFFF)
wSelectedImage.w ;/ selected icon imagelist index, can be I_IMAGECALLBACK (&HFFFF)
cxItem.w ;/ item's label width in pixels (TVM_GETITEMRECT/TRUE)
wIndex.w ;/ visible item's 0-based physical tree Position, is -1 If in collapsed parent, can change
bLevel.b ;/ item's 0-based hierarchical level in the tree
bChildren.b ;/ TVITEM1.cChildren, can't be I_CHILDRENCALLBACK (?)
lParam.l ;/ TVITEM1.lParam, usually points to something internally allocated
;dwID.l ;/ always 1
EndStructure
Structure TREE_ITEM5 ;/ MS internal TreeItem structure (see http://btmtz.mvps.org [TVITEM1Data])
;{/ Microsoft, in its complete freedom to break the undocumented, has done just that.
;/ Begining with Comctl32.dll v5.xx, the TREEITEM structure above has been changed,
;/ not by much, but just enough to break the apps of folks who decided to use it. The
;/ lParam member has been moved up, from below the bChildren member, to below the
;}/ lpszText member. The dwID (was dwIDBit) member's Value has also been changed.
hitemParent.l ;/ handle of the item's parent, can be 0 (root's parent is a dummy item, whose only valid member is the hitemChild, the root itself)
hitemNextSibling.l ;/ handle of the item's Next sibling, can be 0
hitemChild.l ;/ handle of the item's first child, can be 0
lpszText.l ;/ pointer to the item's Unicode text, allocated in DWORD chunks, can be LPSTR_TEXTCALLBACK.
lParam.l ;/ TVITEM1.lParam, usually points to something internally allocated
wState.w ;/ item's state flags, 1st byte is state, low nibble of 2nd byte is overlay image index, high nibble of 2nd byte is state image index
wImage.w ;/ normal icon imagelist index, can be I_IMAGECALLBACK (&HFFFF)
wSelectedImage.w ;/ selected icon imagelist index, can be I_IMAGECALLBACK (&HFFFF)
cxItem.w ;/ item's label width in pixels (TVM_GETITEMRECT/TRUE)
wIndex.w ;/ visible item's 0-based physical tree Position, is -1 If in collapsed parent, can change
bLevel.b ;/ item's 0-based hierarchical level in the tree
bChildren.b ;/ TVITEM1.cChildren, can't be I_CHILDRENCALLBACK (?)
dwID.l ;/ always &HABCD0001 ?
EndStructure
Structure TVITEM1
mask.l
hItem.l
state.l
stateMask.l
pszText.l
cchTextMax.l
iImage.l
iSelectedImage.l
cChildren.l
lParam.l
EndStructure
Global MainWindowEvent.l, MainGadgetID.l, LastlParam.l=0
Global ExplorerTreeNo.l, ExplorerTreeID.l, ListIconNo.l, ListIconID.l, SplitterNo.l
Procedure TreeViewSetCheckBox(tvGadgetNo.l) ;/ Adds CheckBoxes to a TreeView
#TVS_CHECKBOXES = $100
Protected tvGadgetID.l, tvGadgetStyles.l
tvGadgetID = GadgetID(tvGadgetNo)
tvGadgetStyles = GetWindowLong_(tvGadgetID,#GWL_STYLE) | #TVS_CHECKBOXES
SetWindowLong_(tvGadgetID,#GWL_STYLE,tvGadgetStyles)
EndProcedure
Procedure AddInfoRow(*TVITEM1ID.TREE_ITEM5,Level.l,iType.s) ;/ Display TVITEM1Info (TREE_ITEM)
Protected tviSelf.s, tviParent.s, tviNextSibling.s, tviFirstChild.s, tviText.s, tviState.s, tviImage.s
Protected tviSelImage.s, tviLabelWidth.s, tviIndex.s, tviLevel.s, tviChildren.s, tviLparam.s
Protected InfoLine.s
tviSelf = "$"+RSet(Hex(*TVITEM1ID),8,"0")
tviParent = "$"+RSet(Hex(*TVITEM1ID\hitemParent),8,"0") ;/ handle of the item's parent, can be 0 (root's parent is a dummy item, whose only valid member is the hitemChild, the root itself)
tviNextSibling = "$"+RSet(Hex(*TVITEM1ID\hitemNextSibling),8,"0") ;/ handle of the item's Next sibling, can be 0
tviFirstChild = "$"+RSet(Hex(*TVITEM1ID\hitemChild),8,"0") ;/ handle of the item's first child, can be 0
tviText = PeekS(*TVITEM1ID\lpszText,-1,#PB_Unicode) ;/ (pointer to) the item's text, allocated in DWORD chunks, can be LPSTR_TEXTCALLBACK, is Unicode on NT.
tviState = "%"+RSet(Bin(*TVITEM1ID\wState),16,"0") ;/ item's state flags, 1st byte is state, low nibble of 2nd byte is overlay image index, high nibble of 2nd byte is state image index
tviImage = "%"+RSet(Bin(*TVITEM1ID\wImage),16,"0") ;/ normal icon imagelist index, can be I_IMAGECALLBACK (&HFFFF)
tviSelImage = "%"+RSet(Bin(*TVITEM1ID\wSelectedImage),16,"0") ;/ selected icon imagelist index, can be I_IMAGECALLBACK (&HFFFF)
tviLabelWidth = Str(*TVITEM1ID\cxItem)+" px" ;/ item's label width in pixels (TVM_GETITEMRECT/TRUE)
tviIndex = "%"+RSet(Bin(*TVITEM1ID\wIndex),16,"0") ;/ visible item's 0-based physical tree Position, is -1 If in collapsed parent, can change
tviLevel = Str(*TVITEM1ID\bLevel) ;/ item's 0-based hierarchical level in the tree
tviChildren = Str(*TVITEM1ID\bChildren) ;/ TVITEM1.cChildren, can't be I_CHILDRENCALLBACK (?)
tviLparam = "$"+RSet(Hex(*TVITEM1ID\lParam),8,"0") ;/ TVITEM1.lParam, usually points to something internally allocated
InfoLine = Str(Level)+"/"+tviLevel+Chr(10)
InfoLine + iType+" "+Chr(10)
InfoLine + tviSelf+Chr(10)
InfoLine + tviText+Chr(10)
InfoLine + tviParent+Chr(10)
InfoLine + tviNextSibling+Chr(10)
InfoLine + tviFirstChild+Chr(10)
InfoLine + tviState+Chr(10)
InfoLine + tviIndex+Chr(10)
InfoLine + tviImage+Chr(10)
InfoLine + tviSelImage+Chr(10)
InfoLine + tviLparam+Chr(10)
InfoLine + tviChildren+Chr(10)
InfoLine + tviLabelWidth+Chr(10)
AddGadgetItem(ListIconNo,-1,InfoLine)
EndProcedure
Procedure TreeViewDisplay(tvGadgetNo.l) ;/ Display all TreeView elements (currently in memory)
Protected tvGadgetID.l, *TVITEM1ID1.TREE_ITEM, *TVITEM1ID2.TREE_ITEM, *TVITEM1ID3.TREE_ITEM, TVITEM1Level.l=0, TVITEM1Count.l, tvAktItem.l
tvGadgetID = GadgetID(tvGadgetNo)
TVITEM1Count = SendMessage_(tvGadgetID, #TVM_GETCOUNT, 0,0)
AddGadgetItem(ListIconNo,-1,"TreeView"+Chr(10)+"("+Str(TVITEM1Count)+" elements}")
*TVITEM1ID1 = SendMessage_(tvGadgetID, #TVM_GETNEXTITEM, #TVGN_ROOT, 0)
If *TVITEM1ID1 : AddInfoRow(*TVITEM1ID1,TVITEM1Level,"ROOT") : EndIf
For tvAktItem = 1 To TVITEM1Count
*TVITEM1ID2 = SendMessage_(tvGadgetID, #TVM_GETNEXTITEM, #TVGN_CHILD, *TVITEM1ID1)
If *TVITEM1ID2 : TVITEM1Level+1 : AddInfoRow(*TVITEM1ID2,TVITEM1Level,"CHILD") : EndIf
Repeat
If *TVITEM1ID2 = #Null
*TVITEM1ID2 = SendMessage_(tvGadgetID, #TVM_GETNEXTITEM, #TVGN_NEXT, *TVITEM1ID1)
If *TVITEM1ID2 : AddInfoRow(*TVITEM1ID2,TVITEM1Level,"NEXT") : EndIf
EndIf
If *TVITEM1ID2 = #Null
*TVITEM1ID2 = SendMessage_(tvGadgetID, #TVM_GETNEXTITEM, #TVGN_PARENT, *TVITEM1ID1)
If *TVITEM1ID2
*TVITEM1ID3 = SendMessage_(tvGadgetID, #TVM_GETNEXTITEM, #TVGN_NEXT, *TVITEM1ID2)
TVITEM1Level-1
If *TVITEM1ID3
AddInfoRow(*TVITEM1ID3,TVITEM1Level,"PARENT/NEXT")
EndIf
EndIf
EndIf
Until *TVITEM1ID2 <> #Null
If *TVITEM1ID3
*TVITEM1ID1 = *TVITEM1ID3
*TVITEM1ID3=0
Else
*TVITEM1ID1 = *TVITEM1ID2
EndIf
Next
EndProcedure
If OpenWindow(0, 0, 0, 800, 500, "(Explorer)TreeGadget - Infos", #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget)
ExplorerTreeNo = ExplorerTreeGadget(#PB_Any,0,0,0,0,"",#PB_Explorer_NoFiles)
ExplorerTreeID = GadgetID(ExplorerTreeNo)
ListIconNo = ListIconGadget(#PB_Any,0,0,0,0,"Level",0,#PB_ListIcon_FullRowSelect);|#LVS_NOCOLUMNHEADER)
ListIconID = GadgetID(ListIconNo)
SplitterNo = SplitterGadget(#PB_Any,5,5,WindowWidth(0)-10,WindowHeight(0)-10,ExplorerTreeNo,ListIconNo,#PB_Splitter_Vertical)
AddGadgetColumn(ListIconNo,1,"#TVGN_",0) : AddGadgetColumn(ListIconNo,2,"Self",0) : AddGadgetColumn(ListIconNo,3,"Text",0)
AddGadgetColumn(ListIconNo,4,"Parent",0) : AddGadgetColumn(ListIconNo,5,"NextSibling",0) : AddGadgetColumn(ListIconNo,6,"FirstChild",0)
AddGadgetColumn(ListIconNo,7,"State",0) : AddGadgetColumn(ListIconNo,8,"Index",0) : AddGadgetColumn(ListIconNo,9,"Image",0)
AddGadgetColumn(ListIconNo,10,"SelImage",0) : AddGadgetColumn(ListIconNo,11,"lParam",0) : AddGadgetColumn(ListIconNo,12,"Children",0)
AddGadgetColumn(ListIconNo,13,"LabelWidth",0)
TreeViewSetCheckBox(ExplorerTreeNo)
TreeViewDisplay(ExplorerTreeNo)
For x=0 To 13 : SendMessage_(ListIconID,#LVM_SETCOLUMNWIDTH,x,#LVSCW_AUTOSIZE_USEHEADER) : Next
Repeat
MainWindowEvent = WaitWindowEvent()
Select MainWindowEvent
Case #WM_SIZE
ResizeGadget(SplitterNo,#PB_Ignore,#PB_Ignore,(WindowWidth(0)-10),WindowHeight(0)-10)
Case #PB_Event_Gadget
MainGadgetID = EventGadget()
Select MainGadgetID
Case ExplorerTreeNo
If LastlParam <> EventlParam()
LastlParam = EventlParam()
TreeViewDisplay(ExplorerTreeNo)
EndIf
EndSelect
EndSelect
Until MainWindowEvent = #PB_Event_CloseWindow
EndIf