NauticalGent
Ignore List Poster Boy
- Local time
- Yesterday, 21:20
- Joined
- Apr 27, 2015
- Messages
- 6,621
Good morning everyone! My issue should be simple, most of my users and I have a dual monitor set up. I have a main form and one of the command buttons opens up a pop up form. Because the main window can be moved as well as the pop-up, I want to ensure that the pop-up opens on the same monitor that the Access application window in on and that the pop-up form is a certain size.
I consulted ChatGPT and here is what I received:
I know I can simply open the form and close it and it will stay where I last put it and that applies to the size as well. However, I want to explicitly set the location and size just in case I get a user that likes to play around.
Any ideas?
I consulted ChatGPT and here is what I received:
This did not work and after playing with it some, I was able to detemine that the DoCmd.MoveSize code I have on the pop-up's OnLoad event was causing the issue. Once I removed it, it opened on the right monitor but the size was WAY off.To ensure that a form in Microsoft Access opens on the same screen as the calling form, you can use the Windows API to detect the monitor where the calling form is located and then position the new form accordingly.
Here's how you can achieve this:
Step 1: Declare the API Functions
Add these declarations to a standard module:
Private Declare PtrSafe Function MonitorFromPoint Lib "User32.dll" (ByVal x As Long, ByVal y As Long, ByVal dwFlags As Long) As Long
Private Declare PtrSafe Function MonitorFromRect Lib "User32.dll" (ByRef lprc As RECT, ByVal dwFlags As Long) As Long
Private Declare PtrSafe Function MonitorFromWindow Lib "User32.dll" (ByVal hwnd As LongPtr, ByVal dwFlags As Long) As Long
Private Declare PtrSafe Function GetWindowRect Lib "User32.dll" (ByVal hwnd As LongPtr, ByRef lpRect As RECT) As Long
Private Declare PtrSafe Function GetDesktopWindow Lib "User32.dll" () As LongPtr
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Const MONITOR_DEFAULTTONEAREST = &H2
Step 2: Create a Function to Get the Monitor Position
This function calculates the monitor where the calling form is located.
Function GetFormMonitor(frm As Form) As RECT
Dim hwnd As LongPtr
Dim r As RECT
' Get the window handle of the form
hwnd = frm.hWnd
' Get the form's screen rectangle
GetWindowRect hwnd, r
' Get the monitor based on the form's rectangle
MonitorFromRect r, MONITOR_DEFAULTTONEAREST
GetFormMonitor = r
End Function
Step 3: Set the Position of the New Form
When opening the second form, position it based on the screen bounds of the first form's monitor:
vba
Copy code
Private Sub OpenSecondForm()
Dim r As RECT
Dim frmMain As Form
Dim frmNew As Form
' Reference the calling form
Set frmMain = Me
' Get the monitor position of the calling form
r = GetFormMonitor(frmMain)
' Open the second form
DoCmd.OpenForm "SecondForm", acNormal
Set frmNew = Forms("SecondForm")
' Position the second form within the monitor bounds
With frmNew
.Move Left:=r.Left + 50, Top:=r.Top + 50 ' Offset a bit from the monitor bounds
End With
End Sub
Notes
Replace "SecondForm" with the actual name of the form you are opening.
The Move method positions the form, where Left and Top are measured in twips (1 inch = 1440 twips).
You can adjust the Left and Top offsets to ensure the form appears neatly on the same screen.
Let me know if you need help refining this for your specific setup!
I know I can simply open the form and close it and it will stay where I last put it and that applies to the size as well. However, I want to explicitly set the location and size just in case I get a user that likes to play around.
Any ideas?
Last edited: