Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get notified of monitor re-activate? I don't get a WM_SYSCOMMAND message when monitor is turned on again

Tags:

winapi

vb6

I need to track the monitor getting to sleep and awaking from sleep (energy saving):

Private Const SC_MONITORPOWER = &HF170&
Private Const MONITOR_OFF = 2&
Private Const MONITOR_ON = -1&
Private Const MONITOR_STANDBY = 1&

Here is my subclassing code:

If (uMsg = WM_SYSCOMMAND) Then
    If (wParam = SC_MONITORPOWER) Then
        If (lParam = MONITOR_OFF) Then
            'I do receive this event!
            Debug.Print("Monitor is turned off")
        ElseIf (lParam = MONITOR_ON) Then
            Stop 'This is never called
        Else
            Stop 'This is never called
        End If
    End If
End If

If the monitor goes to sleep, a WM_SYSCOMMAND message is broadcast.

However, I don't get a WM_SYSCOMMAND when the monitor is turned on again (for example by moving the mouse).

How do I track then monitor gets re-activated / turned on again?

What am I doing wrong?

Thank you!

like image 750
tmighty Avatar asked Sep 27 '21 10:09

tmighty


1 Answers

Per the documentation:

In WM_SYSCOMMAND messages, the four low-order bits of the wParam parameter are used internally by the system. To obtain the correct result when testing the value of wParam, an application must combine the value 0xFFF0 with the wParam value by using the bitwise AND operator.

You are not doing that, so it is possible that you are not detecting SC_MONITORPOWER properly when the monitor is turned on, if other system flags are also present in the wParam.

Try this instead:

If (uMsg = WM_SYSCOMMAND) Then
    If ((wParam And &HFFF0) = SC_MONITORPOWER) Then
        If (lParam = MONITOR_OFF) Then
            Debug.Print("Monitor is turned off")
        ElseIf (lParam = MONITOR_ON) Then
            Debug.Print("Monitor is turned on")
        Else
            Debug.Print("Monitor is on standby")
        End If
    End If
End If

UPDATE: however this is moot, as you say you are not even getting a WM_SYSCOMMAND message when the monitor is turned on. In that case, try registering for Power Events, requesting to receive change notifications for either GUID_MONITOR_POWER_ON or GUID_CONSOLE_DISPLAY_STATE (Win8+):

GUID_CONSOLE_DISPLAY_STATE

6FE69556-704A-47A0-8F24-C28D936FDA47

The current monitor's display state has changed.

Windows 7, Windows Server 2008 R2, Windows Vista and Windows Server 2008: This notification is available starting with Windows 8 and Windows Server 2012.

The Data member is a DWORD with one of the following values.

0x0 - The display is off.

0x1 - The display is on.

0x2 - The display is dimmed.

GUID_MONITOR_POWER_ON

02731015-4510-4526-99E6-E5A17EBD1AEA

The primary system monitor has been powered on or off. This notification is useful for components that actively render content to the display device, such as media visualization. These applications should register for this notification and stop rendering graphics content when the monitor is off to reduce system power consumption. The Data member is a DWORD that indicates the current monitor state.

0x0 - The monitor is off.

0x1 - The monitor is on.

Windows 8 and Windows Server 2012: New applications should use GUID_CONSOLE_DISPLAY_STATE instead of this notification.

Your window will then receive a WM_POWERBROADCAST(PBT_POWERSETTINGCHANGE) message whenever the requested monitor state changes.

like image 158
Remy Lebeau Avatar answered Oct 19 '22 12:10

Remy Lebeau