VFP 5.0 Top-Level Forms
By Richard A. Schummer
Originally Published in the July 1997 issue of FoxTalk
Copyrighted 1997 - Richard A. Schummer
The new Top-Level Forms open Visual FoxPro developers to a variety of opportunities. Rick gives you the low-down on this new type of form and some of the potential uses for them.
Visual FoxPro 5.0 introduces FoxPro developers to many new concepts, one of them is the Single-Document Interface (SDI) form. SDI Forms are known as Top-Level Forms. These forms run outside of the Visual FoxPro frame, also known as the VFP main window. Each SDI Form is independent and appears separately on the Windows desktop. This article will introduce you to the new Top-Level forms, explain what you need to do to create a Top-Level form, some of the new menu capabilities associated with Top-Level forms, and most importantly some uses of this new capability.
Top-Level form is a modeless form that runs without a parent form. It can appear in front or behind other Windows applications, including Visual FoxPro. Each instance of a Top-Level form will appear on the Windows taskbar and can contain child frames as well.
The VFP Debugger application is an example of a SDI Form. The main Debugger window can be configured to run outside of the VFP main window. Within the Debugger there are several child forms that are contained inside of the Debugger “form”. Another example of a Top-Level form is the Windows Help System. The help system also spawns off other Top-level forms for searching and the glossary.
Form ShowWindow Property
The ShowWindow property is the only form property you need to set to make the form be a Top-level form. There are three settings available:
This setting defaults to 0 which means all application forms will run inside of the VFP frame. To make the form run outside of the VFP frame set this property to 2. Try running a form and note that you can move the form outside of VFP. This could be done in VFP 3.0b using the Desktop form property. The big difference between the ShowWindow and Desktop property is when the VFP frame is minimized. If the Desktop property is used the form disappears when VFP is minimized. Using the ShowWindow setting to create a Top-level form will remain visible even when the VFP frame is not visible. Another difference between the Desktop and ShowWindow property is each SDI form also gets a separate entry in the Window’s Taskbar. This does not happen with the Desktop property.
Hiding the Main VFP Window
So you just built your first SDI form after reading initial part of this article and are thinking how powerful this technology is, but wonder how do I get rid of the VFP frame. There are a couple of ways to accomplish this. The first is a new VFP configuration setting called SCREEN in CONFIG.FPW. Just place the following line in the application’s CONFIG.FPW:
SCREEN = OFF
This setting is critical for your applications to have the shrink-wrap look and feel. This is the only way to remove the VFP frame during application start up. The VFP Frame is displayed by default when a Visual FoxPro application is started.
It is important to note that this setting works differently with the development version of VFP. VFP is still displayed after the initial startup, but is not visible during the boot of Visual FoxPro or while a startup program called from CONFIG.FPW is running.
The second method is useful if you want to hide VFP when a SDI form is executed from inside of the development environment. To accomplish this place any of the following lines of code in the Form.Init() method:
Application.Visible = .F.
_VFP.Visible = .F.
_SCREEN.Visible = .F.
To have VFP redisplayed when the form is shut down, place any of the following lines of code in the Form.Destroy() method:
Application.Visible = .T.
_VFP.Visible = .T.
_SCREEN.Visible = .T.
If you don’t make the main VFP frame visible, you will return control to an invisible session of VFP. This is impossible to reinstate and you will need to end the task or reboot. The application object (Application, or _VFP,) is an object reference created for each instance of Visual FoxPro. This exposes properties and methods for each application. You can also use _SCREEN like you did in the VFP 3.0 days as well.
Where to use Top-Level Forms
Now that you have all this new information to create really cool forms, how can we use this technology to better our customer’s applications? I have found 5 uses for these forms including application splash screens, extending legacy applications, launcher forms, a replacement for _SCREEN, and Visual FoxPro developer utilities.
The splash screen was the most obvious use for these forms. For those developers who are not familiar with splash screens, these are the forms that are displayed right away when an application is started to keep the user busy reading. This way they don’t notice the lag time before the application is available for them to use. By using the SCREEN = OFF in the CONFIG.FPW and a SDI form you can create a start up process that mimics many shrink-wrapped applications.
I have included a form called SPLASH.SCX on the companion disk that demonstrates how to build a splash screen. There are a couple of quick notes I wanted to discuss about this form. Obviously I set the ShowWindow Property to “2 - As Top-Level Form”, but there are several other form properties that give this type of form a style like many of the shrink-wrapped packages we buy.
ShowWindow = 2
AutoCenter = .T.
BorderStyle = 0
Caption = ""
ControlBox = .F.
Closable = .F.
MaxButton = .F.
MinButton = .F.
Movable = .F.
AlwaysOnTop = .T.
Most of the properties are self explanatory like no caption, no close button, no minimize and maximize buttons, and no control menu. So why is the Movable property set to false? This was set to remove the title bar at the top of the form. This took me a bit of time to figure out and hopefully it will save you some frustration.
Extending Legacy Applications
How many times has one of your customers asked for new functionality in a legacy application? This could be a FoxPro 2.x application that has been running in production for quite some time. Typically you are working on the next killer application for this customer in Visual FoxPro. If you have been developing in VFP for a while you may find it a little difficult using FoxPro 2.6 DOS Windows, but the customer is willing to pay. To keep your customer satisfied, you agree to extend the functionality. What if you could add the functionality using Visual FoxPro without rewriting the entire application?
One example of this is a postal code search routine I developed for my wife. She maintains a customer list for a small company using a FoxPro application developed in FoxPro 2.6 for Windows. Since I did not have time to deal with the intimate details of this application and she wanted a postal code lookup routine incorporated, I quickly developed a SDI form that runs as a standalone app. She continues using the FPW 2.6 app and runs this quick SDI form to perform her lookups. It provides her the ability to cut the postal code or city to the Windows clipboard and paste it into the customer data entry form.
This is a unique way of incorporating Visual FoxPro technology into legacy applications without rewriting the entire system. In my case I did not have time to convert the old application and did not want to write 2.6 based code. The drawback of this type of extension is that the machine will be loading both the FoxPro for Windows code and the Visual FoxPro code which could be a problem on machines configured with 8 to 12 Megabytes of memory.
One of the neat ideas presented during the VFP 5.0 beta for using SDI forms was the concept of a “Launcher”. The base idea consists of a SDI form that has CommandButtons or icons that can be clicked to run other forms. This is one kind of menu interface that can be presented to a client without using conventional menus. It is also a way of presenting a Windows 95 and Windows NT 4.0 Explorer interface in your custom applications. An example of this type of interface is the Window’s Control Panel.
I built a simplified example of this concept in a application called SDIArticle.exe (along with the source code on the companion disk). This application starts with a SDI splash screen form then presents the Launcher form. Clicking on the different forms in the ListView (see Figure xxxx)object will execute these other SDI forms. The ListView object is populated with all the forms that are in the default directory. Additional forms could be added by simply dropping a new form file in the directory. This may not be the ideal way to extend a customers application, but shows the power of the “Launcher” concept.
The concept of replacing the _SCREEN is simply building a Top-Level form that houses the application. This Top-Level form contains a Top-Level menu (see sidebar “Top-Level Menus”) and child forms. These child forms are designed just like we did in VFP 3.0 except that they become child forms of the Top-Level forms.
What are the advantages of building a replacement for the _SCREEN. The primary advantage is that you can add custom properties and methods to a Top-Level form and cannot modify the _SCREEN object. This is a very powerful capability. One example I have read about is adding code to the “application” window Resize() or Click() methods. If the application window is resized you might want to perform some action. None of these Methods exist for the _SCREEN object.
Visual FoxPro Utilities
I often use SDI forms for my interactive development utilities which I want to run separately from the development version of VFP. It keeps the VFP frame clean and allows the application to be quickly accessed from the taskbar when I need it. I start the utility once and let it run in the “background”. One example of these utilities is the Hex Editor that ships with Visual FoxPro.
One utility I wrote is called “Hack VCX/SCX”. Have you ever renamed a Visual Class Library? I can already hear the groans and see the looks of terror on the faces of all the developers who read this line. What happens next? Try opening a Form that has objects you renamed in the class library. “Error instantiating class. Cannot find <classname> in <class library>”. Sure you can locate the renamed classes and the form is displayed in the Form Designer. Close the form, open it up again and see that the locate dialog is presented again. Even though you pointed the object to the right class the Form Designer never noted the form changed to kick in the Save logic when closed down. Nice, huh? Sounds like a bug to me. Make another change to the form to work around this. Even more aggravating than this is that every object that was renamed (or if the class library was renamed) will spawn the locate dialog. The same dialog is displayed over and over even if the new class or class library were located before. This can be quite frustrating after the first 5 or so changes.
So what happens when something does go wrong and you just need to get inside the .VCX or .SCX? One can USE the file and browse it. Unfortunately all the stuff you want to see is in memo fields. Now you have to start looking for all the fields you want to look into, resize them, move them to another place so the information is viewable, etc. The next time you open it up with a BROWSE LAST you will be okay, but a new class will cause you this grief all over again!
I built the Hack VCX/SCX form to get around some of the configuration frustrations that came along with the BROWSE technique. This Top-Level form allows you to select a Form or Visual Class Library. It opens it and displays the information inside the file. I protected some of the fields I felt I had no business changing at all. The rest are open to modify to my hearts content (or until I can disable the file all together).
VFP developer utility Hack VCX/SCX.
Nice thing when the table is open is that you can manipulate the data in ways we have been doing for years with invoices, customers, and the widget tables using the BROWSE. Even with Hack VCX/SCX you can make the global replacements. Jump over to Visual FoxPro and bring up the DataSession dialog. Change the DataSession to the Hack VCX/SCX session (private datasession for the form). Type in the REPLACE logic in the Command Window.
REPLACE ALL ClassLoc WITH "c:\devvfp5apps\common\cBaseClass" ;
FOR UPPER(ClassLoc) = "C:\DEVVFP5APPS\COMMON\BASEOBJ"
Presto, the changes are reflected back in the form. This form gives the viewing capability in a more usable format than the BROWSE without sacrificing the flexibility.
Granted this does not directly help out the customer, but if it helps the developer speed up the time to market with the application they are working on it ultimately helps the customer.
Issues with Top-Level Forms
There are a few issues I have experienced with Top-Level forms that I want to pass along.
Ever since FoxPro was released on the Windows platform developers have asked for the capability to build applications without displaying the FoxPro Main Window. They stated that their applications would be more professional and polished if they could start customized solutions with a splash screen, then the main application frame. Visual FoxPro 5.0 delivers the capability to develop applications with this requested functionality. Enjoy!
Sidebar - Top-Level Menus
Top-Level menus allow VFP developers to add menus to the Top-Level Forms. The Top-Level menu runs in the Top-Level form just like a standard VFP menu runs in the VFP frame. There is no real magic to these menus, but they are slightly different from the standard menus we have been using for years in FoxPro.
The first difference is checking the Top-Level Form on the menu General Options dialog.
GenMenu generates code in the .MPR file which including some new code that handles the needed changes for the menu to run in a Top-Level form. It also has some excellent documentation on how to implement the menu.
For years in FoxPro we have been running menus by running code like:
Top-Level menus are run in a similar fashion from the SDI Form.Init() method.
DO SDImenu.mpr WITH THIS,.T.
There are a couple of specific parameters for Top-Level menus. The first parameter is a reference to the form. The second parameter can either be the name of the menu or a logical that tells the menu to rename the form to the name of the menu. This is used if you run multiple instances of the form. If you choose to change the form Name property via this parameter make sure that all references to the form are appropriately THISFORM or THIS, not a hard coded reference to the Name property. Otherwise your code may not work.
It is important to note (and is helpfully stated in the generated code) to remove the menu from memory in the SDI Form.Destroy() method unless you wish to reactivate it later in a new form. If you ran the menu using the parameters in the example above you can place the following code in the Form.Destroy() method:
RELEASE MENU (THIS.Name)
This site is designed to be viewed in 800x600 video resolution or higher, but it should work fairly well at any resolution and with any of the major browsers (all free!). Optimized for MS Internet Explorer, Firefox, and Opera (mostly works with Mozilla and Netscape Navigator).
Copyrighted 1998-2005 Richard A. Schummer