_app.lOktoRun = StartupCheck() // in CONFIG.PRG
The StartupCheck() code resides in my CONFIG.PRG which in turn contains lots of startup, configuration and validation code, etc. Among the things that take place, the StartupCheck() method/function validates that the user id exists in the user table. If so, it acquires the user name and user level from fields in that table. It store these values to _app variables (see "_app.userlevel" below for example).
IF _app.lOktoRun // if not, something crapped out - app will close
// set a reference to the menu
private c
// Set menu name based on user level
if _app.userlevel > 2 // System admin user
this.menuclassname = "mspdlog3menu"
else
this.menuclassname = "mspdlogmenu"
endif
/* NOTE: The menu "mspdlogmenu.mnu" contains If/Endif constructs
using _app.userlevel. It constructs some top level menu
items ONLY if the userlevel is sufficiently high (>1). See below */
//build the menu command (a 'macro'):
c = 'this.rootMenu = new '+this.MenuClassName+;
'(_app.framewin,"Root")'
// execute it:
&c
ELSE // Something is not right (user will know what)
close databases
super::close() // close the application
ENDIF
If you examine the code above, you can see that administrative users (level 3 or above) see a different menu structure ("mspdlog3menu") than those with a lower level (level 1 or 2 get the "mspdlogmenu"). The contents of the menu for admin users is not really relevant so I won't list it here. However, the menu for level 1 and 2 users is a bit different than most. I designed this menu for the level 2 user. There is a top line menu item though ("Utilities") that is not supposed to be seen by level 1 users.
Once the level 2 menu was designed using the menu designer, I opened it in the source code editor and changed it manually. The process was quite simple. I placed the constructor code for the Utilities menu inside an "IF/ENDIF" (see code below).
//The following is part of the constructor code for
if val(_app.userlevel) > 1 // power user
this.UTILMENU = new MENU(this)
with (this.UTILMENU)
text = "&Utilities"
endwith
this.UTILMENU.MENU7 = new MENU(this.UTILMENU)
with (this.UTILMENU.MENU7)
text = "&Officer List"
endwith
this.UTILMENU.MENU8 = new MENU(this.UTILMENU)
with (this.UTILMENU.MENU8)
text = "&Category List"
endwith
this.UTILMENU.MENU9 = new MENU(this.UTILMENU)
with (this.UTILMENU.MENU9)
text = "&Posts"
endwith
endif
That's all there is to it. If a user has a level 2 status, they see the Utilities menu. If they are level 1, this menu item never appears. If they have a level 3 or higher status, they see a completely different menu structure. How simple is that?
With this knowledge under my belt, I can now implement any number of menu combinations as the need arises. Combining this capability with dBASE's DEO functionality provides for a very powerful and robust means of giving users the menu structure they need. My users recently told me they needed a small change to the level 3 menu. Five minutes later, I sent them a small .MNO file and told them to copy it to their designated DEO folder. All done. Very cool. Very happy users.
I hope these notes are useful to you. If you have any questions or comments about this text, please feel free to email me at the address below. If you have general dBASE questions, please visit the dBASE newsgroups.
Email address: