Emulating SubForms
by Jason Tyro - GUI Computing
Here is a neat and simple form design initially developed for a system that required a … neat and simple user interface.
The primary concern was the low computer literacy of the potential users, so forms with minimal controls and big self-descriptive buttons were a must. Also, as users would be clicking between screens, we didn't want multiple documents open all over the screen as this would become increasingly distressing to all concerned. No menu bar would be required, just big, bold buttons allowing the user to enter and retrieve data from a variety of screens.
We could have used the TAB control to display the separate screens, however the users really were low in skills (and would remain that way) and all those controls on a series of Tabs sounded like a recipe for all sorts of resource and development issues.
The obvious answer was an Outlook-style interface, but we really needed each panel to be able to be worked on and loaded separately.
Well, after what was probably several minutes of brainstorming, the great Jim Karabatsos came up with a gem of a user interface which not only is a complete solution to the described problem, but is a piece of cake to implement. Bizarrely, the resulting approach ends up working like subforms do in MS Access - back to the future?
Step 1.
Create the Parent Form (frmMain)

Paste in this code
Option Explicit
Const BUTTONS = 3 'Number of buttons and forms
Dim F(1 To BUTTONS) As New frmClient
Dim CurrentForm As Integer
Private Sub MDIForm_Load()
'Set up main form and load OutlookBar form
Load frmOutlookBar 'This will be a form that sits on the side on the Parent
frmOutlookBar.Width = frmOutlookBar.cmdMain(1).Width _
+ 2 * frmOutlookBar.cmdMain(1).Left
+ Screen.TwipsPerPixelX 'Set the width of the Outlook bar form
Dim I As Integer
For I = 1 To BUTTONS 'Load all 3 Forms
F(I).Visible = False
F(I).lblID.Caption = "This is form " & Format$(I) 'Set caption on label
Next I
RequestResize 'Resize form
NotifyClick 1 'Initialize with first form
End Sub
Private Sub MDIForm_Resize()
'Resize stuff, OutlookBar form is scaled to Parent form
Dim T As Single, L As Single, W As Single, H As Single
H = Me.ScaleHeight
T = 0
L = frmOutlookBar.Width
W = Me.ScaleWidth - L
If H < 0 Then H = 0
If W < 0 Then W = 0
Dim I As Integer
For I = 1 To 3
F(I).Move L, T, W, H 'Scale client forms to new Parent size
Next I
frmOutlookBar.Height = H
End Sub
Public Sub RequestResize(Optional Sender As Object)
MDIForm_Resize
End Sub
Public Sub NotifyClick(ByVal nButton As Integer)
'Click event that displays the required form
If CurrentForm > 0 Then
F(CurrentForm).Hide 'Hide currently displayed form
End If
CurrentForm = nButton 'Select form depending on button index
F(CurrentForm).Show 'Show selected form
End Sub
Step 2.
Create the Outlook style form (frmOutlookBar)
| The command buttons are a control array called cmdMain.
Of course there's nothing stopping you from using other types of controls to select between the forms. For a proper Outlook 'look' GreenTree's GTGrouplist (part of their Active ToolBox, reviewed last issue) is probably the neatest solution going around at the moment. But for now, buttons will do. |
Paste in this code
Option Explicit Private Sub cmdMain_Click(Index As Integer) 'Call NotifyClick event in the parent form frmMain.NotifyClick Index End Sub
Step 3.
Create the Client form that form the basis of the array declared in the Parent form (frmClient)

This form has no code behind it and contains nothing but a label control whose name is 'lblID'. This label is only there to show which form you have currently displayed.
That's it! The result for all this hard work should look like...

Of course to be of any use to anyone the client forms should all be different and not the same with a differing label!
A rather neat idea for a user interface methinks.