program ASMENU2,1.1(011) !ASMENU.BAS - Demonstrated adding and deleting menus to A-Shell/Windows !----------------------------------------------------------------------- !EDIT HISTORY: ! 1. 13-Oct-99 Add symbols (note that opcodes 2 & 3 were incorrect in the ! UPDATE.TXT file - 2 is change state and 3 is delete); ! disable "Bevelling" and delete "Scheduling" menus; ! add explanation of STATUS values /jdm ! 2. 15-Oct-99 More refinements; demonstrate disable & delete of built-in ! menus (previously this didn't work) /jdm ! 3. 11-Sep-02 Add a few ShellExecute options /jdm ! 4. 12-Feb-03 Demonstrate use of new simplified file-based interface/jdm ! 5. 17-Feb-03 Fix incorrect reference to "mnx" (should be "mdf) /jdm ! 6. 09-Jun-05 Add context (popup) menu; use new symbols, AUI_MENU /jdm ! 7. 11-Aug-05 Add option to popup menu directly /jdm ! 8. 01-Sep-06 Add 2 sep bars to file menu to test reported problem /jdm ! 9. 03-Nov-08 Add an SBX:item /jdm !Version 1.1--- !10. 12-Jun-09 Add checked menu items, modernize to use official syms /jdm !11. 15-Jun-09 Add itemid, use it to reference Custom menu /jdm !------------------------------------------------------------------------ ++include ashinc:ashell.def ! [6] ! ![11] define a structure for convenience to allow us to keep track ![11] of our custom menu items defstruct ST_MENU_ITEM ! [11] map2 text,s,32 map2 cmd,s,50 map2 state,b,4 map2 menuid,b,2 map2 itemid,b,2 endstruct MAP1 MENUID MAP2 MID'TOP,B,1,0 ! top level menu bar MAP2 MID'FILE,B,1,1 ! File menu id MAP2 MID'EDIT,B,1,2 ! Edit menu id MAP2 MID'SETTINGS,B,1,3 ! Settings menu id MAP2 MID'HELP,B,1,4 ! Help menu id MAP2 MID'CUS1,B,1,5 ! Custom menu #1 MAP2 MID'CONTEXT,F,6,-1 ! [6] Context menu #1 MAP1 MNU'NAME$(5),S,10 ! names of menus MAP1 MISC MAP2 I,F,6 MAP2 SEL'MID,F,6 ! menu we are working on MAP2 STATUS,F MAP2 MOP,B,2 MAP2 MFILE,S,40 MAP2 STATE,B,1 DATA "File", "Edit", "Settings", "Help" ! menu id names for I = 1 to 4 read MNU'NAME$(I) next I START: ? ? "ASMENU - Test adding & deleting menus to A-Shell/Windows" ? ![7] input "Enter 1)File-based interface, 2)Original interface, 3)Popup, 4)Delete popup:",I input "1)File mode, 2)Orig. mode, 3)Def. Popup, 4)Del. popup, 5)Show popup:",I IF I<1 or I>5 goto ENDIT on I call SIMPLE'MENU, TRADITIONAL'MENU, & POPUP'MENU'DEF, POPUP'MENU'DELETE, POPUP'MENU'SHOW ! [7] goto START ENDIT: ? "End" end !------------------------------------------------------------------------------- ! Traditional menu interface involves individual XCALLs to add/delete/change ! each menu item. This routine just provides some examples of what is possible. !------------------------------------------------------------------------------- TRADITIONAL'MENU: ! (traditional interface) SEL'MID = MID'FILE ! add to File menu ? "Adding Separator bar to ";MNU'NAME$(SEL'MID);" menu..."; MOP = MNUOP_ADD ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,SEL'MID,"s1",MBST_ENABLE, & MBF_SEP,"","",STATUS ? "STATUS = ";STATUS ? "Adding WINHELP menu to ";MNU'NAME$(SEL'MID);" menu..."; MOP = MNUOP_ADD ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,SEL'MID,"Help on WINHELP",MBST_ENABLE, & MBF_CMDLIN, "WINHELP C:\WINHELP.HLP","",STATUS ? "STATUS = ";STATUS; call SHOW'STATUS ! [8] ? "Adding Another Separator bar to ";MNU'NAME$(SEL'MID);" menu..."; MOP = MNUOP_ADD ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,SEL'MID,"s2",MBST_ENABLE, & MBF_SEP,"","",STATUS ? "STATUS = ";STATUS ? "Adding WINHELP 'printing' menu to ";MNU'NAME$(SEL'MID);" menu..."; MOP = MNUOP_ADD ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,SEL'MID,"WINHELP key=printing",MBST_ENABLE, & MBF_CMDLIN, "WINHELP -kprinting C:\WINHELP.HLP","",STATUS ? "STATUS = ";STATUS; call SHOW'STATUS ? "Adding Custom menu to top level..."; MOP = MNUOP_ADD ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,MID'TOP,"&Custom",MBST_ENABLE, & MBF_SUBMNU,"","",STATUS,0,1005 ? "STATUS = ";STATUS; call SHOW'STATUS ! Note that we can add the " $" suffix to the command to make sure ! that this window (A-Shell) does not get suspended while the other ! window is up. ? "Adding Edit INI menu to custom menu..."; MOP = MNUOP_ADD ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,MID'CUS1,"openf1.bmp::Edit MIAME.INI"+chr(9)+"F5",MBST_ENABLE, & MBF_CMDLIN, "NOTEPAD ..\..\MIAME.INI $","",STATUS ? "STATUS = ";STATUS; call SHOW'STATUS ? "Adding Calculator menu to custom menu..."; MOP = MNUOP_ADD ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,1005,"Calculator",MBST_ENABLE, & MBF_CMDLIN, "CALC.EXE $","",STATUS ? "STATUS = ";STATUS; call SHOW'STATUS ? "Adding Microsabio.com to custom menu..."; MOP = MNUOP_ADD ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,MID'CUS1,"MicroSabio Home Page",MBST_ENABLE, & MBF_SHLEXC, "http://www.microsabio.com","",STATUS ? "STATUS = ";STATUS; call SHOW'STATUS ? "Adding SBX:ATECFX to custom menu..."; ! [9] MOP = MNUOP_ADD ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,MID'CUS1,"ATECFX",MBST_ENABLE, & MBF_CMDLIN, "SBX:ATECFX,1","",STATUS ? "STATUS = ";STATUS; call SHOW'STATUS ? "Adding Checked menu item to custom menu..."; ![10] MOP = MNUOP_ADD ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,MID'CUS1,"Checked Item Ctrl+T", & MBST_ENABLE or MBST_CHECKED, MBF_CHKMNU, "","",STATUS ? "STATUS = ";STATUS; call SHOW'STATUS ? "Adding SubMenu to custom menu..."; ![11] MOP = MNUOP_ADD ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,MID'CUS1,"Options...", & MBST_ENABLE, MBF_SUBMNU, "","",STATUS,0,2000 ? "STATUS = ";STATUS; call SHOW'STATUS ? "Adding item to submenu..."; ![11] MOP = MNUOP_ADD ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,2000,"Option 1", & MBST_ENABLE or MBST_CHECKED, MBF_RADIOMNU, "","",STATUS,0,2001 ? "STATUS = ";STATUS; call SHOW'STATUS ? "Adding item to submenu..."; ![11] MOP = MNUOP_ADD ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,2000,"Option 2", & MBST_ENABLE, MBF_RADIOMNU, "","",STATUS,0,2002 ? "STATUS = ";STATUS; call SHOW'STATUS ? "Adding Another checked item to custom menu..."; ![10] MOP = MNUOP_ADD ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,MID'CUS1,"Checked Item2 Ctrl+1", & MBST_ENABLE, MBF_CHKMNU, "","",STATUS ? "STATUS = ";STATUS; call SHOW'STATUS ? ? "Menus added, try testing them. Then hit RETURN to proceed" STOP ? ? "Disabling 'Calculator' on custom menu..."; MOP = MNUOP_STA ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,MID'CUS1,"Calculator",MBST_DISABLE, & MBF_CMDLIN,"","",STATUS ? "STATUS = ";STATUS; call SHOW'STATUS ? "Hiliting checked item n custom menu..."; ![10] MOP = MNUOP_STA ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,MID'CUS1,"Checked Item", & MBST_ENABLE+MBST_HILITE+MBST_CHECKED, MBF_CHKMNU, "","",STATUS ! remove MBST_CHECKED ? "STATUS = ";STATUS; call SHOW'STATUS ? ? "You can check it before hitting RETURN to delete the added menus" STOP ? ? "Unchecking item on custom menu..."; ![10] MOP = MNUOP_STA ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,MID'CUS1,"Checked Item", & MBST_ENABLE, MBF_CHKMNU, "","",STATUS ! remove MBST_CHECKED ? "STATUS = ";STATUS; call SHOW'STATUS ? ? "You can check it before hitting RETURN to delete the added menus" STOP ? ! Note that on delete, the menu is identified by the text ! parameter, which must match exactly (although not case sensitive) ? "Deleting microsabio.com menu from custom menu..."; ! Note menu text not case sensitive MOP = MNUOP_DEL ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,MID'CUS1,"MicroSabio Home Page",0,0,"","",STATUS ? "STATUS = ";STATUS; call SHOW'STATUS ? "Deleting Calculator menu from custom menu..."; ! Note menu text not case sensitive MOP = MNUOP_DEL ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,MID'CUS1,"CALCULATOR",0,0,"","",STATUS ? "STATUS = ";STATUS; call SHOW'STATUS ? "Deleting Edit MIAME.INI menu from custom menu..."; MOP = MNUOP_DEL ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,MID'CUS1,"Edit MIAME.INI",0,0,"","",STATUS ? "STATUS = ";STATUS; call SHOW'STATUS ? "Deleting Custom menu from main menu..."; MOP = MNUOP_DEL ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,MID'TOP,"&Custom",0,0,"","",STATUS ? "STATUS = ";STATUS; call SHOW'STATUS ? "Deleting WINHELP menu from ";MNU'NAME$(SEL'MID);" menu..."; MOP = MNUOP_DEL ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,SEL'MID,"Help on WINHELP",0,0,"","",STATUS ? "STATUS = ";STATUS; call SHOW'STATUS ! [8] ? "Deleting Separator bar #2 from ";MNU'NAME$(SEL'MID);" menu..."; MOP = MNUOP_DEL ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,SEL'MID,"s2",0,0,"","",STATUS ? "STATUS = ";STATUS; call SHOW'STATUS ? "Deleting WINHELP 'printing' menu from ";MNU'NAME$(SEL'MID);" menu..."; MOP = MNUOP_DEL ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,SEL'MID,"WINHELP key=printing",0,0,"","",STATUS ? "STATUS = ";STATUS; call SHOW'STATUS ? "Deleting Separator bar #1 from ";MNU'NAME$(SEL'MID);" menu..."; MOP = MNUOP_DEL ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,SEL'MID,"s1",0,0,"","",STATUS ? "STATUS = ";STATUS; call SHOW'STATUS ! [2] Operations on built-in menus must use zero-relative position instead ! [2] of menu text. Note that separators take up a position. ! [2] Also note that deleting an item causes the ones below it to shift up, ! [2] so you should delete from the bottom up. ! [2] Finally, note that it is possible that the built-in menu layout could ! [2] change, so it may be wise to parameterize any such references to make ! [2] it easy to adjust your app later if necessary. ? ? "Disabling 'Bevelling' on Settings menu..."; MOP = MNUOP_STA ! (for benefit of SHOW'STATUS) ! "Bevelling" is 3rd item on menu (i.e. "2") xcall AUI,AUI_MENU,MOP,MID'SETTINGS,"2",MBST_DISABLE, & MBF_CMDLIN,"","",STATUS ? "STATUS = ";STATUS; call SHOW'STATUS ? "Deleting 'Scheduling' on Settings menu..."; MOP = MNUOP_DEL ! (for benefit of SHOW'STATUS) ! "Scheduling" is 1st item on menu (i.e. "0") xcall AUI,AUI_MENU,MOP,MID'SETTINGS,"0",0,0,"","",STATUS ? "STATUS = ";STATUS; call SHOW'STATUS ! [2] Deleting top level menus is possible also, although not recommended ! ? "Deleting 'Settings' menu..."; ! MOP = MNUOP_DEL ! (for benefit of SHOW'STATUS) ! ! "Settings" is 3rd item on menu (i.e. "2") ! xcall AUI,AUI_MENU,MOP,MID'TOP,"2",0,0,"","",STATUS ! ? "STATUS = ";STATUS; ! call SHOW'STATUS return SHOW'STATUS: ? " "; if STATUS = 0 ? "OK"; :& if MOP=MNUOP_STA and MFILE="" then ? " (was enabled)"; if STATUS = 1 ? "OK"; :& if MOP=MNUOP_STA then ? " (was grayed)"; if STATUS = -1 ? "Operation failed"; if STATUS = -2 ? "Menu not found"; if STATUS = -3 ? "Out of memory"; if STATUS = -4 ? "Too many menus added"; if STATUS = -5 ? "No menu buffer"; if STATUS = -6 ? "Illegal opcode"; if STATUS = -7 ? "Menu already exists"; if STATUS = -8 ? "Illegal menu ID"; if STATUS = 2147483647 ? "Enable/disable failed"; if (STATUS > 1 and STATUS < 2147483647) or STATUS < -8 ? "Other error"; ? return !------------------------------------------------------------------------- ! Simplified menu interface allows you to store the menu information ! in a text file and then add or delete a batch of menus in one step. ! The format of the text file is: ! ;(comment lines start with ;) ! MNU#,TEXT,TYPE,VALUE ! MNU#,TEXT,TYPE,VALUE ! etc. ! Where: ! MNU# is the top level menu # (0=top, 1=File, 2=Edit, 3=Settings...) ! (You can also use "FILE", "EDIT", "SETTINGS", "HELP") ! TEXT is the menu text. For separator bars, specify an arbitrary ! string (e.g. "s1", "s2") to uniquely identify it. ! TYPE is the menu type, from the following: ! "REG" - Registry-associated file. The VALUE will be ! a filespec whose associated application will ! be launched to open it. ! "SUB" - New submenu. (Use with MNU#=0 to add a top level mnu) ! "SEP" - Separator bar ! "KBD" - VALUE contents will be treated as keyboard text ! "CMD" - VALUE contents will be executed as a Windows cmd line ! VALUE - Menu value (see above). May be omitted for TYPE "SEP" !--------------------------------------------------------------------------- SIMPLE'MENU: xcall CCON ! make sure we can abort with ^C print "Enter menu definition file (.mdf) (try sample asmenu.mdf) " input line " or blank for default doc\ashelp.mdf (or ^C to abort): ",MFILE input "Enter 1 to add, 2 to enable/disable, 3 to delete: ",MOP if MOP <= 2 then & input "Enter 0 to enable, 1 to disable: ",STATE xcall AUI,AUI_MENU,MOP,MFILE,STATUS,STATE ? "STATUS = ";STATUS; call SHOW'STATUS ? return !------------------------------------------------------------------------- ! Popup menu definition uses the same syntax as the traditional ! version. Main differences are: ! ! 1. There can be only one context menu for the main window and one ! for each dialog. (The menu is associated with the current dialog ! if there is one; else with the main window.) ! ! 2. The menu ID of the context menu must be negative (typically -1 for ! the main window, -2 for the first dialog, etc.) ! ! 3. To add clipboard operations copy and paste to the popup menu, ! use the MBF_CMDLIN format with the special commands "$COPY" and ! "$PASTE". ($CUT doesn't really apply in this context. ! ! 4. Defining a context menu does not automatically change the cursor to ! an arrow, but you can do that with the TAB(-1,160);chr(32); command ! and TAB(-1,160);chr(48) to set it back to an I-beam. ! ! 5. You can delete the context menu with a single xcall AUI,AUI_MENU ! with OPCODE=3 and TEXT="*". !--------------------------------------------------------------------------- POPUP'MENU'DEF: ? "Creating context menu for main window..." ! Note that we can add the " $" suffix to the command to make sure ! that this window (A-Shell) does not get suspended while the other ! window is up. ? "Adding Edit INI menu to context menu..."; MOP = MNUOP_ADD ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,MID'CONTEXT,"Edit MIAME.INI",MBST_ENABLE, & MBF_CMDLIN, "NOTEPAD ..\..\MIAME.INI $","",STATUS ? "STATUS = ";STATUS; call SHOW'STATUS ? "Adding Calculator to context menu..."; MOP = MNUOP_ADD ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,MID'CONTEXT,"Calculator",MBST_ENABLE, & MBF_CMDLIN, "CALC.EXE $","",STATUS ? "STATUS = ";STATUS; call SHOW'STATUS ? "Adding Separator bar..."; MOP = MNUOP_ADD ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,MID'CONTEXT,"s1",MBST_ENABLE, & MBF_SEP,"","",STATUS ? "STATUS = ";STATUS ? "Adding Microsabio.com to context menu..."; MOP = MNUOP_ADD ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,MID'CONTEXT,"MicroSabio Home Page",MBST_ENABLE, & MBF_SHLEXC, "http://www.microsabio.com","",STATUS ? "STATUS = ";STATUS; call SHOW'STATUS ? "Adding another Separator bar..."; MOP = MNUOP_ADD ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,MID'CONTEXT,"s2",MBST_ENABLE, & MBF_SEP,"","",STATUS ? "STATUS = ";STATUS ? "Adding Clipboard Copy..."; MOP = MNUOP_ADD ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,MID'CONTEXT,"Copy",MBST_ENABLE, & MBF_CMDLIN,"$COPY","",STATUS ? "STATUS = ";STATUS ? "Adding Clipboard Paste..."; MOP = MNUOP_ADD ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,MID'CONTEXT,"Paste",MBST_ENABLE, & MBF_CMDLIN,"$PASTE","",STATUS ? "STATUS = ";STATUS ? "Adding Hello World..."; MOP = MNUOP_ADD ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,MID'CONTEXT,"Hello World",MBST_ENABLE, & MBF_KBD,"Hello World","",STATUS ? "STATUS = ";STATUS ? "Setting cursor to arrow..." ? tab(-1,160);chr(32) ? ? "Context menu created; right click to test." STOP ? "Disabling Calculator item on context menu..."; MOP = MNUOP_STA ! (for benefit of SHOW'STATUS) xcall AUI,AUI_MENU,MOP,MID'CONTEXT,"Calculator",MBST_DISABLE, & MBF_CMDLIN, "CALC.EXE $","",STATUS ? "STATUS = ";STATUS; call SHOW'STATUS return !------------------------------------------------------------------------- ! Delete context menu !------------------------------------------------------------------------- POPUP'MENU'DELETE: ? "Deleting context menu..."; MOP = MNUOP_DEL xcall AUI,AUI_MENU,MOP,MID'CONTEXT,"*",MBST_ENABLE, & MBF_CMDLIN,"","",STATUS ? "STATUS = ";STATUS ? "Setting cursor back to I-Beam..." ? tab(-1,160);chr(48) return !------------------------------------------------------------------------- ! Show context menu under program control ! [7] !------------------------------------------------------------------------- POPUP'MENU'SHOW: xcall AUI,AUI_MENU,4,MID'CONTEXT,"",1,50,"","",STATUS return !defstruct ST_MENU_ITEM ! [11] ! map2 text,s,32 ! map2 cmd,s,50 ! map2 state,b,4 ! map2 menuid,b,2 ! map2 itemid,b,2 !endstruct ![11] !---------------------------------------------------------------------- ! Function: ! Add new menu item ! Params: ! text [s,in] text which appears in menu item ! cmd [s,in] ! Returns: ! >=0 success ! Function Fn'AddMenuItem(text as s32, cmd as s200, state as b4, & menuid as b2, itemid as b2) as i2 End Function