11.13 Collect and Display Information on the System and the Access Installation

2.7 Size a Form's Controls to Match the Form's Size

2.7.1 Problem

Windows users have become accustomed to resizing forms on their screens. A professional-looking application will proportionally resize the controls on a form when you stretch or shrink that form. You'd like to be able to resize your forms while the application is running and have the controls on the form react appropriately. For example, the Database Explorer window's list box expands when you expand the window. How can you do this on your own forms?

2.7.2 Solution

Because Access can notify your application when the user resizes a form, you can attach code to the Resize form event and react to the change in size. Access also triggers this event when it first draws the form, so you can place your controls correctly then, too. Base your calculations on the form's InsideWidth and InsideHeight properties.

Load and run the form frmExpando in 02-07.MDB. Resize the form and watch the size of the large text box. Also notice the positions of the two command buttons. Figure 2-13 shows the form in design mode, and Figure 2-14 shows two copies of the form sized to different proportions. Though it's perfectly reasonable to change the size of all the controls, this form does not. It uses three different techniques:

Do nothing

The label above the text box doesn't change at all as you resize the form.

Change position only

The two command buttons move with the right edge of the form, but they don't change size.

Change size

The large text box changes its size to match the size of the form.

Figure 2-13. frmExpando in design mode

figs/acb_0213.gif

Figure 2-14. Two copies of frmExpando with different proportions

figs/acb_0214.gif

The code that does the work in this case is specific to the particular form. Follow the steps below to create a form similar to frmExpando. Once you've gone through these steps, you should be able to expand on the concepts (pun intended) and create your own self-sizing forms.

  1. Create a new form and create controls and properties as shown in Table 2-5.

     

    Table 2-5. Controls and their properties for frmExpando

    Control type

    Property

    Value

    Label

    Name

    lblSample

     

    Left

    0.1 in

     

    Top

    0.0833 in

     

    Width

    1.7917 in

     

    Height

    0.1667 in

     

    Caption

    Enter some text

    Text box

    Name

    txtEntry

     

    Left

    0.1 in

     

    Top

    0.3333 in

     

    Width

    1.8 in

     

    Height

    0.8333 in

    Command button (OK)

    Name

    cmdOK

     

    Caption

    &OK

     

    Left

    2 in.

     

    Top

    0.3333 in

     

    Width

    0.6979 in

     

    Height

    0.25 in

    Command button (Cancel)

    Name

    cmdCancel

     

    Caption

    &Cancel

     

    Left

    2 in.

     

    Top

    0.6667 in

     

    Width

    0.6979 in

     

    Height

    0.25 in

     

  2. Place the following code in the form's Resize event procedure. You can copy this code from frmExpando's.

    Private Sub Form_Resize(  )     Dim intHeight As Integer     Dim intWidth As Integer     Dim ctl As Control     Static fInHere As Integer          Const acbcMinHeight = 2000     Const acbcMinWidth = 4000     ' Optimize a bit. If you're already executing the code in here,      ' just get out. This can happen if you're in here because of an      ' auto-resize (if you try and size the form too small).     If fInHere Then GoTo ExitHere     fInHere = True     On Error GoTo HandleErr     ' Get the current screen coordinates.     intHeight = Me.InsideHeight     intWidth = Me.InsideWidth          ' Make sure the width and height aren't too small. If they are,      ' resize the form accordingly. This could force Access to call      ' this sub again, so use fInHere to avoid that extra overhead.     If intWidth < acbcMinWidth Then         DoCmd.MoveSize , , acbcMinWidth         intWidth = Me.InsideWidth     End If     If intHeight < acbcMinHeight Then         DoCmd.MoveSize , , , acbcMinHeight         intHeight = Me.InsideHeight     End If          ' Set the detail section's height to be the same as the form's.     ' Change this if you want to include header and footer sections.     Me.Section(0).Height = intHeight     ' Align all the other controls, based on the left margin of the text box.     Set ctl = Me!txtEntry     With ctl         ' Make the left and bottom margins equal.         .Height = intHeight - (.Left + .Top)         ' The new width is the width of the form, minus the width of the          ' buttons, minus 3 times the gap (the left margin). Two gaps are          ' for the buttons, and one more is for the left margin itself.         .Width = intWidth - Me!cmdOK.Width - (3 * .Left)     End With     ' Set the positions of the two buttons.     With Me!cmdOK         .Left = intWidth - .Width - ctl.Left     End With     With Me!cmdClose         .Left = intWidth - .Width - ctl.Left     End With      ExitHere:     Exit Sub HandleErr:     fInHere = False     Resume ExitHere End Sub

2.7.3 Discussion

The code used in this solution reacts to the Resize events that occur when you resize a form in run mode (and when you open the form). The code retrieves the form's current size (its InsideWidth and InsideHeight properties) and resizes the controls accordingly.

This example starts out by checking a flag, fInHere, and causes the subroutine to exit if the variable's value is True. It's possible that the procedure itself might cause another Resize event (if you've sized the form smaller than the preset minimum size); this flag ensures that the routine doesn't do more work than it needs to do.

 

Using the Static Keyword

The fInHere flag was declared with the Statickeyword. This keyword indicates that Access will maintain the value of the variable between calls to the function. You could accomplish the same effect by making fInHere global, but making the variable static makes it exist as long as the form is loaded, maintains its value from one call to another, and is local to the current procedure. The variable performs its task (as a sentry) without possible intervention from any other procedure.

 

The code next retrieves the current form size and stores the values into local variables. By placing these values into variables, Access eliminates the need to retrieve the values of the properties every time you need to use them. This speeds up the operation, because retrieving property values is expensive in terms of operating speed.

' Get the current screen coordinates. intHeight = Me.InsideHeight intWidth = Me.InsideWidth

Once it has retrieved the sizes, the procedure verifies that the form hasn't been sized too small by the user. If it has been, it forces the form to be at least as large as the preset values of acbcMinWidth and acbcMinHeight:

If intWidth < acbcMinWidth Then    DoCmd.MoveSize , , acbcMinWidth    intWidth = Me.InsideWidth End If If intHeight < acbcMinHeight Then    DoCmd.MoveSize , , , acbcMinHeight    intHeight = Me.InsideHeight End If

Finally, the procedure sets the sizes and locations of each of the controls based on the new width and height of the form. First, it sets the height of the form's detail section, Section(0), so that there will be room for all of the controls at the new height. It then sets the width and height of the text box and sets the left coordinates of the command buttons. This preserves their sizes but resets their positions:

Set ctl = Me!txtEntry With ctl    .Height = intHeight - (.Left + .Top)    .Width = intWidth - Me!cmdOK.Width - (3 * .Left) End With ' Set the positions of the two buttons. With Me!cmdOK    .Left = intWidth - .Width - ctl.Left End With With Me!cmdClose    .Left = intWidth - .Width - ctl.Left End With

The values used as offsets in this example were all arbitrarily chosen. They work for this particular example, but you'll need to vary them for your own forms. Remember, also, that this example was quite simple. You'll be doing many more calculations if you want to resize a multicolumn list box, for example. In any case, the concepts are the same: resize each of the controls based on the current size of the form. The tricky part is finding some "reference" on which you can base your sizing decisions; in this example, we used the offset of the expanding text box from the left edge of the form.



Access Cookbook
Access Data Analysis Cookbook (Cookbooks)
ISBN: 0596101228
EAN: 2147483647
Year: 2005
Pages: 174

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net