Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Folder Menu Function


  • Please log in to reply
10 replies to this topic
savage
  • Members
  • 207 posts
  • Last active: Jul 03 2008 03:12 AM
  • Joined: 02 Jul 2004
This here's a function for building menus from paths. I know there's a script on the forum already, but this works better as a function.

FolderMenu(path, menu)
{   
    global
    local f_FolderList, nextmenu, f_FileList, f_LenFileName, f_MenuItemName, varname, MenuName
    If menu =
	MenuName := String2Hex(path)
    else
	MenuName := menu
    Loop, %path%\*, 2
	f_FolderList = %f_FolderList%`n%A_LoopFileFullPath%
    Sort, f_FolderList
    Loop, parse, f_FolderList, `n
    {
	If A_LoopField =
	    continue
	f_MenuItemName := FileShortName(A_LoopField)
	nextmenu := FolderMenu(A_LoopField,"")
	varname := MenuName . "path" . String2Hex(f_MenuItemName)
	%varname% = %A_LoopField%
	Menu, %MenuName%, add, %f_MenuItemName%, :%nextmenu%
    }
    Loop, %path%\*, 0
	f_FileList = %f_FileList%`n%A_LoopFileFullPath%
    Sort, f_FileList
    Loop, parse, f_FileList, `n
    {
	If A_LoopField =
	    continue
	f_MenuItemName := FileShortName(A_LoopField)
	varname := MenuName . "path" . String2Hex(f_MenuItemName)
	%varname% = %A_LoopField%
	Menu, %MenuName%, add, %f_MenuItemName%, FolderMenuHandler
    }
    return MenuName
}

FolderMenuHandler:
    If menu_RButton = true
    {
	Msgbox, Right Click
	menu_RButton = false
    }
    varname := A_ThisMenu . "path" . String2Hex(A_ThisMenuItem)
    cmd := %varname%
    If cmd = 
	return
    else
	Run, %cmd%
return

FileShortName(path)
{
    StringSplit, tokens, path, \/
    last := tokens%tokens0%
    StringSplit, half, last, .
    If half1 =
	return last
    else
	return half1
}

String2Hex(x)                 ; Convert a string to a huge hex number starting with X
{
   StringLen Len, x
   format = %A_FormatInteger%
   SetFormat Integer, H
   hex = X
   Loop %Len%
   {
      Transform y, ASC, %x%   ; ASCII code of 1st char, 15 < y < 256
      StringTrimLeft y, y, 2  ; Remove leading 0x
      hex = %hex%%y%
      StringTrimLeft x, x, 1  ; Remove 1st char
   }
   SetFormat Integer, %format%
   Return hex
}

I snagged the hex function from the list library by Laszlo Hars.

This function makes it really easy to insert paths onto your existing menus.
It recurses all subdirectories as well.
The first parameter is the path to build the menu from.
The second parameter can be the name of a menu to add the contents of the path to. This parameter can be blank, in which case the function generates a name. In all cases the function returns the menu name it used.

Here's an example of how to use it:

FolderMenu("C:\command\shortcuts\programs","TopMenu")
Menu, TopMenu, add, Opus, menu_opus
name := FolderMenu("C:\command\docs","")
Menu, TopMenu, add, Docs, :%name%

This produces a menu that looks like this:
Games >
Media >
Net >
Prog > 
Tools >
Opus
Docs >

As you can see, the contents of the program directory (all folders) are added right on the menu, followed by a normal menu item, followed by the contents of the docs directory in a submenu. Very simple to use, yes? Selecting one of the items on the file menus will run it.

I'm currently trying to make right click open the context menu, but I'm not even going to bother with the c code I need for that until I get the right click part working, and I'm not sure ahk can manage it right now.

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Thanks for posting it. It's good to have a self-contained menu-builder ready to plug in to existing scripts.

I'm currently trying to make right click open the context menu, but I'm not even going to bother with the c code I need for that until I get the right click part working, and I'm not sure ahk can manage it right now.

Some improvements for GUI context menus are planned for the future. It will probably be either built-in context menus or the ability to define a GuiClick subroutine that catches all clicks done inside the GUI window.

savage
  • Members
  • 207 posts
  • Last active: Jul 03 2008 03:12 AM
  • Joined: 02 Jul 2004
By context menu, I meant the explorer context menu for the file. I've got some code for showing it I pulled from a litestep module. It seems to be totally self contained and independent code, so it should be a simple matter to throw into a dll.

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
That sounds great. I've often wanted a better, faster Search Companion window that still has the full Explorer context menu.

Atomhrt
  • Members
  • 124 posts
  • Last active: Nov 13 2006 09:18 PM
  • Joined: 02 Sep 2004
Thanks very much for this savage! It was easy for me to replace my popup-menu script with your better functions.

Here is my script with my minor addition of file extensions filtering. This script will pop-up a menu where ever the mouse cursor is. Note that I use XButton2 to popup the menu in this example, but for a regular mouse, I would use LAlt & RButton::.

; List only files with these extensions
myext = .lnk,.exe,.ahk,.cmd,.bat

; Use some other tray icon for this
;Menu, Tray, Icon, %A_WinDir%\system32\Shell32.dll, 174

; Folders with or without sub-directories containing programs
FolderMenu("C:\toolbar\tlb\tbars\QL","tray")
name := FolderMenu("C:\cmdfiles\pstools","")
Menu, tray, add, Pstools, :%name% 
return

XButton2::
menu, tray, show
return

FolderMenu(path, menu)
{   
    global
    local f_FolderList, nextmenu, f_FileList, f_LenFileName, f_MenuItemName, varname, MenuName
    If menu =
       MenuName := String2Hex(path)
    else
       MenuName := menu

    Loop, %path%\*, 2
       f_FolderList = %f_FolderList%`n%A_LoopFileFullPath%
    Sort, f_FolderList
    Loop, parse, f_FolderList, `n
    {
        If A_LoopField =
           continue
        f_MenuItemName := FileShortName(A_LoopField)
        nextmenu := FolderMenu(A_LoopField,"")
        varname := MenuName . "path" . String2Hex(f_MenuItemName)
        %varname% = %A_LoopField%
        Menu, %MenuName%, add, %f_MenuItemName%, :%nextmenu%
    }
    Loop, %path%\*, 0
       f_FileList = %f_FileList%`n%A_LoopFileFullPath%
    
    Sort, f_FileList
    Loop, parse, f_FileList, `n
    {
       If A_LoopField =
          continue
       
       Filename=%A_LoopField%

       If Filename contains %myext%
       {

          f_MenuItemName := FileShortName(A_LoopField)
          varname := MenuName . "path" . String2Hex(f_MenuItemName)
          %varname% = %A_LoopField%
          Menu, %MenuName%, add, %f_MenuItemName%, FolderMenuHandler
       }
    }
    return MenuName
}

FolderMenuHandler:
    If menu_RButton = true
    {
       Msgbox, Right Click
       menu_RButton = false
    }
    
    varname := A_ThisMenu . "path" . String2Hex(A_ThisMenuItem)
    cmd := %varname%
    If cmd =
       return
    else
       Run, %cmd%
return

FileShortName(path)
{
    StringSplit, tokens, path, \/
    last := tokens%tokens0%
    StringSplit, half, last, .
    If half1 =
       return last
    else
       return half1
}

String2Hex(x)                 ; Convert a string to a huge hex number starting with X
{
   StringLen Len, x
   format = %A_FormatInteger%
   SetFormat Integer, H
   hex = X
   Loop %Len%
   {
      Transform y, ASC, %x%   ; ASCII code of 1st char, 15 < y < 256
      StringTrimLeft y, y, 2  ; Remove leading 0x
      hex = %hex%%y%
      StringTrimLeft x, x, 1  ; Remove 1st char
   }
   SetFormat Integer, %format%
   Return hex
} 


I am he of whom he speaks!

infinisri
  • Guests
  • Last active:
  • Joined: --
I am learning ahk by studying some of your scripts. I hope you don't mind my asking a question.

What is purpose of converting string to hex in your scripts for foldermenu?

Thanks, Sri

Rajat
  • Members
  • 1904 posts
  • Last active: Jul 17 2015 07:45 AM
  • Joined: 28 Mar 2004
its probably used to turn all special characters into 0-9-A-F... so that they don't error -out the script. i've used that in some scripts so i know this is a good idea.

MIA

CleanNews.in : Bite sized latest news headlines from India with zero bloat


robiandi
  • Guests
  • Last active:
  • Joined: --
I take the script of Atomhrt Sat May 28, 2005 5:38 pm and as auto-exec part:
FolderMenu("C:\","tray")
name := FolderMenu("C:\tmp","")
Menu, tray, add, tmp, :%name%
return
This gives

Error: Submenu does not exist. The current thread will exit.

Am I doing something wrong? Where is my mistake?
AHK 1.0.44.04

Thracx
  • Members
  • 14 posts
  • Last active: Jul 08 2011 10:29 PM
  • Joined: 12 Mar 2007
Thanks for the work savage! I look forward to future updates to this AHK script.

I've been using ShortPopUp for some time now. It's an awesome little app, but it's no longer being maintained. I've been trying remove the need for having tons of small apps by figuring out how to use AutoHotKey for everything. I'm close to achieving this, but ShortPopUp continues to find uses.

Perhaps you could take a look at how it operates, in the very least to get feature/enhancement ideas for your AHK script.
-Thracx

"Man wants to know, and when he ceases to do so, he is no longer a man."
-Fridtjof Nansen

  • Guests
  • Last active:
  • Joined: --
Wow! ShortPopUp is very good!

It will be great if we can make an AHK script with same functionallity.

Thracx
  • Members
  • 14 posts
  • Last active: Jul 08 2011 10:29 PM
  • Joined: 12 Mar 2007

It will be great if we can make an AHK script with same functionallity.


That's what I'm saying! Hopefully our posts will encourage more work being put into the FolderMenu script!
-Thracx

"Man wants to know, and when he ceases to do so, he is no longer a man."
-Fridtjof Nansen