Attribute VB_Name = "modMultiMon" Option Explicit ' Use the "UseDebugWndProc" conditional compile argument in the IDE ' http://msdn.microsoft.com/vbasic/downloads/components/controls.aspx Private Declare Function EnumDisplayMonitors Lib "User32.dll" (ByVal hDC As Long, ByRef lprcClip As Any, ByVal lpfnEnum As Long, ByVal dwData As Long) As Long #If (EDaisUseNotifyWnd) Then Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long Private Declare Function CreateWindowEx Lib "user32" Alias "CreateWindowExA" (ByVal dwExStyle As Long, ByVal lpClassName As String, ByVal lpWindowName As String, ByVal dwStyle As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hWndParent As Long, ByVal hMenu As Long, ByVal hInstance As Long, ByRef lpParam As Any) As Long Private Declare Function DefWindowProc Lib "user32" Alias "DefWindowProcA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Private Declare Function DestroyWindow Lib "user32" (ByVal hWnd As Long) As Long Private Declare Function RemoveProp Lib "user32" Alias "RemovePropA" (ByVal hWnd As Long, ByVal lpString As String) As Long Private Declare Function SetProp Lib "user32" Alias "SetPropA" (ByVal hWnd As Long, ByVal lpString As String, ByVal hData As Long) As Long Private Declare Function GetProp Lib "user32" Alias "GetPropA" (ByVal hWnd As Long, ByVal lpString As String) As Long Private Declare Function IsWindow Lib "user32" (ByVal hWnd As Long) As Long Private Declare Sub RtlMoveMemory Lib "kernel32" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long) Private Const GWL_WNDPROC As Long = (-4) Private Const WS_OVERLAPPED As Long = &H0 Private Const WS_EX_TOOLWINDOW As Long = &H80 Private Const WM_DISPLAYCHANGE As Long = &H7E Private Const EDObjProp As String = "EDmmObjPtr" Private Const EDOldProp As String = "EDmmOldProc" Private Const NotifyName As String = "EDNotifyWindow" Private Const NotifyClass As String = "Static" #If (UseDebugWndProc) Then Private DebugHook As WindowProcHook #End If #End If Private Type RectAPI Left As Long Top As Long Right As Long Bottom As Long End Type Private hMonitors() As Long Private NumMonitor As Long Public Function EDmmEnumMonitors() As Long() ' HMONITOR[] Erase hMonitors NumMonitor = 0 Call EnumDisplayMonitors(0&, ByVal 0&, AddressOf MonitorEnumProc, 0&) EDmmEnumMonitors = hMonitors End Function Private Function MonitorEnumProc(ByVal hMonitor As Long, ByVal hdcMonitor As Long, _ ByRef lprcMonitor As RectAPI, ByVal dwData As Long) As Long ReDim Preserve hMonitors(NumMonitor) As Long hMonitors(NumMonitor) = hMonitor NumMonitor = NumMonitor + 1 MonitorEnumProc = 1 End Function #If (EDaisUseNotifyWnd) Then Public Function EDmmCreateNotifyWnd(ByRef inParent As clsMonitors) As Long Dim OldProc As Long EDmmCreateNotifyWnd = CreateWindowEx(WS_EX_TOOLWINDOW, NotifyClass, NotifyName, _ WS_OVERLAPPED, 0&, 0&, 0&, 0&, 0&, 0&, App.hInstance, ByVal 0&) If (EDmmCreateNotifyWnd = 0) Then Exit Function #If (UseDebugWndProc) Then Set DebugHook = Nothing Set DebugHook = CreateWindowProcHook() With DebugHook Call .SetMainProc(AddressOf NotifyProc) OldProc = SetWindowLong(EDmmCreateNotifyWnd, GWL_WNDPROC, .ProcAddress) Call .SetDebugProc(OldProc) End With #Else OldProc = SetWindowLong(EDmmCreateNotifyWnd, GWL_WNDPROC, AddressOf NotifyProc) #End If Call SetProp(EDmmCreateNotifyWnd, EDObjProp, ObjPtr(inParent)) Call SetProp(EDmmCreateNotifyWnd, EDOldProp, OldProc) End Function Public Sub EDmmDestroyNotifyWnd(ByVal inWnd As Long) Dim OldProc As Long If (IsWindow(inWnd) = 0) Then Exit Sub OldProc = GetProp(inWnd, EDOldProp) Call SetWindowLong(inWnd, GWL_WNDPROC, OldProc) #If (UseDebugWndProc) Then Set DebugHook = Nothing #End If Call RemoveProp(inWnd, EDObjProp) Call RemoveProp(inWnd, EDOldProp) Call DestroyWindow(inWnd) End Sub Private Function NotifyProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Dim ParentPtr As Long Dim ParentObj As clsMonitors If (uMsg = WM_DISPLAYCHANGE) Then ParentPtr = GetProp(hWnd, EDObjProp) Call RtlMoveMemory(ParentObj, ParentPtr, 4&) If (Not (ParentObj Is Nothing)) Then Call ParentObj.OnDisplayChange Call RtlMoveMemory(ParentObj, 0&, 4&) End If NotifyProc = DefWindowProc(hWnd, uMsg, wParam, lParam) End Function #End If