
Jumping right into the code, you’ll notice that every form includes a public function named ResizeControls() which accepts two arguments: lObjWidth and lObjHeight. This function is called by the PARENT form, and the values passed are determined by Form properties called InsideWidth and InsideHeight. You will need to adjust the Height by subtracting the Form Header and Footer space, as that is part of the inside Height. It looks something like this …
Public Const cGap As Long = 100
lngObjWidth = Me.InsideWidth - (cGap * 2)
lngHeadFoot = Me.Section(acHeader).Height + Me.Section(acFooter).Height
lngObjHeight = Me.InsideHeight - (lngHeadFoot + (cGap * 2))
The code (both above and below) references a constant named cGap. This is a global constant which is set once and used everywhere. It allows me to tweak the appearance, giving more or less space between objects with a single edit. (This public constant must be placed in a standard module or the main form module, so it is always available.)
The parent form, after loading the requested subform in the subform object, invokes the ResizeControls method, passing the appropriate width and height. If that subform has subforms, it simply repeats this process, determining the allotted space for each subform and invoking that subform’s ResizeControls property. While this process isn’t trivial, once you get used to it, writing the code becomes routine. Most of the important stuff happens on the ResizeControls() function. (See my comments inline with the code.)
Public Function ResizeControls
(ByVal lObjWidth As Long, ByVal lObjHeight As Long) As Long
On Error GoTo Err_Handler
Dim lngWidthLeft As Long
Dim lngWidthRight As Long
Dim lngHeightLeft As Long
Dim lngHeight As Long
Dim lngHorOffset As Long
Dim lngVerOffset As Long
Call SetFormColors(Me)
g_lngResult = SetHeaderCtls(Me, lObjWidth)
lngHorOffset = GetScrollbarOffset(Me, "V") + (cGap * 2)
lngWidthLeft = (lObjWidth - lngHorOffset) * 0.7
lngWidthRight = (lObjWidth - lngHorOffset) * 0.3
lngVerOffset = GetScrollbarOffset(Me, "H") + (cGap * 2)
+ Me.Section(acHeader).Height
lngHeight = (lObjHeight - lngVerOffset) / 2
Me!objEmployee.Left = cGap
Me!objEmployee.Top = cGap
Me!objEmployee.Width = lngWidthLeft
Me!objEmployee.Height = lngHeight
g_lngResult = Me!objEmployee.Form.ResizeControls(lngWidthLeft, lngHeight)
Me!objCustomer.Left = cGap
Me!objCustomer.Top = Me!objEmployee.Top + (lngHeight) + cGap
Me!objCustomer.Width = lngWidthLeft
Me!objCustomer.Height = lngHeight
g_lngResult = Me!objCustomer.Form.ResizeControls(lngWidthLeft, lngHeight)
Me!objProduct.Left = cGap + lngWidthLeft + cGap
Me!objProduct.Top = cGap
Me!objProduct.Width = lngWidthRight
Me!objProduct.Height = lngHeight
g_lngResult = Me!objProduct.Form.ResizeControls(lngWidthRight, lngHeight)
Me!objOrders.Left = cGap + lngWidthLeft + cGap
Me!objOrders.Top = Me!objProduct.Top + (lngHeight) + cGap
Me!objOrders.Width = lngWidthRight
Me!objOrders.Height = lngHeight
g_lngResult = Me!objOrders.Form.ResizeControls(lngWidthRight, lngHeight)
Exit_Here:
Exit Function
Err_Handler:
MsgBox Err.Description, vbCritical
Resume Next
End Function
As you poke around in the sample application, you’ll notice that every form has an array of header controls: lblCaption and lblDescription and sometimes hyperlink labels named New, Edit and Delete. Again, for consistency, I try to include these labels on every form, even if they are not used. (You can set the properties of an invisible label, but you’ll get an error if you try to reference a non-existent control.)
Below is the code that is called from every ResizeControls() function. It takes three arguments: The calling form (by reference), a width and an optional comma-delimited string list of control names that should be formatted as hyperlinks. See inline comments for an explanation of the code.
Public Function SetHeaderCtls(ByRef frm As Access.Form,
ByVal lWidth As Long,
Optional ByVal sHyperLinks As String) As Boolean
On Error GoTo Err_Handler
Dim lngScroll As Long
Dim strForm As String
Dim strControls() As String
Dim iCtl As Integer
Dim ctl As Control
Dim lngStartLblPos As Long
Dim fLblCaption As Boolean
Dim fLblDescr As Boolean
Dim strCaption As String
Dim strDescr As String
Dim strCriteria As String
strForm = frm.Name
lngScroll = GetScrollbarOffset(frm, "V")
lWidth = lWidth - lngScroll
If IsMissing(sHyperLinks) Then sHyperLinks = ""
If Trim(sHyperLinks) <> "" Then
strControls = Split(sHyperLinks, ",")
lngStartLblPos = cGap
For iCtl = 0 To UBound(strControls())
Set ctl = frm.Controls(strControls(iCtl))
ctl.Top = 50
ctl.Left = lngStartLblPos
ctl.Height = 210
lngStartLblPos = lngStartLblPos + (ctl.Width + cGap)
ctl.HyperlinkAddress = " "
Next
End If
fLblCaption = False
fLblDescr = False
For Each ctl In frm.Controls
If ctl.Name = "lblCaption" Then fLblCaption = True
If ctl.Name = "lblDescription" Then fLblDescr = True
Next
strCriteria = "[FormName]='" & strForm & "'"
strCaption = Nz(DLookup("[CaptionText]", "FormLookup", strCriteria))
strDescr = Nz(DLookup("[DescriptionText]", "FormLookup", strCriteria))
If strCaption = "" Then strCaption = ParseFormName(strForm)
If strDescr = "" Then strDescr = "No description found for [" & strCaption & "]"
If fLblCaption Then
With frm.Controls("lblCaption")
If .Visible = True Then
.Caption = " " & strCaption
.Width = lWidth
.ForeColor = cCaptionForeColor
.BackColor = cCaptionBackColor
.BackStyle = cNormal
.FontName = "Tahoma"
.FontBold = True
End If
End With
End If
If fLblDescr Then
With frm.Controls("lblDescription")
If .Visible Then
.Caption = " " & strDescr
.Left = 0
.Width = lWidth
.ForeColor = cDescripForeColor
.BackColor = cDescripBackColor
.BackStyle = cNormal
.FontName = "Tahoma"
.FontBold = True
End If
End With
End If
Exit_Here:
Exit Function
Err_Handler:
MsgBox Err.Description, vbCritical
Resume Next
End Function
Fun and Frustration
This object resize code works pretty well and I’m pleased with the applications where I’ve implemented it. That doesn’t mean, however, that it is without frustration. Getting things to line up and display where desired will take some tweaking. If you set one property incorrectly, the whole page will look screwy. Those who attempt to implement this will undoubtedly want to write me for assistance and I’ll be happy to help, but ultimately you are going to have to use trial and error to get your pages to display the way you want. Please check and double check the TOP, LEFT, WIDTH and HEIGHT properties before assuming the code is broken. Remember, it works in the demo, so if you have difficulty, the solution is in your implementation code.
» See All Articles by Columnist Danny J. Lesandrini