繁体   English   中英

打开/关闭监视器

[英]Turn on/off monitor

是否可以通过代码(C#)以编程方式打开/关闭监视器?

你甚至尝试过谷歌搜索吗?

第一次点击: http : //www.codeproject.com/KB/cs/Monitor_management_guide.aspx

您需要使用 Windows 提供的某些 DLL,我并不感到惊讶。

(我猜您需要一个 C# 解决方案,因为这是您应用的唯一标签)。

2013 年 2 月 8 日编辑:

有人提到该解决方案在 Windows 7 en 8 下不再有效。这是一个在 Windows 7 下运行良好的解决方案,还没有尝试过 Windows 8。

http://cocoa.ninja/posts/Turn-off-your-monitor-in-Csharp.html

namespace MonitorOff {

    public enum MonitorState {
        MonitorStateOn = -1,
        MonitorStateOff = 2,
        MonitorStateStandBy = 1
    }

    public partial class Form1 : Form {
        [DllImport("user32.dll")]
        private static extern int SendMessage(int hWnd, int hMsg, int wParam, int lParam);

        public Form1() {
            InitializeComponent();
            SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
        }

        void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e) {
            SetMonitorInState(MonitorState.MonitorStateOff);
        }

        private void button1_Click(object sender, EventArgs e) {
            SetMonitorInState(MonitorState.MonitorStateOff);
        }

        private void SetMonitorInState(MonitorState state) {
            SendMessage(0xFFFF, 0x112, 0xF170, (int)state);
        }
    }
}

按下开/关按钮


如果你想在代码中做到这一点,显然这在 Win32 API 中是可能的:

SendMessage hWnd、WM_SYSCOMMAND、SC_MONITORPOWER、参数

其中 WM_SYSCOMMAND = 0x112 和 SC_MONITORPOWER = 0xF170 参数表示将监视器置于的模式: -1 :开 2 :关 1 :节能模式

hWnd 可以是任何窗口的句柄 - 所以如果你有一个表单,这样的东西应该可以工作

int WM_SYSCOMMAND = 0x112;
int SC_MONITORPOWER = 0xF170;

[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);

public static void Main(string[] args)
{
    Form f = new Form();
    bool turnOff = true;   //set true if you want to turn off, false if on
    SendMessage(f.Handle, WM_SYSCOMMAND, (IntPtr)SC_MONITORPOWER, (IntPtr)(turnOff ? 2 : -1));
}

注意我还没有真正尝试过这个......

上面的答案https://stackoverflow.com/a/713504/636189非常适合关闭 Windows 7/8 显示器,但不适用于唤醒它。 在这些系统上,您需要做一些像这样的hackish(如发现https://stackoverflow.com/a/14171736/636189 ):

[DllImport("user32.dll")]
static extern void mouse_event(Int32 dwFlags, Int32 dx, Int32 dy, Int32 dwData, UIntPtr dwExtraInfo);

private const int MOUSEEVENTF_MOVE = 0x0001;

private void Wake(){
mouse_event(MOUSEEVENTF_MOVE, 0, 1, 0, UIntPtr.Zero);
Sleep(40);
mouse_event(MOUSEEVENTF_MOVE, 0, -1, 0, UIntPtr.Zero);
}

对于想要在控制台应用程序上使用此功能的人:

using System;
using System.Runtime.InteropServices;
using System.Timers;

namespace TurnScreenOFF
{
    class Program
    {
        private static int WM_SYSCOMMAND = 0x0112;
        private static uint SC_MONITORPOWER = 0xF170;

        public static void Main(string[] args)
        {
            SendMessage(GetConsoleWindow(), WM_SYSCOMMAND, (IntPtr)SC_MONITORPOWER, (IntPtr)2);
        }

        [DllImport("kernel32.dll")]
        static extern IntPtr GetConsoleWindow();

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);
    }
}

适应和测试。 100% 在 Windows 8 上工作。

此代码可用于打开和关闭。它也适用于 Windows 7。

   private int SC_MONITORPOWER = 0xF170;

    private uint WM_SYSCOMMAND = 0x0112;

    [DllImport("user32.dll")]
    static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);



    enum MonitorState
    {
        ON = -1,
        OFF = 2,
        STANDBY = 1
    }
    private void SetMonitorState(MonitorState state)
    {
        Form frm = new Form();

        SendMessage(frm.Handle, WM_SYSCOMMAND, (IntPtr)SC_MONITORPOWER, (IntPtr)state);

    }

要调用该函数,您必须执行以下操作:

SetMonitorState(MonitorState.ON);

或者

SetMonitorState(MonitorState.OFF);

注意:此代码在 WPF 应用程序中进行了测试。 使用以下命名空间:

using System.Runtime.InteropServices;
using System.Windows.Forms;

我找不到复制粘贴示例,所以自己创建了一个,不要忘记添加对 System.Windows.Forms 的引用。

using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;


namespace monitor_on_off
{
    class Program
    {
        [DllImport("user32.dll")]
        static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
        [DllImport("user32.dll")]
        static extern void mouse_event(Int32 dwFlags, Int32 dx, Int32 dy, Int32 dwData, UIntPtr dwExtraInfo);

        private const int WmSyscommand = 0x0112;
        private const int ScMonitorpower = 0xF170;
        private const int MonitorShutoff = 2;
        private const int MouseeventfMove = 0x0001;

        public static void MonitorOff(IntPtr handle)
        {
            SendMessage(handle, WmSyscommand, (IntPtr)ScMonitorpower, (IntPtr)MonitorShutoff);
        }

        private static void MonitorOn()
        {
            mouse_event(MouseeventfMove, 0, 1, 0, UIntPtr.Zero);
            Thread.Sleep(40);
            mouse_event(MouseeventfMove, 0, -1, 0, UIntPtr.Zero);
        }

        static void Main()
        {
            var form = new Form();

            while (true)
            {
                MonitorOff(form.Handle);
                Thread.Sleep(5000);
                MonitorOn();
                Thread.Sleep(5000);
            }
        }
    }
}

我已经完成了每个人发布的让显示器进入睡眠状态并稍后在其他时间唤醒它的每一种方法。 授予SendMessage()确实适用于 Windows XP,但在监视器休眠一段时间后它不会唤醒监视器。 我曾尝试使用 C#、DOS、用于处理电源配置文件的脚本和 Powershell。 最终我放弃了并回到了起点,我的第一个想法被证明是正确的。 您需要在关闭监视器后使用PostMessage() ,更好的是,您应该始终使用PostMessage()


所以你之前看到的所有代码都是正确的,而是使用以下代码:

using System.Runtime.InteropServices;
[DllImport("user32.dll")]
static extern IntPtr PostMessage(int hWnd, int msg, int wParam, int lParam);
PostMessage(-1, WM_SYSCOMMAND, SC_MONITORPOWER, MONITOR_OFF);

在执行和正常工作的这个时候(2015 年 5 月 11 日)我正在运行

  • Windows 7 专业版 6.1.7601 Service Pack 1 Build 7601
  • Visual Studio Professional 2013 版本 12.0.31101.00 更新 4
  • .NET 框架 4.5.51209
  • C#

我的系统是完全最新的。

SLOC最少的答案:

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

static class Program
{
    [DllImport("user32.dll")]
    static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);

    [STAThread]
    static void Main()
    {
        SendMessage(new Form().Handle, 0x0112, 0xF170, 2);
    }
}

对于 Windows 10(在 Pro 64 位上测试),我能够使用本页中提到的SendMessage()技术关闭显示器。 但是,我不可能重新打开显示器:“鼠标移动”技巧不起作用, SendMessage()技术会将屏幕重新打开一秒钟然后关闭,并且使用PostMessage()没有任何改变。

但诀窍实际上非常简单,我所要做的就是使用SendKeys()模拟按键。 我在这里使用 ALT 是因为它本身对系统没有影响,但它可以是任何其他键。

SendKeys.SendWait("%");

如果您不使用 Windows.Forms, 使用SendInput()发送“ALT”也有效,但实现时间更长。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM