Xplorer2Hack: Menu++ Customizable menu for Xplorer2

A collection of especially useful xplorer² topics and ideas. New users may find it helpful to look here before searching the other forums for information. >>>>>> Please post new material in the relevant forum. (New stuff posted here will be removed.) Thanks. -fg-

Moderators: fgagnon, nikos

gerald
Member
Member
Posts: 19
Joined: 2005 Jun 28, 11:30
Location: Germany

Menu++ not running properly anymore

Post by gerald »

I have used Menu++ without any problems on a Windows XP 32-bit machine for years. Now I have moved to Windows 7 Professional 64-bit and encounter irregularly, not reproducible errors:
1.The selected menu item/action is not executed, instead the xplorer2 window would close itself.
2.One of the actions out of the list of available actions is executed but not the selected one.
3.The displayed list of actions cannot be closed via the escape sequence, but only via configure and then close.
I am still running an older xplorer2 version (1.8.1.1 [Unicode] 22.12.2010, 32-bit). Any chances that my problems are related to this fact?
Does anyone have any suggestions how to proceed? I am using Menu++ heavily to run batch templates and compiled executable from batch templates (see my postings from several years ago).
User avatar
snakebyte
Gold Member
Gold Member
Posts: 430
Joined: 2003 May 07, 07:14
Location: Seattle
Contact:

Re: Xplorer2Hack: Menu++ Customizable menu for Xplorer2

Post by snakebyte »

I have been using Menu++ on Windows 7 and Windows 8 x64 without any problems.

When did you last download Menu++? I remember recompiling it with the latest autohotkey binaries and uploading it around the time when windows 7 was released. Try to download the latest executable and see if the issues you are seeing are gone.

BTW, here is the latest Menu++ code if anyone is interested.

Code: Select all

;Menu++ v1.2
;Author: Snakebyte

if %1%
    configFile = %A_ScriptDir%\%1%
else
{
    MsgBox, 0,Menu++ v1.2 by Snakebyte,Invalid parameter `n`n Usage: Menu++.exe <CONFIG_FILE_NAME> <$S>.
    return
}

IfNotExist,%configFile%
{
    MsgBox, The config file `n`n %configFile% `n`n does not exists.
    return
}

SetTitleMatchMode 2

;Get Title of the window under mouse cursor
MouseGetPos,,, hWnd
WinGetTitle, windowUnderCursorTitle, ahk_id %hWnd%

actionFlag = 0
ArrayCount = 0
comandlineCount = %0%
selectedFileCount := comandlineCount - 1
currentTitle = ""
loopActiveWindow =
loopActiveWindowTitle =

;MsgBox %windowUnderCursorTitle%


;MsgBox %comandlineCount% : %selectedFileCount%
; This loop retrieves each line from the file, one at a time.
; it creates the menu structure and adds correspoinding action into an array
Loop, Read, %configFile%   
{
    ; Skip lines with comments or whitespaces
    FoundPos := RegExMatch( A_LoopReadLine, "iS)^(\s*#.*|\s*|\s*endwinactive)\s*$")
    if (FoundPos == 1)
    {
        continue
    }
	else if( inStr( A_LoopReadLine, "IfWinActive") >0)
	{
	
		;Reading conditional Menu window title
        FoundPos := RegExMatch(  A_LoopReadLine, "iS)^\s*IfWinActive\s*,\s*(.*)\s*$", windowTitle)
        if( FoundPos == 1 )
        {
			loopActiveWindow = %windowTitle1%
			WinGetTitle, loopActiveWindowTitle, %loopActiveWindow%
		}
	}
    else if( inStr( A_LoopReadLine, "Title") >0 && (actionFlag == 0 || actionFlag == 2))
    {
		if(loopActiveWindow <> "" && loopActiveWindowTitle != windowUnderCursorTitle)
		{
			; Current entry is not global and does not belong to active window
			; Skip it
			actionFlag = 0
			continue
		}
	
        ;Reading Title line
        FoundPos := RegExMatch(  A_LoopReadLine, "iS)^\s*Title\s*=\s*'(.*)'\s*$", title)
        if( FoundPos == 0 )
        {
            MsgBox Parse error in config file %configFile% at line# %A_Index% `n`n%A_LoopReadLine%
            return
        }
        currentTitle = %title1%
        actionFlag = 1
    }
    else if ( actionFlag == 1 )
    {
        ;Reading the action line corresponding to the 'Title' read in the above 'if' block
        FoundPos := RegExMatch(  A_LoopReadLine, "iS)^\s*Action\s*=\s*0|((Send|Run|Menu|CmdID|Bookmark)\s*,(.*))\s*$", action)
        if( FoundPos == 0 )
        {
            MsgBox Parse error in config file %configFile% at line# %A_Index% `n`n%A_LoopReadLine%
            return
        }
        if ( title == "")
        {
            ; Add menu separator line.
            Menu, MyMenu, Add  
        }
        else
        {
            ; Add menu item
            Menu, MyMenu, Add, %title1%, MenuHandler
        }
       ;Remove all white spaces surrounding comma in the action string
        action1 := RegExReplace(action1, "\s*,\s*", ",")  

        ArrayCount += 1  ; Keep track of how many items are in the array.
        Array%ArrayCount% := action1  ; Store this line in the next array element.
        actionFlag = 2
    }
    else if ( actionFlag == 2 )
    {
        ;The next line could be DisableIfNoSelections or Title
       ;MsgBox Read line %A_LoopReadLine% - %currentTitle%

        menuStateFoundPos := RegExMatch(  A_LoopReadLine, "iS)^\s*DisableIfNoSelections\s*=\s*(0|1)\s*$", menuState)
        titleFoundPos := RegExMatch(  A_LoopReadLine, "iS)^\s*Title\s*=\s*'(.*)'\s*$", title)

        if( menuStateFoundPos == 0 && titleFoundPos ==0)  
        {
            MsgBox ~Parse error in config file %configFile% at line# %A_Index% `n`n%A_LoopReadLine%
            return
        }
        else
        {
            if( menuStateFoundPos > 0)
            {
                ;MsgBox Read line %A_LoopReadLine% - %selectedFileCount%
                if ( menuState1 == 1 && selectedFileCount == 0 && currentTitle != "")
                {
                    Menu, MyMenu, Disable, %currentTitle%
                }
                actionFlag = 0
            }
            else if( titleFoundPos >0)
            {
              ;Read action line next
              actionFlag = 1
              currentTitle = %title1%
            }
        }
    }
}

;Append the configure menu item at the end
Menu, MyMenu, Add  
Menu, MyMenu, Add, Configure...., ConfigureMenuHandler
Menu, MyMenu, Add, Exit, ExitHandler

Menu, MyMenu, Icon, Configure...., shell32.dll, 177
Menu, MyMenu, Icon, Exit, shell32.dll, 216


; Debug block to read the array contents
;Loop %ArrayCount%
;{
;    element := Array%A_Index%
;    MsgBox % "Element number " . A_Index . " is " . Array%A_Index%
;}

; Display the Menu
Menu, MyMenu, Show

; End of script's auto-execute section
return  

ExitHandler:
return

MenuHandler:

    ;Retrive menu action from the array
    action := Array%A_ThisMenuItemPos%
    ;msgbox %action%

    ;Get Handle of the window under mouse
    MouseGetPos,,, hWnd

    ;Get Title of the active window
    WinGetTitle, Title, ahk_id %hWnd%

    IfInString,action,Send`,
    {
        StringTrimLeft,action,action,5
        StringSplit,action_,action,`,
        Loop, %action_0%
        {
            current_action:= action_%a_index%
            Send,%current_action%
            sleep 50
        }
    }
    IfInString,action,Run`,
    {
        StringTrimLeft,action,action,4
        StringSplit,action_,action,`,
        Run,%action_1%,%action_2%,%action_3%
    }
    IfInString,action,Menu`,
    {
        StringTrimLeft,action,action,5
        StringSplit,action_,action,`,
        WinMenuSelectItem,ahk_id %hWnd%,,%action_1%,%action_2%,%action_3%,%action_4%,%action_5%,%action_6%
    }
    IfInString,action,CmdID`,
    {
        StringTrimLeft,wparam,action,6
        SendMessage, 0x0111 , wparam , 0, ,%Title%
    }
return


ConfigureMenuHandler:
    run %configFile%
return
Help! I'm an AI running around in someone's universe simulator.
User avatar
FrizzleFry
Platinum Member
Platinum Member
Posts: 1241
Joined: 2005 Oct 16, 19:09

Re: Xplorer2Hack: Menu++ Customizable menu for Xplorer2

Post by FrizzleFry »

Thanks for posting the Menu++ source code.

Is there a way to add icons for menu items like you do for configure and exit?

The version currently available for download is 1.1 and the files are dated June 2, 2007.
User avatar
snakebyte
Gold Member
Gold Member
Posts: 430
Joined: 2003 May 07, 07:14
Location: Seattle
Contact:

Re: Xplorer2Hack: Menu++ Customizable menu for Xplorer2

Post by snakebyte »

When I originally wrote menu++ Autohotkey menu command did not support icons. This support has been added now
http://l.autohotkey.net/docs/commands/Menu.htm#MenuIcon

Someday when I have time, I will add the icon support ;-)

I would like to mention that with version v1.2, Menu++ is not just restricted to Xplorer2, but now it can be used to execute commands for any application. The menu commands can have global menu options as well as application specific options which shows up depending upon which application is currently under the mouse cursor.

I have currently configured additional button on my mouse to launch Menu++ but you can use any global hot key for this as well. How you launch Menu++ initially is totally upon you.

My configuration ini file with global and application specific commands looks something like this.

Code: Select all

#Global Commands
Title='Paste N' Go	Ctrl+V+Enter'
Action=Send, ^v{ENTER}

Title=''
Action=0

Title='Execute Clipboard	Win+O'
Action=Send,{LWINDOWN}o{LWINUP}

Title='Execute Selected	Win+Shift+O'
Action=Send, {LWINDOWN}{SHIFTDOWN}o{LWINUP}{SHIFTUP}

Title='Search Selected	Win+Shift+G'
Action=Send, {LWINDOWN}{SHIFTDOWN}g{SHIFTUP}{LWINUP}

Title='Menu++ Help'
Action=Run,E:\Cloud\SkyDrive\Scripts\Xplorer2\Menu++\readme.txt


# Visual Studio
IfWinActive, Microsoft Visual Studio

	Title=''
	Action=0

	Title='<-- Move To Previous Tab Group'
	Action=Send,!wr{enter}
	
	Title='--> Move To Next Tab Group'
	Action=Send,!wx
	
	Title='|| New Vertical Window'
	Action=Send,!wv

	Title='Toggle Outlining	Ctrl M, L'
	Action=Send, ^ml	
	
	Title=''
	Action=0

	Title='Copy File Path	Ctrl+Shift+C'
	Action=Send,^+c
	
	Title='Launch in Xplorer2	Ctrl+Shift+C, Ctrl+Alt+Shift+X'
	Action=Send,^+c,^!+x

	Title = 'Recent Edits	Ctrl+Alt+,'
	Action=Send, ^!,

	Title = 'Recent Files	Ctrl+,'
	Action=Send, ^,	
	
	Title='VS Open Windows	Alt+W, W'
	Action=Send,!w,w
	
	Title='Format Selection	Ctrl+K, Ctrl+F'
	Action=Send, ^k^f
	
	Title='Parameter Info	Ctrl+K, P'
	Action=Send, ^k,p
	
	Title='Configuration Manager	Alt+B, O'
	Action=Send, !b,o,!p

EndIfWinActive

# Notepad++ Commands
IfWinActive, ahk_class Notepad++
	
	Title=''
	Action=0

	Title='Npp Commands	Win+O'
	Action=Send,{LWINDOWN}o{LWINUP}

	Title='Execute Selected	Win+Shift+O'
	Action=Send, {LWINDOWN}{SHIFTDOWN}o{LWINUP}{SHIFTUP}

	Title='Search Selected	Win+Shift+G'
	Action=Send, {LWINDOWN}{SHIFTDOWN}g{SHIFTUP}{LWINUP}

EndIfWinActive


# Chrome
IfWinActive, ahk_class Chrome_WidgetWin_0

	Title=''
	Action=0

	Title='Developer Tools	Ctrl+Shift+I'
	Action=Send, ^+i

	Title='FireBug	F12'
	Action=Send, {F12}

	Title='Reopen Last Closed Tab	Ctrl+Shift+T'
	Action=Send, ^+t	

	Title='AddressBar	F6'
	Action=Send, {F6}
	
	Title='AddressBar Search	Ctrl+K'
	Action=Send, ^k
	
EndIfWinActive


# X2 Commands
IfWinActive, ahk_class ATL:ExplorerFrame

	Title='Duplicate Tab in current Pane'
	Action=Send,^{Ins}

	Title='Swap Tabs	Ctrl+U'
	Action=Send,^u
	
	Title=''
	Action=0
		
	Title='Select Same Base Name	Shift+Alt+Num+'
	Action=Send,+!{NumpadAdd}
		
	Title='Select Same File Type	Ctrl+Alt+Num+'
	Action=Send,^!{NumpadAdd}

	Title='Show Selected Type Only	Ctrl+Alt+Num+,Ctrl+Alt+J'
	Action=Send,^!{NumpadAdd},^!j
	
EndIfWinActive

# Outlook

# Firefox 

# IE

# LinqPad

# Winamp
Help! I'm an AI running around in someone's universe simulator.
User avatar
FrizzleFry
Platinum Member
Platinum Member
Posts: 1241
Joined: 2005 Oct 16, 19:09

Re: Xplorer2Hack: Menu++ Customizable menu for Xplorer2

Post by FrizzleFry »

Thanks for that config file as well... looking at the source I was wondering what the IfWinActive was used for...
pj
Gold Member
Gold Member
Posts: 471
Joined: 2006 Jan 26, 14:01
Location: Florida

Re: Xplorer2Hack: Menu++ Customizable menu for Xplorer2

Post by pj »

snakebyte wrote:I have been using Menu++ on Windows 7 and Windows 8 x64 without any problems.

When did you last download Menu++? I remember recompiling it with the latest autohotkey binaries and uploading it around the time when windows 7 was released. Try to download the latest executable and see if the issues you are seeing are gone.

BTW, here is the latest Menu++ code if anyone is interested.
Snakebyte - Thanks again for sharing these tools!

One problem I'm having that I hope you can help with is the lack of BOOKMARK support in the latest MENU++ code you posted. I'm interested in adding the icon support like you've done in your latest global script.

I compiled the .EXE's using the latest AutoHotKey release (1.1.11.02).

Looking through the script, I couldn't locate any code in the MenuHandler section for running the BOOKMARK commands. Is the BOOKMARK command handled somewhere else?

--------------------------------------
PJ in FL
User avatar
snakebyte
Gold Member
Gold Member
Posts: 430
Joined: 2003 May 07, 07:14
Location: Seattle
Contact:

Re: Xplorer2Hack: Menu++ Customizable menu for Xplorer2

Post by snakebyte »

You may add the bookmark functionality by inserting following code at the end of MenuHandler: block

Code: Select all

IfInString,action,Bookmark`,
    {
        Title := "ahk_class ATL:ExplorerFrame"
        StringTrimLeft,path,action,9
        ; Create a new tab
        SendMessage, 0x0111 , 33036 , 0, ,%Title%
        ; Set focus on Address bar
        SendMessage, 0x0111 , 32859 , 0, ,%Title%
        ;Set new path in address bar
        ControlSetText, Edit1, %path%, %Title% 
        ;Press Enter in address bar
        Send {Enter}
    }
Help! I'm an AI running around in someone's universe simulator.
dmattote
Member
Member
Posts: 20
Joined: 2009 Jul 28, 03:41

Re: Xplorer2Hack: Menu++ Customizable menu for Xplorer2

Post by dmattote »

Snakebyte could you please explain how to add icon support, I have not coded for a long time, frankly since the late 80's. :D
Thank you very much.
dmattote
Member
Member
Posts: 20
Joined: 2009 Jul 28, 03:41

Re: Xplorer2Hack: Menu++ Customizable menu for Xplorer2

Post by dmattote »

Greeting snakebyte, I still have not been able to figure out the code changes to add icons to the menu items in Menu++. I love the utility but I would like to see icons. I would appreciate any help you could give me. For reference I am using Win XP SP2 (a little old but then so am I) Thanks in advance!
unknowing
New Member
Posts: 4
Joined: 2015 Oct 01, 22:03

Re: Xplorer2Hack: Menu++ Customizable menu for Xplorer2

Post by unknowing »

thanks you for script, it's indeed really useful; though I wish this would be implemented natively in X2 as a drop-down combobox element like in other FM. Like that I could add all my favourite tools under a single icon in the toolbar.

the script works fine, but one thing I did not figure out.

Code: Select all

Action=run,notepad

lauches Notepad as expected; but how would one pass the x2 parameter eg. "$A" to open the selected file immediately?

btw, is it possible to add custom icons? how?
thank you for your help!
User avatar
FrizzleFry
Platinum Member
Platinum Member
Posts: 1241
Joined: 2005 Oct 16, 19:09

Re: Xplorer2Hack: Menu++ Customizable menu for Xplorer2

Post by FrizzleFry »

Menu++ does not support the x2 tokens so you cannot directly do what you want...

There is a workaround...
create an x2 user command and then call that command from Menu++ like this

Action=Menu,Customize,User Commands,6&

where the 6 is the position of the notepad user command in the customize/user commands menu
the first user command is in position 5

BTW, if you are actually using notepad, you should probably use the $F token instead of $A since notepad can only open one file at a time... but with $F you should enclose it in quotes ("$F") to handle spaces in file/folder names
unknowing
New Member
Posts: 4
Joined: 2015 Oct 01, 22:03

Re: Xplorer2Hack: Menu++ Customizable menu for Xplorer2

Post by unknowing »

Thank you so much FrizzleFry. It works now! :party:
wingood
Member
Member
Posts: 11
Joined: 2016 Apr 07, 09:39

Re: Xplorer2Hack: Menu++ Customizable menu for Xplorer2

Post by wingood »

FrizzleFry wrote:Menu++ does not support the x2 tokens so you cannot directly do what you want...

There is a workaround...
create an x2 user command and then call that command from Menu++ like this

Action=Menu,Customize,User Commands,6&

where the 6 is the position of the notepad user command in the customize/user commands menu
the first user command is in position 5

BTW, if you are actually using notepad, you should probably use the $F token instead of $A since notepad can only open one file at a time... but with $F you should enclose it in quotes ("$F") to handle spaces in file/folder names
Been glued to this thread over 30mins, this forum over an hour... I love the generosity of the scripting community. well done guys!

Re this $F | $A notepad titbit... if $A were used, is it app-dependent re whether multiple instances are launched (notepad++ would it default to opening all in new tabs in existing windows? I wonder).

It sounds like this clever menu++ thing can be used to do ALL SORTS. If anyone's done any of this spying, and knows how to 'get the command code' (I was just hacking, usually wrecking, MRU content, mcbuilder to rebuild.. ie a shortcut to expose the Close all windows (of app-group) via shift+right-click of a taskbar icon - ya know?
so much to implement!
N1ck1
New Member
Posts: 6
Joined: 2022 Dec 01, 23:30

Re: Xplorer2Hack: Menu++ Customizable menu for Xplorer2

Post by N1ck1 »

This Menu++ script is still working great!
snakebyte wrote: 2013 Jul 08, 20:12 BTW, here is the latest Menu++ code if anyone is interested.

Code: Select all

;Menu++ v1.2
;Author: Snakebyte

if %1%
    configFile = %A_ScriptDir%\%1%
else
{
    MsgBox, 0,Menu++ v1.2 by Snakebyte,Invalid parameter `n`n Usage: Menu++.exe <CONFIG_FILE_NAME> <$S>.
    return
}

IfNotExist,%configFile%
{
    MsgBox, The config file `n`n %configFile% `n`n does not exists.
    return
}

SetTitleMatchMode 2

;Get Title of the window under mouse cursor
MouseGetPos,,, hWnd
WinGetTitle, windowUnderCursorTitle, ahk_id %hWnd%

actionFlag = 0
ArrayCount = 0
comandlineCount = %0%
selectedFileCount := comandlineCount - 1
currentTitle = ""
loopActiveWindow =
loopActiveWindowTitle =

;MsgBox %windowUnderCursorTitle%


;MsgBox %comandlineCount% : %selectedFileCount%
; This loop retrieves each line from the file, one at a time.
; it creates the menu structure and adds correspoinding action into an array
Loop, Read, %configFile%   
{
    ; Skip lines with comments or whitespaces
    FoundPos := RegExMatch( A_LoopReadLine, "iS)^(\s*#.*|\s*|\s*endwinactive)\s*$")
    if (FoundPos == 1)
    {
        continue
    }
	else if( inStr( A_LoopReadLine, "IfWinActive") >0)
	{
	
		;Reading conditional Menu window title
        FoundPos := RegExMatch(  A_LoopReadLine, "iS)^\s*IfWinActive\s*,\s*(.*)\s*$", windowTitle)
        if( FoundPos == 1 )
        {
			loopActiveWindow = %windowTitle1%
			WinGetTitle, loopActiveWindowTitle, %loopActiveWindow%
		}
	}
    else if( inStr( A_LoopReadLine, "Title") >0 && (actionFlag == 0 || actionFlag == 2))
    {
		if(loopActiveWindow <> "" && loopActiveWindowTitle != windowUnderCursorTitle)
		{
			; Current entry is not global and does not belong to active window
			; Skip it
			actionFlag = 0
			continue
		}
	
        ;Reading Title line
        FoundPos := RegExMatch(  A_LoopReadLine, "iS)^\s*Title\s*=\s*'(.*)'\s*$", title)
        if( FoundPos == 0 )
        {
            MsgBox Parse error in config file %configFile% at line# %A_Index% `n`n%A_LoopReadLine%
            return
        }
        currentTitle = %title1%
        actionFlag = 1
    }
    else if ( actionFlag == 1 )
    {
        ;Reading the action line corresponding to the 'Title' read in the above 'if' block
        FoundPos := RegExMatch(  A_LoopReadLine, "iS)^\s*Action\s*=\s*0|((Send|Run|Menu|CmdID|Bookmark)\s*,(.*))\s*$", action)
        if( FoundPos == 0 )
        {
            MsgBox Parse error in config file %configFile% at line# %A_Index% `n`n%A_LoopReadLine%
            return
        }
        if ( title == "")
        {
            ; Add menu separator line.
            Menu, MyMenu, Add  
        }
        else
        {
            ; Add menu item
            Menu, MyMenu, Add, %title1%, MenuHandler
        }
       ;Remove all white spaces surrounding comma in the action string
        action1 := RegExReplace(action1, "\s*,\s*", ",")  

        ArrayCount += 1  ; Keep track of how many items are in the array.
        Array%ArrayCount% := action1  ; Store this line in the next array element.
        actionFlag = 2
    }
    else if ( actionFlag == 2 )
    {
        ;The next line could be DisableIfNoSelections or Title
       ;MsgBox Read line %A_LoopReadLine% - %currentTitle%

        menuStateFoundPos := RegExMatch(  A_LoopReadLine, "iS)^\s*DisableIfNoSelections\s*=\s*(0|1)\s*$", menuState)
        titleFoundPos := RegExMatch(  A_LoopReadLine, "iS)^\s*Title\s*=\s*'(.*)'\s*$", title)

        if( menuStateFoundPos == 0 && titleFoundPos ==0)  
        {
            MsgBox ~Parse error in config file %configFile% at line# %A_Index% `n`n%A_LoopReadLine%
            return
        }
        else
        {
            if( menuStateFoundPos > 0)
            {
                ;MsgBox Read line %A_LoopReadLine% - %selectedFileCount%
                if ( menuState1 == 1 && selectedFileCount == 0 && currentTitle != "")
                {
                    Menu, MyMenu, Disable, %currentTitle%
                }
                actionFlag = 0
            }
            else if( titleFoundPos >0)
            {
              ;Read action line next
              actionFlag = 1
              currentTitle = %title1%
            }
        }
    }
}

;Append the configure menu item at the end
Menu, MyMenu, Add  
Menu, MyMenu, Add, Configure...., ConfigureMenuHandler
Menu, MyMenu, Add, Exit, ExitHandler

Menu, MyMenu, Icon, Configure...., shell32.dll, 177
Menu, MyMenu, Icon, Exit, shell32.dll, 216


; Debug block to read the array contents
;Loop %ArrayCount%
;{
;    element := Array%A_Index%
;    MsgBox % "Element number " . A_Index . " is " . Array%A_Index%
;}

; Display the Menu
Menu, MyMenu, Show

; End of script's auto-execute section
return  

ExitHandler:
return

MenuHandler:

    ;Retrive menu action from the array
    action := Array%A_ThisMenuItemPos%
    ;msgbox %action%

    ;Get Handle of the window under mouse
    MouseGetPos,,, hWnd

    ;Get Title of the active window
    WinGetTitle, Title, ahk_id %hWnd%

    IfInString,action,Send`,
    {
        StringTrimLeft,action,action,5
        StringSplit,action_,action,`,
        Loop, %action_0%
        {
            current_action:= action_%a_index%
            Send,%current_action%
            sleep 50
        }
    }
    IfInString,action,Run`,
    {
        StringTrimLeft,action,action,4
        StringSplit,action_,action,`,
        Run,%action_1%,%action_2%,%action_3%
    }
    IfInString,action,Menu`,
    {
        StringTrimLeft,action,action,5
        StringSplit,action_,action,`,
        WinMenuSelectItem,ahk_id %hWnd%,,%action_1%,%action_2%,%action_3%,%action_4%,%action_5%,%action_6%
    }
    IfInString,action,CmdID`,
    {
        StringTrimLeft,wparam,action,6
        SendMessage, 0x0111 , wparam , 0, ,%Title%
    }
return


ConfigureMenuHandler:
    run %configFile%
return
A note on the following Menu++ bookmark code, if you just happen to have more than one folder selected at the time of clicking a Menu++ bookmark, any and all extra selected folders over 1 will also be automatically opened into new tabs along with the Menu++ bookmark. A simple fix to stop that behavior is to add one extra line of code that will first unselect all items before opening the Menu++ bookmark, which I'm providing below this original code and including into the full script.
snakebyte wrote: 2013 Aug 16, 01:06 You may add the bookmark functionality by inserting following code at the end of MenuHandler: block

Code: Select all

IfInString,action,Bookmark`,
    {
        Title := "ahk_class ATL:ExplorerFrame"
        StringTrimLeft,path,action,9
        ; Create a new tab
        SendMessage, 0x0111 , 33036 , 0, ,%Title%
        ; Set focus on Address bar
        SendMessage, 0x0111 , 32859 , 0, ,%Title%
        ;Set new path in address bar
        ControlSetText, Edit1, %path%, %Title% 
        ;Press Enter in address bar
        Send {Enter}
    }
Here is the full Menu++ script with the bookmark code included into it and the extra unselect all code line to stop extra folders from opening into new tabs.

Code: Select all

;Menu++ v1.2
;Author: Snakebyte

if %1%
    configFile = %A_ScriptDir%\%1%
else
{
    MsgBox, 0,Menu++ v1.2 by Snakebyte,Invalid parameter `n`n Usage: Menu++.exe <CONFIG_FILE_NAME> <$S>.
    return
}

IfNotExist,%configFile%
{
    MsgBox, The config file `n`n %configFile% `n`n does not exists.
    return
}

SetTitleMatchMode 2

;Get Title of the window under mouse cursor
MouseGetPos,,, hWnd
WinGetTitle, windowUnderCursorTitle, ahk_id %hWnd%

actionFlag = 0
ArrayCount = 0
comandlineCount = %0%
selectedFileCount := comandlineCount - 1
currentTitle = ""
loopActiveWindow =
loopActiveWindowTitle =

;MsgBox %windowUnderCursorTitle%


;MsgBox %comandlineCount% : %selectedFileCount%
; This loop retrieves each line from the file, one at a time.
; it creates the menu structure and adds correspoinding action into an array
Loop, Read, %configFile%   
{
    ; Skip lines with comments or whitespaces
    FoundPos := RegExMatch( A_LoopReadLine, "iS)^(\s*#.*|\s*|\s*endwinactive)\s*$")
    if (FoundPos == 1)
    {
        continue
    }
	else if( inStr( A_LoopReadLine, "IfWinActive") >0)
	{
	
		;Reading conditional Menu window title
        FoundPos := RegExMatch(  A_LoopReadLine, "iS)^\s*IfWinActive\s*,\s*(.*)\s*$", windowTitle)
        if( FoundPos == 1 )
        {
			loopActiveWindow = %windowTitle1%
			WinGetTitle, loopActiveWindowTitle, %loopActiveWindow%
		}
	}
    else if( inStr( A_LoopReadLine, "Title") >0 && (actionFlag == 0 || actionFlag == 2))
    {
		if(loopActiveWindow <> "" && loopActiveWindowTitle != windowUnderCursorTitle)
		{
			; Current entry is not global and does not belong to active window
			; Skip it
			actionFlag = 0
			continue
		}
	
        ;Reading Title line
        FoundPos := RegExMatch(  A_LoopReadLine, "iS)^\s*Title\s*=\s*'(.*)'\s*$", title)
        if( FoundPos == 0 )
        {
            MsgBox Parse error in config file %configFile% at line# %A_Index% `n`n%A_LoopReadLine%
            return
        }
        currentTitle = %title1%
        actionFlag = 1
    }
    else if ( actionFlag == 1 )
    {
        ;Reading the action line corresponding to the 'Title' read in the above 'if' block
        FoundPos := RegExMatch(  A_LoopReadLine, "iS)^\s*Action\s*=\s*0|((Send|Run|Menu|CmdID|Bookmark)\s*,(.*))\s*$", action)
        if( FoundPos == 0 )
        {
            MsgBox Parse error in config file %configFile% at line# %A_Index% `n`n%A_LoopReadLine%
            return
        }
        if ( title == "")
        {
            ; Add menu separator line.
            Menu, MyMenu, Add  
        }
        else
        {
            ; Add menu item
            Menu, MyMenu, Add, %title1%, MenuHandler
        }
       ;Remove all white spaces surrounding comma in the action string
        action1 := RegExReplace(action1, "\s*,\s*", ",")  

        ArrayCount += 1  ; Keep track of how many items are in the array.
        Array%ArrayCount% := action1  ; Store this line in the next array element.
        actionFlag = 2
    }
    else if ( actionFlag == 2 )
    {
        ;The next line could be DisableIfNoSelections or Title
       ;MsgBox Read line %A_LoopReadLine% - %currentTitle%

        menuStateFoundPos := RegExMatch(  A_LoopReadLine, "iS)^\s*DisableIfNoSelections\s*=\s*(0|1)\s*$", menuState)
        titleFoundPos := RegExMatch(  A_LoopReadLine, "iS)^\s*Title\s*=\s*'(.*)'\s*$", title)

        if( menuStateFoundPos == 0 && titleFoundPos ==0)  
        {
            MsgBox ~Parse error in config file %configFile% at line# %A_Index% `n`n%A_LoopReadLine%
            return
        }
        else
        {
            if( menuStateFoundPos > 0)
            {
                ;MsgBox Read line %A_LoopReadLine% - %selectedFileCount%
                if ( menuState1 == 1 && selectedFileCount == 0 && currentTitle != "")
                {
                    Menu, MyMenu, Disable, %currentTitle%
                }
                actionFlag = 0
            }
            else if( titleFoundPos >0)
            {
              ;Read action line next
              actionFlag = 1
              currentTitle = %title1%
            }
        }
    }
}

;Append the configure menu item at the end
Menu, MyMenu, Add  
Menu, MyMenu, Add, Configure...., ConfigureMenuHandler
Menu, MyMenu, Add, Exit, ExitHandler

Menu, MyMenu, Icon, Configure...., shell32.dll, 177
Menu, MyMenu, Icon, Exit, shell32.dll, 216


; Debug block to read the array contents
;Loop %ArrayCount%
;{
;    element := Array%A_Index%
;    MsgBox % "Element number " . A_Index . " is " . Array%A_Index%
;}

; Display the Menu
Menu, MyMenu, Show

; End of script's auto-execute section
return  

ExitHandler:
return

MenuHandler:

    ;Retrive menu action from the array
    action := Array%A_ThisMenuItemPos%
    ;msgbox %action%

    ;Get Handle of the window under mouse
    MouseGetPos,,, hWnd

    ;Get Title of the active window
    WinGetTitle, Title, ahk_id %hWnd%

    IfInString,action,Send`,
    {
        StringTrimLeft,action,action,5
        StringSplit,action_,action,`,
        Loop, %action_0%
        {
            current_action:= action_%a_index%
            Send,%current_action%
            sleep 50
        }
    }
    IfInString,action,Run`,
    {
        StringTrimLeft,action,action,4
        StringSplit,action_,action,`,
        Run,%action_1%,%action_2%,%action_3%
    }
    IfInString,action,Menu`,
    {
        StringTrimLeft,action,action,5
        StringSplit,action_,action,`,
        WinMenuSelectItem,ahk_id %hWnd%,,%action_1%,%action_2%,%action_3%,%action_4%,%action_5%,%action_6%
    }
    IfInString,action,CmdID`,
    {
        StringTrimLeft,wparam,action,6
        SendMessage, 0x0111 , wparam , 0, ,%Title%
    }
	IfInString,action,Bookmark`,
    {
        Title := "ahk_class ATL:ExplorerFrame"
        StringTrimLeft,path,action,9
	; Unselect all items
	SendMessage, 0x0111 , 32803 , 0, ,%Title%
        ; Create a new tab
        SendMessage, 0x0111 , 33036 , 0, ,%Title%
        ; Set focus on Address bar
        SendMessage, 0x0111 , 32859 , 0, ,%Title%
        ;Set new path in address bar
        ControlSetText, Edit1, %path%, %Title% 
        ;Press Enter in address bar
        Send {Enter}
    }
return


ConfigureMenuHandler:
    run %configFile%
return
And for anyone who doesn't need/want the extra 'Configure' and 'Exit' listings included on their Menu++ menu lists for a cleaner and shorter list, the following code is the same as above but with those two default menu listings blocked out in the script.

Code: Select all

;Menu++ v1.2
;Author: Snakebyte

if %1%
    configFile = %A_ScriptDir%\%1%
else
{
    MsgBox, 0,Menu++ v1.2 by Snakebyte,Invalid parameter `n`n Usage: Menu++.exe <CONFIG_FILE_NAME> <$S>.
    return
}

IfNotExist,%configFile%
{
    MsgBox, The config file `n`n %configFile% `n`n does not exists.
    return
}

SetTitleMatchMode 2

;Get Title of the window under mouse cursor
MouseGetPos,,, hWnd
WinGetTitle, windowUnderCursorTitle, ahk_id %hWnd%

actionFlag = 0
ArrayCount = 0
comandlineCount = %0%
selectedFileCount := comandlineCount - 1
currentTitle = ""
loopActiveWindow =
loopActiveWindowTitle =

;MsgBox %windowUnderCursorTitle%


;MsgBox %comandlineCount% : %selectedFileCount%
; This loop retrieves each line from the file, one at a time.
; it creates the menu structure and adds correspoinding action into an array
Loop, Read, %configFile%   
{
    ; Skip lines with comments or whitespaces
    FoundPos := RegExMatch( A_LoopReadLine, "iS)^(\s*#.*|\s*|\s*endwinactive)\s*$")
    if (FoundPos == 1)
    {
        continue
    }
	else if( inStr( A_LoopReadLine, "IfWinActive") >0)
	{
	
		;Reading conditional Menu window title
        FoundPos := RegExMatch(  A_LoopReadLine, "iS)^\s*IfWinActive\s*,\s*(.*)\s*$", windowTitle)
        if( FoundPos == 1 )
        {
			loopActiveWindow = %windowTitle1%
			WinGetTitle, loopActiveWindowTitle, %loopActiveWindow%
		}
	}
    else if( inStr( A_LoopReadLine, "Title") >0 && (actionFlag == 0 || actionFlag == 2))
    {
		if(loopActiveWindow <> "" && loopActiveWindowTitle != windowUnderCursorTitle)
		{
			; Current entry is not global and does not belong to active window
			; Skip it
			actionFlag = 0
			continue
		}
	
        ;Reading Title line
        FoundPos := RegExMatch(  A_LoopReadLine, "iS)^\s*Title\s*=\s*'(.*)'\s*$", title)
        if( FoundPos == 0 )
        {
            MsgBox Parse error in config file %configFile% at line# %A_Index% `n`n%A_LoopReadLine%
            return
        }
        currentTitle = %title1%
        actionFlag = 1
    }
    else if ( actionFlag == 1 )
    {
        ;Reading the action line corresponding to the 'Title' read in the above 'if' block
        FoundPos := RegExMatch(  A_LoopReadLine, "iS)^\s*Action\s*=\s*0|((Send|Run|Menu|CmdID|Bookmark)\s*,(.*))\s*$", action)
        if( FoundPos == 0 )
        {
            MsgBox Parse error in config file %configFile% at line# %A_Index% `n`n%A_LoopReadLine%
            return
        }
        if ( title == "")
        {
            ; Add menu separator line.
            Menu, MyMenu, Add  
        }
        else
        {
            ; Add menu item
            Menu, MyMenu, Add, %title1%, MenuHandler
        }
       ;Remove all white spaces surrounding comma in the action string
        action1 := RegExReplace(action1, "\s*,\s*", ",")  

        ArrayCount += 1  ; Keep track of how many items are in the array.
        Array%ArrayCount% := action1  ; Store this line in the next array element.
        actionFlag = 2
    }
    else if ( actionFlag == 2 )
    {
        ;The next line could be DisableIfNoSelections or Title
       ;MsgBox Read line %A_LoopReadLine% - %currentTitle%

        menuStateFoundPos := RegExMatch(  A_LoopReadLine, "iS)^\s*DisableIfNoSelections\s*=\s*(0|1)\s*$", menuState)
        titleFoundPos := RegExMatch(  A_LoopReadLine, "iS)^\s*Title\s*=\s*'(.*)'\s*$", title)

        if( menuStateFoundPos == 0 && titleFoundPos ==0)  
        {
            MsgBox ~Parse error in config file %configFile% at line# %A_Index% `n`n%A_LoopReadLine%
            return
        }
        else
        {
            if( menuStateFoundPos > 0)
            {
                ;MsgBox Read line %A_LoopReadLine% - %selectedFileCount%
                if ( menuState1 == 1 && selectedFileCount == 0 && currentTitle != "")
                {
                    Menu, MyMenu, Disable, %currentTitle%
                }
                actionFlag = 0
            }
            else if( titleFoundPos >0)
            {
              ;Read action line next
              actionFlag = 1
              currentTitle = %title1%
            }
        }
    }
}

/*
;Append the configure menu item at the end
Menu, MyMenu, Add  
Menu, MyMenu, Add, Configure...., ConfigureMenuHandler
Menu, MyMenu, Add, Exit, ExitHandler

Menu, MyMenu, Icon, Configure...., shell32.dll, 177
Menu, MyMenu, Icon, Exit, shell32.dll, 216
*/

; Debug block to read the array contents
;Loop %ArrayCount%
;{
;    element := Array%A_Index%
;    MsgBox % "Element number " . A_Index . " is " . Array%A_Index%
;}

; Display the Menu
Menu, MyMenu, Show

; End of script's auto-execute section
return  

/*
ExitHandler:
return
*/

MenuHandler:

    ;Retrive menu action from the array
    action := Array%A_ThisMenuItemPos%
    ;msgbox %action%

    ;Get Handle of the window under mouse
    MouseGetPos,,, hWnd

    ;Get Title of the active window
    WinGetTitle, Title, ahk_id %hWnd%

    IfInString,action,Send`,
    {
        StringTrimLeft,action,action,5
        StringSplit,action_,action,`,
        Loop, %action_0%
        {
            current_action:= action_%a_index%
            Send,%current_action%
            sleep 50
        }
    }
    IfInString,action,Run`,
    {
        StringTrimLeft,action,action,4
        StringSplit,action_,action,`,
        Run,%action_1%,%action_2%,%action_3%
    }
    IfInString,action,Menu`,
    {
        StringTrimLeft,action,action,5
        StringSplit,action_,action,`,
        WinMenuSelectItem,ahk_id %hWnd%,,%action_1%,%action_2%,%action_3%,%action_4%,%action_5%,%action_6%
    }
    IfInString,action,CmdID`,
    {
        StringTrimLeft,wparam,action,6
        SendMessage, 0x0111 , wparam , 0, ,%Title%
    }
    IfInString,action,Bookmark`,
    {
        Title := "ahk_class ATL:ExplorerFrame"
        StringTrimLeft,path,action,9
		; Unselect all items
		SendMessage, 0x0111 , 32803 , 0, ,%Title%
        ; Create a new tab
        SendMessage, 0x0111 , 33036 , 0, ,%Title%
        ; Set focus on Address bar
        SendMessage, 0x0111 , 32859 , 0, ,%Title%
        ;Set new path in address bar
        ControlSetText, Edit1, %path%, %Title% 
        ;Press Enter in address bar
        Send {Enter}
    }
return

/*
ConfigureMenuHandler:
    run %configFile%
return
*/
If you have the AutoHotkey app (either installed or portable) you can just point xplorer² directly to the .ahk without needing to compile into a .exe, which I find is even slighter faster at opening the Menu++ menus.
Example format to add Menu++ menus into xplorer² user commands:
Name:
Bookmarks
Description:
>"C:\Program Files\AutoHotkey\AutoHotkey.exe" "C:\Users\NAME\Path\To\Script\Menu++.ahk" Bookmarks.ini $S

A known tip when creating menus with custom user commands, folder groups, and macros is you can point directly to their entry names just as you would go to click them within the xplorer² menu structure. Just make sure you're using the full name of whatever entry item, including the number associated to it, but not including the keyboard shortcut if it has one.
For example, I have a custom made macro named Select All & Delete, it's the number 4 macro within a list of 9 macros, and it has the keyboard shortcut Ctrl+Shift+0. The xplorer² menu structure would show it as: 4 Select All & Delete .......... Ctrl+Shift+0
And the working Menu++ format to call that macro would be:
Title='Select All & Delete Macro'
Action=Menu,Customize,Macros,4 Select All & Delete
DisableIfNoSelections=0


Definitely a great script to create custom menus of only exactly what you want.
User avatar
johngalt
Gold Member
Gold Member
Posts: 559
Joined: 2008 Feb 10, 19:41
Location: 3rd Rock
Contact:

Re: Xplorer2Hack: Menu++ Customizable menu for Xplorer2

Post by johngalt »

Nice! And Thank You for the fix!
Image

Image
Post Reply