使用NativeWindow禁用屏幕保护程序

时间:2010-07-05 06:58:46

标签: c# winforms

我想禁用屏幕保护程序并关闭电源。在这个阶段,没有窗户形式,我可以。因此,我不想使用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);
    }
}

问题是,没有使用WM_SYSCOMMAND调用WndProc。实际上,WndProc被称为4次。在最后一次调用时,有msg.Msg == WM_CREATE。

我想我缺少一些创建参数。有人有建议吗?

问候迈克尔

更新

我在非STA线程中运行代码。因此,窗口没有显示任何消息,而不是初始消息。现在我收到了WM_SYSCOMMAND消息。但是当屏幕保护程序激活时,没有消息。

我还尝试用相同的结果覆盖Form的WndProc。但这曾经在Windows XP中运行。 Windows 7中是否有变化?

操作系统:Windows 7 64位。

作为此Question个州的评论,只有前景窗口可以取消屏幕保护程序。因此上面的代码无法工作。 NativeWindow非常适合接收消息,但不适用于取消屏幕保护程序。对于后者,我建议回答这个问题。

3 个答案:

答案 0 :(得分:6)

执行此操作的正确方法是告诉Windows您的线程需要激活显示。常用于视频播放器。 P /调用SetThreadExecutionState()API函数,传递ES_DISPLAY_REQUIRED。并且ES_SYSTEM_REQUIRED可防止机器自动关闭。访问pinvoke.net获取所需的声明。

答案 1 :(得分:0)

根据this KB article

,禁用屏幕保护程序要容易得多
  

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

SystemParametersInfo( SPI_SETSCREENSAVEACTIVE,
                      FALSE,
                      0,
                      SPIF_SENDWININICHANGE
                    );
     

[...]

     

如果您需要再次启动屏幕保护程序,则需要重新初始化超时期限。通过[c] alling SystemParametersInfo (SPI_SETSCREENSAVEACTIVE, TRUE, 0, SPIF_SENDWININICHANGE)执行此操作。

答案 2 :(得分:0)

您可以尝试覆盖DefWndProc

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

我现在不在Windows机器上,所以我无法测试。如果有效,请告诉我。