Sizing Access Window

T

Toxalot

I want to size the access window to fit my form perfectly.

I tried using AdjustWindowRect to determine the size I would need, but
it was not quite right. I tried a variation of different constants.
The closest seemed to be WS_CAPTION|WS_THICKFRAME, but it was 4 pixels
short in the width and 10 in the height. If I was sure that it would
always be the same, then I could just adjust manually, but I came
across the following in another thread (from 96).

"The consensus of opinion is that AdjustWindowRect is no use at all.
The only "reliable"
way of computing a client area is to do the calculation yourself,
using
the data returned from GetSystemMetrics."

Can anyone help me with calculating this? Which values do I need to
use?

Jennifer
 
J

Jon Lewis

Can you be more specific about what you want to achieve?

Do you want to size the Access Window to the size of your Form? or the Form
to the Access Window? What happens when either of the these windows's size
changes (if they can?)

GetWindowRect normally works OK for me. You may want to differentiate
between the Main Access Window (Application.hWndAccessApp) and the Access
MDI ClentWindow as they are different. Use FindWindowEx to get a handle to
this window e.g.

Dim hWndMDIClient
hWndMDIClient = FindWindowEx(Application.hWndAccessApp, 0&, "MDIClient", "")

Other considerations when calculating windows sizes are the Title Bar size
and Frame size which are obtainable using GetSystemMetrics e.g.

GetSystemMetrics(SM_CYCAPTION)

and

Dim BorderX As Long, BorderY As Long
'Get form's border size
Select Case intBorderStyle 'I'm supplying this as a function parameter
Case 0 'None
Case 1 'Thin
BorderX = GetSystemMetrics(SM_CXBORDER)
BorderY = GetSystemMetrics(SM_CYBORDER)
Case 2 'Sizeable
BorderX = GetSystemMetrics(SM_CXFRAME)
BorderY = GetSystemMetrics(SM_CYFRAME)
Case 3 'Dialog
BorderX = GetSystemMetrics(SM_CXFIXEDFRAME)
BorderY = GetSystemMetrics(SM_CYFIXEDFRAME)
End Select

HTH

Jon
 
T

Toxalot

The form size is constant. I want Access Window to be the size of the
form. I'm using AdjustWindowRect to determine what the overall size of
the Access Window should be based on the size of the desired client
area.

I've narrowed down my code and created a sample.

Const APP_WIDTH = 800 'width of main form
Const APP_HEIGHT = 647 'height of main form
Const WS_CAPTION = &HC00000
Const WS_THICKFRAME = &H40000

Type RECT
x1 As Long
y1 As Long
x2 As Long
y2 As Long
End Type

Declare Function AdjustWindowRect Lib "user32" (ByRef lpRect As RECT,
_
ByVal dwStyle As Long, ByVal bMenu As Long) As Long

Declare Function MoveWindow Lib "user32" (ByVal hWnd As Long, ByVal _
X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight _
As Long, ByVal bRepaint As Long) As Long

Sub StartUp()

Dim x As Long
Dim y As Long
Dim R As RECT

x = 0 'later calculate based on SPI_GETWORKAREA
y = 0 'later calculate based on SPI_GETWORKAREA

R.x1 = 0
R.x2 = APP_WIDTH
R.y1 = 0
R.y2 = APP_HEIGHT

AdjustWindowRect R, WS_CAPTION Or WS_THICKFRAME, 1
MoveWindow Application.hWndAccessApp, x, y, R.x2 - R.x1, Ry2 - R.y1,
1
DoCmd.OpenForm "frmMain"
DoCmd.Restore
MoveWindow Forms!frmMain.hWnd, 0, 0, APP_WIDTH, APP_HEIGHT, 1
End Sub

The above code runs from an AutoExec macro. I have a button on the
form that uses GetWindowRect to tell me size of the Access Window.

When I run the above code, the Access Window sizes to 808 x 701 and I
get scroll bars. I manually size the Access Window until it fits and
the Access Window is 812 x 711.

If I remove images from the Menu Bar, I'm able to size down to 812 x
708. So the images cause the menu bar to be 3 pixels higher. But there
is still 4 pixels in width and height that don't seem to be accounted
for.

Am I not using the right constants with AdjustWindowRect?

Jennifer
 
T

Toxalot

Correction. It's not the image that causes the menu bar to be higher.
It's a custom menu bar vs the built-in menu bar. The built-in menu bar
is 23 pixels high, but as soon as I add even a text custom button, it
gains 3 pixels.

Jennifer
 
T

Toxalot

GetSystemMetrics(SM_CYCAPTION)

This returns 26 which makes sense.
BorderX = GetSystemMetrics(SM_CXFRAME)
BorderY = GetSystemMetrics(SM_CYFRAME)

These return 4 which seems to be the same as what AdjustWindowRect
uses. To get my form and access window to fit nicely, my window needs
to be 12 pixels wider than my form. There are only two borders, so
where does the extra 4 pixels come in?

The height of a window without a menu bar is also out by 4 pixels.

And is there a value in GetSystemMetrics for the height of the menu
bar? I figure the built-in menu is 23 and the custom menu is 26, but I
don't see anything that returns either of those values. SM_CYMENU
returns 20.

Oh, and BTW, my form has border style set to none. Though that doesn't
seem to matter because the MoveWindow function sizes the outside
dimensions. I get the same results no matter which border style my
form uses.

Jennifer
 
J

Jon Lewis

The MDI Clent Window is the client area of an MDI Window. It has its own
windows handle but I don't think that will be of use to you as if you were
to size this window to 800 x 647 you would still have to size the main
window to contain it.

I'm not familiar with AdjustWindowRect but would guess that it has to assume
a standard height for a menu so any variance on that height would throw the
window size out.

If your menu size is constant, what happens if you use MoveWindow on
Application.hWndAccessApp allowing for a Caption, the Frame (using
GetSystemMatrics as in my previous post) and Your Known Menu Height?

MoveWindow Application.hWndAccessApp, x, y, 800 + (2*
GetSystemMetrics(SM_CYFRAME)), _
647 + (2*GetSystemMetrics(SM_CXFRAME)) + GetSystemMetrics(SM_CYCAPTION) +
YourMenuHeight ,1

OR use
hWndMDIClient = FindWindowEx(Application.hWndAccessApp, 0&, "MDIClient", "")
GetWindowRect hWndMDIClient, R

and hard code the MoveWindow Application.hWndAccessApp call until you get
the correct size of hWndMDIClient

HTH

Jon
 
T

Toxalot

The following seems to work for a window without the menu. Notice the
extra 2 pixels added all the way around.
MoveWindow Application.hWndAccessApp, x, y, 800 + _
(2 * (GetSystemMetrics(SM_CXFRAME) + 2)), 647 + _
(2 * (GetSystemMetrics(SM_CYFRAME) + 2)) + _
GetSystemMetrics(SM_CYCAPTION), 1

The following seems to work for a window with the built-in menu.
Notice the additional 3 pixels added to the height.
MoveWindow Application.hWndAccessApp, x, y, 800 + _
(2 * (GetSystemMetrics(SM_CXFRAME) + 2)), 647 + _
(2 * (GetSystemMetrics(SM_CYFRAME) + 2)) + _
GetSystemMetrics(SM_CYCAPTION) + _
GetSystemMetrics(SM_CYMENU) + 3, 1

And if the menu is custom, then I need to add another 3 pixels.

The above code seems to work on WinXP SP2 XP Style Theme. The Classic
theme needs 1 more pixel in height. Classic style with large font need
4 instead of 1 and it doesn't make a difference whether the menu is
custom or not.

I can code it manually and since this is only being distributed to
select end users, I know what systems they have, but I still want to
understand why I need to add in the extra pixels.

Jennifer
 
J

Jon Lewis

I don't know Jennifer

Try asking on microsoft.public.vb.winapi

You still haven't said what you are trying to achieve with this approach

What happens if the Access window is resized or maximised?

Jon
 
T

Toxalot

It looks good if the form (border style none) fits to the Access
Window. It looks like a complete contained application. Not sure if
I'm explaining that right, but it's basically for aesthetic reasons.

I don't stop the user from resizing or maximizing. They can if the
wish. And there is an option to save the new size as their preference
or to reset the size to fit.

I will try posting on microsoft.public.vb.winapi

Jennifer
 
J

Jon Lewis

Try this approach which works well and would be Windows version and Theme
and Menu independent:

I use this routine in the open event of a 'dummy' form set to display at
start up. The MDI background colour is changed to match the standard form
colour. The form has borderstyle none and is blank apart from a subform
control, which can hold your real start up form. This gives you a great
desk top.

Private Sub Form_Open(Cancel As Integer)
'Position form top left and change Access MDI background to match
Dim lngBrush As Long
Dim lngOldBrush As Long
Dim hWndMDIClient As Long
Dim rct As Rect

lngBrush = CreateSolidBrush(GetSysColor(COLOR_BTNFACE))

hWndMDIClient = FindWindowEx(Application.hWndAccessApp, 0&, "MDIClient", "")

Call GetWindowRect(hWndMDIClient, rct)

With rct
..Bottom = .Bottom - .Top
..Top = 0
..Right = .Right - .Left
..Left = 0
End With
lngOldBrush = SetClassLong(hWndMDIClient, GCL_HBRBACKGROUND, lngBrush)
Call InvalidateRect(hWndMDIClient, rct, True) ' This forces redraw of the
MDI client window with the new colour
Call SetWindowPos(Me.hwnd, HWND_TOP, 0, 0, 1, 1, SWP_NOSIZE Or SWP_NOZORDER)
Call DeleteObject(lngOldBrush)

End Sub
 
T

Toxalot

This is a neat idea and I may incorporate it. But I still want a
default size for the Access Window so that, if the screen is big
enough, the application will start without any scroll bars.

I'm preparing a sample to illustrate my issue so I can post to
microsoft.public.vb.winapi

Jennifer
 
T

Toxalot

I haven't gotten an answer from the other group yet, but I have
discovered a couple more things.

The Access MDI Client window has a 2 pixel border.

There is a difference of 4 pixels in the width and height between the
MDI client window's GetWindowRect and GetClientRect. The MDI Client's
client rectangle also takes into account the variations for the menu
bar size.

To get what I want, I'm comparing the MDI Client's client rectangle to
the rectangle I want and adding the difference to the Access Window's
current rectangle.

Jennifer
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top