Get notified when the monitor is turned off by Windows or get notified of some other related changes (you'll need to change the Power Setting GUID and probably data check) that are supported by the RegisterPowerSettingNotification API.
I used GUID_SESSION_DISPLAY_STATUS
cPowerChangeNotification.cls code:
mSubclass.bas code:
Code:
' Power Setting GUIDs
Private Const GUID_ACDC_POWER_SOURCE As String = "{5D3E9A59-E9D5-4B00-A6BD-FF34FF516548}"
Private Const GUID_BATTERY_PERCENTAGE_REMAINING As String = "{A7AD8041-B45A-4CAE-87A3-EECBB468A9E1}"
Private Const GUID_CONSOLE_DISPLAY_STATE As String = "{6FE69556-704A-47A0-8F24-C28D936FDA47}"
Private Const GUID_GLOBAL_USER_PRESENCE As String = "{786E8A1D-B427-4344-9207-09E70BDCBEA9}"
Private Const GUID_IDLE_BACKGROUND_TASK As String = "{515C31D8-F734-163D-A0FD-11A08C91E8F1}"
Private Const GUID_LIDSWITCH_STATE_CHANGE As String = "{BA3E0F4D-B817-4094-A2D1-D56379E6A0F3}"
Private Const GUID_MONITOR_POWER_ON As String = "{02731015-4510-4526-99E6-E5A17EBD1AEA}"
Private Const GUID_POWER_SAVING_STATUS As String = "{E00958C0-C213-4ACE-AC77-FECCED2EEEA5}"
Private Const GUID_ENERGY_SAVER_STATUS As String = "{550E8400-E29B-41D4-A716-446655440000}"
Private Const GUID_POWERSCHEME_PERSONALITY As String = "{245D8541-3943-4422-B025-13A784F679B7}"
Private Const GUID_MIN_POWER_SAVINGS As String = "{8C5E7FDA-E8BF-4A96-9A85-A6E23A8C635C}"
Private Const GUID_MAX_POWER_SAVINGS As String = "{A1841308-3541-4FAB-BC81-F71556F20B4A}"
Private Const GUID_TYPICAL_POWER_SAVINGS As String = "{381B4222-F694-41F0-9685-FF5BB260DF2E}"
Private Const GUID_SESSION_DISPLAY_STATUS As String = "{2B84C20E-AD23-4DDF-93DB-05FFBD7EFCA5}"
Private Const GUID_SESSION_USER_PRESENCE As String = "{3C0F4548-C03F-4C4D-B9F2-237EDE686376}"
Private Const GUID_SYSTEM_AWAYMODE As String = "{98A7F580-01F7-48AA-9C0F-44352C29E5C0}"
' More info at https://learn.microsoft.com/en-us/wi...-setting-guids
cPowerChangeNotification.cls code:
Code:
Option Explicit
Private Type CREATESTRUCT
lpCreateParams As Long
hInstance As Long
hMenu As Long
hWndParent As Long
cy As Long
cx As Long
y As Long
x As Long
style As Long
lpszName As String
lpszClass As String
ExStyle As Long
End Type
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, lpParam As Any) As Long
Private Declare Function DestroyWindow Lib "user32" (ByVal hwnd As Long) As Long
' For subclassing:
Private Declare Function DefSubclassProc Lib "comctl32.dll" Alias "#413" (ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function SetWindowSubclass Lib "comctl32.dll" Alias "#410" (ByVal hwnd As Long, ByVal pfnSubclass As Long, ByVal uIdSubclass As Long, Optional ByVal dwRefData As Long) As Long
Private Declare Function RemoveWindowSubclass Lib "comctl32.dll" Alias "#412" (ByVal hwnd As Long, ByVal pfnSubclass As Long, ByVal uIdSubclass As Long) As Long
Private Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Private Declare Function KillTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long
Private Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(0 To 7) As Byte
End Type
Private Type POWERBROADCAST_SETTING
PowerSetting As GUID
DataLength As Long
Data(3) As Byte
End Type
Private Declare Function RegisterPowerSettingNotification Lib "user32" (ByVal hRecipient As Long, ByRef PowerSettingGuid As GUID, ByVal Flags As Long) As Long
Private Declare Function UnregisterPowerSettingNotification Lib "user32" (ByVal hRecipient As Long) As Long
Private Declare Function CLSIDFromString Lib "OLE32.DLL" (ByVal lpsz As Long, ByRef pCLSID As GUID) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
' Power Setting GUIDs
Private Const GUID_ACDC_POWER_SOURCE As String = "{5D3E9A59-E9D5-4B00-A6BD-FF34FF516548}"
Private Const GUID_BATTERY_PERCENTAGE_REMAINING As String = "{A7AD8041-B45A-4CAE-87A3-EECBB468A9E1}"
Private Const GUID_CONSOLE_DISPLAY_STATE As String = "{6FE69556-704A-47A0-8F24-C28D936FDA47}"
Private Const GUID_GLOBAL_USER_PRESENCE As String = "{786E8A1D-B427-4344-9207-09E70BDCBEA9}"
Private Const GUID_IDLE_BACKGROUND_TASK As String = "{515C31D8-F734-163D-A0FD-11A08C91E8F1}"
Private Const GUID_LIDSWITCH_STATE_CHANGE As String = "{BA3E0F4D-B817-4094-A2D1-D56379E6A0F3}"
Private Const GUID_MONITOR_POWER_ON As String = "{02731015-4510-4526-99E6-E5A17EBD1AEA}"
Private Const GUID_POWER_SAVING_STATUS As String = "{E00958C0-C213-4ACE-AC77-FECCED2EEEA5}"
Private Const GUID_ENERGY_SAVER_STATUS As String = "{550E8400-E29B-41D4-A716-446655440000}"
Private Const GUID_POWERSCHEME_PERSONALITY As String = "{245D8541-3943-4422-B025-13A784F679B7}"
Private Const GUID_MIN_POWER_SAVINGS As String = "{8C5E7FDA-E8BF-4A96-9A85-A6E23A8C635C}"
Private Const GUID_MAX_POWER_SAVINGS As String = "{A1841308-3541-4FAB-BC81-F71556F20B4A}"
Private Const GUID_TYPICAL_POWER_SAVINGS As String = "{381B4222-F694-41F0-9685-FF5BB260DF2E}"
Private Const GUID_SESSION_DISPLAY_STATUS As String = "{2B84C20E-AD23-4DDF-93DB-05FFBD7EFCA5}"
Private Const GUID_SESSION_USER_PRESENCE As String = "{3C0F4548-C03F-4C4D-B9F2-237EDE686376}"
Private Const GUID_SYSTEM_AWAYMODE As String = "{98A7F580-01F7-48AA-9C0F-44352C29E5C0}"
' More info at https://learn.microsoft.com/en-us/windows/win32/power/power-setting-guids
Public Event Change(ByVal Value As Variant)
Private mStarted As Long
Private mNotifyHandle As Long
Private mWnd As Long
Private mPtrMWndProc As Long
Private mTimerHandle As Long
Public Sub StartNotify(Optional NotifyStartingCondition As Boolean = True)
Dim CS As CREATESTRUCT
Const DEVICE_NOTIFY_WINDOW_HANDLE As Long = 0
If mStarted Then
StopNotify
End If
mWnd = CreateWindowEx(0, "STATIC", " ", 0, 0, 0, 1, 1, 0, 0, App.hInstance, CS)
mPtrMWndProc = GetPtrMWndProc(AddressOf MWindowProc)
Call SetWindowSubclass(mWnd, mPtrMWndProc, mWnd, ObjPtr(Me))
If Not NotifyStartingCondition Then
mTimerHandle = SetTimer(mWnd, 0&, 15&, 0&)
End If
' Register for power setting notifications
mNotifyHandle = RegisterPowerSettingNotification(mWnd, GUIDFromString(GUID_SESSION_DISPLAY_STATUS), DEVICE_NOTIFY_WINDOW_HANDLE)
End Sub
Private Function GetPtrMWndProc(p As Long) As Long
GetPtrMWndProc = p
End Function
Private Function GUIDFromString(nGUID As String) As GUID
CLSIDFromString StrPtr(nGUID), GUIDFromString
End Function
Friend Function MyWindowProc(ByVal hwnd As Long, ByVal iMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Const WM_POWERBROADCAST As Long = &H218&
Const PBT_POWERSETTINGCHANGE As Long = &H8013&
Const WM_DESTROY = &H2
Const WM_TIMER = &H113
If iMsg = WM_POWERBROADCAST Then
If mTimerHandle = 0 Then
Dim iPOWERBROADCAST_SETTING As POWERBROADCAST_SETTING
If wParam = PBT_POWERSETTINGCHANGE Then
CopyMemory iPOWERBROADCAST_SETTING, ByVal lParam, 24
If iPOWERBROADCAST_SETTING.Data(0) = 0 Then
RaiseEvent Change(False) '"Monitor ON"
Else
RaiseEvent Change(True) '"Monitor OFF"
End If
End If
End If
ElseIf iMsg = WM_DESTROY Then
StopNotify
ElseIf iMsg = WM_TIMER Then
KillTimer mWnd, mTimerHandle
mTimerHandle = 0
End If
End Function
Public Sub StopNotify()
If mNotifyHandle <> 0 Then
UnregisterPowerSettingNotification mNotifyHandle
mNotifyHandle = 0
End If
If mWnd <> 0 Then
Call RemoveWindowSubclass(mWnd, mPtrMWndProc, mWnd)
DestroyWindow mWnd
mWnd = 0
End If
If mTimerHandle <> 0 Then
KillTimer mWnd, mTimerHandle
mTimerHandle = 0
End If
mStarted = False
End Sub
Private Sub Class_Terminate()
StopNotify
End Sub
Code:
Option Explicit
Private Declare Function GetMem4 Lib "msvbvm60.dll" (ByRef Source As Any, ByRef Dest As Any) As Long
Public Function MWindowProc(ByVal hwnd As Long, ByVal iMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal uIdSubclass As Long, ByVal dwRefData As Long) As Long
Dim iObj As cPowerChangeNotification
GetMem4 dwRefData, iObj
iObj.MyWindowProc hwnd, iMsg, wParam, lParam
GetMem4 0&, iObj
End Function