[ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7] [ 8 ] [ 9 ]

Table with Form Mediator PEMs

Property/Method Comments
Hold the name of a context toolbar class and classlibrary you wish to attach to this mediator's host document.  This item and the context menu file, below, can be used alongside the "go" menu and toolbar provided by the framework if you like. Unlike the "go" menu and toolbar, these are intended to be completely outside the framework, application- or form-specific items.  The framework will share them among forms and dispose of them when no form needs them.
Hold the name, menu popup name, and menu pad name of a context menu you wish to attach to this mediator's host document.   See above for intended use.
lAdding   Stores information about whether the framework invoked the host document as "new" or "open".
Specify whether or not the host document has been assigned a navigation toolbar and/or menu by the application and its metatable entry.  This happens automatically (you don't need to set these properties).
The two logical properties specify whether the mediator should load session settings using the application's defaults, and whether the mediator should load data-session-specific user settings using the application's information about user preferences. 
The first of these defaults to .F., and is a convenience you may not need or want to use – it’s likely to happen too late in the startup session to be reliable for your table-opening needs.  If you rely on this ability, also, you are implicitly saying that the form will not be used outside the framework (since many of these settings, such as SET MULTILOCKS, are critical to table behavior). 
The second defaults to .T., and will be appropriate in most instances.  More about this feature below, in the section on Options.
DoSessionSets(), which evaluates these two logical properties and applies them as necessary, will happen at startup but may be called later if the user changes options while the form is running.
GetAppRef ( )
The cAppRef  property holds the name of the reference variable for the running app so the mediator can evaluate it to an object reference when necessary.  The mediator does not store any object references, for safety.  Instead, it or its clients use GetAppRef to RETURN an object reference to the app whenever necessary
LoadApp( ),
LoadApp() is called by the application object when this form or formset is instantiated, if the mediator object is available. This gives the mediator a chance to store the reference string it needs to get an app reference later, and to apply app attributes to a form, including session settings, as directed by its lSessionSettings and lUserSessionSettings properties. If context menu file or toolbar items are filled out, the mediator tells the App to manage this menu and/or toolbar during LoadApp() as well. If lAddAppIcon is .T., which is the default, LoadApp will apply the application's standard Icon to the form's Icon property if the form's Icon property has been left empty.
The first method here wraps the app DoTableOutput() method. The second wraps it passing a scope of one record.  Either of these methods can be used with the cOutput… properties below.  These methods are intended to allow you to provide quick output from a form or perhaps a form button.
cOutputCaption PrepareOutputAlias(),
This set of properties and methods is intended to "focus" the form's use of the DoTableOutput() method provided by the application object.  DoTableOutput provides quick, table-oriented output of various sorts and to various devices, even when no appropriate report is available.
Left to itself, DoTableOutput(), which the user may call at any time from a the standard toolbar's "print" button or the menu, will simply focus on the current alias in the current data session.  If DoTableOutput() finds a mediator, however, it will look for alternative information using these properties and methods. 
If you have filled out cOutputAlias, it knows you mean this alias to be SELECTed for the purposes of table output.  If cOutputCaption is filled out, it will show up when the application object instantiates the output dialog, to serve as the dialog's caption.
The two methods here are abstract.  They're designed when you need to do more than simply SELECT a table for output.  DoTableOutput() calls these methods when the mediator exists, giving you a chance to put together a cursor, filter data, or otherwise prepare an appropriately "output-focused" table with information before output, and destroy it afterwards.. 
QueryUnload( )
Datachanged( )
The DataChanged() method wraps the application's QueryDataChanged() method for use by this form and its members.
QueryUnload( ) does the same for the application's QueryDataSessionUnload( ) method.  You can, and probably should, call this method in the form's QueryUnload() to handle any data changes, updates, or reverts before the form is closed in the same manner the application will handle it when the user tries to exit the application. IChangeMode is sent on to the app's cusDataSession object to determine what constitutes a "data change" during this process. See the _datasession object in FFC's _APP.VCX for more information
SetDocumentToNew( ),
PickRecordToWorkOn( )
SetDocumentToNew stores the app's lAddingNewDocument flag at the time the app attributes are loaded, so the form can evaluate what record to work on. PickRecordToWorkOn is an abstract method, designed to make use of this information and to allow you to decide what you want to do with the form and the new/open information the framework has given it. 
It isn't called directly, because it's up to you and your data handling to decide when to call it (when you've loaded your data) and what should happen then.  In "open" mode, do you want to add a browse for the user to pick a record? Do you want to determine this record using an application cCurrentID property you invent? In "new" mode, should you APPEND a BLANK, and to which table in this data session?

How does your form take advantage of these features? Any form with a mediator, even one added at runtime, will get certain basic services. If it is built by the Wizard, the Wizard form baseclasses will take advantage of the data-handling PEMs of the form mediator. If you add a mediator to a form manually, and especially if you subclass the mediator and use your own subclass, obviously you can write any code and handle the relationship anyway you want.

For a good example of the way a form can use a mediator to access and apply framework features, take a look at the _ErrorLogViewer class in _FRAMEWK.VCX. In this dialog, the mediator object augments its DoSessionSets() method to apply the application object's cTextDisplayFont property, which allows the user or the application to store a preferred non-proportional font, to a similar property of the dialog class. An assign method on the dialog's cTextDisplayFont property then applies this property value to appropriate dialog elements. Since DoSessionSets( ) runs when the dialog first initializes, and then again whenever the user chooses to apply a new set of preferences through the options dialog, you can watch these elements change in the error log viewer. This is extremely simple code leading to a very satisfying result.

This simple code is written directly into the _ErrorLogViewer class and is directly tailored to this class. However, if you would like to enhance the relationship between your forms and their mediators, whether base class mediators or your own subclasses, you will probably wish to automate the relationship in some way.

Obviously you can build the behavior and the member into your form classes, and specify these classes for your teams' use. This is the standard way to re-use and inherit good behavior. But this requirement does not cover all cases and all forms. It also hides the functionality so that a beginner can't learn about it, which may be a consideration in some circumstances.

Remember: this framework should take care of any forms built by anybody, not just ones built to a set of specifications. If, as a senior developer, you know how you would like this relationship to work, you want access to this relationship for the first form, built from scratch in the Form Designer, that your apprentice developer contributes to your application. You provide this access using a Project Hook object.

The Project Hook functions as a builder for the Project Manager. Like any builder, you can make its actions automatic and discreet or you can allow an interface in which the user makes choices.

For this example project hook class, subclassed from the APPHOOK.VCX project hook class used by the shipping Application Wizard and Builder-generated framework applications, I've made the action of framework-enabling forms required and automatic (without an interface). However I've provided a log in which a developer can see what actions were taken. This seems to be a good compromise; the apprentice developer doesn't have to understand what's going on to make things work, but s/he is not left out or manipulated without recourse.

You'll find this project hook object in PHOOK folder of your source code, in the NEWHOOK.VCX. You attach it to a project using the Project Info dialog.

A subclass of the shipping project hook object produces an "action log" and some VFP 6 framework-specific additions.

[ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7] [ 8 ] [ 9 ]