1.15 Use a Query to Create a New Table Complete with Indexes

2.10 Store the Sizes and Locations of Forms

2.10.1 Problem

Your application uses a number of forms that you can move around the screen. You'd like to store the last location away somewhere so that the forms will appear in the same location the next time you start the application.

2.10.2 Solution

Some Windows applications are "smart" and can save the locations of their windows when they exit. Your application can do this, too, using the system registry. You can store settings when you close a form and read them back the next time you open it.

Open and run the form frmSavePos in 02-10.MDB. Move it around the screen, and perhaps resize it. When you close the form, code attached to the Close event will save its coordinates in the system registry database. When you reopen the form, if the form can find the keys in the registry, it'll reload the last set of coordinates and resize/position itself accordingly.

To use this technique with your own forms, follow these steps:

  1. Import the module basSaveSize from 02-10.MDB into your own application. This module contains the functions necessary to save and restore a form's size and location in the registry.

  2. Add the following code to your form's Load event procedure. This will restore the form's size and location when you load the form:

    Private Sub Form_Load (  )    acbRestoreSize Me End Sub
  3. Add the following code to your form's Unload event procedure. This will save the size and location when you close the form:

    Private Sub Form_Unload (Cancel As Integer)    acbSaveSize Me End Sub

2.10.3 Discussion

Most of the work involved in saving and restoring the form size and location happens in the imported module, basSaveSize. The two event procedures, called from the form's Load and Unload events, simply call procedures in the imported module, passing a reference to the current form.

This solution relies heavily on two built-in functions: SaveSetting and GetSetting. These two functions store and retrieve values from the registry database that's a part of Windows 9x, Windows ME, Windows NT, and Windows 2000. The sample code uses SaveSetting to save each of the four coordinates for a form and GetSetting to retrieve the same information.

SaveSetting and GetSetting make it easy to get and put values in the registry, but they're very limited. They work only with the path HKEY_CURRENT_USER\Software\VB and VBA Program Settings (see Figure 2-17), and they create a new key for each value you save (rather than storing multiple values in one key). We hope that future versions of Access will expand the functionality of these functions. If you're interested, investigate their coverage in online help, along with their companion functions, DeleteSetting and GetAllSettings.

Figure 2-17. The registry holds the information about saved form locations

figs/acb_0217.gif

The procedures in basSaveSize also hinge on two Windows API functions. GetWindowRect, aliased as acb_apiGetWindowRect, gets the coordinates of a screen window. MoveWindow, aliased as acb_apiMoveWindow, moves and sizes a window on screen.

 

Why Use MoveWindow Rather than MoveSize?

You might wonder why you shouldn't use the Access built-in MoveSize macro action: it requires that you select a form first, and this causes the form to display at that point. This looks ugly on screen and makes the procedure less generic. In addition, it requires some work to convert from screen coordinates (pixels), which GetWindowRect uses, to twips, which MoveSize uses.

 

The GetRelativeCoords subroutine in basSaveSize retrieves the coordinates of a given form. Because the MoveWindow function requires a position relative to that of the window's parent to move a window, GetRelativeCoords must find the coordinates of both the requested window and its parent window. It calls the Windows API function GetParent, aliased as acb_apiGetParent, to find the parent and retrieves the coordinates of both. It fills in a user-defined structure with the relative coordinates.

' Store rectangle coordinates. Type acbTypeRect    lngX1 As Long    lngY1 As Long    lngX2 As Long    lngY2 As Long End Type Private Sub GetRelativeCoords(frm As Form, rct As acbTypeRect)    ' Fill in rct with the coordinates of the window. Deal with    ' the conversion from screen coordinates (pixels) to twips.    Dim hwndParent As Integer    Dim rctParent As acbTypeRect    ' Find the position of the window in question, in relation to    ' its parent window (the Access desktop, most likely, unless    ' the form is modal).    hwndParent = acb_apiGetParent(frm.hWnd)    ' Get the coordinates of the current window and its parent.    acb_apiGetWindowRect frm.hWnd, rct    ' If the form is a pop-up window, its parent won't be the Access    ' main window. If so, don't bother subtracting off the coordinates    ' of the main Access window.    If hwndParent <> Application.hWndAccessApp Then       acb_apiGetWindowRect hwndParent, rctParent       ' Subtract off the left and top parent coordinates, since you need       ' coordinates relative to the parent for the acb_apiMoveWindow(  )       ' function call.       With rct          .lngX1 = (.lngX1 - rctParent.lngX1)          .lngY1 = (.lngY1 - rctParent.lngY1)          .lngX2 = (.lngX2 - rctParent.lngX1)          .lngY2 = (.lngY2 - rctParent.lngY1)       End With    End If End Sub

The acbSaveSize procedure first retrieves the current coordinates for the requested form and then saves those values to the registry. Figure 2-17 shows the registry after saving the settings for the sample form. The function creates a key named Form Sizes in the registry, with a subkey for each form whose coordinates you save. Within each subkey, the procedure creates a separate value entry for each of the four coordinates. The source code related to the acbSaveSize procedure is:

Const acbcRegTag = "Form Sizes" Const acbcRegLeft = "Left" Const acbcRegRight = "Right" Const acbcRegTop = "Top" Const acbcRegBottom = "Bottom" Public Sub acbSaveSize(frm As Form)    Dim rct As acbTypeRect    GetRelativeCoords frm, rct    With rct       SaveSetting acbcRegTag, frm.Name, acbcRegLeft, .lngX1       SaveSetting acbcRegTag, frm.Name, acbcRegRight, .lngX2       SaveSetting acbcRegTag, frm.Name, acbcRegTop, .lngY1       SaveSetting acbcRegTag, frm.Name, acbcRegBottom, .lngY2    End With End Sub

When it comes time to retrieve the saved coordinates, the acbRestoreSize procedure retrieves the four coordinates from the registry and then, if the width and the height of the new form would be greater than 0, resizes the form. Its source code is:

Public Sub acbRestoreSize(frm As Form)    Dim rct As acbTypeRect    Dim lngWidth As Integer    Dim lngHeight As Integer    With rct       .lngX1 = GetSetting(acbcRegTag, frm.Name, acbcRegLeft, 0)       .lngX2 = GetSetting(acbcRegTag, frm.Name, acbcRegRight, 0)       .lngY1 = GetSetting(acbcRegTag, frm.Name, acbcRegTop, 0)       .lngY2 = GetSetting(acbcRegTag, frm.Name, acbcRegBottom, 0)       lngWidth = .lngX2 - .lngX1       lngHeight = .lngY2 - .lngY1       ' No sense even trying if both aren't greater than 0.       If (lngWidth > 0) And (lngHeight > 0) Then          ' You would think the MoveSize action would work here, but that          ' requires actually SELECTING the window first. That seemed like          ' too much work, when this procedure will move/size ANY window.          ' Also, MoveSize must DISPLAY the window before it can move it.          ' It looked quite ugly.          acb_apiMoveWindow frm.hWnd, .lngX1, .lngY1, _           lngWidth, lngHeight, True       End If    End With End Sub

You may want to store properties other than the size and location of the form for instance, the current record number for a bound form, or which control was last selected. In any case, the example in 02-10.MDB stores information in such a way that you can store as many properties as you would like by adding to the group describing each form in the registry.



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