While this seems trivial, unfortunately, it isn't, and we're going to need to use a fair amount of WinAPI. That makes it really hard for beginners.
We need a couple of things:
- We need to be able to determine on which monitor the form is
- We need to be able to determine where that monitor is in the "virtual screen" (think about positioning monitors relative to eachother)
- We need to be able to determine the size of the current window in pixels
- We need to be able to position the form on the "virtual screen".
For that, we need a couple of declarations. These are best kept on separate modules, but if you're 100% sure they will only be used on this form, they can go on the form too.
First, the type and value declarations:
'https://docs.microsoft.com/en-us/windows/win32/api/windef/ns-windef-rect
Public Type RECT
left As Long
top As Long
right As Long
bottom As Long
End Type
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-monitorinfo
Public Type MONITORINFO
cbSize As Long
rcMonitor As RECT
rcWork As RECT
dwFlags As Long
End Type
'Either look this one up by Googling, or create a C++ program that references winuser.h and print it
Public Const MONITOR_DEFAULTTONEAREST = &H2
Then, the function declarations:
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmonitorinfow
Public Declare PtrSafe Function GetMonitorInfoW Lib "User32.dll" (ByVal hMonitor As LongPtr, ByRef lpmi As MONITORINFO) As Boolean
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-monitorfromwindow
Public Declare PtrSafe Function MonitorFromWindow Lib "User32.dll" (ByVal hWnd As LongPtr, ByVal dwFlags As Long) As LongPtr
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-movewindow
Public Declare PtrSafe Function MoveWindow Lib "User32.dll" (ByVal hWnd As LongPtr, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Boolean) As Boolean
'https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowrect
Public Declare PtrSafe Function GetWindowRect Lib "User32.dll" (ByVal hWnd As LongPtr, ByRef lpRect As RECT) As Boolean
And then, on the form, putting it all to work:
Private Sub Command0_Click()
Dim mi As MONITORINFO
Dim monitor As LongPtr
Dim myrect As RECT
'Get the current size and position of the window
GetWindowRect Me.hWnd, myrect
'Determine which monitor it is on
monitor = MonitorFromWindow(Me.hWnd, MONITOR_DEFAULTTONEAREST)
'Make sure WinAPI knows the size of the MONITORINFO struct we're working with
mi.cbSize = LenB(mi)
'Get the monitor info
GetMonitorInfoW monitor, mi
'Move the window to the top right, keep width and height equal to the current values
MoveWindow Me.hWnd, mi.rcMonitor.left, mi.rcMonitor.top, myrect.right - myrect.left, myrect.bottom - myrect.top, True
End Sub
Unfortunately, that's quite a lot more code and more complicated concepts than DoCmd.MoveSize(0 ,0), but I do not know of a simpler approach. VBA doesn't really have any support for multiple monitors, so you'll often have to go to WinAPI to account for them.