c#, Как получить события, когда экран/дисплей идет для выключений или НА?

Привет я искал, но я не могу найти ответ. Как я знаю, когда экран уходит или на. Не SystemEvents. PowerModeChanged. Я не знаю, как получить СОБЫТИЯ дисплея/экрана

 private const int WM_POWERBROADCAST     = 0x0218;
        private const int WM_SYSCOMMAND         = 0x0112;
        private const int SC_SCREENSAVE         = 0xF140;
        private const int SC_CLOSE              = 0xF060; // dont know
        private const int SC_MONITORPOWER       = 0xF170;
        private const int SC_MAXIMIZE           = 0xF030; // dont know
        private const int MONITORON = -1;
        private const int MONITOROFF = 2;
        private const int MONITORSTANBY = 1; 
[DllImport("user32.dll")]
        //static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
        private static extern int SendMessage(IntPtr hWnd, int hMsg, int wParam, int lParam);
        public void Init(Visual visual)
        {
            SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
            HwndSource source = ((HwndSource)PresentationSource.FromVisual(visual));
            source.AddHook(MessageProc);
            Handle = source.Handle;

        }
public void SwitchMonitorOff()
        { // works
                SendMessage(Handle, WM_SYSCOMMAND, SC_MONITORPOWER, MONITOROFF);
        }
        public  void SwitchMonitorOn()
        {// works
            SendMessage(Handle, WM_SYSCOMMAND, SC_MONITORPOWER, MONITORON);
        }
        public  void SwitchMonitorStandBy()
        {// works
            SendMessage(Handle, WM_SYSCOMMAND, SC_MONITORPOWER, MONITORSTANBY);
        }

 private IntPtr MessageProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {


             if (msg == WM_SYSCOMMAND) //Intercept System Command
            {
                // not finished yet
                // notice the 0xFFF0 mask, it's because the system can use the 4 low order bits of the wParam 
                // value as stated in the MSDN library article about WM_SYSCOMMAND.
                int intValue = wParam.ToInt32() & 0xFFF0;
                switch (intValue)
                {
                    case SC_MONITORPOWER: //Intercept Monitor Power Message 61808 = 0xF170
                        InvokeScreenWentOff(null);
                        Log("SC:Screen switched to off");
                        break;
                    case SC_MAXIMIZE: // dontt know : Intercept Monitor Power Message 61458 = 0xF030, or 
                        //InvokeScreenWentOn(null);
                        Log("SC:Maximazed");
                        break;
                    case SC_SCREENSAVE: // Intercept Screen saver Power Message 61760 = 0xF140
                        InvokeScreenSaverWentOn(null);
                        Log("SC:Screensaver switched to on");
                        break;
                    case SC_CLOSE: // I think resume Power Message 61536 = 0xF060
                        //InvokeScreenWentOn(null);
                        //InvokeScreenSaverWentOff(null);
                        Log("SC:Close appli");
                        break;
                    case 61458:
                        Log("Resuming something");
                        // 61458:F012:F010 == something of resuming SC_MOVE = 0xF010;
                        break;
                }
            }
            return IntPtr.Zero;
        }  

Править

Возможно, я могу объяснить свое содержание, таким образом, существует, возможно, лучшее решение. У меня есть Двойная привязка сервисная работа WCF. Это работает на Archos (портативный планшетный ПК). Я хочу это, когда пользователь прекратил работать в течение времени простоя, соединение закрывает immediatly, и когда компьютер возвращается из неактивного, он повторно подключает immediatly. Идея Приложения, Неактивного на проекте Кода от Tom уже, является хорошей идеей. Чем меньше потребляемой мощности, тем лучше. Запуск должен быть максимально быстро.

13
задан Manu 7 February 2010 в 17:21
поделиться

1 ответ

Загляните в этот блог здесь , который поможет вам делать то, что вы пытаетесь достичь. Кроме того, вам нужно создать собственное событие, чтобы сделать это для вас примерно так:

public enum PowerMgmt{
    StandBy,
    Off,
    On
};

public class ScreenPowerMgmtEventArgs{
    private PowerMgmt _PowerStatus;
    public ScreenPowerMgmtEventArgs(PowerMgmt powerStat){
       this._PowerStatus = powerStat;
    }
    public PowerMgmt PowerStatus{
       get{ return this._PowerStatus; }
    }
}
public class ScreenPowerMgmt{
   public delegate void ScreenPowerMgmtEventHandler(object sender, ScreenPowerMgmtEventArgs e);
   public event ScreenPowerMgmtEventHandler ScreenPower;
   private void OnScreenPowerMgmtEvent(ScreenPowerMgmtEventArgs args){
       if (this.ScreenPower != null) this.ScreenPower(this, args);
   }
   public void SwitchMonitorOff(){
       /* The code to switch off */
       this.OnScreenPowerMgmtEvent(new ScreenPowerMgmtEventArgs(PowerMgmt.Off));
   }
   public void SwitchMonitorOn(){
       /* The code to switch on */
       this.OnScreenPowerMgmtEvent(new ScreenPowerMgmtEventArgs(PowerMgmt.On));
   }
   public void SwitchMonitorStandby(){
       /* The code to switch standby */
       this.OnScreenPowerMgmtEvent(new ScreenPowerMgmtEventArgs(PowerMgmt.StandBy));
   }

}

Изменить: Поскольку Ману не знал, как получить события, это редактирование будет включать пример кода как использовать этот класс, как показано ниже.

Using System;
Using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.Interop;
using System.Text;

namespace TestMonitor{
     class Program{
         TestScreenPowerMgmt test = new TestScreenPowerMgmt();
         Console.WriteLine("Press a key to continue...");
         Console.ReadKey();
     }

     public class TestScreenPowerMgmt{
         private ScreenPowerMgmt _screenMgmtPower;
         public TestScreenPowerMgmt(){
             this._screenMgmtPower = new ScreenPowerMgmt;
             this._screenMgmtPower.ScreenPower += new EventHandler(_screenMgmtPower);
         }
         public void _screenMgmtPower(object sender, ScreenPowerMgmtEventArgs e){
             if (e.PowerStatus == PowerMgmt.StandBy) Console.WriteLine("StandBy Event!");
             if (e.PowerStatus == PowerMgmt.Off) Console.WriteLine("Off Event!");
             if (e.PowerStatus == PowerMgmt.On) Console.WriteLine("On Event!");
         }

     }
}

Посмотрев на этот код и поняв, что что-то не так, меня осенило, что Ману искал способ опросить систему, чтобы определить состояние питания монитора, которое недоступно, но код показывает, что программно монитор можно включить / выключить / перейти в режим ожидания, одновременно инициируя событие, но он хотел, чтобы он мог подключиться к WndProc формы и обработать сообщение, указывающее статус Монитора ... а теперь я собираюсь высказать свое мнение по этому поводу.

Я не уверен на 100%, можно ли это сделать, или действительно ли Windows отправляет широковещательное сообщение вроде «Эй! Монитор собирается спать »или« Эй! Монитор включается », я боюсь сказать, что мониторы на самом деле не отправляют программный сигнал в Windows, чтобы сообщить, что он переходит в спящий режим / выключение / включение. Теперь, если у кого-то есть предложения, подсказки, подсказки по этому поводу, не стесняйтесь оставлять свой комментарий ...

Программное обеспечение Energy Star как часть вкладки ScreenSaver, которая открывается, когда вы щелкаете правой кнопкой мыши по рабочему столу в любом месте, появляется всплывающее меню, щелкает левой кнопкой мыши на «Свойства», появляется диалоговое окно «Дисплей» с разными На страницах вкладок щелкните левой кнопкой мыши «Заставка экрана», нажмите кнопку «Питание» как часть группового окна «Мощность монитора», эта часть диалогового окна каким-то образом запускает подсистему Windows (видеокарта? / драйвер Energy Star?) отправить аппаратный сигнал для включения функции энергосбережения самого монитора ... (На новых мониторах эта функция не включена по умолчанию, AFAIK ... не стесняйтесь отбросить это понятие ...)

Если нет недокументированный API где-то встроен и похоронен глубоко в программном драйвере Energy-Power (API определенно запускается в отношении того, как нажатие кнопки `` Power '' отправляет этот сигнал на монитор, в котором режим Power действительно активируется в результате !) затем, возможно, запустив поток в фоновом режиме указанной формы приложение, опрос для проверки этого еще, неизвестная функция или API для проверки состояния питания - там должно быть что-то, о чем знает только Microsoft ... в конце концов, Energy Star показала Microsoft, как запустить режим энергосбережения на самом мониторе , неужели это не улица с односторонним движением? или это так?

Извини, Ману, если я больше не мог помочь ....: (

Edit # 2: Я подумал о том, что написал ранее в редактировании, и немного покопался в поисках ответа, и я думаю, что нашел ответ, но сначала у меня возникла мысль моя голова, посмотрите этот документ здесь - документ в формате pdf с 'terranovum.com', ключ (или я так думал ...) был в реестре, используя последние два ключа реестра на последней странице документа содержит указанное смещение в количестве секунд, и в сочетании с этой статьей CodeProject , чтобы узнать время простоя, было бы легко определить, когда монитор переходит в режим ожидания, звучит просто или поэтому я подумал, что Ману тоже не понравится эта идея ....

Дальнейшее исследование с Google привело меня к такому выводу, ответ заключается в расширении спецификации VESA BIOS DPMS (Display Power Management Signaling), теперь возникает вопрос, как вы запрашиваете эту сигнализацию на V ESA bios, в настоящее время многие современные видеокарты оснащены VESA Bios, поэтому где-то должен быть аппаратный порт, где вы можете считывать значения контактов, использование этого маршрута потребует использования InpOut32 или, если у вас 64-битная Windows, есть InpOut64 через pinvoke. В принципе, если вы можете вспомнить использование Turbo C или Turbo Pascal (оба 16-битных для DOS), была процедура, называемая inport / outport или аналогичная для чтения аппаратного порта, или даже GWBASIC с использованием peek / poke.Если адрес аппаратного порта может быть найден, то значения можно запросить, чтобы определить, находится ли монитор в режиме ожидания / выключен / приостановлен / включен, путем проверки горизонтальной синхронизации и вертикальной синхронизации, это, на мой взгляд, более надежное решение. ..

Извиняюсь за длинный ответ, но я чувствовал, что должен записать свои мысли ....

Есть еще надежда, Ману :);)

8
ответ дан 2 December 2019 в 01:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: