Click here to Skip to main content
14,828,731 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am trying to create a menu that creates new menu items for each Directory and files in a specific directory. Each menu item that are files will open the corresponding file. This will be similar to the Windows Start Menu.

What I have tried:

So far I have the following code:
Dim lst As New List(Of String), intIndex As Integer 
For Each tmp In GetDirectories("C:\", "*", IO.SearchOption.AllDirectories)
 If GetDirectories(tmp, "*", IO.SearchOption.AllDirectories).Count = 0 Then lst.Add(tmp.Substring(("C:\").Length)) 'Gets a list of all the directories that aren't parent directories and removes the root directory 
For Each itm In lst
 Dim tsi As ToolStripDropDownItem = MenuStrip1
 For Each folder In Split(itm, "\")
  intIndex = 0
  If tsi.DropDownItems.ContainsKey(folder) = False Then 'Checks if the menu already as a existing item for the directory from a previous run of loop
   tsi.DropDownItems.Add(folder) 'Adds menu item
   tsi.DropDownItems(intIndex).Name = folder 'Specify name of menu item
   If GetFiles(DrivePath & "WINDOWS\Start Menu\Programs\" & itm.Substring(0, itm.IndexOf(folder) + folder.Length)).Count > 0 Then 'If the directory has files in it then it will add them
    tsi = tsi.DropDownItems(intIndex) 'makes the menu item that was just created the menu item variable 
    For Each file In GetFiles(DrivePath & "WINDOWS\Start Menu\Programs\" & itm) 'Loops through
     Dim index As Integer = 0
     tsi.DropDownItems.Add(IO.Path.GetFileNameWithoutExtension(file)) 'Adds files to drop down of new menu item
     tsi.DropDownItems(index).Name = folder 'Specify name of menu item
     index += 1
   End If
   intIndex += 1
  End If

Indents modified to fit better in web browser.
I have not yet incorporated the event handler for each menu menu item that is a file, but I know how to do that, so I add that later.
Hopefully my code can be understood.
Updated 31-Dec-18 10:17am
Richard MacCutchan 27-Dec-18 6:40am
Why not use a TreeView control?
LeMS_Studios 27-Dec-18 11:04am
As far as I can tell, I could not use a TreeView for this. I am using this in a game I am making where its 1998 and you have windows 95 and you find time travel software and travel to different time periods with different operating systems. The original developer of the game had the Start Menu (in the fake Windows 95 environment) prebuilt, but I would like the Start Menu to be created by actual folders and shortcuts.
W.G.C. 30-Dec-18 16:45pm
What is not working about it?
LeMS_Studios 30-Dec-18 18:16pm
Currently Some Directories are being added multiple times, and all sub menus are subs of the first item of the parent menu. Here is a link to the image of the comparison:
The image on left is what it currently looks like, and on right is what a previous version of the game looked like.
Hope this helps!

1 solution

Option Explicit On
Option Strict On
Option Infer Off
Public Class frmDirectoryMenuTest
	' This assumes that there is a form with a MenuStrip named 
	' MenuStrip1 with a ToolStripMenuItem named tsmiRootItem
	Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
		Dim RootPath As String
		RootPath = "C:\"
		BuildMenuFromPathData(RootPath, tsmiRootItem)
	End Sub
	''' <summary>
	''' Builds a menu item tree from files and directories in a specified root path
	''' </summary>
	''' <param name="RootPath">The top-level path that the tree should start from</param>
	''' <param name="MenuParent">The ToolStripItem that the menu tree will be added to.  The text will also be set to the name if the directory.</param>
	''' <returns>True if no error occured, false otherwise.</returns>
	Private Function BuildMenuFromPathData(RootPath As String, MenuParent As ToolStripItem) As Boolean
		Dim DirList As List(Of String), Dir As String
		Dim SubDir As String, File As String
		Dim CurrentDirectoryMenuItem As ToolStripItem

			If RootPath.EndsWith(IO.Path.DirectorySeparatorChar) Then MenuParent.Text = IO.Path.GetFileName(RootPath.Remove(RootPath.Length - 1, 1)) Else MenuParent.Text = IO.Path.GetFileName(RootPath)
			DirList = ListDirs(RootPath)
			For Each Dir In DirList
				CurrentDirectoryMenuItem = CreateToolStripDropDownItem(IO.Path.GetFileName(Dir), MenuParent)
				For Each SubDir In ListDirs(Dir)
					BuildMenuFromPathData(SubDir, CreateToolStripDropDownItem(SubDir, CurrentDirectoryMenuItem))
				CreateToolStripDropDownItems(ListFiles(Dir), CurrentDirectoryMenuItem)
			CreateToolStripDropDownItems(ListFiles(RootPath), MenuParent)
			Return True
		Catch ex As Exception
			Return False
		End Try
	End Function
	''' <summary>
	''' Adds a new ToolStripMenuItem to the specified parent item
	''' </summary>
	''' <param name="Text">The new item's label text.</param>
	''' <param name="ParentItem">The parent item that the new item will be added to</param>
	''' <returns>The new item as a ToolStripItem</returns>
	Private Function CreateToolStripDropDownItem(Text As String, ParentItem As ToolStripItem) As ToolStripItem
		If ParentItem Is Nothing Then Return Nothing Else Return DirectCast(DirectCast(ParentItem, ToolStripMenuItem).DropDownItems.Add(Text), ToolStripItem)
	End Function
	''' <summary>
	''' Adds new ToolStripMenuItems to the specified parent item
	''' </summary>
	''' <param name="ItemTexts">A list of label texts for the new items</param>
	''' <param name="ParentItem">The parent item that the new item will be added to</param>
	''' <returns>The parent item</returns>
	Private Function CreateToolStripDropDownItems(ItemTexts As List(Of String), ParentItem As ToolStripItem) As ToolStripItem
		If ItemTexts Is Nothing OrElse ParentItem Is Nothing Then Return ParentItem
		For Each ItemText As String In ItemTexts
			DirectCast(ParentItem, ToolStripMenuItem).DropDownItems.Add(ItemText)
		Return ParentItem
	End Function
	''' <summary>
	''' Returns a list of directories in a directory.
	''' </summary>
	''' <param name="Path">Path to enumerate</param>
	''' <returns>A list of directory paths</returns>
	Private Function ListDirs(Path As String) As List(Of String) 'Dictionary(Of String, String)
		Dim DirList As New List(Of String) 'Dictionary(Of String, String)
		Dim Index As Integer
		Dim Dir As IO.DirectoryInfo, Dirs As IO.DirectoryInfo()
			Dir = New IO.DirectoryInfo(Path)
			Dirs = Dir.GetDirectories("*.*", IO.SearchOption.TopDirectoryOnly)
			For Index = 0 To Dirs.Length - 1
				'DirList.Add(Dirs(Index).FullName, IO.Path.GetFileName(Dirs(Index).FullName))
			Return DirList
		Catch ex As Exception
			Return Nothing
		End Try
	End Function
	''' <summary>
	''' Returns a list of files in a directory.
	''' </summary>
	''' <param name="Path">Path to enumerate</param>
	''' <returns>A list of file paths</returns>
	Private Function ListFiles(Path As String) As List(Of String)
		Dim FileList As New List(Of String)
		Dim File As IO.DirectoryInfo, Files As IO.FileInfo()
			File = New IO.DirectoryInfo(Path)
			Files = File.GetFiles("*.*", IO.SearchOption.TopDirectoryOnly)
			FileList.AddRange(Files.Select(Function(Info) Info.Name))
			Return FileList
		Catch ex As Exception
			Return Nothing
		End Try
	End Function
End Class

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900