簡體   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