Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Center content on form dynamically 2

Status
Not open for further replies.

ptuck

MIS
Aug 8, 2003
130
US
My form opens maximized which is what I want. However, depending on the resolution and/or monitor the content on the form is not always centered. Is there an easy way to have the content on the form to automatically center to the size of the form?

Thanks for the help..
Paul
 
Here's a link to a commercial site which offers a possible solution to your problem. It worked well for an A97 project I developed a few years ago. There are some demo's so you don't have to buy a pig in a poke.

 
Here's some code I put together real quick, but haven't had time to clean it up (or check for all control possibilities). But should work for you. Just create a new module and copy and paste the code in it. Then, in the OnOpen event of the form, call the function.

Note that strFormName is the name of the form (i.e. Me.Name) and varFarLeft is the name of the control that is the farthest to the left on the form. (Also, haven't attempted to handle the positioning of the form if it goes to far to the right. Should be a problem, though, in most cases.)
Code:
Function CenterForm(strFormName As String, _
           Optional varFarLeft As Variant)

    Dim frm As Form
    Dim ctl As Control
    Dim ctlChild As Control
    Dim tabElement As Control
    
    Dim i As Integer
    
    Dim lngLeftOffset As Long
    Dim lngWidth As Long
    Dim lngWidthChild As Long
    Dim x As Long
    
    Set frm = Forms(strFormName)

    Application.Echo False
    
    lngLeftOffset = (frm.InsideWidth \ 2) - (frm.Width \ 2)
    If (Not IsMissing(varFarLeft)) Then
        If (varFarLeft + lngLeftOffset < 0) Then Exit Function
    Else
        x = frm.Width
        For Each ctl In frm.Controls
            If (ctl.Left < x) Then x = ctl.Left
        Next
        If (x + lngLeftOffset < 0) Then Exit Function
    End If
    
    For Each ctl In frm.Controls

        If (ctl.ControlType = acTabCtl) Then
            GoSub MoveTabCtl

        ElseIf (ctl.Parent.Name = strFormName) And (ctl.ControlType = acOptionGroup) Then
            Set tabElement = ctl
            GoSub MoveOptionGroup
        
        ElseIf (ctl.Parent.Name = strFormName) And (ctl.ControlType <> acOptionGroup) And (ctl.ControlType <> acTabCtl) Then
            On Error Resume Next
            If (ctl.ControlType <> 103) Then
                For Each ctlChild In ctl.Controls
                    ctlChild.Left = ctlChild.Left + lngLeftOffset
                Next
            End If
30:
            Err.Clear
            On Error GoTo ErrHandler
            ctl.Left = ctl.Left + lngLeftOffset
        End If
            
    Next

'********************
'*  Exit Procedure  *
'********************
        
ExitProcedure:

    Application.Echo True
    
    Exit Function

'****************************
'*  Error Recovery Section  *
'****************************
        
ErrHandler:
        
    MsgBox Err.Description, vbExclamation        
    Resume ExitProcedure

MoveTabCtl:

    lngWidth = ctl.Width
    
    For i = 0 To ctl.Pages.Count - 1

        For Each tabElement In ctl.Pages(i).Controls
    
            If (tabElement.ControlType = acOptionGroup) Then
                GoSub MoveOptionGroup
            Else
                If (tabElement.Parent.Name <> strFormName) Then
                    If (tabElement.Parent.ControlType <> acOptionGroup) Then
                        If (tabElement.Parent.Parent.ControlType <> acOptionGroup) Then tabElement.Left = tabElement.Left + lngLeftOffset
                    End If
                        
                End If
            End If
        

        Next

    Next i
    
    ctl.Left = ctl.Left + lngLeftOffset
    ctl.Width = lngWidth

    Return
    
MoveOptionGroup:

    lngWidthChild = tabElement.Width
    For Each ctlChild In tabElement.Controls
        ctlChild.Left = ctlChild.Left + lngLeftOffset
    Next
    tabElement.Left = tabElement.Left + lngLeftOffset
    tabElement.Width = lngWidthChild

    Return

End Function
 
As I stated in my previous post, I put the code together quickly. In testing it, my form's popup property was set to Yes. Consequently, everything worked fine. I just tried it without the popup property set and it didn't work. To make it work reqardless of whether or not it's a popup, change the code from

lngLeftOffset = (frm.InsideWidth \ 2) - (frm.Width \ 2)

to

lngLeftOffset = (frm.WindowWidth \ 2) - (frm.Width \ 2)
 
Thanks for the replay FancyPrairie....The code you provided will resize all the content inside/on the form right???? It is not just resized the form???
 
Thank you this is great. When I call the function I need to pass the form name and the control farthest on the left?
 
Note that the 2nd argument is optional and represents the value of the LEFT property of the control. If you don't pass the 2nd argument, the function will determine which control is farthest to the left. Therefore, you can call it 1 of 2 ways (I call the function in the OnLoad event of the form).

CenterForm Me.Name

or

CenterForm Me.Name, YourControlName.Left
 
I'm glad it worked for you. There is another way of doing what you want. That is, before you create your form set your desktop properties to the lowest resolution your user's machine is set to (i.e. 800x600). Layout your form at that resolution. When your form opens, check the resolution of the pc. If it's 800x600, open the form maximized, else restored. Here's how you would do it.

Create a module and name it something like basPublicDeclarations. Then insert the following declaration in the module.

Public Declare Function apiGetSystemMetrics Lib "User32" Alias "GetSystemMetrics" (ByVal nIndex As Integer) As Integer

In the OnOpen event of your form, do this:

If (apiGetSystemMetrics(16) > 800) Then 'Returns size of screen (width) 17=height (i.e. 800x600)
DoCmd.Restore
Else
DoCmd.Maximize
End If
 
I have one more question for the expert. What is the best way to have all forms and access open maximized and never change. I have used the docmd.maximize, but sometimes the forms will revert back to minimized for some reason. What do you recommend?
 
Try putting your Docmd.Maximize command in the OnActive event of the form. That way if one of your forms issues a docmd.restore and then closes, the OnActivate event of the previous form will be launched and the Docmd.maximize event will be executed again.
 
Is there not an easy way to just have everything maximized all the time with out using code? Using the docmd.maximize causes a lot of flashing on the screen...not as smooth as I like it. Any thoughts?????
 
The function you have provided works great, but only once. It is holding the form name of the first form that uses the function in memory. Where is the magic place to reset the variables?
 
I don't see how that could be. When you call the function, you're passing it the name of the form that you want centered. Post examples of how you call the function.
 
After further testing, it appears to be looking for one form always. I think I remember it working earlier today on multiple forms, but not sure now. Below are some examples:

Private Sub Form_Load()
DoCmd.Maximize
CenterForm Me.Name
End Sub

Private Sub Form_Load()
DoCmd.Maximize
CenterForm "frmMainMenu"
End Sub

Right now it has remembered the form that I am calling by Me.Name (frmClassificationMenu). This is the first form that is loaded then I click a button to call the main menu form and then it gives the error that it can not find frmClassificationMenu.

Thanks for your help.

 
I don't see anything out of the ordinary. Use debug to step thru your code to determine what's going on. If you don't know how to use debug, here's a quick lesson.

Place the word Stop right before the line "CenterForm Me.Name". Or click on the line and press F9. F9 toggles the breakpoint on/off. Now open the form as you normally would. When your program encounters the stop statement (or the breakpoint), it will pause execution. To step thru the code 1 line at a time, press F8. To examine a variable, either hold the cursor over the variable name (tooltip will display its value) or type ?variableName within debugs Immediate Window. For example, once you step into the function, examine strFormName to see what it is. Press F5 to continue execution of your code until it either encounters another stop statement, breakpoint, or reachs the end.
 
Not sure what is going on,but after stepping through the code it appears to be working with one exception. It is now doing a maximize (like my code tells it to do) then doing the centering, but then it is doing a restore and the controls are still centered as if the screen was maximized.
 
FancyPrairie and ptuck,

I have been sitting in on your posts, and ran into a samll problem. I hope you don't mind me bumping it. When I call the function from the form's on open, I get the following error:

Compile Error: Expected procedure or variable, not module

This may be an easy fix, but I'm not sure what I am doing wrong. Any help would be apprciated. Thanks in advance.

Jeremy
 
No spelling error with the function call ?
Is the scope of the function letting it visible from the form ? ie you may try to declare it as [/b]Public[/b]

Hope This Help, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884 or FAQ222-2244
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top