我試圖強制MS-Access窗體相對於主窗口的右邊緣採取某個位置(實際上我想將它居中,但我可以看到它也想將它停靠在一邊或另一邊)。我可以重新定位這個與Me.Move
形式,例如,我如何找到MS-Access中父窗口的寬度
Me.Move newWindowLeft, newWindowTop, newWidth, newHeight
但是,我怎麼能找到父窗口有多寬?
我試圖強制MS-Access窗體相對於主窗口的右邊緣採取某個位置(實際上我想將它居中,但我可以看到它也想將它停靠在一邊或另一邊)。我可以重新定位這個與Me.Move
形式,例如,我如何找到MS-Access中父窗口的寬度
Me.Move newWindowLeft, newWindowTop, newWidth, newHeight
但是,我怎麼能找到父窗口有多寬?
不知道您使用的是哪個版本的Access,但在Access 2003中,似乎沒有辦法直接獲取此信息。
這裏是一個黑客:
DoCmd.Maximize
w = Forms("yourForm").WindowWidth
h = Forms("yourForm").WindowHeight
這將當前窗口最大化,讓我們假設這是你的形式。然後,您可以測量表單以獲取父窗口的顯示區域的大小,然後取消最大化,並根據您現在知道的父窗口的大小移動窗體。
如果有一種方法可以在Access中關閉ScreenUpdating,那麼可以在最大化和測量代碼之前執行此操作,然後再打開它,並且只要用戶不需要任何明顯的時間關心。
編輯:即使沒有隱藏用戶的最大化命令,整個最大化和移動操作發生得比用戶可以看到的更快。
這是一個醜陋的黑客,但它確實有效。
您可以使用Windows API:
(更新至返回緹)
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
試過了,它原本看起來很正確,但是我發現我無法使用我正在返回的寬度/高度來將窗口準確定位在我想要的位置。它被關閉了一些倍數(我試着乘以20來轉換成緹,但是沒有效果)。不過,無論如何+1。 – BIBD 2009-08-17 22:01:50
它返回的像素數 - 你必須將其轉換爲緹。緹=像素*(1440/dpi)請參閱:http://www.applecore99.com/api/api012.asp – 2009-08-17 22:12:48
呃,什麼? TWIPS =像素*英寸,或者您正在使用的任何其他測量 - 您必須指定測量單位。窗體/報表/控件(頂部,高度,左側,寬度)的位置和大小屬性在TWIPS中以返回的方式返回,所以如果您調整大小以適應現有對象,則不需要進行轉換。 – 2009-08-17 23:44:56
下面是我用
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
不會由於chrome問題,這會返回除準確數字之外的其他內容嗎?也就是說,當你恢復時,你最終會得到一個標題欄,當它被最大化時,它不是窗口的一部分。而不同的Windows皮膚(即MS術語中的「主題」)可以產生不同的結果。 – 2009-08-17 23:46:22
的確,我確實得到了工具欄高度的下移。讓我重新考慮這一點。 – BIBD 2009-08-18 14:55:58
實際的代碼,這可能會感興趣:http://www.mvps.org/access/downloads/clFormWindow.bas
它說:
'' 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. *
我意識到這是一個非常古老的問題,但我想分享一些代碼,我已經創建來處理這個問題的初衷所期望的最終結果 - 重新定位窗口,使它們對齊另一個現有實體。
This module暴露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
這些簡單地測量中的一個單元與其它之間進行轉換。兩者都接受長整型參數輸入和來自Dimension
enum的值(X或Y),它們可用於指定是否應根據水平或垂直顯示設置完成轉換。值得注意的是,在99.99999%的時間內,兩個維度的值都是相同的,所以通常可以省略第二個參數。兩者都返回一個長整數。
該模塊在內部爲所有內容使用像素,因此這些轉換函數僅爲便於偏好以緹爲單位的應用程序提供。
PositionWindow (_
hWnd As Long, _
Mode As PositionMode, _
Optional OffsetX As Long = 0, _
Optional OffsetY As Long = 0 _
)
hWnd
是窗口的句柄被定位(例如,定位這可以使用objForm.hWnd
得到形式窗口)。Mode
是從PositionMode
枚舉中的選項構建的位掩碼(參見下文)。OffsetX
是在對Mode
進行了評估之後,在水平尺寸中調整位置的像素數。OffsetY
是在對Mode
進行了評估後,在垂直維度上調整位置的像素數量。模式
每個定位呼叫需要X分量和Y分量。這些組件由兩個子組件組成,即基礎和位置。
的鹼作爲用於計算新的位置的基準來使用的實體,並且可以是DISPLAY
一個(本機上的活動的物理顯示器),WINDOW
(Access主窗口)或CURSOR
(鼠標指針) 。爲方便起見,這些值合併在PositionMode
enum的值中。
使用主Access窗口的中心像素確定活動顯示。如果這超出了連接到機器的物理顯示器上的區域範圍,則會調整該值以進行補償,並且將使用應用程序最大可見部分的顯示。
X組件的位置可以是LEFT
,RIGHT
或X_CENTER
中的一個。 Y組件有TOP
,BOTTOM
和Y_CENTER
。
使用LEFT
使目標窗口的最左側的像素與基座實體的最左邊的像素對準,並且該圖案遵循RIGHT
,TOP
和BOTTOM
。 CENTER
位置會導致目標窗口的中心線與基礎實體的中心線對齊。
PositionMode
enum的值與按位運算符Or
組合以實現所需的表達式。
處理顯示溢出
有時當WINDOW
或CURSOR
被用作組分之一的基極,該目標窗口可被定位成使得一些或所有的它不是一個可見顯示上。爲避免這種情況,您可以使用PREVENT_OVERFLOW_X
和PREVENT_OVERFLOW_Y
標誌。這些可簡單地包含在使用位運算符Or
傳遞給Mode
參數的位掩碼中。
如果需要,這些標記會導致位置被調整,以確保整個目標窗口位於活動監視器的邊緣內。
爲方便起見,枚舉中還包含PREVENT_OVERFLOW
項目,這與指定PREVENT_OVERFLOW_X
和PREVENT_OVERFLOW_Y
的項目相同。
Oveflow預防不適用於基於DISPLAY
的職位。
偏移
的OffsetX
和OffsetY
參數可以使用它已在由Mode
指定的方式被對準後調整窗口的位置。兩者都可以是正數或負數,表示通過相關維度來改變位置的像素數量。
顯示器溢出阻止將覆蓋偏移量 - 偏移量仍將應用,但如果結果位置導致目標窗口的一部分或全部位於活動顯示器之外,則會調整位置以將其返回到邊界。
限制
用於多個顯示器的處理代碼使得2個假設:
以我的經驗,在現實世界中,這些都是相當安全的假設。
不支持同時重新定位和調整尺寸(與objForm.Move
一樣)。您需要將這些視爲單獨的任務。
例子
' 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
在我的機器,我可以看到最大化和恢復發生,所以我不得不關閉/打開更新(Application.echo假/真)。 – BIBD 2009-08-17 22:05:31