vba 如何在 MS-Access 中找到父窗口的宽度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1290125/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I find the width of the parent window in MS-Access
提问by BIBD
I'm trying to force an MS-Access form to take a certain position relative to the right edge of the main window (actually I want to center it, but I can see also wanting to dock it to one side or another). I can reposition the form this with Me.Move
, e.g.,
我试图强制 MS-Access 窗体相对于主窗口的右边缘占据某个位置(实际上我想将它居中,但我也可以看到想要将它停靠在一侧或另一侧)。我可以重新定位这个表格Me.Move
,例如,
Me.Move newWindowLeft, newWindowTop, newWidth, newHeight
However, how can I find out how wide the parent window is?
但是,我怎样才能知道父窗口的宽度?
回答by DJ.
You can use a windows API:
您可以使用 Windows API:
(UPDATED to return twips)
(更新以返回缇)
Type Rect
x1 As Long
y1 As Long
x2 As Long
y2 As Long
End Type
Declare Function GetClientRect Lib "user32" (ByVal hwnd As Long, lpRect As Rect) As Long
Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As Long
Declare Function GetDeviceCaps Lib "gdi32" (ByVal hdc As Long, ByVal nIndex As Long) As Long
Const LOGPIXELSX = 88
Const LOGPIXELSY = 90
Const DIRECTION_VERTICAL = 1
Const DIRECTION_HORIZONTAL = 0
Public Function GetMainWindowSize()
Dim MDIRect As Rect
Dim lWidthPixels As Long
Dim lWidthTwips As Long
' Get the screen coordinates and window size of the MDIClient area'
GetClientRect Application.hWndAccessApp, MDIRect
lWidthPixels = MDIRect.x2 - MDIRect.x1
lWidthTwips = PixelsToTwips(lWidthPixels, DIRECTION_HORIZONTAL)
MsgBox "Width (Pixels) = " & lWidthPixels & " Width (Twips) = " & lWidthTwips
End Function
Function PixelsToTwips(lPixels As Long, lDirection As Long) As Long
Dim lDeviceHandle As Long
Dim lPixelsPerInch As Long
lDeviceHandle = GetDC(0)
If lDirection = DIRECTION_HORIZONTAL Then
lPixelsPerInch = GetDeviceCaps(lDeviceHandle, LOGPIXELSX)
Else
lPixelsPerInch = GetDeviceCaps(lDeviceHandle, LOGPIXELSY)
End If
lDeviceHandle = ReleaseDC(0, lDeviceHandle)
PixelsToTwips = lPixels * 1440 / lPixelsPerInch
End Function
回答by Stewbob
Not sure what version of Access you are using, but in Access 2003, there does not appear to be a way to directly get this information.
不确定您使用的是哪个版本的 Access,但在 Access 2003 中,似乎没有直接获取此信息的方法。
Here's a hack:
这是一个黑客:
DoCmd.Maximize
w = Forms("yourForm").WindowWidth
h = Forms("yourForm").WindowHeight
This will maximize the current window, let's assume that it's your form. You can then measure the form to get the size of the parent window's display area, then un-maximize, and move the form based on the size of the parent window that you now know.
这将最大化当前窗口,让我们假设它是您的表单。然后您可以测量窗体以获得父窗口显示区域的大小,然后取消最大化,并根据您现在知道的父窗口大小移动窗体。
If there is a way to turn off ScreenUpdating in Access, you can do this before the maximize and measure code, then turn it back on, and it won't take any noticeable amount of time as far as the user is concerned.
如果有办法关闭 Access 中的 ScreenUpdating,您可以在最大化和测量代码之前执行此操作,然后将其重新打开,就用户而言,它不会花费任何明显的时间。
EDIT:Even without hiding the maximize command from the user, the whole maximize and move operation happens more quickly than the user can see.
编辑:即使没有对用户隐藏最大化命令,整个最大化和移动操作的发生速度也比用户看到的要快。
It's an ugly hack, but it does work.
这是一个丑陋的黑客,但它确实有效。
回答by BIBD
Here's the actual code I used
这是我使用的实际代码
Application.Echo False 'turn off screen updates
DoCmd.Maximize
w = Me.WindowWidth
h = Me.WindowHeight
DoCmd.Restore 'restore the window to it's old size
Application.Echo True 'turn on screen updates
DoCmd.MoveSize w / 2 - myWidth / 2, _
h / 2 - myHeigth / 2, _
myWidth, _
myHeigth
回答by DaveRandom
I realise this is a very old question, but I want to share some code I've created to handle the desired end result of the original purpose of this question - repositioning windows so they are aligned with another existing entity.
我意识到这是一个非常古老的问题,但我想分享一些我创建的代码来处理这个问题的原始目的的预期最终结果 - 重新定位窗口,使它们与另一个现有实体对齐。
This moduleexposes 3 functions:
该模块公开了 3 个函数:
TwipsToPixels ( _
Twips As Long, _
Optional Dimension As Dimension = DIMENSION_X _
) As Long
PixelsToTwips ( _
Pixels As Long, _
Optional Dimension As Dimension = DIMENSION_X _
) As Long
These simply convert between one unit of measurement and the other. Both accept a long integer argument input and a value from the Dimension
enum, either X or Y, which can be used to specify whether the conversion should be done according the to horizontal or vertical display settings. It's worth noting that 99.99999% of the time, the value will be the same in both dimensions, so you can usually omit the second argument. Both return a long integer.
这些只是在一种计量单位和另一种计量单位之间进行转换。两者都接受一个长整数参数输入和一个来自Dimension
枚举的值,X 或 Y,可用于指定是否应根据水平或垂直显示设置进行转换。值得注意的是,在 99.99999% 的情况下,两个维度的值都相同,因此通常可以省略第二个参数。两者都返回一个长整数。
The module uses pixels for everything internally, so these conversion functions are only provided as a convenience for applications that prefer to work in twips.
该模块在内部对所有内容使用像素,因此提供这些转换功能只是为了方便那些喜欢以缇为单位工作的应用程序。
PositionWindow ( _
hWnd As Long, _
Mode As PositionMode, _
Optional OffsetX As Long = 0, _
Optional OffsetY As Long = 0 _
)
hWnd
is the handle of the window to be positioned (for example, to position a form window this can be obtained usingobjForm.hWnd
).Mode
is a bit mask constructed from the options in thePositionMode
enum (see below).OffsetX
is the number of pixels to adjust the position by in the horizontal dimension, afterMode
has been evaluated.OffsetY
is the number of pixels to adjust the position by in the vertical dimension, afterMode
has been evaluated.
hWnd
是要定位的窗口的句柄(例如,定位一个窗体窗口,这可以使用 获得objForm.hWnd
)。Mode
是从PositionMode
枚举中的选项构造的位掩码(见下文)。OffsetX
是Mode
经过评估后在水平维度上调整位置的像素数。OffsetY
是在Mode
评估后在垂直维度上调整位置的像素数。
Modes
模式
Every positioning call requires an X component and a Y component. These components consist of two sub-components, a base and a position.
每个定位调用都需要一个 X 分量和一个 Y 分量。这些组件由两个子组件组成,一个基数和一个位置。
The base is an entity to use as a reference for calculating the new position, and can be one of DISPLAY
(the active physical display on the machine), WINDOW
(the main Access window) or CURSOR
(the mouse pointer). For convenience, these are combined in the values from the PositionMode
enum.
基础是用作计算新位置的参考的实体,可以是DISPLAY
(机器上的活动物理显示)、WINDOW
(主访问窗口)或CURSOR
(鼠标指针)之一。为方便起见,将这些值组合到PositionMode
枚举中。
The active display is determined using the center pixel of the main Access window. If this falls outside the bounds of the area show on the physical displays attached to the machine, the value is adjusted to compensate, and the display with the largest visible part of the application on it will be used.
活动显示是使用主访问窗口的中心像素确定的。如果这超出了连接到机器的物理显示器上的区域显示范围,则会调整该值以进行补偿,并且将使用具有最大应用程序可见部分的显示器。
The position of the X component can be one of LEFT
, RIGHT
or X_CENTER
. The Y component has TOP
, BOTTOM
and Y_CENTER
.
X 分量的位置可以是LEFT
、RIGHT
或 之一X_CENTER
。Y 分量具有TOP
、BOTTOM
和Y_CENTER
。
Using LEFT
causes the left-most pixel of the target window to be aligned with the left-most pixel of the base entity, and this pattern follows for RIGHT
, TOP
and BOTTOM
. The CENTER
positions cause the center-line of the target window to be aligned with the center-line of the base entity.
UsingLEFT
导致目标窗口最左边的像素与基本实体的最左边的像素对齐,并且这种模式遵循RIGHT
,TOP
和BOTTOM
。这些CENTER
位置使目标窗口的中心线与基础实体的中心线对齐。
The values from the PositionMode
enum are combined with the bitwise Or
operator to achieve the desired expression.
PositionMode
枚举中的值与按位运算Or
符组合以实现所需的表达式。
Handling display overflow
处理显示溢出
Sometimes when WINDOW
or CURSOR
are used as a base for one of the components, the target window may be positioned so that some or all of it is not on a visible display. To avoid this, you can use the PREVENT_OVERFLOW_X
and PREVENT_OVERFLOW_Y
flags. These can simply be included in the bit mask passed to the Mode
argument using the bitwise Or
operator.
有时,当WINDOW
或被CURSOR
用作组件之一的基础时,目标窗口可能会被定位成使其部分或全部不在可见显示器上。为避免这种情况,您可以使用PREVENT_OVERFLOW_X
和PREVENT_OVERFLOW_Y
标志。这些可以简单地包含在Mode
使用按位运算Or
符传递给参数的位掩码中。
These flags cause the position to be adjusted, if necessary, to ensure that the entire of the target window is within the edges of the active monitor.
如有必要,这些标志会导致调整位置,以确保整个目标窗口都在活动监视器的边缘内。
For convenience, a PREVENT_OVERFLOW
item is also included in the enum, this is the same as specifying both PREVENT_OVERFLOW_X
and PREVENT_OVERFLOW_Y
.
为方便起见,PREVENT_OVERFLOW
枚举中还包含一个项目,这与同时指定PREVENT_OVERFLOW_X
和相同PREVENT_OVERFLOW_Y
。
Oveflow prevention is not applied to DISPLAY
-based positions.
溢出预防不适用于DISPLAY
基于位置。
Offsets
偏移量
The OffsetX
and OffsetY
arguments can be used to adjust the position of the window after it has been aligned in the manner specified by Mode
. Both can be a positive or negative number, indicating a number of pixels to alter the position by in the relevant dimension.
的OffsetX
和OffsetY
参数可以使用它已在通过指定的方式进行了对准后,调整窗口的位置Mode
。两者都可以是正数或负数,表示在相关维度中改变位置的像素数。
Display overflow prevention will override offsets - the offsets will still be applied, but if the resulting position results in a portion or all of the target window being outside the active display, the position will be adjusted to bring it back inside the boundaries.
显示溢出预防将覆盖偏移 - 仍将应用偏移,但如果结果位置导致目标窗口的一部分或全部位于活动显示之外,则将调整位置以使其回到边界内。
Limitations
限制
The handling code for multiple displays makes 2 assumptions:
多个显示器的处理代码有两个假设:
- That the virtual display area (the combination of all displays treated as a single display) is uniform - so it won't play nice with L shaped setups or other such ridiculous configurations.
- That all active displays use the same resolution.
- 虚拟显示区域(所有显示器的组合被视为单个显示器)是统一的 - 因此它不会与 L 形设置或其他此类荒谬的配置配合使用。
- 所有活动显示器都使用相同的分辨率。
In my experience, in the real world, these are fairly safe assumptions.
根据我的经验,在现实世界中,这些都是相当安全的假设。
No support for simultaneously re-positioning and re-sizing is provided (as it is with objForm.Move
). You will need to treat these as separate tasks.
不支持同时重新定位和重新调整大小(与 一样objForm.Move
)。您需要将这些视为单独的任务。
Examples
例子
' Get the window handle for frm_MyForm
Dim hWnd As Long
hWnd = Forms("frm_MyForm").hWnd
' Align the form to the top left corner of the active display
PositionWindow hWnd, DISPLAY_LEFT Or DISPLAY_TOP
' Align the form to the center of the Access main window
PositionWindow hWnd, WINDOW_X_CENTER Or WINDOW_Y_CENTER
' Align the form to the bottom right of the mouse pointer position, prevent the
' window from disappearing off the screen
' This effectively sets the top left corner of the window to the pointer location
PositionWindow hWnd, CURSOR_RIGHT Or CURSOR_BOTTOM Or PREVENT_OVERFLOW
' Horizontally center the form on the display, vertically center on the mouse
PositionWindow hWnd, DISPLAY_X_CENTER Or CURSOR_Y_CENTER
' Center the window on the mouse pointer then move it 200px right and 30px up
PositionWindow hWnd, CURSOR_X_CENTER Or CURSOR_Y_CENTER, 200, -30
回答by Fionnuala
This may be of interest: http://www.mvps.org/access/downloads/clFormWindow.bas
这可能很有趣:http: //www.mvps.org/access/downloads/clFormWindow.bas
It says it:
它说:
'' Moves and resizes a window in the coordinate system *
'' of its parent window. *
'' N.B.: This class was developed for use on Access forms *
'' and has not been tested for use with other window *
'' types. *