关闭windows中的显示器

问题描述 投票:0回答:1

我需要在代码中关闭显示器。 我用谷歌搜索并找到了一些应该执行此操作的代码,但是当我运行它时,什么也没有发生,我只得到 0 WinAPI 结果。 我做错了什么?

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

    [DllImport("user32.dll")]
    private static extern IntPtr GetDesktopWindow();

    const int SC_MONITORPOWER = 0xF170;
    const int WM_SYSCOMMAND = 0x0112;
    const int MONITOR_OFF = 2;

    static void Main(string[] args)
    {
        Console.WriteLine(
            SendMessage( 
                GetDesktopWindow(), 
                WM_SYSCOMMAND, 
                (IntPtr) SC_MONITORPOWER, 
                (IntPtr) MONITOR_OFF));
        Console.WriteLine("Hello World!");
    }
}
winapi
1个回答
4
投票

摘自Raymond Chen的文章在黑暗中摸索并偶然发现错误的解决方案

桌面窗口是一个非常特殊的窗口并且通常应该避免,因为它的行为不像应用程序创建的窗口。特别是,作者尝试向桌面窗口发布消息。这曾经在“历史上开放的窗口管理器世界”中起作用,但安全性和稳健性问题已经优先于兼容性。

真正的解决方案是创建自己的窗口并向其发送消息,其他任何方法都是黑客。

如果你不介意黑客攻击,至少尝试找到一个合适的窗口:

[DllImport("user32.dll", SetLastError = false)] public static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); const int SC_MONITORPOWER = 0xF170; const int WM_SYSCOMMAND = 0x0112; const int MONITOR_OFF = 2; static void Main(string[] args) { IntPtr w; for (; IntPtr.Zero == (w = GetForegroundWindow());) System.Threading.Thread.Sleep(1000); PostMessage(w, WM_SYSCOMMAND, (IntPtr) SC_MONITORPOWER, (IntPtr) MONITOR_OFF); }

因为它是一种黑客攻击,所以有时它可能不起作用。在您发布消息之前,您借用的窗口可能会被销毁。您可能无权向其发送消息 (UAC)。或者它可能决定不将此消息传递给 
DefWindowProc

另一个稍微好一点的技巧是创建一个临时窗口:

[DllImport("user32.dll")] static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll")] static extern int DestroyWindow(IntPtr hWnd); [DllImport("user32.dll", SetLastError=true)] public static extern IntPtr CreateWindowEx(uint dwExStyle, string lpClassName, IntPtr cap, uint dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam); const int SC_MONITORPOWER = 0xF170; const int WM_SYSCOMMAND = 0x0112; const int MONITOR_OFF = 2; static void Main(string[] args) { IntPtr w = CreateWindowEx(0, "Button", IntPtr.Zero, 0, 0, 0, 0, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); if (w != IntPtr.Zero) { SendMessage(w, WM_SYSCOMMAND, (IntPtr) SC_MONITORPOWER, (IntPtr) MONITOR_OFF); DestroyWindow(w); } }

这仍然有点像黑客,因为它实际上从未发送消息。

© www.soinside.com 2019 - 2024. All rights reserved.