C# 使用NativeWindow禁用屏幕保护程序

C# 使用NativeWindow禁用屏幕保护程序,c#,winforms,C#,Winforms,我想禁用屏幕保护程序并关闭显示器电源。在这个阶段没有windows窗体,我可以使用它。因此,我不想使用NativeWindow 这是我的密码 sealed class ObserverWindow : NativeWindow, IDisposable { internal ObserverWindow() { this.CreateHandle(new CreateParams() { Parent= IntPtr.Zer

我想禁用屏幕保护程序并关闭显示器电源。在这个阶段没有windows窗体,我可以使用它。因此,我不想使用NativeWindow

这是我的密码

sealed class ObserverWindow : NativeWindow, IDisposable
{
    internal ObserverWindow()
    {
        this.CreateHandle(new CreateParams()
        {
            Parent= IntPtr.Zero
        });

    }

    public void Dispose()
    {
        DestroyHandle();
    }

    protected override void WndProc(ref Message msg)
    {
        if (msg.Msg == WM_SYSCOMMAND &&
            ((((long)msg.WParam & 0xFFF0) == SC_SCREENSAVE) ||
            ((long)msg.WParam & 0xFFF0) == SC_MONITORPOWER))
        {
            msg.Msg = 0;
            msg.HWnd = IntPtr.Zero;
        }
        base.WndProc(ref msg);
    }
}
问题是WndProc不是用WM_SYSCOMMAND调用的。实际上,WndProc被调用了4次。最后一个调用是msg.msg==WM\u CREATE

我想我缺少了一些create参数。有人有什么建议吗

问候迈克尔

更新

我在非STA线程中运行代码。因此,除了最初的消息外,窗口没有显示任何消息。现在我正在接收WM_SYSCOMMAND消息。但是当屏幕保护程序被激活时,没有消息

我还试图用同样的结果覆盖表单的WndProc。但这在Windows XP中曾经起作用。Windows7有变化吗

操作系统:Windows7 64位

解决方案


在此状态下,作为注释,只有前台窗口可以取消屏幕保护程序。因此,上述代码无法工作。NativeWindow非常适合接收消息,但不适合取消屏幕保护程序。对于后者,我建议回答这个问题。

根据以下说明,禁用屏幕保护程序要容易得多:

这可以通过以下方式轻松完成:

SystemParametersInfo( SPI_SETSCREENSAVEACTIVE,
                      FALSE,
                      0,
                      SPIF_SENDWININICHANGE
                    );
[……]

如果需要再次启动屏幕保护程序,则需要重新初始化超时时间。通过[c]调用
系统参数info(SPI\u设置屏幕激活,TRUE,0,SPIF\u发送WinInChange)
完成此操作

您可以尝试重写


我现在不在Windows设备上,因此无法测试此功能。让我知道它是否有效。

正确的方法是告诉Windows您的线程需要激活显示。通常由视频播放器使用。P/调用SetThreadExecutionState()API函数,传递所需的显示。以及防止机器自动关闭所需的ES_系统_。请访问pinvoke.net获取所需声明。

FYI:Message number 1是
WM_CREATE
。这可能会做到,但我的意图是暂时禁用屏幕保护程序。您的方法将覆盖用户所做的任何更改。无论如何,我没有提到,我不想禁用节能也。太好了,这正是我要找的。
public override void DefWndProc(ref Message msg)
{
    if (msg.Msg == WM_SYSCOMMAND &&
        ((((long)msg.WParam & 0xFFF0) == SC_SCREENSAVE) ||
        ((long)msg.WParam & 0xFFF0) == SC_MONITORPOWER))
    {
        msg.Msg = 0;
        msg.HWnd = IntPtr.Zero;
    }
    base.DefWndProc(ref msg);
}