Programmatically prevent Windows screensaver from

2019-01-11 03:28发布

Is there a recommended way to prevent the Windows screensaver from starting? The closest thing I've found is this article, but what I would really like to do is just tell Windows that the computer isn't idle rather than fooling with the currently set screensaver values.

10条回答
一夜七次
2楼-- · 2019-01-11 03:57

Subtle. The official way to tell Windows that the system is not idle is SetThreadExecutionState. This resets the idle timer, (or turns it off, if you pass ES_CONTINUOUS ). However, even though SetThreadExecutionState resets the idle timer, it does not stop the screensaver!

查看更多
再贱就再见
3楼-- · 2019-01-11 03:58

This blog post details what you need to do in C++.

The actual code snippet from the website:

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  switch (uMsg)                  
  {
    case WM_SYSCOMMAND:
    {
      switch (wParam)
      {
        case SC_SCREENSAVE:  
          return 0;
        case SC_MONITORPOWER:
          return 0;      
      }
      break;      
    }

    case WM_CLOSE:                
    {
      PostQuitMessage(0);            
      return 0;        
    }
  }
  return DefWindowProc(hWnd,uMsg,wParam,lParam);

}

查看更多
混吃等死
4楼-- · 2019-01-11 03:59

I use Mouse Jiggler to reset the idle state. This gets around a Group Policy that tends to start my screensaver (and lock the machine) at inopportune times: when I'm reading a long document, studying a complex chunk of code, or talking/listening/not-constantly-typing during a meeting.

As it can be slightly annoying to have the mouse jump 1px diagonally every second, I intend to use AutoHotKey to write a script that does basically the same thing, but only after a configured keyboard/mouse idle timeout, and maybe use the Shift key (or Scroll Lock) instead of a mouse move.

查看更多
干净又极端
5楼-- · 2019-01-11 04:01

From MSDN:

Windows does not start the screen saver if any of the following conditions exist:

  • The active application is not a Windows-based application.
  • A CBT window is present.
  • The active application receives the WM_SYSCOMMAND message with the wParam parameter set to the SC_SCREENSAVE value, but it does not pass the message to the DefWindowProc function.

There's a caveat though:

Windows Vista and later: If password protection is enabled by policy, the screen saver is started regardless of what an application does with the SC_SCREENSAVE notification.

That seems to apply even if you use the SetThreadExecutionState with ES_CONTINUOUS.

So, if it weren't for the caveat, your choices would be:

  1. SetThreadExecutionState with ES_CONTINUOUS (as described in other answers).
  2. Put up a computer-based training window (which requires hooks).
  3. Don't let the WM_SYSCOMMAND with SC_SCREENSAVE be passed onto DefWindowProc. (Assuming you care only when your application is the active application.)
  4. Install a dongle that simulates mouse jiggle.

The last option is nice in that it works even with the password protection policy.

查看更多
登录 后发表回答