by Dr. Peter Wayne
| Alpha Five version 4 limits the number of users who can access a database, but there is no limit to the number of sessions that each user can control. With creative programming you can allow your users access to one, two, or more copies of your application. |
Most professional applications allow a user to have more than one window open at a time. Think of Microsoft Word or Corel's WordPerfect - each will allow you to alternate among multiple documents. If you allow your users access to the Control Panel, then your users can also run multiple copies of your application.
But what if you don't allow your users free access to the Control Panel? Letting someone into the Control Panel, with those tempting table and form editing tools, is a recipe for meddling at best and sabotage at worst! Can you structure your Alpha Five application to let your user open up more than one copy of your application, but still keep your application safely isolated from the Control Panel?
Of course the answer is yes, or else I wouldn't be writing this article!
Let's start with the alphabet blocks of Alpha Five, the Invoice.adb application that comes with A5v4. We're going to modify the one-item custom menu that's attached to this form. We want to add a new category, Form, with a drop-down list of New Form and Other form. When we start the Invoice application, we can choose to open a New Form and we'll have 2 copies of the application running. We can alternate between the copies of the application by choosing Other form. Let's get to work!
The Main Menu form in the application has a custom menu named B2. You can see the custom menu choice by placing the form into design mode, selecting Properties, and then choosing the Menus/Toolbars tab. You have to scroll all the way to the right-most tab of the form's Properties card to get to Menus/Toolbars:
Figure 1. B2 is the custom menu for the Main Menu form in Invoice.adb
Now, let's edit B2. We can do that by going to the Control Panel and choosing the Code tab, right-clicking on B2 and choosing Design:

Figure 2. Menu B2 as supplied by Alpha.
Next, right-click on the menu item that's been defined, and choose Insert item that has a drop-down list for our Form menu category:
Figure 3. Add menu items to the custom menu.
And type Form as the caption:

Figure 4. Add a caption.
Next, double-click on Formto open up a new level of menuing:
Figure 5. A new level of menuing.
Right-click on the new blank menu item and choose Insert item that plays an action. Enter New Form for the Caption, and choose Play Xbasic commands for the Type:
Figure 6. The New Form option will play Xbasic commands.
A little Xbasic editing window will open up. Type script_play("New
Form") in this window:
Figure 7. Enter the Xbasic in the little editing window.
Now, it is perfectly legitimate to type a whole script in this small editing window, but it's hard to navigate in the window, and it's much easier to work with the regular Xbasic editor. So even though we haven't written the New Form script, we can edit the B2 menu and tell it that we want to run that script when we choose Form, New Form.
Following exactly similar steps, add a menu item for Other form that plays an Xbasic script, Other form. In this case, check the little box that says Disable this menu item?. We won't let our user open the Other form until we create one, so the new form will start with this menu item disabled:
Figure 8. Check the box to disable the next menu item.
Save the menu, and then we can create the proper scripts.
We're ready to create the 2 scripts that will do most of the work for this double-duty application. From the Control Panel, choose the Code tab, then New and choose to create a new Script. Make sure you select Xbasic as the scripting editor, and enter New Form as the script's name:

Figure 9. Create a new Global Script
Type in the new global script as follows:
dim f as p
f=form.view("Main Menu")
this.MenuItemEnable("Other form",.t.)
f.MenuItemEnable("Other form",.t.)
this.MenuItemEnable("New Form",.f.)
f.MenuItemEnable("New Form",.f.)
Script 1. The New Form script.
What does Script 1 do? It opens a new instance of the Main Menu form, and then it enables the Other form drop-down menu choice and disables the New Form menu option. We don't want our user cluttering up her screen with an indefinite number of copies of our application - 2 is enough, thank you!
| Although you might be tempted to allow your users to open 3, 4 or 5 windows, from a practical matter 2 is enough and more can be confusing. |
The Other form script is equally brief. In this script we take advantage of the fact that Alpha Five will rename the second copy of the form "Main Menu0":
dim nm as c
dim f as p
nm=this.name_get()
if right(nm,1)="0" then
f=obj("Main Menu")
f.activate()
else
f=obj("Main Menu0")
f.activate()
end if
Script 2. The Other form script.
Script 2 finds out whether the current form is "Main Menu" or "Main Menu0" and activates the corresponding other form. Notice that in a menu, the "pronoun" or alias of this. refers to the current form to which the menu is attached.
At this point, it's possible to open 2 copies of the application and to alternate between the 2 copies. However, we still will have a problem if we close one of the copies. When one copy of the application is closed, the Other form option no longer makes sense, and we want to re-enable the New Form optoin. How do we let our custom menu know that one copy has been closed and that the remaining copy is the only valid one remaining?
We have to write code for 2 form-level events, the OnActivate event, which fires any time focus is given to the form, and the OnExit event, which is triggered when the form closes. Here is the code for the OnActivate event:
nm=this.name()
if right(nm,1)="0" then
' check to see if the original form is open
f=obj("Main Menu")
else
' we're in the original form, see if the second form is open
f=obj("Main Menu0")
end if
if is_object(f) then
this.MenuItemEnable("Other form",.t.)
this.MenuItemEnable("New Form",.f.)
else
this.MenuItemEnable("New Form",.t.)
this.MenuItemEnable("Other form",.f.)
end if
Script 3. The OnActivate script for the Main Menu form.
Each time a form is activated, this script checks to see if another copy is running. If so, then it enables the Other form option for each form's menu and disables the New Form option. If no other copy of the form is present, then Script 3 will enable the New Form menu option for the current solo form.
The OnExit script already exists for the form. We will add a few lines to the end of the script:
close_if_exists("inventory")
close_if_exists("vendors")
close_if_exists("products")
close_if_exists("customer_information")
close_if_exists("invoice")
close_if_exists("reports")
close_if_exists("review_of_sales")
close_if_exists("help")
close_if_exists("vendor_information")
close_if_exists("productzoom")
close_if_exists("customerzoom")
close_if_exists("invoicezoom")
' the new lines come here
nm=this.name()
if right(nm,1)="0" then
' check to see if another form is open
f=obj("Main Menu")
else
f=obj("Main Menu0")
end if
if is_object(f) then
f.MenuItemEnable("Other form",.f.)
f.MenuItemEnable("New Form",.t.)
else
controlpanel.show()
controlpanel.activate()
end if
Script 4. The modified OnExit script for the form.
So what have we accomplished? Here is an example of how 2 copies of the same
application can be running on one person's screen:

Figure 10. 2 copies of the same form are running, but they are poised to execute different tasks.
If there's no such thing as a free lunch, then there certainly is no such thing as coding your way to a free second copy of Alpha Five. If you code for a duplicate copy of your application, you should bear in mind that Alpha Five's propensity to rename a second copy of your form by appending a "0" to it does not end with the master form. If your main form opens other forms, then those other forms might also be named "vendors0" and "customers0". In fact, you can't predict how Alpha Five will name your forms, because the naming depends on how many copies are already open: the first copy of the "customer" form will be named "customer", even if it is opened by the second instance of the "Main Menu" form. And if a subsequent copy of "customer" is then opened by the first instance of "Main Menu", then that second copy will be "customer0." Does this confuse you? It should. There is no way you could possibly keep track of all this, and this means that you have to exercise care if you want your application to hang together while you open up a second copy. Here are a few rules to keep you out of trouble:
2/15/99
Don't forget, we need your feedback to make this site better!