Option Explicit
Private Type POINTAPI
x As Long
y As Long
End Type
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Type WINDOWPLACEMENT
Length As Long
flags As Long
showCmd As Long
ptMinPosition As POINTAPI
ptMaxPosition As POINTAPI
rcNormalPosition As RECT
End Type
Private Type MONITORINFO
cbSize As Long
rcMonitor As RECT
rcWork As RECT
dwFlags As Long
End Type
Private Type uData
#If Win64 Then
hOriginalWindow As LongLong
hNewlWindow As LongLong
#Else
hOriginalWindow As Long
hNewlWindow As Long
#End If
End Type
#If VBA7 Then
Private Declare PtrSafe Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long
Private Declare PtrSafe Function GetMonitorInfo Lib "user32" Alias "GetMonitorInfoA" (ByVal hMonitor As LongPtr, lpmi As MONITORINFO) As Long
Private Declare PtrSafe Function MonitorFromWindow Lib "user32" (ByVal hwnd As LongPtr, ByVal dwFlags As Long) As LongPtr
Private Declare PtrSafe Function EnumDisplayMonitors Lib "user32" (ByVal hDc As LongPtr, lprcClip As Any, ByVal lpfnEnum As LongPtr, dwData As uData) As Long
Private Declare PtrSafe Function MoveWindow Lib "user32" (ByVal hwnd As LongPtr, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long
Private Declare PtrSafe Function SetWindowPlacement Lib "user32" (ByVal hwnd As LongPtr, ByRef lpwndpl As WINDOWPLACEMENT) As Long
#Else
Private Declare Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long
Private Declare Function GetMonitorInfo Lib "user32" Alias "GetMonitorInfoA" (ByVal hMonitor As Long, lpmi As MONITORINFO) As Long
Private Declare Function MonitorFromWindow Lib "user32" (ByVal hWnd As Long, ByVal dwFlags As Long) As Long
Private Declare Function EnumDisplayMonitors Lib "user32" (ByVal hDc As Long, lprcClip As Any, ByVal lpfnEnum As Long, dwData As uData) As Long
Private Declare Function MoveWindow Lib "user32" (ByVal hwnd As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long
Private Declare Function SetWindowPlacement Lib "user32" (ByVal hwnd As Long, ByRef lpwndpl As WINDOWPLACEMENT) As Long
#End If
Sub Test()
OpenNewWindowInSecondMonitor ThisWorkbook
End Sub
Sub OpenNewWindowInSecondMonitor(ByVal Wb As Workbook)
Const SM_CMONITORS = 80
Dim dwData As uData
Dim oNewWindow As Window
If GetSystemMetrics(SM_CMONITORS) > 1 Then
dwData.hOriginalWindow = Wb.Windows(1).hwnd
Set oNewWindow = Wb.Windows(1).NewWindow
dwData.hNewlWindow = oNewWindow.hwnd
Call EnumDisplayMonitors(ByVal 0, ByVal 0, AddressOf Monitorenumproc, dwData)
End If
End Sub
#If Win64 Then
Function Monitorenumproc( _
ByVal hMonitor As LongLong, _
ByVal hDc As LongLong, _
lpRect As RECT, _
lParam As uData _
) As Long
#Else
Function Monitorenumproc( _
ByVal hMonitor As Long, _
ByVal hDc As Long, _
lpRect As RECT, _
lParam As uData _
) As Long
#End If
Const MONITOR_DEFAULTTONEAREST = &H2&
Const SW_SHOWNORMAL = 1
Dim uMI As MONITORINFO
Dim uWP As WINDOWPLACEMENT
uMI.cbSize = LenB(uMI)
Call GetMonitorInfo(hMonitor, uMI)
If MonitorFromWindow(lParam.hOriginalWindow, MONITOR_DEFAULTTONEAREST) <> hMonitor Then
uWP.Length = Len(uWP)
uWP.showCmd = SW_SHOWNORMAL
Call SetWindowPlacement(lParam.hNewlWindow, uWP)
With uMI.rcMonitor
Call MoveWindow(lParam.hNewlWindow, .Left, .Top, .Right - .Left, .Bottom - .Top, True)
End With
Monitorenumproc = 0
Else
Monitorenumproc = 1
End If
End Function