Chapter 24. Using Data-Aware Print Forms in SIMPOL
The printform1 family of types provides the ability to design, save, load, and print data-aware forms with an accuracy to the nearest micrometer. This chapter discusses how to use the set of types that implement this functionality.
![]() | Note |
|---|---|
As is the case with other chapters, this chapter will not make much sense unless you have already read and feel comfortable with the earlier chapters covering variables and grammar. |
The Design of printform1
The approach to printform1 was to provide a method of printing accurate forms to the print preview window and to the printer, without needing to previously display the printed form to the user. Although it is possible to display the printed forms, all coordinates are stored in micrometers and are then converted as well as possible to pixels for display purposes. At the time of writing, no significant testing has been done with the display of these forms. That has been reserved for the period of time when the Print Form Designer is being developed.
The first step in working with the printform1 family of types is to learn the members of the family and what role they play. Here is a list of the types:
printform1
printform1page
printform1graphic
printform1control
printform1arc
printform1ellipse
printform1line
printform1rectangle
printform1triangle
printform1text
printform1bitmap
Understanding the list is fairly easy. The first element is the form, the second represents a page on the form. The third is a generic type that incorporates most of the elements that the graphic controls have in common, the same is true of the fourth item, but for controls. This was done because it turns out that the SIMPOL IDE is able to provide context help for variables that are declared using a type tag if that type tag name is also defined as a type. All of the graphic elements: the arc, ellipse, line, rectangle, and triangle, are type tagged using printform1graphic, and the text and bitmap items with printform1control, which greatly eases the development in the IDE of applications that use variables based on the type tag.
Each of the graphic types incorporate the related wxgraphic type, for use when displayed. In addition, they have a duplicate
of the all the properties that affect the final look, prefaced in most cases with the word "print".
The reason for this is that the design required that each of the elements carry the most accurate units, plus that it should
be possible to have the entire form created without needing access to the embedded wxWidgets control, since that would require
the control to be created in some displayable form. Since it was necessary to be able to draw the control directly into a
wxprintout object, all of the elements that affected that result needed to be part of the property list for the
graphic or control.
Let's go through each of the properties of the types, to see how they are constructed. The first and most complex of these is the printform1 type. It has many similarities with the dataform1 type. So many, in fact, that the original dataform1 type was also type tagged with dataform1, and the printform1 also carries this type tag, as well as the dataform1linkcontainer tag. Doing this allowed printform1 to reuse many of the types used in the dataform1 family of types, such as: dataform1datasource and dataform1link. Here is the type definition:
type printform1 (printform1, dataform1, dataform1linkcontainer) \
export
embed
printform1private _private
boolean valid
integer defpagewidth
integer defpageheight
integer defpagebackcolor
boolean designmode
boolean dirty
boolean createdisplayform
boolean locked
SBLNumSettings defnumericlocale reference
SBLlocaledateinfo defdatelocale reference
string defnumberformat
string defdateformat
string deftimeformat
string defdatetimeformat
string defintegerformat
string defbooleanformat
string name
string filename
string printpreviewtitle
dring datasources
dring tables
dring bitmaps
dring controls
dring graphics
dring pages
dring siblinglinks
event onselect
event onsave
reference
type(*) _
type(*) __ resolve
dataform1table mastertable
dataform1record masterrecord
type(wxcontainer) container
wxfont deffont
printform1page currentpage
array fonts
function addbitmap
function addcontrol
function addgraphic
function adddatasource
function addpage
function addtable
function blank
function builddisplayform
function clearsiblinglinks
function findbitmapsource
function findcontrol
function finddatasource
function findgraphic
function findsiblinglink
function findtable
function getfieldandtable
function getfont
function lock
function nameinuse
function print
function refresh
function removedisplayform
function saverecord
function selectcurrent
function selectfirst
function selectkey
function selectlast
function selectnext
function selectprevious
function setcontainer
function setdirtystate
function setmastertable
function showpage
function unlock
end type
Much of the type definition of printform1 is taken from that of
dataform1, so let's look only at the differences. The
createdisplayform indicates if, while creating the form, it should also
create a displayable form using wxform and related types. There is also a
printpreviewtitle property, which is used as the caption of the print
preview window if the form is printed to that destination. Although there is an
onsave event, this type was not designed for doing data-entry, and it
may be removed at a later date. Like the dataform1 type, it contains numerous
default properties and various rings of controls, graphics, tables, data sources, and the
like. The methods are also quite consistent with those used in dataform1. One
significant difference is the builddisplayform() method. This can be
called after the form has been created to produce the display version of the form, by
converting the print coordinates to display versions. The other method that is new is
print(). This method takes a boolean parameter called
showprintpreview that defaults to .true. It also
takes a dialogdata parameter that can contain the printer information,
so that the print dialog does not need to be shown to the user. This can be very handy for
unattended printing.
The next type we wish to look at is the page. Like with the form, the page is very similar to the dataform1page type and it has also been type tagged as dataform1page. Here is the type definition:
type printform1page(dataform1page) export reference wxform wxformpage embed dring controls dring graphics integer pagenum string name integer printbackgroundrgb // These are the actual values for the printout in micrometers integer printwidth integer printheight reference type(*) _ type(*) __ resolve dlistnode formnode printform1 form function addcontrol function addgraphic function builddisplayform function changename function print function resize function setactive end type
The significant differences are again specific to the print capabilities.
The printbackgroundrgb property contains the background color. The
printwidth and printheight properties contain the
paper size that will be passed in when producing the wxprintpagetemplate. As with
the form, there are also the two methods: builddisplayform() and
print(). The first is called to create the display version of a
single page. The second is called to transfer the page to a printout, which is passed to it by
the form version of print().
Adding graphics and controls to the print form is very much the same as adding them to a
dataform1 object. To add a graphic call the
addgraphic() method, and to add a control call the
addcontrol() method. The parameters to each are slightly different
to those for the dataform1 versions, and are worth a look. Here is the parameter
list for the printform1.addgraphic() method:
addgraphic()
Methodtype
graphictypepoint
printpoint1point
printpoint2point
printpoint3point
printmidpointinteger
rgbinteger
borderrgbinteger
widthinteger
borderwidthboolean
visibleboolean
bordervisiblestring
printnametype(printform1graphic)
nextprintform1page
pageinteger
error
As we can see from the preceding description, most of the parameters have the
same name, but the point parameters differ. This was partly because in the
original design it was possible to pass both the display and the print parameters in, until it
was redesigned to always calculate the display parameters from the print ones. The same thing
is true in most ways with the printform1.addcontrol()
method. Here are the parameters for that:
addcontrol()
Methodtype
controltypeinteger
printleftinteger
printtopinteger
printwidthinteger
printheightstring
textboolean
visiblewxbitmap
bitmapstring
scalinginteger
backgroundrgbinteger
textrgbstring
printalignmentwxfont
fontstring
printnameboolean
backgroundvisibleboolean
undergraphicsboolean
underbitmapstype(printform1control)
nextprintform1page
pagetype(db1field)
fielddataform1table
tablestring
displayformatinteger
error
Again the majority of the parameters are the same as those from the
dataform1.addcontrol() method, but a few differences
are clearly visible. All of the position parameters have the word
"print" as the first part of their name, as do the alignment
and name parameters. For the alignment that is because the type of alignment control allowed
on a wxprintout is more intricate than that on a wxform. Some of the
other new parameters are specific to capabilities of the wxprintbitmapitem and
wxprinttextitem types. Rather than go into each of the graphics and controls,
since they are very similar to the standard ones, it is probably better to just look at how to
create and print a form. The next section will do just that.



![[Note]](images/note.png)