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

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

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

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

Ken Getz; Paul Litwin; Andy Baron

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

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

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










Recipe 11.1 Remove a Form's System Menu and Maximize/Minimize Buttons



11.1.1 Problem


Access
makes it easy to remove the control box (often called the system
menu) and the minimize and maximize buttons when you design forms,
but there doesn't seem to be a way to do this at
runtime. You have an application for which you'd
like to be able to remove these buttons to control how users interact
with the application. Is there a way to remove these items and then
replace them later?


11.1.2 Solution


Removing or replacing these window
controls requires changing the style bits for the particular window.
Every window maintains a 32-bit value that describes its physical
characteristics: for example, its border type and the existence of
scrollbars, a system menu, and the minimize and maximize buttons. The
values are stored as bit flags, in which the state of a single bit in
the 32-bit value indicates the value of some characteristic of the
window. In general, you can't change the state of
many of these flags without recreating the window; by setting or
clearing the bits in the window's style value,
however, you can force the system menu and the minimize/maximize
buttons to appear or disappear.

Load and run frmSystemItems from

11-01.MDB . This
form, shown in Figure 11-1, allows you to add or
remove the control menu, the minimize button, and the maximize button
from the current form. Select items on the form to make the
corresponding items visible, or deselect to remove them. Once
you've made your choices, click on the Execute
button, and the code will remove or replace the items
you've chosen.


Figure 11-1. frmSystemItems allows you to remove or replace any of the system items


To include this functionality in your own applications, follow these
steps:

  1. Import the module basControl from

    11-01.MDB .

  2. To remove or replace a form's system items, call the
    acbFormSystemItems subroutine, passing to it the four parameters
    shown in Table 11-1.

    For example, the following statement,
    called from a button's Click event in a
    form's module, will show the system menu but will
    hide the minimize and maximize buttons:

    acbFormSystemItems Me, True, False, False

    Though Access does provide the
    ControlBox, MaxButton, and MinButton properties for forms,
    they're read-only once the form is in use; if you
    need to alter these properties at runtime, you'll
    need to use acbFormSystemItems instead of changing
    the properties directly.


Table 11-1. Parameters for acbFormSystemItems

Parameter


Type


Value


 frm


Form


Reference to the current form


 blnShowSystemMenu


Integer


True = Show system menu; False = Hide


 blnShowMaxButton


Integer


True = Show maximize button; False = Hide


 blnShowMinButton


Integer


True = Show minimize button; False = Hide


Old Versus New Use of Window Buttons


The behavior of the control box and minimize and maximize buttons has
changed. If you're running Windows 95 or later,
using acbFormSystemItems to remove one of the
minimize or maximize buttons leaves them both visible but disables
the one you've requested to hide. Removing them both
with acbFormSystemItems makes them both invisible.
Under Windows NT and earlier, these buttons are independent, and
using the subroutine to remove one makes it invisible. Under Windows
95 or later, removing the control box also removes the minimize and
maximize buttons. Under Windows NT or earlier, these items are
independent.


11.1.3 Discussion


The bulk of the work in controlling these system items takes place in
the private HandleStyles function in the basControl module. This
function accepts a window handle (the hWnd property of a form) and
three True/False values
indicating which options you want to see and which you want removed.
Like every window, the window you want to alter maintains a 32-bit
value, its style value. Within that long integer, each of the 32
positions represents one of the possible styles for the window. If
the bit is 1, the style is set on; if it's 0, the
style is set off. HandleStyles builds up two long
integers, each containing a series of 32 bits. The first,
lngStylesOn, contains all 0s, except for the bits
representing the styles you want turned on, which contain 1s. The
other, lngStylesOff, contains all 1s, except for
the bits representing the styles you want turned off, which contain
0s.

Using the AND operator
to combine the current window style with
lngStylesOff sets each style whose bit contains 0
in lngStylesOff to be 0. Using the
OR operator to combine the current window style
with lngStylesOn sets each style whose bit
contains 1 in lngStylesOn to be 1. For example,
suppose the current window style value is this:

10001000 10001010 10101011 01101101

The value in lngStylesOff contains 1s in all
positions except the ones you want turned off, which contain 0s. If
the value of lngStylesOff is this:

11111111 11111111 11111111 11111011

the result of using the AND operator with the
original style and lngStylesOff will be this:

10001000 10001010 10101011 01101001

The value in lngStylesOn contains 0s in all
positions except the ones you want turned on, which contain 1s. If
the value of lngStylesOn is this:

00000000 00000000 00010000 10000000

the result of using the OR operator with
lngStylesOn and the result of
ANDing the original style with
lngStylesOff will be this:

10001000 10001010 10111011 11101001

This final result will have three changed values: one bit that was 1
is now 0 due to the settings in lngStylesOff, and
two bits that were are now 1 due to the settings in
lnStylesOn.

To retrieve and replace the
window's style information, the code uses the
GetWindowLong and SetWindowLong
API functions. Given a window handle and a flag
(GWL_STYLE) indicating which 32-bit value to
retrieve or set, these functions allow you to get the current value,
do your work with it, and then set it back. This is the line of code
that does all the work:

HandleStyles = SetWindowLong(hWnd, GWL_STYLE, _
(GetWindowLong(hWnd, GWL_STYLE) And lngStylesOff) _
Or lngStylesOn)

It sets the window style to be the value
GetWindowLong retrieved, combined with the two
style flags the code previously built up based on your choices.

The entire HandleStyles procedure looks like this:

Private Function HandleStyles(ByVal hWnd As Long, blnShowSystemMenu As Boolean, _
blnShowMaxButton As Boolean, blnShowMinButton As Boolean) As Long
Dim lngStylesOn As Long
Dim lngStylesOff As Long
On Error GoTo HandleStylesExit
' Set all bits off.
lngStylesOn = 0
' Set all bits on.
lngStylesOff = &HFFFFFFFF
' Turn ON bits to set attribute; turn OFF bits to turn attribute off.
If blnShowSystemMenu Then
lngStylesOn = lngStylesOn Or WS_SYSMENU
Else
lngStylesOff = lngStylesOff And Not WS_SYSMENU
End If
If blnShowMinButton Then
lngStylesOn = lngStylesOn Or WS_MINIMIZEBOX
Else
lngStylesOff = lngStylesOff And Not WS_MINIMIZEBOX
End If
If blnShowMaxButton Then
lngStylesOn = lngStylesOn Or WS_MAXIMIZEBOX
Else
lngStylesOff = lngStylesOff And Not WS_MAXIMIZEBOX
End If
' Set the attributes as necessary.
HandleStyles = SetWindowLong(hWnd, GWL_STYLE, _
(acb_apiGetWindowLong(hWnd, GWL_STYLE) And lngStylesOff) _
Or lngStylesOn)
' The 1 in the third parameter tells the window
' to repaint its entire border.
Call SendMessage(hwnd, WM_NCPAINT, 1, 0)
HandleStylesExit:
Exit Function
End Function

After
the style bits are set, there's still one issue
left: you must coerce the window into repainting itself so the
changes become visible. Simply changing the styles
isn't enough, because they don't
become visible until the next time the window repaints its border.

If you resize the form, Access repaints
the border, but there's no reasonable programmatic
way to do this. To solve the problem, the procedure adds one more
line. It calls the SendMessage API, which sends a specific message to
any window (this time, it sends a message to the form itself ). The
message it sends, a constant named WM_NCPAINT,
tells the form to repaint its non-client area (that is, its border):

' The 1 as the third parameter tells the window
' to repaint its entire border.
Call acb_SendMessage(hwnd, WM_NCPAINT, 1, 0)


/ 232