Download as pdf or txt
Download as pdf or txt
You are on page 1of 5

Smart Access

Resize With Class


2000
Stuart Kinnear
In this article, Stuart Kinnear completes his review of the product to your code, and various design considerations.
Access form resizer tools by taking a free version through his The language is easy to understand, and the concepts are
test suite. The tool not only works well, but handles some readily grasped. The product’s limitations are clearly
problems that defeated the previous products. indicated. For example, the control won’t resize the fonts
on datasheets because the process is inherently unreliable.

I
N the December 2000 issue, I wrote an article There’s also no font substitution code, so fonts need to be
evaluating three resizing tools (“Everything About True Type fonts in order for them to resize properly. I’m
Resizing Controls”). In that article, I made reference pleased to see that these limitations are discussed openly.
to the coverage of the resizing problem in the Access It’s disappointing to discover a product’s faults several
Developer’s Handbook. Shortly after the article was hours or days into a development project.
published, Ken Getz, one of the book’s authors and a For my previous article, I’d sent the vendors a
respected speaker and Access authority, asked me to battery of questions. I submitted the same battery to
evaluate the resizing tool that the book discusses. Ken’s Ken, and I was happy to obtain responses to all of my
tool comes with the Access 2000 Developer’s Handbook and questions. Available with this month’s Source Code file at
can be downloaded from www.developershandbook.com www.smartaccessnewsletter.com is a transcript of the
for free. Ken’s product is attractive not only because it’s responses Ken sent me (I’ve also included the responses
free and effective but because of its clever use of classes to from Peter’s Software, the only other company to respond
control the resizing process. to all of my questions).
Ken has produced a resizing product for Access 2000
and Access 97 that not only has the capacity to resize Testing
forms and their controls but also has the ability to restrict Ken, as with the other resizing product suppliers, has you
controls in resizing or moving in relation to the form. place code in the Open event procedure of the form that
Under the hood, the tool is a well-constructed product you want to resize. Unlike the other controls, though, you
that encapsulates the concepts of object-oriented design don’t have to put code in the form’s Resize event. Ken
(at least, as far as Access will allow). The product is well- uses WithEvents to catch events fired by the form and
supported with documentation explaining the underlying catch the Resize event for you. This makes for much less
theory, its application, and the tool’s limitations. coding on your behalf.
When products are free, I’m initially skeptical of a The main catch with using WithEvents event sinks is
product’s quality and ask the obvious question: “What’s that you must have the HasModule property set to True
the catch?” Well, there isn’t any real catch—or any on the form, and any code you want to use separately on
question of the tool’s quality. The only catch is that if the Open and Resize events must be marked as an [Event
you don’t purchase the Access 2000 Developer’s Handbook, Procedure]. Otherwise, the Event call you try to apply will
you don’t get the source code. Of course, I’d highly be eradicated (this is documented in Ken’s notes as well).
recommend that every serious Access developer have the In the December 2000 article, I built a test harness for
version of the Access Developer’s Handbook (by Litwin, the controls that used a common procedure to open my
Getz, and Gilbert) that’s appropriate for the version of sample forms. That procedure applied a class using
Access that they’re developing with (versions exist for WithEvents in a similar fashion to Ken’s, allowing me to
Access 2.0 and up). apply resizing code to every form without having to code
At present, the downloadable resizer tool is available each form. The same class, albeit with modifications, was
for Access 2000 (with source) and Access 97 (in MDE used with success on this product. If you have many
format) only. It isn’t a tough task to convert the Access forms in your application or need to retrofit to an existing
2000 program back to Access 97 if you need the source on application, this approach saves many hours of coding
that platform, although you’ll need to grasp some of the and reduces your margin for error.
newer language facilities such as Enum and Friend. Initially, however, I couldn’t get a stable environment
The tool’s documentation is an Adobe Acrobat PDF for resizing using this approach (NT’s Dr. Watson kept on
file, which explains what resizing has to deal with in producing access violation errors). I thought the code was
terms of screen resolutions and fonts, how to apply the crashing because both routines were using WithEvents

http://www.smartaccessnewsletter.com Smart Access May 2001 13


and Access was just bamboozled. I almost gave up until, after the first opening event (that is, when the
with a bit of persistence, I discovered something underlying form was maximized).
interesting. If I created a module-level reference to Ken’s
resizing class and then terminated it within my form The eToolsResizer and ShrinkerStretcher products
opening routine, Access would crash. Since I did want to were written in Access. So, with a bit of tinkering, you
disconnect Ken’s resizing control from my sample forms could adjust for weaknesses and problems (provided
in my test harness, this created a problem. In the end, all I that you had that capability and the time to do it). I
needed to do was change the Resize event in the test form paid particular attention to these areas to check for any
to an empty string (“”). Ken reckons that this is a known problems as I tested Ken’s tool.
bug in Access 97 and 2000 and will be fixed (supposedly)
in Access 2002. Bit of a shame I didn’t know about it at Popup and modal forms
the time! The code in Sub mobjForm_Timer() shows my Ken’s resizer also failed to handle popup and modal
test code: forms, unfortunately. In response to my questions, Ken
suggested that the only possible way to make this
Private mfrmResize As FormResize work would be to subclass Access, although he hasn’t
Private Sub mobjForm_Timer()
investigated this route. Being game, I thought I’d pursue
On Error Resume Next
If mblnResizeOnce = True Then
this avenue, and came to the conclusion that it is indeed
mblnResizeOnce = False possible. One other benefit is that you can also monitor
With mobjForm
.TimerInterval = 0
the Access application resizing events. I was able to
.OnResize = "" create a DLL using VB6 that could monitor and act upon
'-- This will cause a crash the resizing events. I used this tool to hold an Access
'Set mfrmResize.Form = Nothing application at one size, for instance. I’m not comfortable
'Set mfrmResize = Nothing
End With releasing the DLL due to some problems with making it
End If multi-use that I wasn’t able to resolve. You can find an
End Sub. article on the process at www.vbaccelerator.com, but you
should read all that you can about subclassing before
I tested the product on Access 97, Access 2000, tackling this process.
Windows 95/98, NT 4.0, and Windows 2000. It
performed effectively with both versions of Access and Option groups
all of the Windows platforms tested. I set my resolution The resizing controls evaluated in my previous article all
to 640x480, 800x600, 1024x768, and 1152x864 with fonts suffered problems with option groups on tab forms. None
at standard, large, and a custom 200% font size. There of those problems were exhibited in this product, as
were no ill effects with these resolutions and font shown in Figure 1.
combinations, although some of the
labels failed to handle the larger fonts
(with 800x600 and a 200% font size,
you really need careful form design
in the first place).

Test results
In my December 2000 review, the
three controls I tested worked on
very basic form layouts but failed on
forms with even low levels of
complexity. The following areas were
particularly weak:
• Option groups placed on tab
forms lost their shape as the
option buttons pushed out the
borders during resizing.
• The sizing operation in complex
forms, when rapidly resized,
couldn’t keep up.
• On popup and modal forms, the
resize event didn’t seem to fire Figure 1. Multiple option groups on tab forms aren’t a problem.

14 Smart Access May 2001 http://www.smartaccessnewsletter.com


Resizing controls for any control on a form. This property is useful for text
I had some problems with the ActiveX Snapshot viewer entry forms. When a user resizes this form, you’d want to
control when I embedded it on a tab form. It maximized make the text entry area bigger but keep the Close and
to the extent of the form but didn’t recover from the Save buttons at a fixed size in the same relative position
resizing. You also have to be careful with subforms. on the form (for example, in the bottom right corner of the
The subforms need to be the same size as or slightly form). Setting Float but not Size on the buttons would
smaller than the frame used to embed the subform on accomplish that.
the main form. If they’re larger, you risk losing the
subform’s detail. Minimum height and width
As with any resizer, tightly congested controls are This feature works but is faulty. If you set the minimum
difficult to size properly. If, for instance, you have a grid form height and width, the form doesn’t repaint properly
of text boxes and accompanying labels with solid borders, when it expands back to the minimum restraint. I set the
a resize upwards will magnify any slight dimensional figure to 60 percent of the client area and found the form
inconsistencies. A 1% difference in size might not be to be semi-transparent (see Figure 3 on page 16).
apparent until the user significantly increases the form
size—at which point the overlap between the boxes will Performance
be painfully obvious. The form load time isn’t as snappy as a form without
the resizer. But, considering the amount of calculations
Dynamic and static scaling and control resizing, the speed isn’t bad. In my own
The ScaleControls property can be set to scYes to applications, I find that setting the sizing to once-only
dynamically rescale the form or scAtLoad to scale only improved performance considerably. The fact that the
once. Although this facility functioned, I found the application can resize in the first place has greatly
scAtLoad property to be unsatisfactory if you use improved customer acceptance and the professional feel
maximized forms. The form wouldn’t scale to the of my product, more than compensating for any
maximized state, but to some proportion of the design performance hits.
resolution. The easy way around this is to leave the
resizer at scYes and set the resize event to an empty string CenterOnOpen
after the initial maximize call. If you set a form’s AutoCenter property to True, when
a form opens it will center itself, resize by moving to
Size and Float the top left of the screen, and then center again. The
At the control level, Ken has a feature not available in other products that I tested used API calls to attempt to
the other products, called Size and Float. Size and Float freeze screen updates during this process, but there’s a
allows you to fix the size and
position of controls on your forms,
yet allow the rest of the form to resize
(see Figure 2). This is a very powerful
addition to the concept of resizing.
This feature works well and without
any problems.
Here, I’ll define the terms that
Ken uses:
• Scale means that the coordinates,
dimensions, and fonts will
change (the normal behavior of
a resizer).
• Size means that the dimensions
and font will change, but the
control’s position won’t.
• Float means that the control will
reposition to remain at the same
relative offset to the nominated
edge of the form, but the
control’s size won’t change.

All of these properties can be set Figure 2. The same form showing Size and Float in action.

http://www.smartaccessnewsletter.com Smart Access May 2001 15


perceptible jumpiness as the form snaps to the centered use. Ken allows fonts to be as small as one point, where
position. Ken has created a CenterOnOpen property I feel that it’s appropriate to restrict the font to eight
that’s designed to center the form only once and minimize points. However, if you do limit the minimum font size,
these distracting move and resize activities. I found it to you’ll need to apply values to the form’s minimum and
be an effective solution for minimizing screen activity maximum dimensions.
(and it also speeds the form load time). When using If you want to resize fonts within ActiveX controls
Ken’s control, set his property and leave AutoCenter set (for example, to change the fonts used by the Treeview
to False. control), you’ll also need to add your own code to Ken’s
class. To cater for ActiveX controls, you’ll need to adjust
Dealing with fonts the code in the Sub ScaleTheFont and ChangeFont
As Ken noted, he doesn’t do font substitution. The easiest procedures. This is an easy matter if the control supports
solution, if you have non-scaleable fonts, is to change the FontSize property, as you just need to alter the
them to True Type fonts. These fonts include MS Sans ChangeFont function, adding a new Case for the control
Serif and System. As an example, this code will change all type acCustomControl. If the control doesn’t have a
the fonts on your forms to Tahoma: FontSize property, you’ll need to insert further code.
Here’s the code to handle the Treeview control:
Function ChangeAllFonts()
Private Property Get _
Dim contFrm As Container
Dim frmEdit As Form FontSize(ctl As Control) As Long
Dim ctl As Control FontSize = 0
Select Case ctl.ControlType
Dim dbCur As Database
Dim intCtlCount As Integer Case acTextBox, acComboBox, acListBox, _
Dim intFrmCount As Integer acLabel, acCommandButton, acToggleButton, _
acTabCtl
Set dbCur = CurrentDb() FontSize = ctl.FontSize
Set contFrm = dbCur.Containers("Forms") Case acCustomControl
If InStr(ctl.Class, "TreeCtrl") > 0 Then
For intFrmCount = 0 To _ FontSize = ctl.Font.Size
contFrm.Documents.Count – 1 End If
Case Else
DoCmd.OpenForm _
contFrm.Documents(intFrmCount).Name,acDesign End Select
Set frmEdit = _ End Property
Forms(contFrm.Documents(intFrmCount).Name)
On Error Resume Next Private Property Let _
For intCtlCount = 0 To frm.Count – 1 FontSize(ctl As Control,
lngFontSize As Long)
Set ctl = frm(intCtlCount)
Ctl.FontName = "Tahoma" Select Case ctl.ControlType
Next Case acTextBox, acComboBox, acListBox, _
acLabel, acCommandButton, acToggleButton, _
DoCmd.Save acForm, frmEdit.Name
DoCmd.Close A_FORM, frmEdit.Name acTabCtl
Next intFrmCount ctl.FontSize = lngFontSize
End Function

The alternative is to apply a font


substitution routine within the code.
This, of course, means that you’ll
need the source code version of the
product and will need to buy the
Developer’s Handbook (a good idea,
anyway). There are two cases to
consider here: text within Access’s
native controls (text boxes, list boxes)
and text within ActiveX controls.
To apply font substitution code
with Ken’s code, you’ll need to go to
the FormResize class module and
find the Sub ScaleTheFont routine. In
that routine, it’s a simple matter to
insert a Select Case for the fonts you
want to substitute. Examining this
procedure reveals that you can also
do things like apply limits to the
minimum or maximum font size to Figure 3. Forms become semi-transparent when the minimum property is set.

16 Smart Access May 2001 http://www.smartaccessnewsletter.com


Case acCustomControl might not answer all of your resizing needs. Peter’s
If InStr(ctl.Class, "TreeCtrl") > 0 Then
ctl.Font.Size = lngFontSize Software’s ShrinkerStretcher product offers a wider range
End If
Case Else
of features, for instance, but isn’t as polished internally as
End Select Ken’s product. You might consider marrying the features
End Property
of both to meet your own needs. Regardless of which
Private Sub ScaleTheFont( _ control you use, you’ll need to give your application a
ctlr As ControlResize, decFactorX As Variant, _
decFactorY As Variant) thorough testing to determine any problems that might
arise with the addition of any resizing product.
Dim ctl As Control
Dim decFactor As Variant Ken has developed an excellent product, and it
Dim decFontSize As Variant provides a great framework for any enhancements that
Dim strFontProp As String
you want to make. In my previous article, I suggested that
Const cMinFontSize = 7
Const cMaxFontSize = 127
the resizers could do with an object-oriented approach to
their design that was based on classes modules, and Ken
If ScaleFonts Then
Set ctl = ctlr.Control has proven the merits of doing this. What’s even more
decFactor = CDec(Min(decFactorX, decFactorY)) pleasurable is that the base product is available for the
decFontSize = _
RoundWhole(CDec(ctlr.FontSize * decFactor)) cost of your Internet download time, and the source is
available for the cost of purchasing one of the best Access
If decFontSize < cMinFontSize Then
decFontSize = cMinFontSize books available today. ▲
End If
If decFontSize > cMaxFontSize Then
decFontSize = cMaxFontSize RESIZER.ZIP at www.smartaccessnewsletter.com
End If
FontSize(ctl) = decFontSize
End If Stuart Kinnear is managing director of SK Pro-Active! Pty Ltd, Melbourne,
End Sub
Australia (www.skproactive.com). He develops applications in Microsoft
Office and Visual InterDev. When there’s free time, he enjoys time with his
You also need to alter the .FontSize line in the family and outdoor pursuits such as back-country ski touring, wilderness
GetControlInfo rotuine to read : bush walking, and canoeing. skproactive@skproactive.com.

FontSize = FontSize(ctl)

Suggestions
As with the other controls that I tested, there are
enhancements that I’d like to see. These enhancements
are minor, as the product has been well thought-out and
needs very little in the way of improvement.
• Font substitution code would take care of those
people who find it difficult to design with scalable
fonts. This would be especially useful for those who
have inherited projects that originate from Access 1
and 2. Font sizing code for all of the ActiveX controls
supplied by Microsoft in the Developer’s edition
should be available.
• There should be a proportional setting for the forms.
It would be a desirable feature for me to have this for
my own applications, where the forms are heavily
loaded with grids and other controls.
• It would be useful to scale popup forms to the size of
the Access application. I had a situation where the
client had a resolution of 1280x1024, and he wanted
the application to remain at an equivalent size of
800x600. I could do this by setting the application to
800x600 at startup. The main problem is that the
popup forms scaled to the 1280x1024 resolution and
not proportionally to the application size.

Ken’s product is a considerable improvement over the


products evaluated in my December 2000 article, but it

http://www.smartaccessnewsletter.com Smart Access May 2001 17

You might also like