- Local time
- Today, 08:11
- Joined
- Feb 19, 2013
- Messages
- 16,610
I’m trying to line up a form against the left side of a control of another form.
To position it I’m using the form.move method and to line it up perfectly the value for left needs to be 6800 twips in this example. This figure will vary depending on the location of the lower form on the windows screen – so I need to calculate it, which is where I am having the problem.
There are a number of variables in play.
To determine the position of the control on the lower form is simply ctrl.left which is a twips value
To determine the position of the lower form on the desktop I have two options. I can use the form windowleft property (in twips) to determine its location in respect to the access window, plus rect.left value using the getwindowrec function on the access window which returns a screen coordinates value and then use pixelstotwips to convert this value to twips.
Or I can determine the rect.left value using the getwindowrec function which returns a screen coordinates value and then use pixelstotwips to convert this value to twips of the form in relation to the screen.
For completeness, the access window is maximised
References:
Windowsleft: https://msdn.microsoft.com/en-us/library/office/aa663055(v=office.11).aspx
Getwindowrec: https://msdn.microsoft.com/en-us/library/windows/desktop/ms633519(v=vs.85).aspx
Pixelstotwips – calculates to 1440/96=15 twips per pixel:
The code I’m using is
The results I get from the debug is
POS.X..AccessWR.left…FormWR.left…ctrl.left…offset.X…frm.WindowLeft
672......-8……..............357….........….4545……303………..2100
So the calculation:
1. (AccessWR.left*15)+ frm.WindowLeft+ ctrl.left=(-8*15)+2100+4545=6525
2. ((AccessWR.left+FormWR.left)*15)+ ctrl.left=((-8+357)*15)+4545=9780
Neither are particularly close to the target value of 6800.
I would have expected the frm.WindowsLeft value to be equivalent to the FormWR.Left value but there is a big difference - 2100/15=140 v 357 reported. and the FormWR.Left value seems to be the suspect.
I've also converted the ctrl.left to screen coordinates (303) which when added to FormWR.Left and AccessWR.left closely approximates to the mouse position returned from getcursorPOS - I triggered the code from a mouseclick as close to the left of the control as I could to give me a guide of what was required.
I had wondered if the pixeltotwips conversion was calculating correctly, but it is a standard function I am using elsewhere without issue - and just to check I went online to confirm it was reading the screen correctly.
Any thoughts?
To position it I’m using the form.move method and to line it up perfectly the value for left needs to be 6800 twips in this example. This figure will vary depending on the location of the lower form on the windows screen – so I need to calculate it, which is where I am having the problem.
There are a number of variables in play.
To determine the position of the control on the lower form is simply ctrl.left which is a twips value
To determine the position of the lower form on the desktop I have two options. I can use the form windowleft property (in twips) to determine its location in respect to the access window, plus rect.left value using the getwindowrec function on the access window which returns a screen coordinates value and then use pixelstotwips to convert this value to twips.
Or I can determine the rect.left value using the getwindowrec function which returns a screen coordinates value and then use pixelstotwips to convert this value to twips of the form in relation to the screen.
For completeness, the access window is maximised
References:
Windowsleft: https://msdn.microsoft.com/en-us/library/office/aa663055(v=office.11).aspx
Getwindowrec: https://msdn.microsoft.com/en-us/library/windows/desktop/ms633519(v=vs.85).aspx
Pixelstotwips – calculates to 1440/96=15 twips per pixel:
Code:
Private Function PixelsToTwips(ByVal X As Long, ByVal Y As Long) As POINT
Dim ScreenDC As LongPtr
ScreenDC = GetDC(0)
PixelsToTwips.X = X / GetDeviceCaps(ScreenDC, LOGPIXELSX) * TWIPSPERINCH
PixelsToTwips.Y = Y / GetDeviceCaps(ScreenDC, LOGPIXELSY) * TWIPSPERINCH
ReleaseDC 0, ScreenDC
End Function
Private Function TwipsToPixels(ByVal X As Long, ByVal Y As Long) As POINT
Dim ScreenDC As LongPtr
ScreenDC = GetDC(0)
TwipsToPixels.X = X / TWIPSPERINCH * GetDeviceCaps(ScreenDC, LOGPIXELSX)
TwipsToPixels.Y = Y / TWIPSPERINCH * GetDeviceCaps(ScreenDC, LOGPIXELSY)
ReleaseDC 0, ScreenDC
End Function
Code:
Private Function WinTopLeft(frm As Form, ctrl As Object) As POINT
Dim FormWR As RECT
Dim offset As POINT
Dim AccessWR As RECT
Dim POS As POINT
GetWindowRect frm.hwnd, FormWR
GetWindowRect Application.hWndAccessApp, AccessWR
GetCursorPos POS
offset = TwipsToPixels(ctrl.left, ctrl.top)
Debug.Print POS.X; AccessWR.left; FormWR.left; ctrl.left; offset.X; frm.WindowLeft
Code:
[FONT=Tahoma]DoCmd.OpenForm "form2"
Forms!form2.Move 6800 'target twips to line up
'work with p&p to determine calculation[/FONT]
[FONT=Tahoma]
End Function
[/FONT]
POS.X..AccessWR.left…FormWR.left…ctrl.left…offset.X…frm.WindowLeft
672......-8……..............357….........….4545……303………..2100
So the calculation:
1. (AccessWR.left*15)+ frm.WindowLeft+ ctrl.left=(-8*15)+2100+4545=6525
2. ((AccessWR.left+FormWR.left)*15)+ ctrl.left=((-8+357)*15)+4545=9780
Neither are particularly close to the target value of 6800.
I would have expected the frm.WindowsLeft value to be equivalent to the FormWR.Left value but there is a big difference - 2100/15=140 v 357 reported. and the FormWR.Left value seems to be the suspect.
I've also converted the ctrl.left to screen coordinates (303) which when added to FormWR.Left and AccessWR.left closely approximates to the mouse position returned from getcursorPOS - I triggered the code from a mouseclick as close to the left of the control as I could to give me a guide of what was required.
I had wondered if the pixeltotwips conversion was calculating correctly, but it is a standard function I am using elsewhere without issue - and just to check I went online to confirm it was reading the screen correctly.
Any thoughts?