If you save your window position when your application exits, it's good to check to make sure that the monitor it was on is still there and is the same size it used to be when you start up. This code takes in an hWnd and returns true if the window is entirely inside the user's desktop area, allowing you to decide if you need to move the window or not.
This must be placed in a module to work.
This must be placed in a module to work.
Code:
Option Explicit
Private Type Rect
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Declare Function EnumDisplayMonitors Lib "user32" (ByVal hDC As Long, ByVal lprcClip As Long, ByVal lpfnEnum As Long, dwData As Long) As Long
Private Declare Function CombineRgn Lib "gdi32.dll" (ByVal hDestRgn As Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal nCombineMode As Long) As Long
Private Declare Function CreateRectRgnIndirect Lib "gdi32.dll" (ByRef lpRect As Rect) As Long
Private Declare Function GetWindowRect Lib "user32.dll" (ByVal hWnd As Long, ByRef lpRect As Rect) As Long
Private Declare Function DeleteObject Lib "gdi32.dll" (ByVal hObject As Long) As Long
Private Const API_TRUE = 1
Private Const RGN_OR As Long = 2
Private Const RGN_DIFF As Long = 4
Private Const NULLREGION As Long = 1
Private Function MonitorEnumProc(ByVal lngMonitorHandle As Long, _
ByVal lngMonitorHDC As Long, _
ByRef typWorkingScreen As Rect, _
ByRef lngDesktopRegionHandle As Long) As Long
Dim lngWorkingScreenRegion As Long
' Make the screen's rect into a region
lngWorkingScreenRegion = CreateRectRgnIndirect(typWorkingScreen)
' Combine it with all the desktops so far.
CombineRgn lngDesktopRegionHandle, lngWorkingScreenRegion, lngDesktopRegionHandle, RGN_OR
' Dispose of the screen's region
DeleteObject lngWorkingScreenRegion
' Proceeed to the next screen
MonitorEnumProc = API_TRUE
End Function
Public Function hWndIsInDesktopRegion(ByVal hWnd As Long) As Boolean
Dim typRect As Rect
Dim lngSrcRegionHandle As Long
Dim lngDesktopRegionHandle As Long
' Create an empty region that will be used to combine the desktop regions into
' typRect is empty at init per VB convention
lngDesktopRegionHandle = CreateRectRgnIndirect(typRect)
' Create a region that is the window we are interested in
GetWindowRect hWnd, typRect
lngSrcRegionHandle = CreateRectRgnIndirect(typRect)
' Enum the monitors to create the desktop region.
Call EnumDisplayMonitors(0&, 0&, AddressOf MonitorEnumProc, lngDesktopRegionHandle)
' Test to see if our region is in the combined region
If CombineRgn(lngDesktopRegionHandle, lngSrcRegionHandle, lngDesktopRegionHandle, RGN_DIFF) = NULLREGION Then
hWndIsInDesktopRegion = True
Else
hWndIsInDesktopRegion = False
End If
' Dispose of the local and desktop regions
DeleteObject lngSrcRegionHandle
DeleteObject lngDesktopRegionHandle
End Function