Как программно запустить скрин сейвер?

Как известно, в Windows существуют системные команды (system commands), которые поступают в окно в виде сообщения WM_SYSCOMMAND. Идентификатор конкретной команды размещается в параметре wParam. Существуют команды SC_MOVE (перемещение окна), SC_SIZE (масштабирование окна) и т. д. Все эти команды "умеет" обрабатывать стандартная оконная процедура DefWindowProc, нужно только вызвать её с соответствующими параметрами.

Теперь осталось рассказть, что в Windows существует команда SC_SCREENSAVE, инициирующая запуск выбранного пользователем скрин сейвера. Всё, что тербуется от нас - это передать эту команду в оконную процедуру. Для этой цели можно послать собственному окну сообщение WM_SYSCOMMAND, а можно даже вызвать DefWindowProc напрямую, например:


// hWnd - дескриптор окна
PostMessage(hWnd, WM_SYSCOMMAND, SC_SCREENSAVE, 0);

или:


// hWnd - дескриптор окна
DefWindowProc(hWnd, WM_SYSCOMMAND, SC_SCREENSAVE, 0); 

В MFC указанные операции выполняются совершенно аналогично:


// используем CWnd::PostMessage
PostMessage(WM_SYSCOMMAND, SC_SCREENSAVE);

или:


// используем CWnd::DefWindowProc
DefWindowProc(WM_SYSCOMMAND, SC_SCREENSAVE, 0);

Осталось выяснить, что делать, если наше приложение вообще не создаёт окно. Оказывается, сгодится и окно рабочего стола (получить его HWND можно с помощью функции GetDesktopWindow), например:


::DefWindowProc(GetDesktopWindow(), WM_SYSCOMMAND, SC_SCREENSAVE, 0);