Windows C ++屏幕保护程序无法重新打开屏幕

时间:2014-05-09 21:56:47

标签: c++ winapi windows-screensaver screen-off

我正在尝试创建Windows屏幕保护程序,根据人脸检测打开和关闭显示器。这是必要的代码(c ++和winapi):

#define TIMER 1010
unsigned int FREQUENCY_OF_CHECK = 5000;
LRESULT WINAPI ScreenSaverProc(
     HWND hwnd, 
     UINT message, 
     WPARAM wParam, 
     LPARAM lParam)
{
  if(!fChildPreview)
  {
    switch(message) 
    {
      case WM_CREATE:
        //start timer
        SetTimer(hwnd, TIMER, FREQUENCY_OF_CHECK, NULL);
        //create transparent see thru layer
        SetWindowLong(
               hwnd, 
               GWL_EXSTYLE, 
               GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED
               );
        break;

      case WM_DESTROY:
        SendMessage(hwnd, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM) -1);
        KillTimer(hwnd, TIMER);
        break;

      case WM_TIMER:
        //separate process detects face and stores detection into registry
        if(!ProcessRunning("capture.exe")){
            ShellExecute(
               NULL,
               "open",
               "C:/camsaver/capture.exe",
               "",
               "", 
               SW_SHOWNOACTIVATE);
        }
        //load detection from registry and then turn monitor on/off
        bool face;
        readFaceFromRegistry(face);

        if (face){
            //turn monitor on
            SendMessage(hwnd, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM) -1);
        }
        else {
            //turn monitor off
            SendMessage(hwnd, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM) 2);
        }

        break;

      default:
        return DefScreenSaverProc(hwnd, message, wParam, lParam);
      }
    return 0;
  }
}

如果屏幕保护程序在没有检测到面部时自行运行,它只会关闭显示器并停止执行其他操作。我希望它继续运行并转动检测到脸部时重新开启屏幕。就像在预览模式下运行时一样 我的猜测是SendMessage(hwnd, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM) 2);行做了比我所知更多的事情。

1 个答案:

答案 0 :(得分:0)

显然在Win7中,SendMessage(hwnd, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM) 2); 不仅关闭了屏幕,还关闭了屏幕保护程序(甚至没有先打扰它至少发送一个destoy消息)。没有简单的方法可以解决这个问题。
参考:我发现了this,它也导致了msdn上的其他一些线程。 (由于我的声誉,我现在无法链接...)

当我在上面时,上面的代码不能用于Win8,因为SendMessage(hwnd, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM) -1);在Win8中没有打开屏幕。但是,这应该很容易解决,如this C# workaround