c# How to get the events when the screen/display goes to power OFF or ON?

前端 未结 4 1007
隐瞒了意图╮
隐瞒了意图╮ 2020-12-13 15:33

Hi I have been searching but I can\'t find the answer. How do I know when the screen is going off or on. Not the SystemEvents.PowerModeChanged . I dont know how to retrieve

4条回答
  •  暗喜
    暗喜 (楼主)
    2020-12-13 16:28

    This works for me even MainWindow is hidden. The code is based on above post, and C++ code of https://www.codeproject.com/Articles/1193099/Determining-the-Monitors-On-Off-sleep-Status.

    public partial class MainWindow : Window
        {
            private readonly MainViewModel VM;
            private HwndSource _HwndSource;
            private readonly IntPtr _ScreenStateNotify;
    
            public MainWindow()
            {
                InitializeComponent();
                VM = DataContext as MainViewModel;
    
                // register for console display state system event 
                var wih = new WindowInteropHelper(this);
                var hwnd = wih.EnsureHandle();
                _ScreenStateNotify = NativeMethods.RegisterPowerSettingNotification(hwnd, ref NativeMethods.GUID_CONSOLE_DISPLAY_STATE, NativeMethods.DEVICE_NOTIFY_WINDOW_HANDLE);
                _HwndSource = HwndSource.FromHwnd(hwnd);
                _HwndSource.AddHook(HwndHook);
            }
    
            private IntPtr HwndHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
            {
                // handler of console display state system event 
                if (msg == NativeMethods.WM_POWERBROADCAST)
                {
                    if (wParam.ToInt32() == NativeMethods.PBT_POWERSETTINGCHANGE)
                    {
                        var s = (NativeMethods.POWERBROADCAST_SETTING) Marshal.PtrToStructure(lParam, typeof(NativeMethods.POWERBROADCAST_SETTING));
                        if (s.PowerSetting == NativeMethods.GUID_CONSOLE_DISPLAY_STATE)
                        {
                            VM?.ConsoleDisplayStateChanged(s.Data);
                        }
                    }
                }
    
                return IntPtr.Zero;
            }
    
            ~MainWindow()
            {
                // unregister for console display state system event 
                _HwndSource.RemoveHook(HwndHook);
                NativeMethods.UnregisterPowerSettingNotification(_ScreenStateNotify);
            }
        }
    

    And Native methods here:

    internal static class NativeMethods
    {
        public static Guid GUID_CONSOLE_DISPLAY_STATE = new Guid(0x6fe69556, 0x704a, 0x47a0, 0x8f, 0x24, 0xc2, 0x8d, 0x93, 0x6f, 0xda, 0x47);
        public const int DEVICE_NOTIFY_WINDOW_HANDLE = 0x00000000;
        public const int WM_POWERBROADCAST = 0x0218;
        public const int PBT_POWERSETTINGCHANGE = 0x8013;
    
        [StructLayout(LayoutKind.Sequential, Pack = 4)]
        public struct POWERBROADCAST_SETTING
        {
            public Guid PowerSetting;
            public uint DataLength;
            public byte Data;
        }
    
        [DllImport(@"User32", SetLastError = true, EntryPoint = "RegisterPowerSettingNotification", CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr RegisterPowerSettingNotification(IntPtr hRecipient, ref Guid PowerSettingGuid, Int32 Flags);
    
    
    
        [DllImport(@"User32", SetLastError = true, EntryPoint = "UnregisterPowerSettingNotification", CallingConvention = CallingConvention.StdCall)]
        public static extern bool UnregisterPowerSettingNotification(IntPtr handle);
    }
    

提交回复
热议问题