Imports System.Reflection
Imports Softelvdm.Controls
Imports Softelvdm.SftTreeNET

Public Class Form1

Private Const bFlags As BindingFlags = BindingFlags.FlattenHierarchy Or BindingFlags.Instance Or BindingFlags.NonPublic Or BindingFlags.Public Or BindingFlags.Static

Private Sub CloseButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CloseButton.Click
    Close()
End Sub

Private Sub LoadButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LoadButton.Click
    openFileDialog1.ShowDialog()
End Sub

Private Sub openFileDialog1_FileOk(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles openFileDialog1.FileOk
    LoadAssembly(openFileDialog1.FileName)
End Sub

Private Sub LoadAssembly(ByVal asm As Assembly)
    sftTree1.Initializing = True

    Dim itemCollection As ItemCollectionClass = sftTree1.ItemCollection
    itemCollection.Clear()

    ListInfo(itemCollection, asm)
    itemCollection.Sort()

    sftTree1.Headers(0, 0).Text = asm.FullName

    sftTree1.Columns.MakeOptimal(0, True)
    sftTree1.RecalcHorizontalExtent()
    sftTree1.Initializing = False
End Sub

Private Sub LoadAssembly(ByVal newInputFile As String)
    Dim asm As Assembly = Nothing
    Try
        asm = Assembly.LoadFrom(newInputFile)
    Catch e As Exception
        MessageBox.Show(e.Message)
        Return
    End Try
    LoadAssembly(asm)
End Sub

Private Sub ListInfo(ByVal itemCollection As ItemCollectionClass, ByVal a As Assembly)

    Dim item As ItemClass = itemCollection.Add("Custom Attributes")
    item.TagObjects = a.GetCustomAttributes(True)
    If item.TagObjects.Length > 0 Then
        item.ExpandCollapseButton = ExpandCollapseButtonStyleEnum.Show
    Else
        item.ExpandCollapseButton = ExpandCollapseButtonStyleEnum.Hide
    End If

    item = itemCollection.Add("Exported Types")
    item.TagObjects = a.GetExportedTypes()
    If item.TagObjects.Length > 0 Then
        item.ExpandCollapseButton = ExpandCollapseButtonStyleEnum.Show
    Else
        item.ExpandCollapseButton = ExpandCollapseButtonStyleEnum.Hide
    End If

    item = itemCollection.Add("Files")
    item.TagObjects = a.GetFiles()
    If item.TagObjects.Length > 0 Then
        item.ExpandCollapseButton = ExpandCollapseButtonStyleEnum.Show
    Else
        item.ExpandCollapseButton = ExpandCollapseButtonStyleEnum.Hide
    End If

    item = itemCollection.Add("Manifest Resource Names ")
    item.TagObjects = a.GetManifestResourceNames()
    If item.TagObjects.Length > 0 Then
        item.ExpandCollapseButton = ExpandCollapseButtonStyleEnum.Show
    Else
        item.ExpandCollapseButton = ExpandCollapseButtonStyleEnum.Hide
    End If

    item = itemCollection.Add("Properties")

    Dim props() As PropertyInfo = a.GetType().GetProperties(bFlags)
    For Each p As PropertyInfo In props
        Dim sval As String = ""
        Try
            Dim val As Object = p.GetValue(a, Nothing)
            If Not val Is Nothing Then
                sval = val.ToString()
            Else
                sval = "(null)"
            End If
        Catch
            sval = "(?)"
        End Try
        item.Add(New String() {p.Name, sval})
    Next
    item.Children.Sort()
End Sub

Private Sub ListInfo(ByVal itemCollection As ItemCollectionClass, ByVal o As Object)

    Dim tp As Type = o.GetType()

    Dim item As ItemClass = itemCollection.Add("Custom Attributes")
    item.TagObjects = tp.GetCustomAttributes(True)
    item.ExpandCollapseButton = ExpandCollapseButtonStyleEnum.Show

    item = itemCollection.Add("Events")
    item.TagObjects = tp.GetEvents(bFlags)
    If item.TagObjects.Length > 0 Then
        item.ExpandCollapseButton = ExpandCollapseButtonStyleEnum.Show
    Else
        item.ExpandCollapseButton = ExpandCollapseButtonStyleEnum.Hide
    End If

    item = itemCollection.Add("Fields")
    item.TagObjects = tp.GetFields(bFlags)
    If item.TagObjects.Length > 0 Then
        item.ExpandCollapseButton = ExpandCollapseButtonStyleEnum.Show
    Else
        item.ExpandCollapseButton = ExpandCollapseButtonStyleEnum.Hide
    End If

    item = itemCollection.Add("Interfaces")
    item.TagObjects = tp.GetInterfaces()
    If item.TagObjects.Length > 0 Then
        item.ExpandCollapseButton = ExpandCollapseButtonStyleEnum.Show
    Else
        item.ExpandCollapseButton = ExpandCollapseButtonStyleEnum.Hide
    End If

    item = itemCollection.Add("Members")
    item.TagObjects = tp.GetMembers(bFlags)
    If item.TagObjects.Length > 0 Then
        item.ExpandCollapseButton = ExpandCollapseButtonStyleEnum.Show
    Else
        item.ExpandCollapseButton = ExpandCollapseButtonStyleEnum.Hide
    End If

    item = itemCollection.Add("Methods")
    item.TagObjects = tp.GetMethods(bFlags)
    If item.TagObjects.Length > 0 Then
        item.ExpandCollapseButton = ExpandCollapseButtonStyleEnum.Show
    Else
        item.ExpandCollapseButton = ExpandCollapseButtonStyleEnum.Hide
    End If

    item = itemCollection.Add("Nested Types")
    item.TagObjects = tp.GetNestedTypes(bFlags)
    If item.TagObjects.Length > 0 Then
        item.ExpandCollapseButton = ExpandCollapseButtonStyleEnum.Show
    Else
        item.ExpandCollapseButton = ExpandCollapseButtonStyleEnum.Hide
    End If

    item = itemCollection.Add("Properties")
    Dim props() As PropertyInfo = tp.GetProperties(bFlags)
    For Each p As PropertyInfo In props
        Dim sval As String = ""
        Try
            Dim val As Object = p.GetValue(o, Nothing)
            If Not val Is Nothing Then
                sval = val.ToString()
            Else
                sval = "(null)"
            End If
        Catch
            sval = "(?)"
        End Try
        item.Add(New String() {p.Name, sval})
    Next
    item.Children.Sort()
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    sftTree1.Columns.Count = 2
    sftTree1.Headers.Reorderable = sftTree1.Footers.Reorderable = False
    sftTree1.Headers.MergeWithNextDefault = True
    sftTree1.Headers.AllowMergeFromPreviousDefault = True
    sftTree1.Columns(0).MergeWithNextDefault = True
    sftTree1.Columns(1).AllowMergeFromPreviousDefault = True
    sftTree1.MergeStyle = MergeStyleEnum.EmptyCells
    sftTree1.AutoRespond = False
    sftTree1.RowHeaders.Width = 0
    LoadAssembly(Assembly.GetExecutingAssembly())
End Sub

Private Sub ExpandCollapseItem(ByVal item As ItemClass)
    If item.Expanded Then
        item.Collapse(CollapseStyleEnum.SaveCurrent)
    Else
        If (item.HasChildren) Then
            item.Expand(ExpandStyleEnum.RestoreLast)
        Else
            sftTree1.Initializing = True
            If item.TagString = "Single" Then
                item._CreateChildren = True
                ListInfo(item.Children, item.TagObject)
            Else
                For Each o As Object In item.TagObjects
                    Dim newItem As ItemClass = item.Add(o.ToString())
                    newItem.TagObject = o
                    newItem.ExpandCollapseButton = ExpandCollapseButtonStyleEnum.Show
                    newItem.TagString = "Single"
                Next
            End If
            item.Children.Sort()
            item.ExpandCollapseButton = ExpandCollapseButtonStyleEnum.Conditional
            item.Expand(ExpandStyleEnum.DirectOnly)
            sftTree1.Initializing = False
        End If
    End If
    sftTree1.Columns.MakeOptimal(0, True)
    sftTree1.RecalcHorizontalExtent()
End Sub


Private Sub sftTree1_ItemClick(ByVal sender As Object, ByVal e As Softelvdm.SftTreeNET.ItemClickEventArgs) Handles sftTree1.ItemClick
    Debug.Write("ItemClick ")
    DumpValues(e)
    ' user clicks expand/collapse button
    If e.Area = ItemClickAreaEnum.ExpandCollapseButton And Not e.Item Is Nothing Then
        ExpandCollapseItem(e.Item)
    End If
End Sub

Private Sub sftTree1_ItemDoubleClick(ByVal sender As Object, ByVal e As Softelvdm.SftTreeNET.ItemClickEventArgs) Handles sftTree1.ItemDoubleClick
    Debug.Write("ItemDoubleClick ")
    DumpValues(e)
    ' user double clicks on an item
    If e.Area = ItemClickAreaEnum.CellSel And Not e.Item Is Nothing Then
        ExpandCollapseItem(e.Item)
    End If
End Sub

Private Sub sftTree1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles sftTree1.KeyDown
    If e.KeyCode = Keys.Right Then
        ' Right arrow normally expands a parent item. Our items don't (yet) have 
        ' child items, so we'll have to handle the right arrow keys. 
        Dim item As ItemClass = sftTree1.FocusItem
        If Not item Is Nothing Then
            If item.ExpandCollapseButton = ExpandCollapseButtonStyleEnum.Show Then
                ExpandCollapseItem(item)
                e.Handled = True
            End If
        End If
    End If
End Sub

' This is a small helper routine to show all properties and fields of an object
Private Sub DumpValues(ByVal o As Object)
    Dim api() As PropertyInfo = o.GetType().GetProperties()
    For Each pi As PropertyInfo In api
        Dim s As String
        On Error Resume Next
        pi.GetValue(o, New Object() {})
        Debug.Write(" " & pi.Name & " " & s)
    Next
    Dim afi() As FieldInfo = o.GetType().GetFields()
    For Each fi As FieldInfo In afi
        Dim t As Object = fi.GetValue(o)
        Dim s As String = "(null)"
        If Not t Is Nothing Then s = t.ToString()
        Debug.Write(" " & fi.Name & " " & s)
    Next
    Debug.WriteLine("")
End Sub

End Class