1

我正在尝试创建根据面部检测打开和关闭监视器的 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);所做的事情比我意识到的要多。

4

1 回答 1

0

因此,显然在 Win7 中,SendMessage(hwnd, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM) 2); 不仅会关闭屏幕,还会关闭屏幕保护程序(甚至无需先发送至少一条销毁消息)。没有简单的方法来破解这个。
参考:我发现了这个,它也导致了 msdn 的一些其他线程。(由于我的声誉,我现在无法链接......)

虽然我在上面的代码也不适用于 Win8,因为SendMessage(hwnd, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM) -1);在 Win8 中不会打开屏幕。然而,这应该很容易解决,就像在这个 C# workaround中一样。

于 2014-05-10T20:12:05.733 回答