Access Cookbook, 2nd Edition [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Access Cookbook, 2nd Edition [Electronic resources] - نسخه متنی

Ken Getz; Paul Litwin; Andy Baron

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید










Recipe 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 saved
values in the registry, it will reload the last set of coordinates
and will size and 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). 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


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 the
time you call the MoveSize action. 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. To avoid all these issues, the
sample project uses the Windows API method, MoveWindow, instead.

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
' Windows 95/98/NT4/2000 puts a 2-pixel
' border around the MDI client area, which
' doesn't get taken into account automatically.
' If you're using NT 3.51, you're on your own.
Private Const adhcBorderWidthX = 2
Private Const adhcBorderWidthY = 2
Private Sub GetRelativeCoords(frm As Form, rct As acbTypeRect)
' Fill in rct with the coordinates of the window.
Dim hwndParent As Long
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 popup 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.
rct.lngX1 = (rct.lngX1 - rctParent.lngX1 - adhcBorderWidthX)
rct.lngY1 = (rct.lngY1 - rctParent.lngY1 - adhcBorderWidthY)
rct.lngX2 = (rct.lngX2 - rctParent.lngX1 - adhcBorderWidthX)
rct.lngY2 = (rct.lngY2 - rctParent.lngY1 - adhcBorderWidthY)
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:

Private Const acbcRegTag = "Form Sizes"
Private Const acbcRegLeft = "Left"
Private Const acbcRegRight = "Right"
Private Const acbcRegTop = "Top"
Private 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 Long
Dim lngHeight As Long
rct.lngX1 = GetSetting(acbcRegTag, frm.Name, acbcRegLeft, 0)
rct.lngX2 = GetSetting(acbcRegTag, frm.Name, acbcRegRight, 0)
rct.lngY1 = GetSetting(acbcRegTag, frm.Name, acbcRegTop, 0)
rct.lngY2 = GetSetting(acbcRegTag, frm.Name, acbcRegBottom, 0)
lngWidth = rct.lngX2 - rct.lngX1
lngHeight = rct.lngY2 - rct.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, _
rct.lngX1, rct.lngY1, lngWidth, lngHeight, True
End If
End Sub

You may want to store properties other than the size and location of
the formfor 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.


2.10.4 See Also


For more examples using the Windows API, see Chapter 11.


/ 232