Positioning of VBA forms (over element, top left, bottom right, .....)
How is it possible to positioning the form exactly over the element?
The "problem" in this case is that VBA does not use pixel units. It uses the so-called "twips".
The procedure is as followed:
1. get the actual position of the the cursor
2. calculate the the pixel postion into twips units
3. check if the position of the form exeeds the limits of the screen
4. handover the new positioning information to the form
The code below has to be inserted in the LeftClickUp-Event
Name of the LeftClickUp-Event: LeftClickUp_PosOverElement
Name of the UserForm: frmToTest
The code should work for different screen resolutions.
VBA Code:
Option Explicit
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Type POINTAPI
x As Long
y As Long
End Type
Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Private Const SPI_GETWORKAREA& = 48
Private Declare Function SystemParametersInfo Lib "user32" _
Alias "SystemParametersInfoA" _
(ByVal uAction As Long, _
ByVal uParam As Long, _
lpvParam As Any, _
ByVal fuWinIni As Long) As Long
Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As Long
Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal hdc As Long, ByVal nIndex As Long) As Long
Private Const HWND_DESKTOP As Long = 0
Private Const LOGPIXELSX As Long = 88
Private Const LOGPIXELSY As Long = 90
Public Sub LeftClickUp_PosOverElement(obelem As Element)
Dim pTargetPoint As POINTAPI
Dim lRetVal As Long
Dim rc As RECT
lRetVal = GetCursorPos(pTargetPoint)
Call SystemParametersInfo(SPI_GETWORKAREA, 0&, rc, 0&)
'positioning of the form ****
frmToTest.Top = ((rc.Top + pTargetPoint.y) * TwipsPerPixelY / 20) - frmToTest.Height / 2
frmToTest.Left = ((rc.Left + pTargetPoint.x) * TwipsPerPixelX / 20) - frmToTest.Width / 2
'check top border
If (((rc.Top + pTargetPoint.y) * TwipsPerPixelY / 20) - frmToTest.Height / 2) < 0 Then
frmToTest.Top = 0
End If
'check bottom border
If (rc.Top + pTargetPoint.y + frmToTest.Height / 2) > rc.Bottom Then
frmToTest.Top = rc.Bottom * TwipsPerPixelY / 20 - frmToTest.Height
End If
'check left border
If (((rc.Left + pTargetPoint.x) * TwipsPerPixelX / 20) - frmToTest.Width / 2) < 0 Then
frmToTest.Left = 0
End If
'check right border
If (rc.Left + pTargetPoint.x + frmToTest.Width / 2) > rc.Right Then
frmToTest.Left = rc.Right * TwipsPerPixelX / 20 - frmToTest.Width
End If
frmToTest.Init obelem 'hand over all properties to the procedure "Init"
obelem.LeftClickUp 'release the button
End Sub
Function TwipsPerPixelX() As Single
Dim lngDC As Long
lngDC = GetDC(HWND_DESKTOP)
TwipsPerPixelX = 1440 / GetDeviceCaps(lngDC, LOGPIXELSX)
ReleaseDC HWND_DESKTOP, lngDC
End Function
Function TwipsPerPixelY() As Single
Dim lngDC As Long
lngDC = GetDC(HWND_DESKTOP)
TwipsPerPixelY = 1440 / GetDeviceCaps(lngDC, LOGPIXELSY)
ReleaseDC HWND_DESKTOP, lngDC
End Function
Below you can find the code to positioning the form at the corners or in the center.
Replace the code above at the position " 'positioning of the form ****"
VBA Code:
'BottomRight:
frmToTest.Top = rc.Bottom * TwipsPerPixelY / 20 - frmToTest.Height
frmToTest.Left = rc.Right * TwipsPerPixelX / 20 - frmToTest.Width
'BottomLeft:
frmToTest.Top = rc.Bottom * TwipsPerPixelY / 20 - frmToTest.Height
frmToTest.Left = rc.Left * TwipsPerPixelX / 20 '- frmToTest.Width
'TopRight:
frmToTest.Top = rc.Top * TwipsPerPixelY / 20 ' frmToTest.Height
frmToTest.Left = rc.Right * TwipsPerPixelX / 20 - frmToTest.Width
'TopLeft:
frmToTest.Top = rc.Top * TwipsPerPixelY / 20 '- frmToTest.Height
frmToTest.Left = rc.Left * TwipsPerPixelX / 20 '- frmToTest.Width
'Center:
frmToTest.Top = (rc.Bottom / 2) * TwipsPerPixelY / 20 - frmToTest.Height / 2
frmToTest.Left = (rc.Right / 2) * TwipsPerPixelX / 20 - frmToTest.Width / 2
This is a migrated post! Originally posted on 29.11.2007 by user herberto. Please be aware that information can be outdated.