Table of Contents

Flexcel object explorer (VB.Net / netframework)

Note

This demo is available in your FlexCel installation at <FlexCel Install Folder>\samples\vb\VS2022\netframework\10.API\35.Object Explorer and also at https:​//​github.​com/​tmssoftware/​TMS-​FlexCel.​NET-​demos/​tree/​master/​vb/​VS2022/​netframework/​Modules/​10.​API/​35.​Object Explorer

Overview

Shapes in an Excel file can be nested in complex ways. For example, you might have a "Group" shape that inside has a "Picture" shape and other "Group" shape with other pictures inside. You can access the whole hierarchy of objects with ExcelFile.GetObjectProperties but it can be hard to visualize. This application shows a tree view of all the objects in a sheet, and can be useful when trying to understand the structure of the objects in an xls file.

Concepts

  • How to use the API to read the objects and properties in a file.

  • How to use ExcelFile.RenderObject to visually render the object (as shown in the preview pane). Internally, RenderObject uses ExcelFile.GetObjectProperties in the same way as this application, and draws the properties into a .NET image.

  • Custom properties (The ones shown in the grid at the top) can hold integers, booleans, strings or other datatypes. You need to know of which type is the property you are trying to read. Since FlexCel does not know it, it will try to show it as a string or as an integer.

Files

AssemblyInfo.vb

Imports System.Reflection
Imports System.Runtime.CompilerServices

'
' General Information about an assembly is controlled through the following 
' set of attributes. Change these attribute values to modify the information
' associated with an assembly.
'
<Assembly: AssemblyTitle("")>
<Assembly: AssemblyDescription("")>
<Assembly: AssemblyConfiguration("")>
<Assembly: AssemblyCompany("")>
<Assembly: AssemblyProduct("")>
<Assembly: AssemblyCopyright("(c) 2002 - 2014 TMS Software")>
<Assembly: AssemblyTrademark("")>
<Assembly: AssemblyCulture("")>

'
' Version information for an assembly consists of the following four values:
'
'      Major Version
'      Minor Version 
'      Build Number
'      Revision
'
' You can specify all the values or you can default the Revision and Build Numbers 
' by using the '*' as shown below:

<Assembly: AssemblyVersion("6.2.1.0")>

'
' In order to sign your assembly you must specify a key to use. Refer to the 
' Microsoft .NET Framework documentation for more information on assembly signing.
'
' Use the attributes below to control which key is used for signing. 
'
' Notes: 
'   (*) If no key is specified, the assembly is not signed.
'   (*) KeyName refers to a key that has been installed in the Crypto Service
'       Provider (CSP) on your machine. KeyFile refers to a file which contains
'       a key.
'   (*) If the KeyFile and the KeyName values are both specified, the 
'       following processing occurs:
'       (1) If the KeyName can be found in the CSP, that key is used.
'       (2) If the KeyName does not exist and the KeyFile does exist, the key 
'           in the KeyFile is installed into the CSP and used.
'   (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
'       When specifying the KeyFile, the location of the KeyFile should be
'       relative to the project output directory which is
'       %Project Directory%\obj\<configuration>. For example, if your KeyFile is
'       located in the project directory, you would specify the AssemblyKeyFile 
'       attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
'   (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
'       documentation for more information on this.
'
<Assembly: AssemblyDelaySign(False)>
<Assembly: AssemblyKeyFile("")>
<Assembly: AssemblyKeyName("")>

MainForm.Designer.vb

Imports System.Collections
Imports System.ComponentModel
Imports System.IO
Imports FlexCel.Core
Imports FlexCel.XlsAdapter
Namespace ObjectExplorer
	Partial Public Class mainForm
		Inherits System.Windows.Forms.Form

		Private openFileDialog1 As System.Windows.Forms.OpenFileDialog
		Private panel1 As System.Windows.Forms.Panel
		Private splitter1 As System.Windows.Forms.Splitter
		Private panel3 As System.Windows.Forms.Panel
		Private dataGrid As System.Windows.Forms.DataGrid
		Private panel4 As System.Windows.Forms.Panel
		Private splitter2 As System.Windows.Forms.Splitter
		Private PreviewBox As System.Windows.Forms.PictureBox
		Private saveImageDialog As System.Windows.Forms.SaveFileDialog
		Private lblObjects As System.Windows.Forms.Label
		Private WithEvents ObjTree As System.Windows.Forms.TreeView
		Private panel5 As System.Windows.Forms.Panel
		Private lblObjName As System.Windows.Forms.Label
		Private lblObjText As System.Windows.Forms.Label
		Private panel6 As System.Windows.Forms.Panel
		Private label1 As System.Windows.Forms.Label
		Private WithEvents cbSheet As System.Windows.Forms.ComboBox
		Private components As System.ComponentModel.IContainer = Nothing

		''' <summary>
		''' Clean up any resources being used.
		''' </summary>
		Protected Overrides Sub Dispose(ByVal disposing As Boolean)
			If disposing Then
				If components IsNot Nothing Then
					components.Dispose()
				End If
			End If
			MyBase.Dispose(disposing)
		End Sub

		#Region "Windows Form Designer generated code"
		''' <summary>
		''' Required method for Designer support - do not modify
		''' the contents of this method with the code editor.
		''' </summary>
		Private Sub InitializeComponent()
			Dim resources As New System.ComponentModel.ComponentResourceManager(GetType(mainForm))
			Me.openFileDialog1 = New System.Windows.Forms.OpenFileDialog()
			Me.panel1 = New System.Windows.Forms.Panel()
			Me.ObjTree = New System.Windows.Forms.TreeView()
			Me.panel6 = New System.Windows.Forms.Panel()
			Me.cbSheet = New System.Windows.Forms.ComboBox()
			Me.label1 = New System.Windows.Forms.Label()
			Me.panel3 = New System.Windows.Forms.Panel()
			Me.lblObjects = New System.Windows.Forms.Label()
			Me.splitter1 = New System.Windows.Forms.Splitter()
			Me.dataGrid = New System.Windows.Forms.DataGrid()
			Me.panel4 = New System.Windows.Forms.Panel()
			Me.PreviewBox = New System.Windows.Forms.PictureBox()
			Me.splitter2 = New System.Windows.Forms.Splitter()
			Me.saveImageDialog = New System.Windows.Forms.SaveFileDialog()
			Me.panel5 = New System.Windows.Forms.Panel()
			Me.lblObjText = New System.Windows.Forms.Label()
			Me.lblObjName = New System.Windows.Forms.Label()
			Me.mainToolbar = New System.Windows.Forms.ToolStrip()
			Me.btnOpenFile = New System.Windows.Forms.ToolStripButton()
			Me.toolStripSeparator1 = New System.Windows.Forms.ToolStripSeparator()
			Me.btnShowInExcel = New System.Windows.Forms.ToolStripButton()
			Me.btnSaveAsImage = New System.Windows.Forms.ToolStripButton()
			Me.btnExit = New System.Windows.Forms.ToolStripButton()
			Me.btnInfo = New System.Windows.Forms.ToolStripButton()
			Me.toolStripSeparator2 = New System.Windows.Forms.ToolStripSeparator()
			Me.btnStretchPreview = New System.Windows.Forms.ToolStripButton()
			Me.panel1.SuspendLayout()
			Me.panel6.SuspendLayout()
			Me.panel3.SuspendLayout()
			CType(Me.dataGrid, System.ComponentModel.ISupportInitialize).BeginInit()
			Me.panel4.SuspendLayout()
			CType(Me.PreviewBox, System.ComponentModel.ISupportInitialize).BeginInit()
			Me.panel5.SuspendLayout()
			Me.mainToolbar.SuspendLayout()
			Me.SuspendLayout()
			' 
			' openFileDialog1
			' 
			Me.openFileDialog1.DefaultExt = "xls"
			Me.openFileDialog1.Filter = "Excel Files|*.xls;*.xlsx;*.xlsm|Excel 97/2003|*.xls|Excel 2007|*.xlsx;*.xlsm|All " & "files|*.*"
			Me.openFileDialog1.Title = "Open an Excel File"
			' 
			' panel1
			' 
			Me.panel1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D
			Me.panel1.Controls.Add(Me.ObjTree)
			Me.panel1.Controls.Add(Me.panel6)
			Me.panel1.Controls.Add(Me.panel3)
			Me.panel1.Dock = System.Windows.Forms.DockStyle.Left
			Me.panel1.Location = New System.Drawing.Point(0, 38)
			Me.panel1.Name = "panel1"
			Me.panel1.Size = New System.Drawing.Size(176, 472)
			Me.panel1.TabIndex = 4
			' 
			' ObjTree
			' 
			Me.ObjTree.Dock = System.Windows.Forms.DockStyle.Fill
			Me.ObjTree.HideSelection = False
			Me.ObjTree.Location = New System.Drawing.Point(0, 112)
			Me.ObjTree.Name = "ObjTree"
			Me.ObjTree.Size = New System.Drawing.Size(172, 356)
			Me.ObjTree.TabIndex = 1
'			Me.ObjTree.AfterSelect += New System.Windows.Forms.TreeViewEventHandler(Me.ObjTree_AfterSelect)
			' 
			' panel6
			' 
			Me.panel6.BackColor = System.Drawing.Color.DarkSeaGreen
			Me.panel6.Controls.Add(Me.cbSheet)
			Me.panel6.Controls.Add(Me.label1)
			Me.panel6.Dock = System.Windows.Forms.DockStyle.Top
			Me.panel6.Location = New System.Drawing.Point(0, 64)
			Me.panel6.Name = "panel6"
			Me.panel6.Size = New System.Drawing.Size(172, 48)
			Me.panel6.TabIndex = 2
			' 
			' cbSheet
			' 
			Me.cbSheet.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
			Me.cbSheet.Location = New System.Drawing.Point(6, 16)
			Me.cbSheet.Name = "cbSheet"
			Me.cbSheet.Size = New System.Drawing.Size(160, 21)
			Me.cbSheet.TabIndex = 33
'			Me.cbSheet.SelectedIndexChanged += New System.EventHandler(Me.cbSheet_SelectedIndexChanged)
			' 
			' label1
			' 
			Me.label1.BackColor = System.Drawing.Color.LightGoldenrodYellow
			Me.label1.Dock = System.Windows.Forms.DockStyle.Fill
			Me.label1.ForeColor = System.Drawing.Color.Black
			Me.label1.Location = New System.Drawing.Point(0, 0)
			Me.label1.Name = "label1"
			Me.label1.Size = New System.Drawing.Size(172, 48)
			Me.label1.TabIndex = 1
			Me.label1.Text = "Sheet:"
			' 
			' panel3
			' 
			Me.panel3.BackColor = System.Drawing.Color.DarkSeaGreen
			Me.panel3.Controls.Add(Me.lblObjects)
			Me.panel3.Dock = System.Windows.Forms.DockStyle.Top
			Me.panel3.Location = New System.Drawing.Point(0, 0)
			Me.panel3.Name = "panel3"
			Me.panel3.Size = New System.Drawing.Size(172, 64)
			Me.panel3.TabIndex = 0
			' 
			' lblObjects
			' 
			Me.lblObjects.BackColor = System.Drawing.Color.LightGoldenrodYellow
			Me.lblObjects.Dock = System.Windows.Forms.DockStyle.Fill
			Me.lblObjects.ForeColor = System.Drawing.Color.Black
			Me.lblObjects.Location = New System.Drawing.Point(0, 0)
			Me.lblObjects.Name = "lblObjects"
			Me.lblObjects.Size = New System.Drawing.Size(172, 64)
			Me.lblObjects.TabIndex = 1
			Me.lblObjects.Text = "File:"
			' 
			' splitter1
			' 
			Me.splitter1.Location = New System.Drawing.Point(176, 91)
			Me.splitter1.Name = "splitter1"
			Me.splitter1.Size = New System.Drawing.Size(3, 419)
			Me.splitter1.TabIndex = 5
			Me.splitter1.TabStop = False
			' 
			' dataGrid
			' 
			Me.dataGrid.CaptionText = "Object Properties"
			Me.dataGrid.DataMember = ""
			Me.dataGrid.Dock = System.Windows.Forms.DockStyle.Top
			Me.dataGrid.HeaderForeColor = System.Drawing.SystemColors.ControlText
			Me.dataGrid.Location = New System.Drawing.Point(179, 91)
			Me.dataGrid.Name = "dataGrid"
			Me.dataGrid.PreferredColumnWidth = 120
			Me.dataGrid.ReadOnly = True
			Me.dataGrid.Size = New System.Drawing.Size(557, 213)
			Me.dataGrid.TabIndex = 7
			' 
			' panel4
			' 
			Me.panel4.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D
			Me.panel4.Controls.Add(Me.PreviewBox)
			Me.panel4.Dock = System.Windows.Forms.DockStyle.Fill
			Me.panel4.Location = New System.Drawing.Point(179, 307)
			Me.panel4.Name = "panel4"
			Me.panel4.Size = New System.Drawing.Size(557, 203)
			Me.panel4.TabIndex = 8
			' 
			' PreviewBox
			' 
			Me.PreviewBox.Dock = System.Windows.Forms.DockStyle.Fill
			Me.PreviewBox.Location = New System.Drawing.Point(0, 0)
			Me.PreviewBox.Name = "PreviewBox"
			Me.PreviewBox.Size = New System.Drawing.Size(553, 199)
			Me.PreviewBox.TabIndex = 0
			Me.PreviewBox.TabStop = False
			' 
			' splitter2
			' 
			Me.splitter2.Dock = System.Windows.Forms.DockStyle.Top
			Me.splitter2.Location = New System.Drawing.Point(179, 304)
			Me.splitter2.Name = "splitter2"
			Me.splitter2.Size = New System.Drawing.Size(557, 3)
			Me.splitter2.TabIndex = 9
			Me.splitter2.TabStop = False
			' 
			' saveImageDialog
			' 
			Me.saveImageDialog.DefaultExt = "png"
			Me.saveImageDialog.Filter = "PNG Files|*.png"
			' 
			' panel5
			' 
			Me.panel5.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
			Me.panel5.Controls.Add(Me.lblObjText)
			Me.panel5.Controls.Add(Me.lblObjName)
			Me.panel5.Dock = System.Windows.Forms.DockStyle.Top
			Me.panel5.Location = New System.Drawing.Point(176, 38)
			Me.panel5.Name = "panel5"
			Me.panel5.Size = New System.Drawing.Size(560, 53)
			Me.panel5.TabIndex = 10
			' 
			' lblObjText
			' 
			Me.lblObjText.AutoSize = True
			Me.lblObjText.Location = New System.Drawing.Point(16, 32)
			Me.lblObjText.Name = "lblObjText"
			Me.lblObjText.Size = New System.Drawing.Size(31, 13)
			Me.lblObjText.TabIndex = 1
			Me.lblObjText.Text = "Text:"
			' 
			' lblObjName
			' 
			Me.lblObjName.AutoSize = True
			Me.lblObjName.Location = New System.Drawing.Point(16, 8)
			Me.lblObjName.Name = "lblObjName"
			Me.lblObjName.Size = New System.Drawing.Size(38, 13)
			Me.lblObjName.TabIndex = 0
			Me.lblObjName.Text = "Name:"
			' 
			' mainToolbar
			' 
			Me.mainToolbar.Items.AddRange(New System.Windows.Forms.ToolStripItem() { Me.btnOpenFile, Me.toolStripSeparator1, Me.btnShowInExcel, Me.btnSaveAsImage, Me.btnExit, Me.btnInfo, Me.toolStripSeparator2, Me.btnStretchPreview})
			Me.mainToolbar.Location = New System.Drawing.Point(0, 0)
			Me.mainToolbar.Name = "mainToolbar"
			Me.mainToolbar.Size = New System.Drawing.Size(736, 38)
			Me.mainToolbar.TabIndex = 11
			Me.mainToolbar.Text = "toolStrip1"
			' 
			' btnOpenFile
			' 
			Me.btnOpenFile.Image = (CType(resources.GetObject("btnOpenFile.Image"), System.Drawing.Image))
			Me.btnOpenFile.ImageTransparentColor = System.Drawing.Color.Magenta
			Me.btnOpenFile.Name = "btnOpenFile"
			Me.btnOpenFile.Size = New System.Drawing.Size(59, 35)
			Me.btnOpenFile.Text = "Open file"
			Me.btnOpenFile.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText
'			Me.btnOpenFile.Click += New System.EventHandler(Me.btnOpenFile_Click)
			' 
			' toolStripSeparator1
			' 
			Me.toolStripSeparator1.Name = "toolStripSeparator1"
			Me.toolStripSeparator1.Size = New System.Drawing.Size(6, 38)
			' 
			' btnShowInExcel
			' 
			Me.btnShowInExcel.Image = (CType(resources.GetObject("btnShowInExcel.Image"), System.Drawing.Image))
			Me.btnShowInExcel.ImageTransparentColor = System.Drawing.Color.Magenta
			Me.btnShowInExcel.Name = "btnShowInExcel"
			Me.btnShowInExcel.Size = New System.Drawing.Size(82, 35)
			Me.btnShowInExcel.Text = "Show in Excel"
			Me.btnShowInExcel.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText
'			Me.btnShowInExcel.Click += New System.EventHandler(Me.btnOpen_Click)
			' 
			' btnSaveAsImage
			' 
			Me.btnSaveAsImage.Image = (CType(resources.GetObject("btnSaveAsImage.Image"), System.Drawing.Image))
			Me.btnSaveAsImage.ImageTransparentColor = System.Drawing.Color.Magenta
			Me.btnSaveAsImage.Name = "btnSaveAsImage"
			Me.btnSaveAsImage.Size = New System.Drawing.Size(85, 35)
			Me.btnSaveAsImage.Text = "Save as image"
			Me.btnSaveAsImage.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText
'			Me.btnSaveAsImage.Click += New System.EventHandler(Me.btnSaveImage_Click)
			' 
			' btnExit
			' 
			Me.btnExit.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right
			Me.btnExit.Image = (CType(resources.GetObject("btnExit.Image"), System.Drawing.Image))
			Me.btnExit.ImageTransparentColor = System.Drawing.Color.Magenta
			Me.btnExit.Name = "btnExit"
			Me.btnExit.Size = New System.Drawing.Size(59, 35)
			Me.btnExit.Text = "     E&xit     "
			Me.btnExit.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText
'			Me.btnExit.Click += New System.EventHandler(Me.btnExit_Click)
			' 
			' btnInfo
			' 
			Me.btnInfo.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right
			Me.btnInfo.Image = (CType(resources.GetObject("btnInfo.Image"), System.Drawing.Image))
			Me.btnInfo.ImageTransparentColor = System.Drawing.Color.Magenta
			Me.btnInfo.Name = "btnInfo"
			Me.btnInfo.Size = New System.Drawing.Size(74, 35)
			Me.btnInfo.Text = "Information"
			Me.btnInfo.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText
'			Me.btnInfo.Click += New System.EventHandler(Me.btnInfo_Click)
			' 
			' toolStripSeparator2
			' 
			Me.toolStripSeparator2.Name = "toolStripSeparator2"
			Me.toolStripSeparator2.Size = New System.Drawing.Size(6, 38)
			' 
			' btnStretchPreview
			' 
			Me.btnStretchPreview.CheckOnClick = True
			Me.btnStretchPreview.Image = (CType(resources.GetObject("btnStretchPreview.Image"), System.Drawing.Image))
			Me.btnStretchPreview.ImageTransparentColor = System.Drawing.Color.Magenta
			Me.btnStretchPreview.Name = "btnStretchPreview"
			Me.btnStretchPreview.Size = New System.Drawing.Size(92, 35)
			Me.btnStretchPreview.Text = "Stretch preview"
			Me.btnStretchPreview.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText
'			Me.btnStretchPreview.Click += New System.EventHandler(Me.btnStretchPreview_Click)
			' 
			' mainForm
			' 
			Me.AutoScaleDimensions = New System.Drawing.SizeF(6F, 13F)
			Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
			Me.ClientSize = New System.Drawing.Size(736, 510)
			Me.Controls.Add(Me.panel4)
			Me.Controls.Add(Me.splitter2)
			Me.Controls.Add(Me.dataGrid)
			Me.Controls.Add(Me.splitter1)
			Me.Controls.Add(Me.panel5)
			Me.Controls.Add(Me.panel1)
			Me.Controls.Add(Me.mainToolbar)
			Me.Name = "mainForm"
			Me.Text = "FlexCel Object Explorer"
			Me.WindowState = System.Windows.Forms.FormWindowState.Maximized
			Me.panel1.ResumeLayout(False)
			Me.panel6.ResumeLayout(False)
			Me.panel3.ResumeLayout(False)
			CType(Me.dataGrid, System.ComponentModel.ISupportInitialize).EndInit()
			Me.panel4.ResumeLayout(False)
			CType(Me.PreviewBox, System.ComponentModel.ISupportInitialize).EndInit()
			Me.panel5.ResumeLayout(False)
			Me.panel5.PerformLayout()
			Me.mainToolbar.ResumeLayout(False)
			Me.mainToolbar.PerformLayout()
			Me.ResumeLayout(False)
			Me.PerformLayout()

		End Sub
		#End Region

		Private mainToolbar As ToolStrip
		Private WithEvents btnOpenFile As ToolStripButton
		Private toolStripSeparator1 As ToolStripSeparator
		Private WithEvents btnShowInExcel As ToolStripButton
		Private WithEvents btnExit As ToolStripButton
		Private WithEvents btnSaveAsImage As ToolStripButton
		Private WithEvents btnInfo As ToolStripButton
		Private toolStripSeparator2 As ToolStripSeparator
		Private WithEvents btnStretchPreview As ToolStripButton


	End Class
End Namespace


MainForm.vb

Imports System.Collections
Imports System.ComponentModel
Imports System.IO

Imports FlexCel.Core
Imports FlexCel.XlsAdapter

Namespace ObjectExplorer
	''' <summary>
	''' Object explorer.
	''' </summary>
	Partial Public Class mainForm
		Inherits System.Windows.Forms.Form

		Public Sub New()
			InitializeComponent()
			ResizeToolbar(mainToolbar)
		End Sub

		Private Sub ResizeToolbar(ByVal toolbar As ToolStrip)

			Using gr As Graphics = CreateGraphics()
				Dim xFactor As Double = gr.DpiX / 96.0
				Dim yFactor As Double = gr.DpiY / 96.0
				toolbar.ImageScalingSize = New Size(CInt(Fix(24 * xFactor)), CInt(Fix(24 * yFactor)))
				toolbar.Width = 0 'force a recalc of the buttons.
			End Using
		End Sub


		#Region "Global variables"
		Private Xls As XlsFile
		#End Region

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

		Private Sub btnOpenFile_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnOpenFile.Click
			If openFileDialog1.ShowDialog() <> System.Windows.Forms.DialogResult.OK Then
				Return
			End If

			Xls = New XlsFile()
			Xls.Open(openFileDialog1.FileName)


			cbSheet.Items.Clear()
			Dim ActSheet As Integer = Xls.ActiveSheet
			For i As Integer = 1 To Xls.SheetCount
				Xls.ActiveSheet = i
				cbSheet.Items.Add(Xls.SheetName)
			Next i
			Xls.ActiveSheet = ActSheet
			cbSheet.SelectedIndex = ActSheet - 1

			FillListBox()
		End Sub

		Private Sub FillListBox()
			lblObjects.Text = openFileDialog1.FileName
			dataGrid.DataSource = Nothing

			ObjTree.BeginUpdate()
			Try
				ObjTree.Nodes.Clear()

				For i As Integer = 1 To Xls.ObjectCount
					Dim ShapeProps As TShapeProperties = Xls.GetObjectProperties(i, True)
					Dim s As String = "Object " & i.ToString()
					If ShapeProps.ShapeName IsNot Nothing Then
						s = ShapeProps.ShapeName
					End If

					Dim RootNode As New TreeNode(s)
					FillNodes(ShapeProps, RootNode)


					ObjTree.Nodes.Add(RootNode)
				Next i
			Finally
				ObjTree.EndUpdate()
			End Try
		End Sub

		Private Sub FillNodes(ByVal ShapeProps As TShapeProperties, ByVal Node As TreeNode)
			Node.Tag = ShapeProps 'In this simple demo we will use the tag property to store the Shape properties. This is not indented for 'real' use.


			For i As Integer = 1 To ShapeProps.ChildrenCount
				Dim ChildProps As TShapeProperties = ShapeProps.Children(i)
				Dim ShapeName As String = ChildProps.ShapeName
				If ShapeName Is Nothing Then
					ShapeName = "Object " & i.ToString()
				End If
				Dim Child As New TreeNode(ShapeName)
				FillNodes(ChildProps, Child)
				Node.Nodes.Add(Child)
			Next i
		End Sub

		Private Sub btnOpen_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnShowInExcel.Click
			If Xls Is Nothing Then
				MessageBox.Show("There is no open file")
				Return
			End If
			System.Diagnostics.Process.Start(Xls.ActiveFileName)
		End Sub


		Private Sub btnSaveImage_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSaveAsImage.Click
			If PreviewBox.Image Is Nothing Then
				MessageBox.Show("There is no selected image to save", "Error")
				Return
			End If
			If saveImageDialog.ShowDialog() <> System.Windows.Forms.DialogResult.OK Then
				Return
			End If

			PreviewBox.Image.Save(saveImageDialog.FileName)
		End Sub

		Private Sub btnInfo_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnInfo.Click
			MessageBox.Show("Object Explorer allows to explore inside the objects in an Excel file." & vbLf & "Objects in xls files are hierachily distributed, you can have two objects grouped as a third object, " & "and this hierarchy is shown in the 'Objects' pane at the left. The properties for the selected object are displayed at the 'Object properties' pane.")
		End Sub

		Private Sub ObjTree_AfterSelect(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles ObjTree.AfterSelect
			RenderNode(e.Node)
			FillProperties(e.Node)
		End Sub


		Private Sub RenderNode(ByVal Node As TreeNode)
			If Xls Is Nothing Then
				PreviewBox.Image = Nothing
				Return
			End If

			Dim t As TreeNode = Node
			If t Is Nothing Then
				PreviewBox.Image = Nothing
				Return
			End If

			Do While t.Parent IsNot Nothing 'Only root level objects will be rendered.
				t = t.Parent
			Loop

			If t.Index + 1 > Xls.ObjectCount Then
				PreviewBox.Image = Nothing
				Return
			End If

			PreviewBox.Image = Xls.RenderObject(t.Index + 1)


		End Sub

		Private Sub FillProperties(ByVal Node As TreeNode)
			lblObjName.Text = "Name:"
			lblObjText.Text = "Text:"
			Dim Props As TShapeProperties = CType(Node.Tag, TShapeProperties)
			If Props Is Nothing Then
				dataGrid.DataSource = Nothing
				Return
			End If

			Dim ShapeOptions As TShapeOptionList = (TryCast(Node.Tag, TShapeProperties)).ShapeOptions
			If ShapeOptions Is Nothing Then
				dataGrid.DataSource = Nothing
				Return
			End If

			lblObjName.Text = "Name: " & Props.ShapeName
			lblObjText.Text = "Text: " & Convert.ToString(Props.Text)

			Dim ShapeOpts As New ArrayList()
			For Each opt As KeyValuePair(Of TShapeOption, Object) In ShapeOptions
				ShapeOpts.Add(New KeyValue(opt.Key, ShapeOptions))
			Next opt
			dataGrid.DataSource = ShapeOpts
		End Sub

		Private Sub cbSheet_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles cbSheet.SelectedIndexChanged
			Xls.ActiveSheet = cbSheet.SelectedIndex + 1
			FillListBox()
		End Sub

		Private Sub btnStretchPreview_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnStretchPreview.Click
			If btnStretchPreview.Checked Then
				PreviewBox.SizeMode = PictureBoxSizeMode.StretchImage
			Else
				PreviewBox.SizeMode = PictureBoxSizeMode.Normal
			End If

		End Sub

	End Class

	Friend Class KeyValue
		Private FKey As String
		Private FAs1616 As String
		Private FAsLong As String
		Private FAsString As String

		Public Sub New(ByVal aKey As TShapeOption, ByVal List As TShapeOptionList)
			FKey = Convert.ToString(aKey)
			FAs1616 = Convert.ToString(List.As1616(aKey, 0))
			FAsLong = Convert.ToString(List.AsLong(aKey, 0))
			FAsString = List.AsUnicodeString(aKey, "")
		End Sub

		Public Property Key() As String
			Get
				Return FKey
			End Get
			Set(ByVal value As String)
				FKey = value
			End Set
		End Property
		Public Property As1616() As String
			Get
				Return FAs1616
			End Get
			Set(ByVal value As String)
				FAs1616 = value
			End Set
		End Property
		Public Property AsLong() As String
			Get
				Return FAsLong
			End Get
			Set(ByVal value As String)
				FAsLong = value
			End Set
		End Property
		Public Property AsString() As String
			Get
				Return FAsString
			End Get
			Set(ByVal value As String)
				FAsString = value
			End Set
		End Property

		Public Overrides Function ToString() As String
			Return Key
		End Function

	End Class
End Namespace

Program.vb

Namespace ObjectExplorer
	Friend NotInheritable Class Program

		Private Sub New()
		End Sub

		''' <summary>
		''' The main entry point for the application.
		''' </summary>
		<STAThread> _
		Shared Sub Main()
			Application.EnableVisualStyles()
			Application.SetCompatibleTextRenderingDefault(False)
			Application.Run(New mainForm())
		End Sub
	End Class
End Namespace