Заставка Windows C++ не включает экран снова

Я пытаюсь создать заставку 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 ответ

Решение

Так что судя по всему в Win7 SendMessage(hwnd, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM) 2); не только выключает экран, но и выключает экранную заставку (даже не удосужившись посылать ее хотя бы сначала в виде дестоя). Нет простого способа взломать это.
Ссылка: я нашел это, и это также приводит к некоторым другим потокам в msdn. (Который я не могу связать прямо сейчас из-за моей репутации...)

И хотя я на это, приведенный выше код не будет работать для Win8, потому что SendMessage(hwnd, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM) -1); не включается экран в Win8. Однако это должно быть легко решено, как в этом обходном пути C#.

Другие вопросы по тегам