Builders
Builders are utility programs that work on objects in the Form and Class Designers. They can be anything from a simple property manipulators to complex object setup utilities.
07-Jun-04 Click here for the Europa Anchor builder
Here is the simplest general purpose builder:
* mybuild.prg lparameter lcCommand local i, n, laObjects[1] lcCommand = "laObjects[i]." + lcCommand n = aselobj( laObjects ) && all selected objects for i = 1 to n &lcCommand endfor
To use it select the objects you want to manipulate and in the command window do something like:
| mybuild( "FontName = [Arial]" ) | set the font of all the objects to Arial |
| mybuild( "ForeColor = 255" ) | set the objects to red |
Here's a builder that was needed in VFP3 to horizontally center more that one controls. In VFP5 the layout toolbar now provides this functionality. To use this builder select the controls to center and in the command window type: hcenter()
* hcenter.prg 21-Oct-96
* Usage: select object(s) to be horizontally centered within their container
* in the command window enter =hcenter()
* Copyright 1996, DF Software Development, Inc.
local n, laObjects[1]
n = aselobj( laObjects ) && all selected objects
if ( n = 0 )
* nothing to do
wait window "Select one or more controls to center horizontally" nowait
return
endif
local i, loParent, lnMinX, lnMaxX, lnAdjustX
* find the container object
loParent = laObjects[1].Parent
if ( loParent.BaseClass == "Page" )
* if it's a page go on up to the pageframe
loParent = loParent.Parent
endif
* determine the X limits of the selected objects
lnMinX = 999999
lnMaxX = -999999
for i = 1 to n
with laObjects[i]
lnMinX = min( lnMinX, .Left )
lnMaxX = max( lnMaxX, .Left + .Width )
endwith
endfor
* number of X pixels to shift each object
if ( loParent.BaseClass == "Pageframe" )
lnAdjustX = lnMinX - ( loParent.PageWidth - ( lnMaxX - lnMinX ) ) / 2
else
lnAdjustX = lnMinX - ( loParent.Width - ( lnMaxX - lnMinX ) ) / 2
endif
* move each object
for i = 1 to n
with laObjects[i]
.Left = .Left - lnAdjustX
endwith
endfor
The parallel builder for vertical centering:
* vcenter.prg 21-Oct-96
* Usage: select object(s) to be vertically centered within their container
* in the command window enter =vcenter()
* Copyright 1996, DF Software Development, Inc.
local n, laObjects[1]
n = aselobj( laObjects ) && all selected objects
if ( n = 0 )
* nothing to do
wait window "Select one or more controls to center vertically" nowait
return
endif
local i, loParent, lnMinY, lnMaxY, lnAdjustY
* find the container object
loParent = laObjects[1].Parent
if ( loParent.BaseClass == "Page" )
* if it's a page go on up to the pageframe
loParent = loParent.Parent
endif
* determine the Y limits of the selected objects
lnMinY = 999999
lnMaxY = -999999
for i = 1 to n
with laObjects[i]
lnMinY = min( lnMinY, .Top )
lnMaxY = max( lnMaxY, .Top + .Height )
endwith
endfor
* number of Y pixels to shift each object
if ( loParent.BaseClass == "Pageframe" )
lnAdjustY = lnMinY - ( loParent.PageHeight - ( lnMaxY - lnMinY ) ) / 2
else
lnAdjustY = lnMinY - ( loParent.Height - ( lnMaxY - lnMinY ) ) / 2
endif
* move each object
for i = 1 to n
with laObjects[i]
.Top = .Top - lnAdjustY
endwith
endfor
New Updated 15-Aug-97
Here are two builders that provide a nice feature still missing from the VFP5 and VFP3 layout toolbars. The VFP5 designer Format menu includes a Horizontal/Vertical Spacing item but it works slightly different that the functions here. These builders take a group of 3 or more controls and equispace them horizontally or vertically by distributing the controls within the space limits assigned to the controls. That is they put the same amount of space between the controls. To use these builders put one control at the left (top) edge of the area, put the last control at the right (bottom) edge, select all the controls to position and in the command window type: hequispace() or vequispace(). The code looks a lot like the above code for hcenter().
* hequispace.prg 15-Aug-97
* Usage: select object(s) to be horizontally equispaced within their limits
* in the command window enter =hequispace()
* Copyright 1997, DF Software Development, Inc.
PARAMETERS uP1, uP2, uP3 && builders get sent 3 parameters by builder.app
local n, laObjects[1]
n = aselobj( laObjects ) && all selected objects
if ( n < 3 )
* nothing to do
wait window "Select three or more controls to horizontally equispace" nowait
return
endif
local i, lnMinX, lnMaxX, lnAdjustX, lnTotalWidth
* determine the X limits of the selected objects
lnMinX = 999999
lnMaxX = -999999
lnTotalWidth = 0
for i = 1 to n
with laObjects[i]
lnMinX = min( lnMinX, .Left )
lnMaxX = max( lnMaxX, .Left + .Width )
lnTotalWidth = lnTotalWidth + .Width
endwith
endfor
* number of X pixels between each object
lnAdjustX = ( lnMaxX - lnMinX - lnTotalWidth ) / ( n - 1 )
* move objects 2..n-1
for i = 2 to n - 1
with laObjects[i]
.Left = laObjects[i-1].Left + laObjects[i-1].Width + lnAdjustX
endwith
endfor
And the parallel vequispace:
* vequispace.prg 15-Aug-97
* Usage: select object(s) to be vertically equispaced within their limits
* in the command window enter =vequispace()
* Copyright 1997, DF Software Development, Inc.
PARAMETERS uP1, uP2, uP3 && builders get sent 3 parameters by builder.app
local n, laObjects[1]
n = aselobj( laObjects ) && all selected objects
if ( n < 3 )
* nothing to do
wait window "Select three or more controls to vertically equispace" nowait
return
endif
local i, lnMinY, lnMaxY, lnAdjustY, lnTotalHeight
* determine the Y limits of the selected objects
lnMinY = 999999
lnMaxY = -999999
lnTotalHeight = 0
for i = 1 to n
with laObjects[i]
lnMinY = min( lnMinY, .Top )
lnMaxY = max( lnMaxY, .Top + .Height )
lnTotalHeight = lnTotalHeight + .Height
endwith
endfor
* number of Y pixels between each object
lnAdjustY = ( lnMaxY - lnMinY - lnTotalHeight ) / ( n - 1 )
* move objects 2..n-1
for i = 2 to n - 1
with laObjects[i]
.Top = laObjects[i-1].Top + laObjects[i-1].Height + lnAdjustY
endwith
endfor
Maybe you noticed the PARAMETERS statement in the builders, but the parms are not used anywhere. The reason for this is because these builders can be attached to the VFP BUILDER.APP program that is called when you select Builder... from the context menu in the Form/Class designer. The open architecture of the VFP builder allows our own builders to be easily added to the system. All that needs to be done is to "register" the builders in the \WIZARDS\BUILDER.DBF. Here's how to do this from the command window:
use home()+"wizards\builder.dbf"
insert into builder values ("Horizontal Equispacer", ;
"Put the same amount of horizontal space between selected objects", ;
"", "MULTISELECT", "hequispace.prg", "", "", "" )
insert into builder values ("Vertical Equispacer", ;
"Put the same amount of vertical space between selected objects", ;
"", "MULTISELECT", "vequispace.prg", "", "", "" )
use
The value MULTISELECT means that these builders are only to be used when more than one object is selected. Although these builders require 3 or more objects are selected. Now when you select the controls you can access these builders via the context menu instead of using the command window.
Here's a couple of relevant KB Articles Q138979, Q141797 and Q147787