Используйте NativeWindow, чтобы отключить заставку - PullRequest
2 голосов
/ 05 июля 2010

Я хочу отключить заставку и выключить монитор. На данном этапе нет оконной формы, которую я мог бы использовать. Поэтому я не хочу использовать NativeWindow.

Вот мой код

sealed class ObserverWindow : NativeWindow, IDisposable
{
    internal ObserverWindow()
    {
        this.CreateHandle(new CreateParams()
        {
            Parent= IntPtr.Zero
        });

    }

    public void Dispose()
    {
        DestroyHandle();
    }

    protected override void WndProc(ref Message msg)
    {
        if (msg.Msg == WM_SYSCOMMAND &&
            ((((long)msg.WParam & 0xFFF0) == SC_SCREENSAVE) ||
            ((long)msg.WParam & 0xFFF0) == SC_MONITORPOWER))
        {
            msg.Msg = 0;
            msg.HWnd = IntPtr.Zero;
        }
        base.WndProc(ref msg);
    }
}

Проблема в том, что WndProc не вызывается с WM_SYSCOMMAND. На самом деле WndProc вызывается 4 раза. При последнем звонке msg.Msg == WM_CREATE.

Я думаю, что мне не хватает некоторого параметра создания. Кто-нибудь есть совет?

С уважением, Майкл

UPDATE

Я выполнял код в потоке, отличном от STA. Таким образом, окно не показывало никаких сообщений, кроме начальных. Теперь я получаю сообщения WM_SYSCOMMAND. Но когда заставка активирована, сообщения нет.

Я также пытался переписать WndProc формы с тем же результатом. Но это работало в Windows XP. Есть ли изменения в Windows 7?

ОС: Windows 7 64bit.

РЕШЕНИЕ

Как комментарий в этом Вопросе , только экранное окно может отменить заставку Таким образом, приведенный выше код не может работать. NativeWindow отлично подходит для получения сообщений, но не для отмены заставки. Для последнего я рекомендую ответ на этот вопрос.

Ответы [ 3 ]

6 голосов
/ 06 июля 2010

Правильный способ сделать это - сообщить Windows, что в вашем потоке должен быть активен дисплей.Обычно используется видео плеерами.P / вызвать API-функцию SetThreadExecutionState (), передать ES_DISPLAY_REQUIRED.И ES_SYSTEM_REQUIRED, чтобы предотвратить автоматическое выключение машины.Посетите pinvoke.net для необходимых деклараций.

0 голосов
/ 05 июля 2010

Вместо этого вы можете попробовать переопределить DefWndProc.

public override void DefWndProc(ref Message msg)
{
    if (msg.Msg == WM_SYSCOMMAND &&
        ((((long)msg.WParam & 0xFFF0) == SC_SCREENSAVE) ||
        ((long)msg.WParam & 0xFFF0) == SC_MONITORPOWER))
    {
        msg.Msg = 0;
        msg.HWnd = IntPtr.Zero;
    }
    base.DefWndProc(ref msg);
}

Я сейчас не на Windows, поэтому не могу это проверить. Дайте мне знать, если это работает.

0 голосов
/ 05 июля 2010

Отключить заставку намного проще, согласно этой статье базы знаний :

Это легко сделать с помощью:

SystemParametersInfo( SPI_SETSCREENSAVEACTIVE,
                      FALSE,
                      0,
                      SPIF_SENDWININICHANGE
                    );

[...]

Если вам понадобится заставка для повторного запуска, вам нужно будет повторно инициализировать период ожидания. Сделайте это с помощью [c] alling SystemParametersInfo (SPI_SETSCREENSAVEACTIVE, TRUE, 0, SPIF_SENDWININICHANGE).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...