我的屏幕保护程序正在停止屏幕暂停,但我不希望它

Dra*_*rat 6 c# power-management c#-4.0

我在.Net 4.0中制作了一个屏幕保护程序.它基本上只是移动图像中的位并使用.Invalidate在计时器上显示它并覆盖onPaint事件.

到目前为止,它工作得很好 - 但是 - 我注意到它有一个问题.

它会在暂停超时后停止监视器暂停.自从我安装它以来,我的显示器现在全天候停留.

问题是,我没有采取任何措施来专门停止节电功能 - 而且我已经确保我的计算机的省电设置已经设置(它们是).所以我选择了另一个屏幕保护程序,以确保设置仍然有效.超时后监视器暂停.

我需要做些什么才能与电源管理配合使用?我在Google上搜索了这个答案,我发现的一切都是如何阻止电源管理而我没有明确阻止它!我只是想在适当的时候允许暂停.

Dra*_*rat 1

我能够让我的程序“玩得很好”。我不知道为什么它能起作用,而原始代码却不能,但这不仅起作用 - 它实际上使程序更加“节能”友好,因为它通过在屏幕挂起后不进行计算来减少 CPU 周期。简而言之,我预览 WndProc 消息并查找监视器正在挂起的消息,一旦收到消息,我就会停止重绘,直到它恢复(可以恢复并使屏幕保护程序仍然处于活动状态)。

代码更改:

    // Field Definitions
    /// <summary>
    /// Constants that relate to the WndProc messages we wish to intercept and evaluate.
    /// </summary>
    [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:FieldNamesMustNotContainUnderscore", Justification = "Standard practice to use this naming style for Win32 API Constants.")]
    private const int WM_SYSCOMMAND = 0x0112, SC_MONITORPOWER = 0xF170;

    /// <summary>
    /// Gets or sets whether we are suspended. Should coincide with whether the display is turned on or not.
    /// </summary>
    private bool isSuspended = false;


    // New overridden method
    /// <summary>
    /// Intercepts WndProc messages. We are looking for the screen suspend activity. From it, we will return that we are able to suspend and we ourselves will suspend.
    /// </summary>
    /// <param name="m">Message to be checked.</param>
    protected override void WndProc(ref Message m)
    {
        if (m.Msg == WM_SYSCOMMAND)
        {
            // The 0x000F bits are used to indicate the specific state and must be ignored to see if this is a monitor power event.
            if ((m.WParam.ToInt32() & 0xFFF0) == SC_MONITORPOWER)
            {
                switch (m.WParam.ToInt32() & 0x000F)
                {
                    case -1:
                        // Display powering on - resume operation
#if DEBUG
                        System.Diagnostics.Debug.WriteLine("Display powered on.");
#endif
                        this.isSuspended = false;
                        break;
                    case 0:
                    case 1:
                    case 2:
                        // Display being powered off - suspend operation
#if DEBUG
                        System.Diagnostics.Debug.WriteLine("Display suspended");
#endif
                        this.isSuspended = true;
                        break;
                    default:
#if DEBUG
                        System.Diagnostics.Debug.WriteLine(string.Format("Unknown power state: {0}", (m.WParam.ToInt32() & 0x000F).ToString("0")));
#endif
                        // Assuming that unknown values mean to power off. This is a WAG.
                        this.isSuspended = true;
                        break;
                }
            }
        }

        base.WndProc(ref m);
    }


    // Change to my refreshing timer.
    /// <summary>
    /// Called when the refresh timer ticks. This invalidates the form, forcing it to be redrawn, which creates a framerate for us.
    /// </summary>
    /// <param name="sender">Who called this method.</param>
    /// <param name="e">Event Arguments.</param>
    private void RefreshTimer_Tick(object sender, EventArgs e)
    {
        if (this.isSuspended)
        {
            // Program is in suspended mode, so don't do anything this update.
            return;
        }

        // Program is not suspended, so invalidate the client area so it can be painted again.
        this.Invalidate();
    }
Run Code Online (Sandbox Code Playgroud)

进行此更改会在调用挂起时停止所有重绘(并停止 GDI+ 计算),并且在进行更改后,屏幕保护程序将按照电源管理设置进行“行为”。

  • 非常酷 - 如果您不介意的话,我可能会使用它作为更改我们拥有的监控应用程序的模板,该应用程序在运行时会对数据库造成很大影响,并且当屏幕不显示时毫无意义。 (3认同)