Mjolnir Posted April 1, 2011 Share Posted April 1, 2011 Hello all,Using since a long time AutoIt, here my first participation in this forum, hope this helps...Here is a quick dynamic menu creation under right mouse click button, on any file/folder, using a simple ini file for list of "programs" to run.Usage of myFloatingMenu is simple : once compiled (or not), it reads the ini file, and create a dynamic menu under user's cursor, each menu line corresponding to a [Menu_Line_XX] section from ini file.Command line option :myFloatingMenu.exe (call menu under user's cursor)myFloatingMenu.exe <file name>|<foldername> (call menu, with parameter as current file/folder, usable via #CMDLINEx# parameters in ini file)myFloatingMenu.exe /AddReg (Add current menu in registry, using ini RegKey=)myFloatingMenu.exe /AddReg:"my_key" (Add current menu in registry)<BR><TAB>- myFloatingMenu.exe /DelReg (Delete current menu from registry)The trick is, once added in registry (using /AddReg option on command line), this FloatingMenu is available for any right mouse click, on file/folder, to perform <your> specific action(s) described in the ini file Enjoy...---Ini configuration is relatively easy : simply add in ini file list of [Menu_Line_XX] sections, that will cointain :Title = title of menu that will be createdCommand = program to executeOptions = option on "command" command lineHere myFloatingMenu.ini file:expandcollapse popup#~ -------------------------------------------------8<------------------------------------------------- #~ [Default_Config] #~ Debug = [0|1] (to activate "debug" mode, default value = 0) #~ Revision = <any text> (your own revision of current ini file) #~ MenuRegKey = "<any text, may contain a &>" (name of menu entry [in registry + for right click mouse button on any file/folder], default value is = " + my&FloatingMenu...") #~ Menu_Lines = <a number> (it's the number of menu(s) line(s) to take into account below ... ie, number of [Menu_Line_<1-99>] sections to read, to create the dynamic menu) #~ -------------------------------------------------8<------------------------------------------------- [Default_Config] Debug = 0 Revision = A.01 MenuRegKey =" + my&FloatingMenu..." Menu_Lines = 14 #~ -------------------------------------------------8<------------------------------------------------- #~ [Menu_Line_<1-99>] #~ Title = <-> or <Menu Title> or <Menu Title #Options# (and #Options# will be replaced by value of "Options=")> or <Menu Title without "Command=" and without "Option=" (= perform an EXIT)> or <Menu Title with "Options=" only, could contain <BR><HR><TAB> = to show a popup with "Options" as text> #~ Command = <full command line to exe, without quotes (")> or <leave empty> #~ Options = <possible command line option(s) for "Command=">... can use too : <#CMDLINE1#, #CMDLINE2# or #CMDLINE3# or \"#CMDLINE1#\", as parameters taken from script command line> or <leave empty> #~ -------------------------------------------------8<------------------------------------------------- [Menu_Line_1] Title = Start Explorer Command = c:\WINDOWS\explorer.exe [Menu_Line_2] Title = Start Explorer on \"c:\Documents and Settings\" Command = c:\WINDOWS\explorer.exe Options = \"c:\Documents and Settings"\ [Menu_Line_3] Title = Start Explorer, taking first option on script command line (/e,/root,#CMDLINE1#) Command = explorer.exe Options = /e,/root,\"#CMDLINE1#\" [Menu_Line_4] Title = - [Menu_Line_5] Title = Start Internet Explorer (#Options#) Command = c:\Program Files\Internet Explorer\iexplore.exe Options = http://www.google.com [Menu_Line_6] Title = - [Menu_Line_7] Title = Start Notepad Command = notepad [Menu_Line_8] Title = Start Notepad (on file : #Options#) Command = notepad Options = #CMDLINE1# [Menu_Line_9] Title = Excel (with doc. givent as 1st command line parameter) Command = c:\Program Files\Microsoft Office\OFFICE11\EXCEL.EXE Options = \"#CMDLINE1#\" [Menu_Line_10] Title = - [Menu_Line_11] Title = About... Options = About example popup message box<BR>(c) 04/2011<BR><HR><BR>myFloatingMenu.exe is my Dynamic Menu "tool", using a .ini file<BR>for list of programes/actions to perform... [Menu_Line_12] Title = myFloatingMenu.exe usage... Options = Syntaxe usage is<BR><TAB>- myFloatingMenu.exe (call menu)<BR><TAB>- myFloatingMenu.exe <file name>|<foldername> (call menu, with parameter as current file/folder, usable via #CMDLINEx# parameters in ini file)<BR><TAB>- myFloatingMenu.exe /AddReg (Add current menu in registry, using ini RegKey=)<BR><TAB>- myFloatingMenu.exe /AddReg:"my_key" (Add current menu in registry)<BR><TAB>- myFloatingMenu.exe /DelReg (Delete current menu from registry) [Menu_Line_13] Title = Help example... Options = Usage is :<BR><TAB>- Select a menu option to execute command<BR><TAB>- or press [Esc] to "exit" the menu [Menu_Line_13] Title = Nothing as [Menu_Line_13] is duplicated from previous one ! (only first [Menu_Line_xx] occurrence count) [Menu_Line_14] Title = -Exit menu option- [Menu_Line_15] Title = Nothing as out of "Menu_Lines" number... [Menu_Line_16] Title = Nothing as out of "Menu_Lines" number...Here the au3 script expandcollapse popup; -----------------------------------8<----------------------------------- ; myFloatingMenu - Mjr. 04/2011 - Rev E.07 ; -----------------------------------8<----------------------------------- #include <array.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> ; -----------------------------------8<----------------------------------- $Ini_File = StringReplace(StringReplace(@ScriptFullPath,".au3",".ini"),".exe",".ini") ; -----------------------------------8<----------------------------------- $DEBUG = IniRead($Ini_File, "Default_Config", "DEBUG", 0) If $DEBUG = 1 Then $DEBUG = True Else $DEBUG = False EndIf $Menu_Lines = IniRead($Ini_File, "Default_Config", "Menu_Lines",0) ; -----------------------------------8<----------------------------------- $HRValue = "---" ; -----------------------------------8<----------------------------------- $Title = StringReplace(StringReplace(@ScriptName,".au3",""),".exe","") $Rev = IniRead($Ini_File, "Default_Config", "Revision", 0) $Title = $Title & " - " & $Rev ; -----------------------------------8<----------------------------------- ; -----------------------------------8<----------------------------------- ; Registry FloatingMenu /RegAdd or /RegDel ? If $CmdLine[0] = 1 Then If StringUpper(StringLeft($CmdLine[1],7)) = "/REGADD" or StringUpper(StringLeft($CmdLine[1],7)) = "/ADDREG" Then ; Get /RegAdd:"menu title to add in Registry" $RegKey = IniRead($Ini_File, "Default_Config", "MenuRegKey", " + my&FloatingMenu...") If $RegKey = " + my&FloatingMenu..." Then $RegKey = StringMid($CmdLine[1],9) If StringLen($RegKey) = 0 Then $RegKey = " + my&FloatingMenu..." EndIf ; Add current Script to Registry, on any File/Folder right mouse click menu $RetVal = RegWrite("HKEY_CLASSES_ROOT\*\shell\" & $RegKey & "\command","","REG_SZ",@ScriptFullPath & ' "%l"') $RetVal = $RetVal + RegWrite("HKEY_CLASSES_ROOT\Folder\shell\" & $RegKey & "\command","","REG_SZ",@ScriptFullPath & ' "%l"') If $RetVal = 2 Then MSgBox(0+64,$Title,"Successfully added key [" & $RegKey & "] in registry, for any file/folder mouse right button menu.") Else MSgBox(0+48,$Title,"Impossible to add in registry the key [" & $RegKey & "]") EndIf IniWrite($Ini_File, "Default_Config", "MenuRegKey", Chr(34) & $RegKey & Chr(34)) Exit ElseIf StringUpper(StringLeft($CmdLine[1],7)) = "/REGDEL" or StringUpper(StringLeft($CmdLine[1],7)) = "/DELREG" Then ; Get /RegDel:"menu title to delete from Registry" $RegKey = StringMid($CmdLine[1],9) If StringLen($RegKey) = 0 Then ; $RegKey = " + myFloatingMenu..." $RegKey = IniRead($Ini_File, "Default_Config", "MenuRegKey", " + my&FloatingMenu...") EndIf ; Remove current Script from Registry, for any File/Folder right mouse click menu $RetVal = RegDelete("HKEY_CLASSES_ROOT\*\shell\" & $RegKey) $RetVal = $RetVal + RegDelete("HKEY_CLASSES_ROOT\Folder\shell\" & $RegKey) If $RetVal = 2 Then MSgBox(0+64,$Title,"Successfully deleted from registry key [" & $RegKey & "], for any file/folder mouse right button menu.") Else MSgBox(0+48,$Title,"Impossible to delete from registry the key [" & $RegKey & "]") EndIf Exit EndIf EndIf ; -----------------------------------8<----------------------------------- ; -----------------------------------8<----------------------------------- ; Create a Menu Array + fill a header (not really necessary...) : Id, Menu title, Command Local $aMenuRow = 1 Local $aMenuCol = 4 Local $aMenu[$aMenuRow][$aMenuCol] $aMenu[0][0] = "GUICtrlCreateMenuItem Id" ; $aMenu[x][0] : Will contain the "Handle" of the "GUICtrlCreateMenuItem" (see function GUIBuildAndShowMenu() ) $aMenu[0][1] = "Menu Title" ; $aMenu[x][1] : Will contain the "Title" from ini file (see function BuildaMenuArray() ) $aMenu[0][2] = "Command" ; $aMenu[x][2] : Will contain the "Command" from ini file (see function BuildaMenuArray() ) $aMenu[0][3] = "Options" ; $aMenu[x][3] : Will contain the "Options" from ini file (see function BuildaMenuArray() ) ; -----------------------------------8<----------------------------------- ; (only) Parse ini file to fill the Menu array with Title + Command + Options BuildaMenuArray() ; -----------------------------------8<----------------------------------- ; Build & shouw the GUI menu (& fill the last empty column $aMenu[x][0] with the currently created MenuItem "handles") GUIBuildAndShowMenu() ; -----------------------------------8<----------------------------------- ; Wait in loop user's "menu choice", and execute the selected command GUIWaitUserMenuSelectionAndExecuteCommand() Exit ; -----------------------------------8<----------------------------------- ; -----------------------------------8<----------------------------------- ; (only) Parse ini file to fill the Menu array with Title + Command + Options Func BuildaMenuArray() For $mId = 1 to $Menu_Lines $aMenuRow = $aMenuRow + 1 ReDim $aMenu[$aMenuRow][$aMenuCol] $aMenu[$mId][0] = "<Empty at this step, will be GUICtrlCreateMenuItem()>" $aMenu[$mId][1] = StringReplace( IniRead($Ini_File, "Menu_Line_" & $mId, "Title", "") ,'\"',Chr(34)) $aMenu[$mId][2] = StringReplace( IniRead($Ini_File, "Menu_Line_" & $mId, "Command", "") ,'\"',"") $aMenu[$mId][3] = StringReplace( IniRead($Ini_File, "Menu_Line_" & $mId, "Options", "") ,'\"',Chr(34)) ; Below... replace in "Options", any #CMDLINEx# by the current script $CmdLine[X] value(s) ; Not really efficient, as only takes 3x parameters, but works ;-) If StringInStr($aMenu[$mId][3],"#CMDLINE1#") <> 0 Then If $CmdLine[0] >= 1 Then $aMenu[$mId][1] = StringReplace($aMenu[$mId][1],"#CMDLINE1#",$CmdLine[1]) $aMenu[$mId][3] = StringReplace($aMenu[$mId][3],"#CMDLINE1#",$CmdLine[1]) Else $aMenu[$mId][1] = StringReplace($aMenu[$mId][1],"#CMDLINE1#","") $aMenu[$mId][3] = StringReplace($aMenu[$mId][3],"#CMDLINE1#","") EndIf EndIf If StringInStr($aMenu[$mId][3],"#CMDLINE2#") <> 0 Then If $CmdLine[0] >= 2 Then $aMenu[$mId][1] = StringReplace($aMenu[$mId][1],"#CMDLINE2#",$CmdLine[2]) $aMenu[$mId][3] = StringReplace($aMenu[$mId][3],"#CMDLINE2#",$CmdLine[2]) Else $aMenu[$mId][1] = StringReplace($aMenu[$mId][1],"#CMDLINE2#","") $aMenu[$mId][3] = StringReplace($aMenu[$mId][3],"#CMDLINE2#","") EndIf EndIf If StringInStr($aMenu[$mId][3],"#CMDLINE3#") <> 0 Then If $CmdLine[0] >= 3 Then $aMenu[$mId][1] = StringReplace($aMenu[$mId][1],"#CMDLINE3#",$CmdLine[3]) $aMenu[$mId][3] = StringReplace($aMenu[$mId][3],"#CMDLINE3#",$CmdLine[3]) Else $aMenu[$mId][1] = StringReplace($aMenu[$mId][1],"#CMDLINE3#","") $aMenu[$mId][3] = StringReplace($aMenu[$mId][3],"#CMDLINE3#","") EndIf EndIf ; Replace #Options# by "Options=" in Menu Title $aMenu[$mId][1] = StringReplace( $aMenu[$mId][1], "#Options#",$aMenu[$mId][3]) Next ; -----------------------------------8<----------------------------------- If $DEBUG Then _ArrayDisplay($aMenu,"#Debug# - " & $Title & " - " & "aMenu Array created - #Debug#") EndFunc ; -----------------------------------8<----------------------------------- ; -----------------------------------8<----------------------------------- ; Build & shouw the GUI menu (& fill the last empty column $aMenu[x][0] with the currently created MenuItem "handles") Func GUIBuildAndShowMenu() Local $hGui, $msg $pos = MouseGetPos() ; Create a GUI window. $hGui = GUICreate($Title, 0, 0,-1,-1,$WS_POPUP,BitOR($WS_EX_TOPMOST,$WS_EX_TOOLWINDOW)) WinMove($Title, "", $pos[0]-3, $pos[1]-3) ; Create a dummy control and a contextmenu $MenuCtrl = GUICtrlCreateDummy() ; Creates a context menu for a control $MenuContext = GUICtrlCreateContextMenu($MenuCtrl) ; Add lines in this '$MenuContext' menu & Fill the "last enpty column" $aMenu[x][0] with current GUICtrlCreateMenuItem "handle" For $mId = 1 to $Menu_Lines If $aMenu[$mId][1] = "-" Then $aMenu[$mId][0] = GUICtrlCreateMenuItem("", $MenuContext) Else $aMenu[$mId][0] = GUICtrlCreateMenuItem($aMenu[$mId][1], $MenuContext) EndIf Next ; Changes the state of a GUI window (default = Hide) GUISetState() If $DEBUG Then _ArrayDisplay($aMenu,"#Debug# - " & $Title & " - " & "aMenu Array now filled with GUICtrlCreateMenuItem() 'handles' - #Debug#") ; Show the menu GUIShowMenu($hGui, $msg, $MenuContext) EndFunc ; -----------------------------------8<----------------------------------- ; Show a menu in a given GUI window which belongs to a given GUI ctrl Func GUIShowMenu($hWnd, $CtrlID, $nContextID) Local $arPos, $x, $y Local $hMenu = GUICtrlGetHandle($nContextID) $arPos = ControlGetPos($hWnd, "", $CtrlID) $x = $arPos[0] $y = $arPos[1] + $arPos[3] GUIConvertClientToScreen($hWnd, $x, $y) GUIShowAndTrackPopupMenu($hWnd, $hMenu, $x, $y) EndFunc ; -----------------------------------8<----------------------------------- ; Convert the client (GUI) coordinates to screen (desktop) coordinates Func GUIConvertClientToScreen($hWnd, ByRef $x, ByRef $y) Local $stPoint = DllStructCreate("int;int") DllStructSetData($stPoint, 1, $x) DllStructSetData($stPoint, 2, $y) DllCall("user32.dll", "int", "ClientToScreen", "hwnd", $hWnd, "ptr", DllStructGetPtr($stPoint)) $x = DllStructGetData($stPoint, 1) $y = DllStructGetData($stPoint, 2) ; release Struct not really needed as it is a local $stPoint = 0 EndFunc ; -----------------------------------8<----------------------------------- ; Show at the given coordinates (x, y) the popup menu (hMenu) which belongs to a given GUI window (hWnd) Func GUIShowAndTrackPopupMenu($hWnd, $hMenu, $x, $y) DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $x, "int", $y, "hwnd", $hWnd, "ptr", 0) EndFunc ; -----------------------------------8<----------------------------------- ; -----------------------------------8<----------------------------------- ; Wait in loop user's "menu choice", and execute the selected command Func GUIWaitUserMenuSelectionAndExecuteCommand() ; Loop (parse) "forever" menu until option choosed or [Esc] While True ; Wait for menu choice $msg = GUIGetMsg() ; Check for Esc key press If $msg = $GUI_EVENT_CLOSE or $msg = 0 Then ; Destroy menu & exit GUIDelete() Exit EndIf ; Check to execute command... by comparing each $msg to id in aMenu[x][0] For $mId = 1 to $Menu_Lines ; Found a MenuItem "Handle" matching user's choice... build possible command to execute... If $msg = $aMenu[$mId][0] Then ; Execute selected menu command... $FullCommand = Chr(34) & $aMenu[$mId][2] & Chr(34) & " " & $aMenu[$mId][3] If $DEBUG Then MsgBox(0,"#Debug# - " & $Title & " - #Debug#","Selected Menu Item :" & @CR & "- Execute menu id #" & $mId & @CR & "- Title : " & $aMenu[$mId][1] & @CR & "- Command : " & $aMenu[$mId][2] & @CR & "- Option : " & $aMenu[$mId][3] & @CR & "- (Possible) Full executable Command (depending on Command= & Options=) : " & @CR & @TAB & $FullCommand) ; If $aMenu[x][2] is empty ("Command="), then, try to show a popup (if $aMenu[$mId][3] ("Options=") is NOT empty) -or- directly exit menu If $aMenu[$mId][2] = "" Then ; Should we show a popup ? If $aMenu[$mId][3] <> "" Then $Token = $aMenu[$mId][3] $Token = StringReplace($Token,"<BR>", @CR) $Token = StringReplace($Token,"<HR>", $HRValue) $Token = StringReplace($Token,"<TAB>", @TAB) MsgBox(0+64,$Title,$Token) Else ; Execute nothing, as "Command=" is empty => exit from menu ; MsgBox(0+48,$Title,"Exit from menu...") EndIf Else ; Execute the command... $RetVal = Run($FullCommand) If $DEBUG Then If $RetVal = 0 and @error <> 0 Then MsgBox(0,"#Debug# - " & $Title & " - #Debug#","Error on execution of : " & $FullCommand) EndIf EndIf ; Destroy menu & exit GUIDelete() Exit EndIf Next WEnd EndFunc ; -----------------------------------8<----------------------------------- Link to comment Share on other sites More sharing options...
Mjolnir Posted April 5, 2011 Author Share Posted April 5, 2011 Edit on 05/04/2011 : I've improved the menu creation, time to load it & added a possibility to have a sub-branch. Hello all, Using since a long time AutoIt, here my first participation in this forum, hope this helps... Here is a quick dynamic menu creation under right mouse click button, on any file/folder, using a simple ini file for list of "programs" to run. Usage of myFloatingMenu is simple : once compiled (or not), it reads the ini file, and create a dynamic menu under user's cursor, each menu line corresponding to a [Menu_Line_XX] section from ini file. Command line option : myFloatingMenu.exe (call menu under user's cursor)myFloatingMenu.exe <file name>|<foldername> (call menu, with parameter as current file/folder, usable via #CMDLINEx# parameters in ini file)myFloatingMenu.exe /AddReg (Add current menu in registry, using ini RegKey=)myFloatingMenu.exe /AddReg:"my_key" (Add current menu in registry)<BR><TAB>- myFloatingMenu.exe /DelReg (Delete current menu from registry) The trick is, once added in registry (using /AddReg option on command line), this FloatingMenu is available for any right mouse click, on file/folder, to perform <your> specific action(s) described in the ini file Enjoy... --- Ini configuration is relatively easy : simply add in ini file list of [Menu_Line_XX] sections, that will cointain : ( SubMenu = optional sub-branch from main menu)Title = title of menu that will be createdCommand = program to executeOptions = option on "command" command line Here myFloatingMenu.ini file:expandcollapse popup#~ -------------------------------------------------8<------------------------------------------------- #~ [Default_Config] #~ Debug = [0|1] (1 to activate "debug" mode, default value = 0) #~ Revision = <any text> (= your own revision of current ini file, for any TextBox ("Title=" + "Options=" only)) #~ MenuRegKey = "<any text, may contain a &>" (name of menu entry [in registry + for right click mouse button on any file/folder], default value is = " + my&FloatingMenu...") #~ Menu_Lines = <a number> (it's the number of the LAST menu section to take into account below ... ie, number of [Menu_Line_<1-999>] sections to read, to create the dynamic menu, any "gap" will be "jumped" (no menu row will be created) #~ -------------------------------------------------8<------------------------------------------------- [Default_Config] Debug = 0 Revision = A.05 MenuRegKey =" + myFloatingMenu..." Menu_Lines = 100 #~ -------------------------------------------------8<------------------------------------------------- #~ [Menu_Line_<1-999>] #~ ( SubMenu = OPTIONAL !!! <SubMenuName> : any [Menu_Line_xxx] section that will contain this "SubMenu =" paranmeter will be placed in same sub-branch of main menu. ) #~ Title = <-> or <Menu Title> (can contain : #CMDLINE1#, #CMDLINE2# or #CMDLINE3#) or #~ <Menu Title #Options# (and #Options# will be replaced by value of "Options=")> or #~ <Menu Title without "Command=" and without "Option=" (= perform an EXIT)> or #~ <Menu Title with "Options=" only = show a popup>, #~ <if empty, no menu will be shown> #~ Command = <full command line to exe, WITHOUT quotes (")> or <leave empty> or #~ <#COMSPECEXEC# : will directly execute the file/folder specified on "Title=" as it is (without any Option)> #~ Options = <possible command line option(s) for "Command=">... #~ (can use too : #CMDLINE1#, #CMDLINE2# or #CMDLINE3# or \"#CMDLINE1#\", as parameters taken from script command line) or #~ <Menu Title with "Options=" only, with "Options=" that could contain <BR><HR><TAB> = to show a text popup window with "Options" as text> or <leave empty> #~ -------------------------------------------------8<------------------------------------------------- [Menu_Line_10] Title = #CMDLINE1# Command = #COMSPECEXEC# [Menu_Line_11] Title = notepad.exe Command = #COMSPECEXEC# [Menu_Line_12] Title = c:\WINDOWS\ Command = #COMSPECEXEC# [Menu_Line_13] Title = MSDos box (Cmd.exe #Options#) Command = cmd.exe Options = /k echo. && cd && echo. && dir [Menu_Line_14] Title = - [Menu_Line_21] Title = - Dummy (error) exe program (no exec. will be performed) Command = DummyProgramThatWillNotWork.exe Options = \"#CMDLINE1#\" [Menu_Line_22] Title = - [Menu_Line_30] Title = Current selected file/folder is... Options = The current selected "line" (file/folder) is =<BR>#CMDLINE1# [Menu_Line_31] Title = Command line is : #CMDLINE1# #CMDLINE2# #CMDLINE3# Options = Command line is (reverse order) : #CMDLINE3# #CMDLINE2# #CMDLINE1# [Menu_Line_32] Title = - [Menu_Line_40] SubMenu = Explorer... Title = Explorer Command = explorer.exe [Menu_Line_41] SubMenu = Explorer... Title = + Start Explorer on \"c:\Documents and Settings\" Command = c:\WINDOWS\explorer.exe Options = \"c:\Documents and Settings"\ [Menu_Line_42] SubMenu = Explorer... Title = + Start Explorer on \"#CMDLINE1#\" Command = c:\WINDOWS\explorer.exe Options = \"#CMDLINE1#\" [Menu_Line_43] SubMenu = Explorer... Title = + Start Explorer on #Options# Command = explorer Options = \"#CMDLINE1#\" [Menu_Line_44] SubMenu = Explorer... Title = + Start Explorer, taking first option on script command line (/e,/root,#CMDLINExx#) Command = explorer.exe Options = /e,/root,\"#CMDLINE1#\" [Menu_Line_45] Title = - [Menu_Line_50] Title = Start Internet Explorer (#Options#) Command = c:\Program Files\Internet Explorer\iexplore.exe Options = http://www.google.com [Menu_Line_51] Title = - [Menu_Line_60] Title = Start Notepad Command = notepad [Menu_Line_61] Title = Start Notepad (on file : #Options#) Command = notepad Options = #CMDLINE1# #~ [Menu_Line_62] #~ Title = Excel (with doc. givent as 1st command line parameter) #~ Command = c:\Program Files\Microsoft Office\OFFICE11\EXCEL.EXE #~ Options = \"#CMDLINE1#\" [Menu_Line_65] Title = - [Menu_Line_70] SubMenu = Open Folder... Title = Open folder via : Total Commander #Options# Command = c:\Program Files\TOTALCMD.EXE Options = /O /L=c:\WINDOWS [Menu_Line_71] SubMenu = Open Folder... Title = Open folder via : Total Commander #Options# Command = c:\Program Files\TOTALCMD.EXE Options = /O /R=c:\WINDOWS [Menu_Line_72] SubMenu = Open Folder... Title = Open folder via : Explorer #Options# Command = explorer Options = c:\WINDOWS [Menu_Line_80] Title = - [Menu_Line_81] Title = myFloatingMenu.exe : directly modify myFloatingMenu.ini config file... Command = notepad Options = myFloatingMenu.ini [Menu_Line_82] Title = - [Menu_Line_90] SubMenu = Help/About... Title = Help... (myFloatingMenu.exe usage/add to registry/etc...) Options = Syntaxe usage is<BR><TAB>- myFloatingMenu.exe (call current menu)<BR><TAB>- myFloatingMenu.exe <file name>|<foldername> (call menu, with parameter as current file/folder, usable via #CMDLINEx# parameters in ini file)<BR><TAB>- myFloatingMenu.exe /AddReg (Add current menu in registry, using ini RegKey=)<BR><TAB>- myFloatingMenu.exe /AddReg:"my_key" (Add current menu in registry)<BR><TAB>- myFloatingMenu.exe /DelReg (Delete current menu from registry) [Menu_Line_91] SubMenu = Help/About... Title = - [Menu_Line_92] SubMenu = Help/About... Title = About... Options = About example popup message box<BR>(c) 04/2011<BR><HR><BR>myFloatingMenu.exe is my Dynamic Menu "tool" (using a .ini file)<BR>for list of actions (programs) to perform on a selected file/folder. [Menu_Line_92] Title = Nothing as [Menu_Line_91] is duplicated from previous one ! (only first [Menu_Line_xx] occurrence count) [Menu_Line_100] Title = Exit (= dummy menu title option, for simple "exit") [Menu_Line_100] Title = Nothing as already previously defined [Menu_Line_200] Title = Nothing as out of "Menu_Lines" number... Here the au3 script expandcollapse popup; -----------------------------------8<----------------------------------- ; myFloatingMenu - Mjr. 04/04/2011 - Rev F.01 ; -----------------------------------8<----------------------------------- #include <array.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> ; -----------------------------------8<----------------------------------- $Ini_File = StringReplace(StringReplace(@ScriptFullPath,".au3",".ini"),".exe",".ini") ; -----------------------------------8<----------------------------------- $DEBUG = IniRead($Ini_File, "Default_Config", "DEBUG", 0) If $DEBUG = 1 Then $DEBUG = True Else $DEBUG = False EndIf $Menu_Lines = IniRead($Ini_File, "Default_Config", "Menu_Lines",0) ; -----------------------------------8<----------------------------------- $HRValue = "---" ; -----------------------------------8<----------------------------------- $Title = StringReplace(StringReplace(@ScriptName,".au3",""),".exe","") $Rev = IniRead($Ini_File, "Default_Config", "Revision", 0) $Title = $Title & " - " & $Rev ; -----------------------------------8<----------------------------------- ; -----------------------------------8<----------------------------------- ; Registry FloatingMenu /RegAdd or /RegDel ? If $CmdLine[0] = 1 Then If StringUpper(StringLeft($CmdLine[1],7)) = "/REGADD" or StringUpper(StringLeft($CmdLine[1],7)) = "/ADDREG" Then ; Get /RegAdd:"menu title to add in Registry" $RegKey = IniRead($Ini_File, "Default_Config", "MenuRegKey", " + my&FloatingMenu...") If $RegKey = " + my&FloatingMenu..." Then $RegKey = StringMid($CmdLine[1],9) If StringLen($RegKey) = 0 Then $RegKey = " + my&FloatingMenu..." EndIf ; Add current Script to Registry, on any File/Folder right mouse click menu $RetVal = RegWrite("HKEY_CLASSES_ROOT\*\shell\" & $RegKey & "\command","","REG_SZ",@ScriptFullPath & ' "%l"') $RetVal = $RetVal + RegWrite("HKEY_CLASSES_ROOT\Folder\shell\" & $RegKey & "\command","","REG_SZ",@ScriptFullPath & ' "%l"') If $RetVal = 2 Then MSgBox(0+64,$Title,"Successfully added key [" & $RegKey & "] in registry, for any file/folder mouse right button menu.") Else MSgBox(0+48,$Title,"Impossible to add in registry the key [" & $RegKey & "]") EndIf IniWrite($Ini_File, "Default_Config", "MenuRegKey", Chr(34) & $RegKey & Chr(34)) Exit ElseIf StringUpper(StringLeft($CmdLine[1],7)) = "/REGDEL" or StringUpper(StringLeft($CmdLine[1],7)) = "/DELREG" Then ; Get /RegDel:"menu title to delete from Registry" $RegKey = StringMid($CmdLine[1],9) If StringLen($RegKey) = 0 Then ; $RegKey = " + myFloatingMenu..." $RegKey = IniRead($Ini_File, "Default_Config", "MenuRegKey", " + my&FloatingMenu...") EndIf ; Remove current Script from Registry, for any File/Folder right mouse click menu $RetVal = RegDelete("HKEY_CLASSES_ROOT\*\shell\" & $RegKey) $RetVal = $RetVal + RegDelete("HKEY_CLASSES_ROOT\Folder\shell\" & $RegKey) If $RetVal = 2 Then MSgBox(0+64,$Title,"Successfully deleted from registry key [" & $RegKey & "], for any file/folder mouse right button menu.") Else MSgBox(0+48,$Title,"Impossible to delete from registry the key [" & $RegKey & "]") EndIf Exit EndIf EndIf ; -----------------------------------8<----------------------------------- ; -----------------------------------8<----------------------------------- ; Create a Menu Array + fill a header (not really necessary...) : Id, Menu title, Command Local $aMenuRowUnseen = 0 Local $aMenuRow = 0 Local $aMenuCol = 6 Local $aMenu[$aMenuRow+1][$aMenuCol] $aMenu[$aMenuRow][0] = "GUICtrlCreateMenuItem Handle" ; $aMenu[x][0] : Will contain the "Handle" of the "GUICtrlCreateMenuItem" (see function GUIBuildAndShowMenu() ) $aMenu[$aMenuRow][1] = "Menu Title" ; $aMenu[x][1] : Will contain the "Title" from ini file (see function BuildaMenuArray() ) $aMenu[$aMenuRow][2] = "Command" ; $aMenu[x][2] : Will contain the "Command" from ini file (see function BuildaMenuArray() ) $aMenu[$aMenuRow][3] = "Options" ; $aMenu[x][3] : Will contain the "Options" from ini file (see function BuildaMenuArray() ) $aMenu[$aMenuRow][4] = "SubMenu Handle" ; $aMenu[x][4] : Will contain the "Sub Menu branch" title level from ini file (see function BuildaMenuArray() ) $aMenu[$aMenuRow][5] = "SubMenu Title" ; $aMenu[x][5] : Will contain the "Sub Menu branch" Handle (see function GUIBuildAndShowMenu() ) ; -----------------------------------8<----------------------------------- ; (only) Parse ini file to fill the Menu array with Title + Command + Options BuildaMenuArray() ; -----------------------------------8<----------------------------------- ; Build & shouw the GUI menu (& fill the last empty column $aMenu[x][0] with the currently created MenuItem "handles") GUIBuildAndShowMenu() ; -----------------------------------8<----------------------------------- ; Wait in loop user's "menu choice", and execute the selected command GUIWaitUserMenuSelectionAndExecuteCommand() Exit ; -----------------------------------8<----------------------------------- ; -----------------------------------8<----------------------------------- ; (only) Parse ini file to fill the Menu array with Title + Command + Options Func BuildaMenuArray() For $mId = 1 to $Menu_Lines If IniRead($Ini_File, "Menu_Line_" & $mId, "Title", "<No section Found !>") <> "<No section Found !>" Then $aMenuRow = $aMenuRow + 1 ReDim $aMenu[$aMenuRow+1][$aMenuCol] $aMenu[$aMenuRow][0] = "<Empty at this step, will be = GUICtrlCreateMenuItem() during menu creation>" $aMenu[$aMenuRow][1] = StringReplace( IniRead($Ini_File, "Menu_Line_" & $mId, "Title", "") ,'\"',Chr(34)) $aMenu[$aMenuRow][2] = StringReplace( IniRead($Ini_File, "Menu_Line_" & $mId, "Command", "") ,'\"',"") $aMenu[$aMenuRow][3] = StringReplace( IniRead($Ini_File, "Menu_Line_" & $mId, "Options", "") ,'\"',Chr(34)) $aMenu[$aMenuRow][4] = "<Empty at this step, will be = GUICtrlCreateContextMenu() during menu creation>" $aMenu[$aMenuRow][5] = IniRead($Ini_File, "Menu_Line_" & $mId, "SubMenu", "#MAIN#") If StringLen($aMenu[$aMenuRow][5]) = 0 Then $aMenu[$aMenuRow][5] = "#MAIN#" ; Below... replace in "Options", any #CMDLINEx# by the current script $CmdLine[X] value(s) For $cl = 1 to 3 If $CmdLine[0] >= $cl Then If StringInStr($aMenu[$aMenuRow][1],"#CMDLINE" & $cl & "#") <> 0 or StringInStr($aMenu[$aMenuRow][3],"#CMDLINE" & $cl & "#") <> 0 Then $aMenu[$aMenuRow][1] = StringReplace($aMenu[$aMenuRow][1],"#CMDLINE" & $cl & "#",$CmdLine[$cl]) $aMenu[$aMenuRow][3] = StringReplace($aMenu[$aMenuRow][3],"#CMDLINE" & $cl & "#",$CmdLine[$cl]) EndIf Else $aMenu[$aMenuRow][1] = StringReplace($aMenu[$aMenuRow][1],"#CMDLINE" & $cl & "#","") $aMenu[$aMenuRow][3] = StringReplace($aMenu[$aMenuRow][3],"#CMDLINE" & $cl & "#","") EndIf Next ; Replace #Options# by "Options=" in Menu Title $aMenu[$aMenuRow][1] = StringReplace( $aMenu[$aMenuRow][1], "#Options#",$aMenu[$aMenuRow][3]) Else $aMenuRowUnseen = $aMenuRowUnseen + 1 EndIf Next ; -----------------------------------8<----------------------------------- If $DEBUG Then MsgBox(0+64,"#Debug# - " & $Title & " - #Debug#","Generic variables ..." & @CR & @CR & _ "Ini file :" & @CR & _ @TAB & "- declared 'Menu_Lines='" & @TAB & @TAB & $Menu_Lines & @CR & _ @TAB & "- 'unseen/dropped' sections count" & @TAB & $aMenuRowUnseen & @CR & _ @TAB & "- sections '[Menu_Line_xxx]' count" & @TAB & $aMenuRow & @CR & _ @CR & _ "Menu :" & @CR & _ @TAB & "- rows created/available" & @TAB & @TAB & $aMenuRow) _ArrayDisplay($aMenu,"#Debug# - " & $Title & " - " & "aMenu Array created - #Debug#") EndIf EndFunc ; -----------------------------------8<----------------------------------- ; -----------------------------------8<----------------------------------- ; Build & shouw the GUI menu (& fill the last empty column $aMenu[x][0] with the currently created MenuItem "handles") Func GUIBuildAndShowMenu() Local $hGui, $msg $pos = MouseGetPos() ; Create a GUI window. $hGui = GUICreate($Title, 0, 0,-1,-1,$WS_POPUP,BitOR($WS_EX_TOPMOST,$WS_EX_TOOLWINDOW)) WinMove($Title, "", $pos[0]-3, $pos[1]-3) ; Create a dummy control and a contextmenu $MenuCtrl = GUICtrlCreateDummy() ; Creates a context menu for a control $aMenu[0][4] = GUICtrlCreateContextMenu($MenuCtrl) ; Add lines in this '$MenuContext' menu & Fill the "last enpty column" $aMenu[x][0] with current GUICtrlCreateMenuItem "handle" ; If current menu name is <> from previous ($aMenu[$mId][5] => "SubMenu"), then, create a new "GUICtrlCreateMenu") For $mId = 1 to $aMenuRow If $aMenu[$mId][1] = "-" Then ; Create a SubMenu ? If $aMenu[$mId][5] <> "#MAIN#" and $aMenu[$mId][5] <> "" Then $aMenu[$mId][4] = $aMenu[$mId-1][4] $aMenu[$mId][0] = GUICtrlCreateMenuItem("", $aMenu[$mId][4]) Else $aMenu[$mId][4] = $aMenu[0][4] $aMenu[$mId][0] = GUICtrlCreateMenuItem("", $aMenu[0][4]) EndIf Else If StringLen($aMenu[$mId][1]) <> 0 Then ; Create a SubMenu ? If $aMenu[$mId][5] <> "#MAIN#" and $aMenu[$mId][5] <> "" Then If $aMenu[$mId][5] <> $aMenu[$mId-1][5] Then $aMenu[$mId][4] = GUICtrlCreateMenu($aMenu[$mId][5],$aMenu[0][4]) Else $aMenu[$mId][4] = $aMenu[$mId-1][4] EndIf $aMenu[$mId][0] = GUICtrlCreateMenuItem($aMenu[$mId][1], $aMenu[$mId][4]) Else $aMenu[$mId][4] = $aMenu[0][4] $aMenu[$mId][0] = GUICtrlCreateMenuItem($aMenu[$mId][1], $aMenu[0][4]) EndIf Else $aMenu[$mId][0] = "<No menu there !>" EndIf EndIf Next ; Changes the state of a GUI window (default = Hide) GUISetState() If $DEBUG Then _ArrayDisplay($aMenu,"#Debug# - " & $Title & " - " & "aMenu Array now filled with GUICtrlCreateMenuItem() 'handles' - #Debug#") ; Show the menu GUIShowMenu($hGui, $msg, $aMenu[0][4]) EndFunc ; -----------------------------------8<----------------------------------- ; Show a menu in a given GUI window which belongs to a given GUI ctrl Func GUIShowMenu($hWnd, $CtrlID, $nContextID) Local $arPos, $x, $y Local $hMenu = GUICtrlGetHandle($nContextID) $arPos = ControlGetPos($hWnd, "", $CtrlID) $x = $arPos[0] $y = $arPos[1] + $arPos[3] GUIConvertClientToScreen($hWnd, $x, $y) GUIShowAndTrackPopupMenu($hWnd, $hMenu, $x, $y) EndFunc ; -----------------------------------8<----------------------------------- ; Convert the client (GUI) coordinates to screen (desktop) coordinates Func GUIConvertClientToScreen($hWnd, ByRef $x, ByRef $y) Local $stPoint = DllStructCreate("int;int") DllStructSetData($stPoint, 1, $x) DllStructSetData($stPoint, 2, $y) DllCall("user32.dll", "int", "ClientToScreen", "hwnd", $hWnd, "ptr", DllStructGetPtr($stPoint)) $x = DllStructGetData($stPoint, 1) $y = DllStructGetData($stPoint, 2) ; release Struct not really needed as it is a local $stPoint = 0 EndFunc ; -----------------------------------8<----------------------------------- ; Show at the given coordinates (x, y) the popup menu (hMenu) which belongs to a given GUI window (hWnd) Func GUIShowAndTrackPopupMenu($hWnd, $hMenu, $x, $y) DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $x, "int", $y, "hwnd", $hWnd, "ptr", 0) EndFunc ; -----------------------------------8<----------------------------------- ; -----------------------------------8<----------------------------------- ; Wait in loop user's "menu choice", and execute the selected command Func GUIWaitUserMenuSelectionAndExecuteCommand() ; Loop (parse) "forever" menu until option choosed or [Esc] While True ; Wait for menu choice $msg = GUIGetMsg() ; Check for Esc key press If $msg = $GUI_EVENT_CLOSE or $msg = 0 Then ; Destroy menu & exit GUIDelete() Exit EndIf ; Check to execute command... by comparing each $msg to id in aMenu[x][0] For $mId = 1 to $aMenuRow ; Found a MenuItem "Handle" matching user's choice... build possible command to execute... If $msg = $aMenu[$mId][0] Then ; Execute selected menu command... $FullCommand = Chr(34) & $aMenu[$mId][2] & Chr(34) & " " & $aMenu[$mId][3] If $DEBUG Then MsgBox(0+64,"#Debug# - " & $Title & " - #Debug#","Selected Menu Item :" & @CR & "- Execute menu line #" & $mId & " (Row)" & @CR & "- Title : " & $aMenu[$mId][1] & @CR & "- Command : " & $aMenu[$mId][2] & @CR & "- Option : " & $aMenu[$mId][3] & @CR & "- (Possible) Full executable Command (depending on Command= & Options=) : " & @CR & @TAB & $FullCommand) ; If $aMenu[x][2] is empty ("Command="), then, try to show a popup (if $aMenu[$mId][3] ("Options=") is NOT empty) -or- directly exit menu If $aMenu[$mId][2] = "" Then ; Should we show a popup ? If $aMenu[$mId][3] <> "" Then $Token = $aMenu[$mId][3] $Token = StringReplace($Token,"<BR>", @CR) $Token = StringReplace($Token,"<HR>", $HRValue) $Token = StringReplace($Token,"<TAB>", @TAB) MsgBox(0+64,$Title,$Token) Else ; Execute nothing, as "Command=" is empty => exit from menu ; MsgBox(0+48,$Title,"Exit from menu...") EndIf Else ; Execute the command... If $aMenu[$mId][2] = "#COMSPECEXEC#" Then ; Execute directly file/folder on commandline ;~ If FileExists($aMenu[$mId][1]) Then $RetVal = ShellExecute($aMenu[$mId][1]) ;~ Else ;~ MsgBox(0+16,$Title,"File/Folder [ " & $aMenu[$mId][1] & " ] does not exists." & @CR & "Abort.") ;~ EndIf Else ; Execute the FullCommand (Command + Options) $RetVal = Run($FullCommand) EndIf If $DEBUG Then If $RetVal = 0 and @error <> 0 Then MsgBox(0,"#Debug# - " & $Title & " - #Debug#","Error on execution of : " & $FullCommand) EndIf EndIf ; Destroy menu & exit GUIDelete() Exit EndIf Next WEnd EndFunc ; -----------------------------------8<----------------------------------- Link to comment Share on other sites More sharing options...
Gigglestick Posted May 4, 2011 Share Posted May 4, 2011 Simpler: $Ini_File = StringTrimRight(@ScriptFullPath, 4) & ".ini" My UDFs: ExitCodes Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now