2009-08-17 16 views
5

我試圖強制MS-Access窗體相對於主窗口的右邊緣採取某個位置(實際上我想將它居中,但我可以看到它也想將它停靠在一邊或另一邊)。我可以重新定位這個與Me.Move形式,例如,我如何找到MS-Access中父窗口的寬度

Me.Move newWindowLeft, newWindowTop, newWidth, newHeight 

但是,我怎麼能找到父窗口有多寬?

回答

4

不知道您使用的是哪個版本的Access,但在Access 2003中,似乎沒有辦法直接獲取此信息。

這裏是一個黑客:

DoCmd.Maximize 

w = Forms("yourForm").WindowWidth 
h = Forms("yourForm").WindowHeight 

這將當前窗口最大化,讓我們假設這是你的形式。然後,您可以測量表單以獲取父窗口的顯示區域的大小,然後取消最大化,並根據您現在知道的父窗口的大小移動窗體。

如果有一種方法可以在Access中關閉ScreenUpdating,那麼可以在最大化和測量代碼之前執行此操作,然後再打開它,並且只要用戶不需要任何明顯的時間關心。

編輯:即使沒有隱藏用戶的最大化命令,整個最大化和移動操作發生得比用戶可以看到的更快。

這是一個醜陋的黑客,但它確實有效。

+0

在我的機器,我可以看到最大化和恢復發生,所以我不得不關閉/打開更新(Application.echo假/真)。 – BIBD 2009-08-17 22:05:31

7

您可以使用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 
+0

試過了,它原本看起來很正確,但是我發現我無法使用我正在返回的寬度/高度來將窗口準確定位在我想要的位置。它被關閉了一些倍數(我試着乘以20來轉換成緹,但是沒有效果)。不過,無論如何+1。 – BIBD 2009-08-17 22:01:50

+0

它返回的像素數 - 你必須將其轉換爲緹。緹=像素*(1440/dpi)請參閱:http://www.applecore99.com/api/api012.asp – 2009-08-17 22:12:48

+0

呃,什麼? TWIPS =像素*英寸,或者您正在使用的任何其他測量 - 您必須指定測量單位。窗體/報表/控件(頂部,高度,左側,寬度)的位置和大小屬性在TWIPS中以返回的方式返回,所以如果您調整大小以適應現有對象,則不需要進行轉換。 – 2009-08-17 23:44:56

3

下面是我用

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 
+1

不會由於chrome問題,這會返回除準確數字之外的其他內容嗎?也就是說,當你恢復時,你最終會得到一個標題欄,當它被最大化時,它不是窗口的一部分。而不同的Windows皮膚(即MS術語中的「主題」)可以產生不同的結果。 – 2009-08-17 23:46:22

+0

的確,我確實得到了工具欄高度的下移。讓我重新考慮這一點。 – BIBD 2009-08-18 14:55:58

0

實際的代碼,這可能會感興趣: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.            * 
1

我意識到這是一個非常古老的問題,但我想分享一些代碼,我已經創建來處理這個問題的初衷所期望的最終結果 - 重新定位窗口,使它們對齊另一個現有實體。

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,RIGHTX_CENTER中的一個。 Y組件有TOP,BOTTOMY_CENTER

使用LEFT使目標窗口的最左側的像素與基座實體的最左邊的像素對準,並且該圖案遵循RIGHTTOPBOTTOMCENTER位置會導致目標窗口的中心線與基礎實體的中心線對齊。

PositionMode enum的值與按位運算符Or組合以實現所需的表達式。

處理顯示溢出

有時當WINDOWCURSOR被用作組分之一的基極,該目標窗口可被定位成使得一些或所有的它不是一個可見顯示上。爲避免這種情況,您可以使用PREVENT_OVERFLOW_XPREVENT_OVERFLOW_Y標誌。這些可簡單地包含在使用位運算符Or傳遞給Mode參數的位掩碼中。

如果需要,這些標記會導致位置被調整,以確保整個目標窗口位於活動監視器的邊緣內。

爲方便起見,枚舉中還包含PREVENT_OVERFLOW項目,這與指定PREVENT_OVERFLOW_XPREVENT_OVERFLOW_Y的項目相同。

Oveflow預防不適用於基於DISPLAY的職位。

偏移

OffsetXOffsetY參數可以使用它已在由Mode指定的方式被對準後調整窗口的位置。兩者都可以是正數或負數,表示通過相關維度來改變位置的像素數量。

顯示器溢出阻止將覆蓋偏移量 - 偏移量仍將應用,但如果結果位置導致目標窗口的一部分或全部位於活動顯示器之外,則會調整位置以將其返回到邊界。

限制

用於多個顯示器的處理代碼使得2個假設:

  • 即虛擬顯示區域(作爲一個單一的顯示處理的所有顯示器的組合)是均勻 - 因此它贏得用L形設置或其他如此荒謬的配置玩不好。
  • 所有活動的顯示器都使用相同的分辨率。

以我的經驗,在現實世界中,這些都是相當安全的假設。

不支持同時重新定位和調整尺寸(與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 
相關問題