2009-08-17 19 views
5

Estoy tratando de forzar a un formulario de MS-Access a tomar una cierta posición relativa al borde derecho de la ventana principal (en realidad quiero centrarlo, pero puedo ver también querer atracarlo a un lado u otro). Puedo cambiar la posición de la forma con este Me.Move, por ejemplo,¿Cómo puedo encontrar el ancho de la ventana principal en MS-Access

Me.Move newWindowLeft, newWindowTop, newWidth, newHeight 

Sin embargo, ¿cómo puedo saber lo amplio que es la ventana padre?

Respuesta

4

No estoy seguro de qué versión de Access está utilizando, pero en Access 2003, no parece haber una manera de obtener esta información directamente.

Aquí hay un truco:

DoCmd.Maximize 

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

Esto maximizará la ventana actual, vamos a suponer que es su forma. Luego puede medir el formulario para obtener el tamaño del área de visualización de la ventana principal, luego des-maximizar, y mover el formulario según el tamaño de la ventana principal que conoce ahora.

Si hay una manera de desactivar ScreenUpdating en Access, puede hacerlo antes de maximizar y medir el código, luego vuelva a encenderlo y no tardará mucho tiempo en lo que respecta al usuario. preocupado.

EDIT: Incluso sin ocultar el comando maximizar del usuario, toda la operación de maximizar y mover ocurre más rápido de lo que el usuario puede ver.

Es un hack feo, pero funciona.

+0

En mi máquina, que pueden ver el maximizar y restaurar tienen lugar, así que tuve que activar/desactivar las actualizaciones (Application.echo verdadero/falso). – BIBD

7

Se puede utilizar una API de Windows:

(ACTUALIZADO volver 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 
+0

Lo intenté, y parecía correcto originalmente, pero descubrí que no podía usar el ancho/alto que estaba obteniendo para colocar la ventana exactamente donde la quería. Fue un poco múltiple (intenté multiplicar por 20 para convertir a twips, pero no fue en vano). Sin embargo, +1 de todos modos. – BIBD

+0

Devuelve el número de píxeles; debe convertirlo en twips. twips = pixels * (1440/ppp) ver: http://www.applecore99.com/api/api012.asp –

+0

Er, ¿qué? TWIPS = PIXELS * INCHES, o cualquier otra medida que esté usando - debe especificar las unidades de medida. La posición y las propiedades de tamaño de formularios/informes/controles (Superior, Alto, Izquierdo, Ancho) se devuelven en TWIPS para comenzar, por lo que si está dimensionando un objeto existente, no necesitará convertirlo. –

3

Aquí está el código real Solía ​​

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

esto devuelve algo más que números exactos debido a problemas con Chrome?Es decir, cuando restaura, termina con una barra de título, que no formaba parte de la ventana cuando estaba maximizada. Y diferentes máscaras de Windows (es decir, "Temas" en terminología MS) pueden producir resultados diferentes. –

+0

Cierto, obtengo un desplazamiento hacia abajo de aproximadamente la altura de las barras de herramientas. Déjame repensar esto. – BIBD

0

Esto puede ser de interés: http://www.mvps.org/access/downloads/clFormWindow.bas

Lo dice:

'' 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

Comprendo que esto es una pregunta muy antigua, pero quiero compartir algo de código que he creado para manejar el resultado final deseado para el propósito original de esta cuestión - el reposicionamiento de las ventanas para que estén alineados con otro ya existente entidad.

This module expone 3 funciones:


TwipsToPixels (_ 
    Twips As Long, _ 
    Optional Dimension As Dimension = DIMENSION_X _ 
) As Long 

PixelsToTwips (_ 
    Pixels As Long, _ 
    Optional Dimension As Dimension = DIMENSION_X _ 
) As Long 

Estos simplemente la conversión entre una unidad de medida y el otro. Ambos aceptan una entrada de argumento entero largo y un valor de la enumeración Dimension, ya sea X o Y, que se puede utilizar para especificar si la conversión se debe realizar según la configuración de visualización horizontal o vertical. Vale la pena señalar que el 99.99999% del tiempo, el valor será el mismo en ambas dimensiones, por lo que generalmente puede omitir el segundo argumento. Ambos devuelven un entero largo.

El módulo usa píxeles para todo internamente, por lo que estas funciones de conversión solo se proporcionan como una conveniencia para las aplicaciones que prefieren trabajar en twips.


PositionWindow (_ 
    hWnd As Long, _ 
    Mode As PositionMode, _ 
    Optional OffsetX As Long = 0, _ 
    Optional OffsetY As Long = 0 _ 
) 
  • hWnd es el identificador de la ventana pueda ser movido (por ejemplo, a la posición de una ventana forma esto se puede obtener usando objForm.hWnd).
  • Mode es una máscara de bits construida a partir de las opciones en la enumeración PositionMode (consulte a continuación).
  • OffsetX es el número de píxeles para ajustar la posición en la dimensión horizontal, después de que se haya evaluado Mode.
  • OffsetY es el número de píxeles para ajustar la posición en la dimensión vertical, después de que se haya evaluado Mode.

Modos de

cada llamada posicionamiento requiere un componente X y un componente de Y. Estos componentes constan de dos subcomponentes, una base y una posición.

la base es una entidad para utilizar como una referencia para el cálculo de la nueva posición, y puede ser uno de DISPLAY (la pantalla física activa en la máquina), WINDOW (la ventana de acceso principal) o CURSOR (el puntero del ratón) . Por conveniencia, estos se combinan en los valores de la enumeración PositionMode.

La pantalla activa se determina utilizando el píxel central de la ventana de acceso principal. Si esto cae fuera de los límites del área mostrada en las pantallas físicas conectadas a la máquina, el valor se ajusta para compensar y se usará la pantalla con la parte visible más grande de la aplicación.

La posición del componente X puede ser una de LEFT, RIGHT o X_CENTER. El componente Y tiene TOP, BOTTOM y Y_CENTER.

Usando LEFT hace que el píxel más a la izquierda de la ventana de destino para estar alineado con el píxel más a la izquierda de la entidad de base, y este patrón sigue para RIGHT, TOP y BOTTOM. Las posiciones CENTER hacen que la línea central de la ventana objetivo se alinee con la línea central de la entidad base.

Los valores de la enumeración PositionMode se combinan con el operador bit a bit Or para lograr la expresión deseada.

Manipulación pantalla desbordamiento

veces, cuando WINDOW o CURSOR se utilizan como base para uno de los componentes, la ventana de objetivo puede estar colocado de forma que algunos o todos de la misma no es en una pantalla visible. Para evitar esto, puede usar los indicadores PREVENT_OVERFLOW_X y PREVENT_OVERFLOW_Y. Estos simplemente se pueden incluir en la máscara de bits pasada al argumento Mode utilizando el operador bit a bit Or.

Estos indicadores hacen que la posición se ajuste, si es necesario, para garantizar que toda la ventana de destino se encuentre dentro de los límites del monitor activo.

Por conveniencia, un artículo PREVENT_OVERFLOW también se incluye en la enumeración, esto es lo mismo que especificar PREVENT_OVERFLOW_X y PREVENT_OVERFLOW_Y.

La prevención de Oveflow no se aplica a las posiciones basadas en DISPLAY.

Offsets

Los OffsetX y OffsetY argumentos pueden usarse para ajustar la posición de la ventana después de que ha sido alineado en la manera especificada por Mode. Ambos pueden ser un número positivo o negativo, lo que indica un número de píxeles para alterar la posición en la dimensión correspondiente.

La prevención de desbordamiento de pantalla anulará las compensaciones: las compensaciones seguirán aplicándose, pero si la posición resultante da como resultado que una parte o toda la ventana de destino se encuentre fuera de la pantalla activa, la posición se ajustará para volver a colocarla límites.

Limitaciones

El código de manipulación para múltiples pantallas hace 2 supuestos:

  • Que el área de visualización virtual (la combinación de todas las pantallas tratadas como una sola pantalla) es uniforme - por lo que ganaron No juegues bien con configuraciones en forma de L u otras configuraciones tan ridículas.
  • Todas las pantallas activas usan la misma resolución.

En mi experiencia, en el mundo real, estas suposiciones son bastante seguras.

No se proporciona soporte para reposicionamiento y cambio de tamaño simultáneamente (como ocurre con objForm.Move). Tendrá que tratarlos como tareas separadas.

Ejemplos

' 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 
Cuestiones relacionadas