[MHo] recycled an old program from DOS days and created a tcl prog which reads a script file at startup and present this as hierarchical menus. I need this to work on several inhomogeneous systems where the icons where here and there and everywhere and nowhere, and I need a way to quickly run things. Every menu item could be a complete tcl script, with some restrictions and some helper routines like "select" or "msgbox". Example screen: [http://home.arcor.de/hoffenbar/prog/menue.jpg] Some words about keys and functions: * '''''' starts the selected item, that is: going down in the hierarchy or exec'ing the underlying commands. * '''''' locates one matching item after another (does not immediately start anymore as in previous versions). * '''<.>''' goes up one level up in the hierarchy (or ''''''). * '''''' goes to the root menu (or ''''''). * '''''' shows minimal help and some infos. * '''''' shows app-specific help if defined (or ''''''). * '''''' shows a ''hotlist'' of the last ten selected commands. Pick one and re-run immediately. * '''''' shows the commands behind the current item (if not restricted). * '''''' reloads the menu-definition files (but not ''makros'' - they only load on first program start!). * '''''' minimize running instance into the system tray (task tray). Click on task tray icon to restore. * '''''' perform a search in result (text) windows. * '''''' selects all text in result windows. * '''''' shows tcl console (not shown in help). * '''''' hides tcl console (not shown in help). * '''''' shows internal control array and other information (for debug purposes). * '''''' clears every buffered values from entry fields and combo boxes ---- %| You can think of the program as a special two-stage tcl-interpreter. In the first stage, only the two main commands '''menu''' and '''app''' are possible (with various arguments) inside the file(s) interpreted by menue.exe. After interpreting these commands (stage-1), a gui representing the structure appears. Hitting ENTER on an app starts the commands "behind" the app, this means they are again interpreted by tcl (stage-2). |% Without special configuration, the program loads/processes all '''*.mnu'''-files (in that order) out of 1. the (VFS-)internal dir ''plugin''; 1. in the program (.exe) directory; 1. all folders specified via the '''--mnuDir "folder [[folder [[...]]]]"''' switch -or- in the current directory (pwd). Those .MNUs can initially (at the root level of parsing) contain only a very limited set of commands (which together form ''the heart of the whole machinery''...): * '''menu''' {title {code {}} {condition {}}} - adds a submenu. Menus nest. * '''app''' {title {code {}} {condition {}} {help {}} {hotkey {}}} - adds an entry in the current menu (the initial menu, root, is automatically created, so it's possible to add ''app'' statements outside any ''menu''s) where * ''title'' is the text that is shown in the listboxes as a title for applications or submenus (in the latter case suffixed with '''...''') * ''code'' is the (tcl-)code to be executed, if an ''app'' was selected and started via ''return'' or double click. In the case of ''menu'', ''code'' can only contain other ''menu'' or ''app'' statements. * ''condition'', if specified, controls if the menu or app is visible (if the tcl code in ''condition'' evaluates to ''true'') or not (if the tcl code in ''condition'' evaluates to ''false''). This is one instrument to build menus dynamically, depending on the current machines or users environment. * ''help'' this text is shown if user hits while this application entry is selected. * ''hotkey'' specifies a key(-combination) with immediately starts this application from (nearly) everywhere. Have to be specified in a format acceptable by [bind]. * If an ''app''-title begins with an asterisk * it is "executed" right after the start of menue.exe, as a simple kind of ''autostart mechanism'' (without any further control yet, though; with , these entries are not executed again). Some kind of ''special commands'' are available, too: * '''@startmenu''' - a kind of macro: dynamically including the ''current users'' and the ''all users'' startmenu entries at the position where @startmenu appears, through dynamically adding ''menu''- and ''app''-entries as if they where specified directly at that position in the source menu file (at the root level there) * '''@include''' '''''file''''' - opens and reads input from another menu file (same as above: has to appear at the root level). Only makes sense if the file extension doesn't equal ''.mnu'' or if the file is located elsewhere, since all .mnu's are parsed automatically. * '''@store''' '''''title''''' '''''text''''' - stores a block of (reusable) text for later usage (via ''@expand''). Blocks could contain variables which will be substituted at expansion time. * '''@expand''' '''''title''''' ?'''''mapping-list'''''? - inserts the text block previously stored via ''@store'', optionally giving a list of variables and values which is used to map variables in the text block to actual values. This is used to build large menu systems which repeat the same structures over and over with minimal modifications. The result of expansion is then interpreted in normal fashion as if it appears in the input stream instead of ''@expand''. * '''@setexpmap''' ''mapping'' - sets a mapping which will be automatically applied to all ''@expand''sions before the there given mapping occurs (that is, mappings given with ''@expand'' have priority). (...Description should be more detailed here; a simple example for the structure of a .MNU-file should be added!) ---- Additionally, the file(s) '''*.mak''' are sourced at program load time (not again with ) in that order: 1. the (VFS-)internal dir ''plugin''; 1. in the program (.exe) directory. Attention: Those *.MAKs could contain almost any tcl command and some tk commands. '''They are not intended to be edited by an end user'''. For this reason the pwd and other dirs are not parsed for makros, but only the path where the .EXE itself lives (in most situations, the end user has no write access there). Some fundamental macros are already a part of the exe (via Makros provided inside the VFS), containing some useful (at least for me) procs, like * '''start''' {what {confirmWarning 1}} - does essentially the same as the Windows ''start'' command. You can, e.g., '''start xyz.pdf'''. * '''start2''' {what {confirmWarning 1}} - same as above but should work as expected if 'what' contains multiple words... (other implementation, see [exec quotes problem] for further infos) * '''askExec''' {what {title "Wirklich ausführen?"}} - evals arbitrary (tcl) commands after if confirmed. * '''cmd2file''' {cmd {ext ""}} - more an internal utility - writes commands to a temporary file end returns the name of the file. * '''address''' {addr cmd {async "1"}} - executes the ''cmd''s in the environment specified by ''address''. ''address'' currently can be one of wscript, cscript, kix32, autoit3, wsf, or any other interpreter which can read the commands from stdin. Of course, the appropriate interpreters have to exist in the system. * '''tempName''' {} - constructs a unique file name within the %temp% folder an returns that name to the caller. * '''readFile''' {file {encoding ""}} - reads the whole file and returns the content to the caller in one block (Default encoding = [[encoding system]]). * '''shutdown''' {{immediate 0} {beforeScript ""}} - shutdowns the pc. Optionally confirmation (if ''immediate''==1), and optionally performing a script before shutting down. ...and some more which are probably too specific or not of common interest (or some are simply not documented yet), like ''makeAndStartICAFile''. ---- The following commands (and some more) are "built in" right into the .EXE; they are always available (unless overwritten by user macros, of course): * '''select''' {items {title "Auswahl:"} {opt ""}} - Display a subselection list like in the screendump above; ''opt'' not used yet... * '''cmdLineHelp''' {title txt args} - shows a scrollable textbox with output results of commands, for example. can be used to search text. * '''YesNo''' {msg} - for now, the ''title'' is fixed and cannot be specified. * '''AlarmYesNo''' {msg} - same as above but with another icon. * '''msgBox''' {msg {title "Info:"}} - does what the name implies... * '''msgBoxE''' {msg args} - title fixed - don't remember in what state I was when I programmed that... * '''subTitle''' ?{text}? - sets (or queries) the centered text at the top of the screen right below the title line. * '''winTitle''' ?{text}? - sets (or queries) the main window title. * '''scrW''' - is just a shorthand for ''winfo screenwidth .'' * '''scrH''' - is just a shorthand for ''winfo screenheight .'' * '''askValue''' {prompt {title "Eingabe:"} {width 40}} - like VB's ''inputbox''; if width < 0, the input is hidden. * '''console''' - just the console command * '''statusLine''' - sets (overwrites!) the status line at the bottom of the screen (should be better divided into a program and user area) * '''tk_chooseDirectory''' - just that (don't know why I don't created an alias for this...) * '''tk_getOpenFile''' - just that (don't know why I don't created an alias for this...) * '''tk_getSaveFile''' - just that (don't know why I don't created an alias for this...) * '''tk_messageBox''' - just that (a subset or abstraction of that is msgBox(E)) * '''tk_dialog''' - just that (don't know why I don't created an alias for this...) * '''setDefaultValue''' - sets the default value for a ''askValue''-dialog (because of compatibility aspects I was too lazy to add another arg to ''askValue''...) * '''getDefaultValue''' - gets the default value of a ''askValue''-dialog, if any. * '''callApp''' {menupath/to/app appName} - execudes code block from another app definition; can reduce double coding. * '''globx''' - see [Matthias Hoffmann - Tcl-Code-Snippets - misc - globx] for an explanation. * '''bgexec''' - executing commands which populate a ''cmdLineHelp''-windows step by step (not only after finishing) ''cmdLineHelp'' is, despite of it's name, of general interest. It can be used to show the results of commands in a scrollable and searchable (Ctrl+F) Box. In the future I plan to add ''Save As...'', ''Copy to clipboard'' and maybe a ''Print''-button. ---- Optionally, the program writes log entries to a user definable file. To configure this, create a file '''menue.rc''' in the same folder as the program and put the line ====== logFile the_name_of_some_logfile.log ====== in it. Thera are other options for this .rc, which need to be documented... You can find a copy of the program here: [http://home.arcor.de/hoffenbar/prog/menue.zip]. It's not always up to date there, though. Because the menu files I made are very specific, showing some internals of our company, I can't include them in the .ZIP or as an example here. You can ask questions here if you need some complex examples. The program originally only had one command line switch named '''--mnuDir'''. Current version as of Nov. 2011 is '''1.17'''. I have 100 ideas more to improve it, but too little time. In fact, the program is far away from the capabilities of it's DOS ancestor or even away from being nearly complete... ---- '''Known issues:''' * Importing the system's startmenu entries via ''@startmenu'' sometimes lasts very long, because some genious program designers populate the startmenu with all kinds of (unstartable) junk... A kind of interpretation should take place ([file executable] won't probably help that much). * See [Strange phenomen]. * See [Slow Starpack Start]. (Sorry for the many edits - old versions of this page could and should be deleted...) ---- '''Commandline Switches''' (need translation and explanation) ====== Syntax: menue.exe [ -? -@include: {1|0} -@startmenu: {1|0} -askExit: {1|0} -autoStarts: {1|0} -const -ignoreCond -logFile: Log-Datei -logSize: KiloBytes -logWait: Millisekunden -minToTray: {1|0} -mnuDir: Ordner -mnuFile: .mnu-Datei(en) -readmak: {1|0} -run: menuPath item ?exit? -see: menuPath ?item? -showMnuErrs: {1|0} -toTray: {1|0} ] Schalter: -? Diese Hilfe anzeigen. -@include: {1|0} @include-Makros verarbeiten. [1] -@startmenu: {1|0} @startmenu-Makro verarbeiten. [1] -askExit: {1|0} Vor Programmende fragen. [1] -autoStarts: {1|0} Autostarts ausführen. [1] -const Interne Konstantentabelle ausgeben. -ignoreCond Bedingungen ignorieren (als TRUE werten). -logFile: Log-Datei Name einer Protokolldatei. [__test__.log] -logSize: KiloBytes Maximale Grösse in KB -1 = unbegrenzt. [-1] -logWait: Millisekunden Maximale Wartezeit bei Logdateizugriffen. [1000] -minToTray: {1|0} Minimiert in den TaskTray. [0] -mnuDir: Ordner Weitere(r) Suchordner fuer Menue-Dateien. [] -mnuFile: .mnu-Datei(en) NUR DIESE Menue-Datei(en) verarbeiten! [] -readmak: {1|0} .mak-Dateien parsen. [1] -run: menuPath item ?exit? Anwendung direkt aufrufen. [] -see: menuPath ?item? Menü (und Anwendung) anzeigen (vorwählen). [] -showMnuErrs: {1|0} .mnu-Parsing-Fehler anzeigen. [1] -toTray: {1|0} Programm direkt in den TaskTray starten. [0] "Mehrere Wörter sind in {doppelte Anführungszeichen}" einzuschließen. {a|b} bedeutet a oder b, ein solcher ?wert? ist optional. Mit -mnuFile: angegebene Menüdatei(en) können als http://-URL angegeben werden. ====== ---- In some versions. the program contained the [tepam]-module, but due to unresolved issues I removed it and replaced with [GRIDPLUS2] as a build in dialog tool. Since even [GRIDPLUS2] is, for my taste, to complicated, I created some wrappers which allow creating somewhat complex dialogs with very little effort. Here's a simple example: This is a part of some .MNU-file: ====== app {gridplus2-Test3 (mit gpDialog1) ************ mit User-Buttons und anderen Tests} { if {[gpDialog1 dlg2 TestFensterTitel2 [list -title test -taborder row] { {&e "Benutzer" .benutzer} {&e "Neues Kennwort" .passwort + "=vorgabepw"} {"Optionen" &c .unlock} {&b "Testbutton" .b1 ~buttonCmd} {&b "Button-2" .button=btn2} {&b "Button-3" .button=btn3} {&D "Date-Sel1" .ds1} {&b "Button-4" .button=btn4} } { btn2 { msgBox "hallo-2" gpSetU dlg2 benutzer [tk_getOpenFile] } btn3 { msgBox "hallo-3" gpSetU dlg2 passwort Kenn } btn4 { # Test Rekursion if {[gpDialog1 dlg1 TestFensterTitel [list -title test -taborder row] { {&e "Benutzer" .benutzer} {&e "Neues Kennwort" .passwort +} {"Optionen" &c .unlock} {} }] == 1} { msgBox ">>>$dlg1_Val<<<" } } }] == 1} { msgBox ">>>$dlg2_Val<<<" } } ====== And the resulting dialog looks like this: [http://home.arcor.de/hoffenbar/prog/gpDialog1.jpg] ---- [HJG] This program looks useful, but the download does not contain the source. [MHo] You can easily extract the source using the utility [sdx]! But as I have to update the download spot the next days anyway, I can include the source tree as well. Anyway, that source tree won't help you much, since it doesn't contain all sources, as I "compile" with helper routines, which dynamically copy and remove modules as necessary from central shares: [Windows batch script for 'compiling' starpacks]. <> GUI