tags:

views:

408

answers:

4

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.,

    Me.Move newWindowLeft, newWindowTop, newWidth, newHeight

However, how can I find out how wide the parent window is?

+1  A: 

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.

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.

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.

Stewbob
On my machine, I can see the maximize and restore take place, so I had to turn off/on the updates (Application.echo false/true).
CodeSlave
+2  A: 

You can use a 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
DJ
Tried it, and it looked right originally, but I found that I could not use the width/height that I was getting back to position the window exactly where I wanted it. It was off by some multiple (I tried multiplying by 20 to convert to twips, but no no avail). However, +1 anyway.
CodeSlave
It returns the number of pixels - you have to convert it to twips. twips = pixels * (1440/dpi) see: http://www.applecore99.com/api/api012.asp
DJ
Er, what? TWIPS = PIXELS * INCHES, or whatever other measurement you are using -- you have to specify the measurement units. The position and sizing properties of forms/reports/controls (Top, Height, Left, Width) are returned in TWIPS to begin with, so if you're sizing to an existing object, you won't need to convert.
David-W-Fenton
@David - you missed the point - the api returns the width of the main application window in pixels - but access only works in twips so hence the conversion - and to convert you to take into account the dpi of the device
DJ
A: 

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
CodeSlave
Won't this return something other than accurate numbers because of chrome issues? That is, when you restore, you end up with a title bar, which wasn't part of the window when it as maximized. And different Windows skins (i.e., "Themes" in MS terminology) can produce different results.
David-W-Fenton
True, I do get a shift down of about the height of the tool bars. Let me rethink this.
CodeSlave
A: 

This may be of interest: 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.                                               *
Remou