C#中如何获得事件的时候,屏幕/显示器进入关闭电源或ON? [英] c# How to get the events when the screen/display goes to power OFF or ON?

查看:2661
本文介绍了C#中如何获得事件的时候,屏幕/显示器进入关闭电源或ON?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好我一直在寻找,但我无法找到答案。我怎么知道什么时候屏幕会关闭或打开。不是SystemEvents.PowerModeChanged。
我不知道如何来检索画面/屏幕活动

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 the display/screen EVENTS

 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(便携式平板电脑)。我想,当用户停止的空闲时间工作,连接立刻关闭,当计算机从空闲状态回来了,他立刻重新连接。 应用从汤姆代码项目空闲的想法已经是一个不错的主意。在更低的功耗,更好。 。启动必须尽可能快

Perhaps I can explain my intension, so there is perhaps a better solution. I have a Dual binding WCF service running on. It's running on an archos (portable tablet pc). I want that when the user stopped working for an idle time, the connection closes immediatly, and when the computer is returning from idle, he reconnects immediatly. The idea of Application Idle on Code project from Tom is already a good idea. The less power consumption , the better. The startup must be as fast as possible.

推荐答案

有一个看这个博客的here~~V 这将帮助你做你想达到什么目的。另外,你需要做一个自定义事件来为你做这个是这样的:

Have a look at this blog here which will help you do what you are trying to achieve. In addition you need to make a custom event to do this for you something like this:

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));
   }

}

修改 马努不知道如何检索事件,此修改将包括关于如何使用如下图所示这个类的示例代码。

As Manu was not sure how to retrieve the events, this edit will include a sample code on how to use this class as shown below.

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 挂钩的一种形式,并处理信息,指示监视器的状态...现在,在这一点上,我要表达我对这个的看法。

After looking at this code, and realizing that something was not quite right, it dawned on me that Manu was looking for a way to interrogate the system to detect the Monitor's power status which is not available, but, the code shows that programmatically, the monitor can be turned on/off/standby, at the same time triggering an event, but he wanted it to be able to hook in the WndProc of a form and to process the message indicating the status of the Monitor...now, at this point, I am going to express my opinion on this.

我不是100%肯定,如果这是可以做到还是Windows实际上发送广播消息,说像'嘿!显示器进入睡眠或嗨!显示器加电,恐怕说,这显示器并不实际发送一些软件信号到Windows,通知它睡觉/ OFF / ON。现在,如果任何人有关于它的建议,提示,线索,随意张贴您的评论...

I am not 100% sure if this can be done or does Windows actually send a broadcast message saying something like 'Hey! Monitor is going to sleep' or 'Hey! Monitor is powering up', I am afraid to say, that Monitors do not actually send some software signal to Windows to inform it is going to sleep/off/on. Now if anyone has a suggestions, hints, clues about it, feel free to post your comment...

能源之星软件作为屏幕保护程序标签的一部分被发现当你在桌面上右键单击任意位置,会出现一个弹出菜单,在属性,一个显示对话框出现时,用不同的标签页,在屏幕保护程序左键单击左键点击,点击电源按钮作为显示器电源分组框,对话框的那部分的一部分,不知何故会触发Windows子系统(显卡?/能源之星司机?)发送一个硬件信号,对显示器本身的省电功能切换。 ..(显示器是全新没有在默认情况下启用此功能AFAIK ...随意解雇这个概念......)

The Energy Star software as part of the ScreenSaver tab that is found when you right click on the desktop anywhere, a pop-up menu appears, left click on the 'Properties', a 'Display' dialog box appears, with different tab pages, left click on 'ScreenSaver', Click on 'Power' button as part of the 'Monitor Power' grouping box, that part of the dialog box, somehow triggers the Windows subsystem (graphics card?/Energy Star driver?) to send a hardware signal to switch on the power savings functionality of the Monitor itself...(Monitors that are brand new do not have this enabled by default AFAIK...feel free to dismiss this notion...)

除非有一个未公开的API某处嵌入式和能源功率软件驱动程序中深埋(API是绝对确实引发对如何在电源按钮,点击该信号发送到该电源模式确实得到激活,结果显示器!),那么也许,在该表格应用程序的后台运行一个线程,轮询询问该然而,未知功能或API来检查电源状态 - 必须有东西存在,只有微软知道...毕竟,能源之星显示微软如何触发电源监视器本身的省电模式,当然这不是一个单行道? ?抑或是

Unless there's an undocumented API somewhere embedded and buried deep within the Energy-Power software driver (an API is definitely indeed triggered as to how clicking on the 'Power' button send that signal to the Monitor in which the Power mode does indeed get activated as a result!) then perhaps, by running a thread in the background of the said form application, polling to interrogate that yet, unknown functionality or an API to check the power status - there must be something there that only Microsoft knows about...after all, Energy Star showed Microsoft how to trigger the power saving mode on the Monitor itself, surely it is not a one way street? or is it?

对不起马努 - 如果我不能进一步帮助....:(

Sorry Manu if I could not help further .... :(

编辑#2:我想到了我在编辑之前写的,并做了一些四处生根一个答案,我想我想出了答案,但首先,一个念头闪入我的头,请参阅本文档这里 - 从terranovum.com的PDF文档时,线索(或者,所以我想......)是在注册表中,使用文档的最后一页上的最后两个注册表项包含指定偏移量的秒数,并在此的CodeProject 文章,找出空闲时间,它会很容易确定当显示器进入待机状态,听起来很简单,我这样想着,马努也不会喜欢这种想法要么....

Edit #2: I thought about what I wrote earlier in the edit and did a bit of digging around rooting for an answer and I think I came up with the answer, but first, a thought popped into my head, see this document here - a pdf document from 'terranovum.com', the clue (or so I thought...) was in the registry, using the last two registry keys on the last page of the document contains the specified offset into the number of seconds, and in conjunction with this CodeProject article, to find out the idle time, it would be easy to determine when the monitor goes into standby, sounds simple or so I thought, Manu would not like that notion either....

与谷歌进一步的调查使我得出这一结论,答案就在的VESA BIOS 规范 DPMS (显示器电源管理信令),现在,由此产生的问题,是你如何询问,关于VESA BIOS信号,现在,很多现代的显卡有VESA BIOS装进去,所以必须有一个硬件端口的地方在那里你可以读取销的值,使用该路径将需要 InpOut32的使用或者如果你有64位Windows中,有一个 InpOut64 通过的PInvoke。基本上,如果你能记得使用的Turbo C和Turbo Pascal不同,(包括16位的DOS)有一个名为常规INPORT /输出端口或类似的阅读硬件端口,甚至GWBASIC使用偷看/捅。如果无法找到该硬件端口的地址,则值可以被询问,以确定显示器处于待机/关机/暂停/上通过检查水平同步和垂直同步,这个我认为是比较可靠的解决方案。 ..

Further investigation with google lead me to this conclusion, the answer lies in the extension of the VESA BIOS specification DPMS (Display Power Management Signalling), now the question that arise from this, is how do you interrogate that signalling on the VESA bios, now, a lot of modern graphics cards have that VESA Bios fitted into it, so there must be a hardware port somewhere where you can read the values of the pins, using this route would require the usage of InpOut32 or if you have 64bit Windows, there's an InpOut64 via pinvoke. Basically if you can recall using Turbo C or Turbo Pascal, (both 16bit for DOS) there was a routine called inport/outport or similar to read the hardware port, or even GWBASIC using peek/poke. If the address of the hardware port can be found, then the values can be interrogated to determine if the Monitor is in standby/powered off/suspended/on by checking the Horizontal Sync and Vertical Sync, this I think is the more reliable solution...

对于长的答案,但道歉觉得我不得不写下我的想法......

Apologies for the long answer but felt I had to write down my thoughts....

还是有希望有马努:);)

There's still hope there Manu :) ;)

这篇关于C#中如何获得事件的时候,屏幕/显示器进入关闭电源或ON?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆