(Notes provided by Rainer Becker, dFPUG)
About the Author
Rainer Becker is the leader of the German FoxPro User Group, an organization with 1200+ paying members (companies and programmers), president of ISYS GmbH, a MS Solution Provider and contract partner of MS Consulting Services, and president of Wizards & Builders GmbH, a research company. You can reach him at:
About the Speaker
Ted Roche is the Director of Application Development at Blackstone Incorporated, a Boston-based Microsoft Solution Provider specializing in FoxPro development, Microsoft BackOffice and Windows NT-based solutions. Ted is the co-author of The Hacker's Guide to Visual FoxPro, coming soon from Addison-Wesley, and writes the Ask Advisor column for FoxPro Advisor magazine. Contact him at email@example.com or on CompuServe at 76400,2503.
We will start with a short introduction to the principles of Properties, Events and Methods. You need to know these terms to work with controls of any kind. The main part is a guided tour through all Controls. We will visit old, new and changed ones in a sorted order - walking all properties upstairs. The controls are sorted by the number of properties, events and methods they have bringing us some new of each by each new control we see. Finally we will share some words about containers, naming conventions and the use of Builders as well as guide you to some sessions that build on this one.
We can not talk (at least not too much) about the following themes in Visual FoxPro:
Form & Class Designer, Grid-& OLE-Controls, Classes and Inheritance, Non-Visual Objects, Event-Model
But you might get a good base for all of that with this session as you should have a good overview over all types of controls.
Visual FoxPro introduces a lot of new buzz-words. Some of them are really important when you start working with controls. These are properties, events and methods. All three are not that exactly defined and overlap sometimes. The questions we need to answer in the beginning:
What are PROPERTIES?
In FoxPro/Windows we had private and public variables. In Visual FoxPro there are some more types of variables. Additionally all types of controls have properties - think of them as variables bound to a control. Some examples:
commandbutton.caption = text shown on the button
textbox.comment = a note of the developer
Even better might be this description: Propertes can be thought of as public variables with a private path, as you can access properties from everywhere as long as you know where they live.
You can add your own properties to a control! Later on you will need them. You can use them for non-visual objects or even applications-objects.
What are METHODS?
Methods are procedures. Think of them as old-style snippets, saved in a memo-field and compiled when you close the memo. They are procedures bound to Controls/Forms instead staying in an individual program (or generated screen-file).
Refresh Repaint the object
SetFocus Make object the current object
Even better might be this description: Public functions with a private path as you can access methods from everywhere as long as you know where they live. Might remind you to the construct DO <function> IN.
You can add your own methods as you can add properties. You will sometimes need your own methods. Building your own is real fun as you can really encapsulate code with the object and e.g. build protected invisible internal methods that can only seen and used be the object itself.
What are EVENTS?
Events occur outside of program control and the application has to react to them - at least if it is an event-driven application. In connection with controls, events are bound to methods. Therefore you can think of them as old-style snippets called when something happened. They are procedures bound to Windows-Events.
VALID old-fashioned VALID-event
CLICK a mouse-click happened on a control
You can not extend the available set of events. Think of events as a fixed set of methods that are bound to the operating system events, internal events of Visual FoxPro (like a Timer event) or an action of the user (like a mouse-click or mouse-move).
You normally need only some of them - but it is great that there are so many! In most controls nearly all events are left blank except for e.g. the click-event.
As there are a lot of properties, methods and events you can easily get confused. Do not do that <g>. Just remember that both, Events and Methods, have a Procedure that can be called. In case of methods it is only called by your code, in case of events these procedures can be called from somewhere else additionally. By the way: Therefore sometimes code that should be placed in an event is put into a separate method and called from the event instead, to simplify access.
Events could also be seen as an regular Event that occurred and a Method bound to that event. On the other hand some properties are followed by actions (and can be seen as events too).
These Categories are not closed boxes, do not lose too much time to distinguish events and methods. There are many - but most are easy to use! Do not get confused by the sheer mass of things you see in the property sheet.
When dealing with the property sheet and all these properties, events and methods you should obey the graphical hints Visual FoxPro provides:
If you toggle a property and afterwards toggle it back to its default value it is still marked in bold. Use RESET TO DEFAULT (located on the menu of the right mouse button) to get rid of unwanted changes. This sets back the original graphical hints.
As mentioned above you can access all properties of all controls by a special access path. The syntax definition for accessing them:
objectvariable.[form.]control.property = Setting
As the hierarchy of controls can end up with a very long list, there are some shortcuts implemented:
THIS. the actual control
THISFORM. the actual form
THISFORMSET. the actual formset
_SCREEN. the FoxPro main window
ACTIVEFORM. the active form of a form set
ACTIVEPAGE. the active page of a page frame
ACTIVECONTROL. the active control on a container
PARENT. the parent object (not inheritance!)
The THIS-shortcuts can only be used within methods.
The ACTIVE-shortcuts are connected to a logical property of the control - you can cycle through this property in all associated controls to find inactive ones.
The keyword PARENT. should be fully understood. It has nothing to do with the inheritance or the parent class (see below). It is just the object in which the control resides. In case of a option button the parent is the option button group. If a command button is placed on a form the form is the parent, if it is placed in a command button group the group is the parent. This keyword is extremely useful if you build a group of controls that belong together. If you reference the connected objects via PARENT. you never need to know who the parent (Allis?) is.
To shorten writing of references you can use the construct WITH.. ..ENDWITH for a group of properties to be used with the same reference.
If you do not know the children of a container object, there are clauses like COUNT or PAGES that behave like arrays of the child objects and can be used to reference all of them or a special one by adding a number in a bracket.
Controls - A Guided Tour
Here is the list of controls we will visit in this order:
Not all of them are new! Most of them are renamed. Here is the list of renamed controls:
Text => Label control
GET-Field => Text box
Edit Region => Edit box
Popup => Combo box
Radio button => Option button
Screen => Form
ScreenSet => FormSet
Picture => Image
Really new are:
Timers => for timed events (at least a small help)
Pages/Pageframe => for these nice tabbed dialogs
Grid => the all-new-version of the browse-command
Lets start with a new but small one: Timers
|Methods||BASIC, TimerEvent, Reset|
|Tips||Not executed while Menu open, Not exact enough for RealTime|
Special Timer Property/Event/Method
|Interval Property||Timer in milliseconds|
|Timer Event||Procedure called at Event|
|Reset Method||Restart timer|
|Comment||You should use it!|
Top, Left, Height, Width
|Class||Objects belong to classes|
|ClassLibrary||optional: VCX of the class|
|BaseClass||Base class derived from|
|Parentclass||optional: derived from|
|Parent||runtime: container object|
|SaveAsClass||objects from VCX to VCX|
|ReadExpression||Method at design time|
|WriteExpression||Method at design time|
|Events||CLICK, MOUSE, DRAG|
|Methods||Drag, Move, UIEnable, ZOrder|
|Draw- Mode, MousePointer, LineSlant|
Click Events for visible Objects
|Click||Mouse left click|
|DblClick||Mouse double click|
|RightClick||Mouse right click|
Mouse Events for visible Objects
|MouseMove||Mouse over object|
|MouseDown||Mouse pressed for click|
|MousePointer||12 pointer versions|
Drag & Drop for visible Objects
|DragDrop||End of drag, target event|
|DragOver||object over target, target event|
|Drag||Method for manual dragging|
|Move||Method for manual moving|
|DragIcon||Cursor Icon for drag|
|DragMode||automatic / manual|
Properties for Visible Objects
|Visible||Temporary hide object|
|HelpContextID||for Help Compiler|
|ZOrder Method||active Page, tab order|
|UIEnable Event||Page activate event|
|DrawMode||16 different modes|
|LineSlant||special line property|
|ColorScheme/Source, ToolTip; SpecialEffect, Curvature|
|Tips||Shapes in front block the click event|
Properties for Plain Objects
|BackStyle||Transparent / Opaque (Default)|
|BackColor||RGB-Color for Opaque objects|
|FillColorStyle||Transparent, Solid, Lines|
|FillColor||RGB-Color if not transparent|
|ColorSource||Scheme for Above=Source|
|ToolTipText||ToolTip if Form.ShowTips=.T.|
|SpecialEffect||Plain or 3D|
|Curvature||0=rectangle - 99=circle|
|Layout||Picture (Bitmap, Icon)|
|Tips||Stretch also used for OLE|
Objects with Caption
|Layout||Caption, FONT, COLOR, AutoSize, WordWrap, Alignment|
|Tips||The Caption can be a function|
Layout Properties for Objects with Caption
|FontFlags||FontBold, FontItalic, FontStrikeThru,|
|FontOutline, FontUnderline, FontShadow|
|Caption||Text to be shown (function)|
|AutoSize||Resize horizontally. for text|
|WordWrap||Wrap words/resize vertical|
|Methods||ErrorMessage, see EVENTS|
|Layout||DownPicture, DisabledPicture, StatusBarText, (Style=Inv.)|
|Other||TabIndex, TabStop (Forms!)|
|Tips||Use small fonts with pictures Use StatusBarText instead|
Events for accessible objects
|GotFocus||Tabbed to it|
|LostFocus||Tabbed somewhere else...|
|SetFocus||Method (enabled & visible)|
|KeyPress||Key Preview Event|
|Refresh||SHOW GET (Requery,Page)|
|Message||Return Message text (Old!)|
|Data||ControlSource||Field or memvar|
|Value||same type as ControlSource|
|Layout||Alignment (Left/Right) for button|
|SpecialEffect not for command button|
|Tips||Only in Option Button Groups!|
|ControlSource||differs ( memvar, field, function)|
|Methods||InteractiveChangeEvent P rogrammaticChangeEvent|
Objects with entered data
|Data||Format, InputMask, Margin, Read-Only, Open/MemoWindow|
|Layout||SELECT, Style (SAY-compatible), PasswordChar|
|Tips||Play with selected areas!|
|SelStart||Begin of selection|
|SelLength||Number of chars|
|SelText||Complete Selected text|
|HideSelection||Show after LostFocus|
|Layout||ScrollBars (vert. & horiz.)|
|Tips||Selected text" applies here|
|Data||KeyboardHigh/LowValue, SpinnerHigh/LowValue, Increment|
|Tips||Use High/LowValues instead of RangeEvents|
Combo and List boxes
|Layout||ColumnCount, -Lines, -Width,|
|Other||TopIndex, TopItemID, +NEW|
|IncrementalSearch, Listcount, ListIndex, ListItemID|
Layout for Combo box
|ColumnCount||Number of Columns|
|ColumnLines||Show column lines|
|ColumnWidth||Width of columns (colon-delimited)|
Data for Combo box
|RowSource||Type 9 options|
|BoundColumn||Column bound to Value|
|DisplayValue||Text or pos. for display|
|List||Array of text|
|FirstElement||for Arrays only|
|NumberOfElements||for Arrays only|
Methods for Combo box
Other for Combo box
|TopIndex||first visible item|
|ListCount||Number of items|
|ListIndex||(Last) selected item|
What are Ids?
|ItemIDData||Additional value by ID|
|ListItem||Array of text by ID|
|TopItemID||ID of topmost vis. list-item|
|ListItemID||(Last) selected item ID|
Do not get confused by the pairs List / ListItem and ListIndex / ListItemID!
The RowSourceType (0=None), (1=Value)
ID-Methods in a Combo box
|AddItem||Add at position|
|AddListItem||Add with ID|
|RemoveItem||Remove from position|
|RemoveListItem||Remove with ID|
|Clear||Delete all items|
|IndexToItemID||Position -> ID|
|ItemIDToIndex||ID -> Position|
|Tips||Use DisplayValue and Value together for text and offset|
|Form||PageFrame, Grid, Controls|
|Option Group||Option Buttons|
|Command Group||Command Buttons|
Option/Command Button Groups
|Tips||ChangeEvents only in Groups|
|No Inheritance for new buttons|
|Layout||PageCount, PageHeight/Width,Tabs, TabStretch|
|Tips||Drop objects on top for all pages|
|Tips||- Reference all with PAGES|
As Grids are the most complex controls you can have, a separate session is devoted to them. The most important thing for you to know is that a Grid is a container that can consist of Headers and Columns. Columns are containers too as they consist of e.g. text objects or other types of controls. It is really complicated to build a Grid by hand or programmatically. You should start building grids on your own with the help of the Grid Builder - otherwise it will be real pain. The best might be to have a look at the Session Using the Grid Control" from Lisa Slater Nichols.
There are two types of OLE-controls. First you have OLE Bound Controls which are "bound" to General-fields and have no own Events. Second you have OLE Container Controls which are an OCX with own Events connected to it or an other OLE not bound to fields. The OCX-libraries are new to the FoxPro world and give us the power Visual Basic-users had with the old-fashioned VBX-libraries. Have a look at the Session OLE Custom Controls" from Steven Black, who will introduce you lots of never-seen (at least in the FoxPro world) controls you can buy at the fast growing Third-Party-market.
To avoid container-confusion, you need to distinguish three types of controls, that might contain other controls.
Some tips and hints
Ease your work with Builders
You should really ease your work with the new Builders. We have gone the hard way today doing everything manual - but with the builders you are ten times faster for everyday work. There are builders for these controls:
By the way, Builders use the special design methods every control has build in: ReadMethod, WriteMethod, ReadExpression, WriteExpression, and the function ASelObj( )" will help you to find the selected objects in case you build a builder on your own. Take a look at a builder-session to find out more about these successors of GenScrnX. You will love them!
Simplify maintenance with Naming Conventions
If you have not worked with naming conventions, switching to Visual FoxPro is a good point to start with it. To minimize confusion with all these new types of controls, naming conventions are a must. See the help file under the topic 'Naming Conventions for a comprehensive list. For example, use 'chk' for CheckBoxes, 'cmd' for Command buttons. These can be a real help in decoding complex object heirarcies. Fox example, the command:
frsInvoices.frmAddress.cmgNavButtons.cmdLookUp.Visible = .t.
(reading right to left) makes visible the "Look Up" command button, part of the "navButtons" command group, on the Addresses form in the Invoices form set.
Where to go from here?
There is a lot more to learn about Visual FoxPro and its new user interface. Try one of the following sessions here: