Positioning
Create a new Userform and press F5 to display it.
The default position for the Userform should be in the center of the Office application.
When the user only has one monitor, this is fine.
However if the user has multiple screens you might find the Userform is not displayed in the center.
It really all depends how the screens are configured and which monitor is setup as the Primary screen.
Every Userform object has a property called StartUpPosition which can be used to change the default position.
StartUpPosition Property
0 - Manual - Allows you to use the Left and Top properties to specify an exact position.
1 - CenterOwner - (default) Not every time when you have multiple monitors. Only on your primary screen.
2 - CenterScreen - Not every time when you have multiple monitors. Only on your primary screen.
3 - WindowsDefault - Positions the userform in the top left corner of the screen.
StartUpPosition = Manual
There are a number of different approaches you can use to control the positioning of a userform.
The best approach is to calculate the exact Left and Top position and then pass this information to the userform in the Initialize event.
Before we calculate the Top and Left positions we need to change the StartUpPosition property of the userform to Manual (0).
It is worth emphasizing that this property must be changed at design-time and not at run-time.
Adding the following line of code in your Initialize event will not work.
Me.StartUpPosition = 0 'THIS WILL NOT WORK
Approach 1 - Application.UsableHeight
This approach uses the size of the application window.
Private Sub UserForm_Initialize()
Me.Top = Application.Top + (Application.UsableHeight / 2) - (Me.Height / 2)
Me.Left = Application.Left + (Application.UsableWidth / 2) - (Me.Width / 2)
End Sub
Approach 2 - Saving the Position
This approach saves the position the userform was last in to the registry and then uses those values next time.
Private Sub UserForm_Initialize()
Me.Left = GetSetting("Userform Positioning", ThisWorkbook.FullName & "-" & Me.Name, "Left", 0)
Me.Top = GetSetting("Userform Positioning", ThisWorkbook.FullName & "-" & Me.Name, "Top", 0)
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, _
CloseMode As Integer)
Call SaveSetting("Userform Positioning", ThisWorkbook.FullName & "-" & Me.Name, "Left", Me.Left)
Call SaveSetting("Userform Positioning", ThisWorkbook.FullName & "-" & Me.Name, "Top", Me.Top)
End Sub
Approach 3 - Middle of Application Window / Current Screen
This approach uses several Windows APIs to make adjustments for the specific screen resolution.
This code snippet also includes the VBA7 Compiler Constant and the PtrSafe keyword.
Both of these were added in Office 2010 to allow compatibility with Office 64 bit.
Insert the following code into a regular code module.
Option Explicit
#If VBA7 Then
Declare PtrSafe Function GetSystemMetrics Lib "user32" (ByVal Index As Long) As Long
Declare PtrSafe Function GetDC Lib "user32" (ByVal hWnd As Long) As Long
Declare PtrSafe Function ReleaseDC Lib "user32" (ByVal hWnd As Long, ByVal hDC As Long) As Long
Declare PtrSafe Function GetDeviceCaps Lib "gdi32" (ByVal hDC As Long, ByVal Index As Long) As Long
Declare PtrSafe Function GetWindowRect Lib "user32" (ByVal hWnd As Long, ByRef lpRect As udtRECT) As Long
#Else
Declare Function GetSystemMetrics Lib "user32" (ByVal Index As Long) 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 Index As Long) As Long
Declare Function GetWindowRect Lib "user32" (ByVal hWnd As Long, ByRef lpRect As udtRECT) As Long
#End If
Type udtRECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Public Sub ReturnPosition_CenterScreen(ByVal sngHeight As Single, _
ByVal sngWidth As Single, _
ByRef sngLeft As Single, _
ByRef sngTop As Single)
Dim sngAppWidth As Single
Dim sngAppHeight As Single
Dim hWnd As Long
Dim lreturn As Long
Dim lpRect As udtRECT
hWnd = Application.hWnd 'Used in Excel and Word
'hWnd = Application.hWndAccessApp 'Used in Access
lreturn = GetWindowRect(hWnd, lpRect)
sngAppWidth = ConvertPixelsToPoints(lpRect.Right - lpRect.Left, "X")
sngAppHeight = ConvertPixelsToPoints(lpRect.Bottom - lpRect.Top, "Y")
sngLeft = ConvertPixelsToPoints(lpRect.Left, "X") + ((sngAppWidth - sngWidth) / 2)
sngTop = ConvertPixelsToPoints(lpRect.Top, "Y") + ((sngAppHeight - sngHeight) / 2)
End Sub
Public Function ConvertPixelsToPoints(ByVal sngPixels As Single, _
ByVal sXorY As String) As Single
Dim hDC As Long
hDC = GetDC(0)
If sXorY = "X" Then
ConvertPixelsToPoints = sngPixels * (72 / GetDeviceCaps(hDC, 88))
End If
If sXorY = "Y" Then
ConvertPixelsToPoints = sngPixels * (72 / GetDeviceCaps(hDC, 90))
End If
Call ReleaseDC(0, hDC)
End Function
Add the following code to your Userform module.
Private Sub UserForm_Initialize()
Dim sngLeft As Single
Dim sngTop As Single
Call ReturnPosition_CenterScreen(Me.Height, Me.Width, sngLeft, sngTop)
Me.Left = sngLeft
Me.Top = sngTop
End Sub
Approach 4 - Middle of All Screens
This approach uses the GetSystemMetrics Windows API.
Private Sub UserForm_Initialize()
Dim sngScreenWidth As Single
Dim sngScreenHeight As Single
sngScreenWidth = GetSystemMetrics(78)
sngScreenHeight = GetSystemMetrics(79)
sngScreenWidth = ConvertPixelsToPoints(sngScreenWidth, "X")
sngScreenHeight = ConvertPixelsToPoints(sngScreenHeight, "Y")
Me.Left = Application.Left + (sngScreenWidth - Me.Width) / 2
Me.Top = Application.Top + (sngScreenHeight - Me.Height) / 2
End Sub
Microsoft Access
If you are using Microsoft Access with pop-up Forms (as opposed to Userforms) the calculations are similar, but not quite identical.
You need to use twips instead of points.
There are 20 twips per point and you have to use the load event.
Private Sub Form_Load()
Dim sngLeft As Single
Dim sngTop As Single
Call ReturnPosition_CenterScreen(Me.WindowHeight / 20, Me.WindowWidth / 20, sngLeft, sngTop)
sngLeft = sngLeft * 20
sngTop = sngTop * 20
DoCmd.MoveSize sngLeft, sngTop
End Sub
© 2024 Better Solutions Limited. All Rights Reserved. © 2024 Better Solutions Limited TopPrevNext