VB .NET - Desabilitando o protetor de tela do Windows


Os protetores de tela podem ser uma ferramenta útil para proteger o seu monitor e também uma alternativa visualmente mais agradável que as janelas abertas do windows quando o computador não estiver em uso; entretanto, para alguns tipos de software, é necessário desativar temporariamente o protetor de tela.

Neste artigo eu mostro como podemos desabilitar o protetor de tela do Windows.

Não existe uma classe específica na plataforma .NET que que pode ser usada para desativar o protetor de tela, mas sempre existe uma saída, e neste caso vamos ter que usar uma chamada uma função da API do Windows chamada "SetThreadExectionState" através da utilização da Plataform Invocation Services (P/Invoke).

A função SetThreadExecutionState permite que um aplicativo informe ao sistema que ele está em uso, evitando assim que o sistema entre no modo soneca, ative o protetor de tela ou desligue o monitor enquanto o aplicativo está sendo executado. Ela usa uma série de flags para especificar um novo estado para a thread atual.

Essas flags são definidas usando uma enumeração com o atributo Flags. Você pode usar o operador lógico OR para combinar diversas flags e especificar vários comportamentos com uma única chamada. A função retorna um valor composto das mesmas flags. O valor de retorno indica o estado anterior às mudanças que você solicitou ou retorna null se houver um erro.

As 4 enumerações para as flas do nosso interesse são:

  1. ES_DISPLAY_REQUIRED - Esta flag indica que o display esta em uso. Quando passada por si só o temporizador de inatividade do display é redefinido para zero. O temporizador é reiniciado e a proteção de tela será exibida na próxima vez que ele expirar;
  2. ES_SYSTEM_REQUIRED - Indica que o sistema esta inativo. Quando passada sozinha o temporizador de inatividade do sistema é redefinido para zero. O temporizador é reiniciado e a máquina vai entrar em repouso na próxima vez que ele expirar;
  3. ES_CONTINUOUS - Esta flag é usada para indicar que o comportamento das duas flags anteriores é continuo. Ao invés de resetar o temporizador de inatividade de imediato ele é desabilitado até que você informe o contrário. A utilização desta flag significa que você não precisa chamar a função SetThreadExecutionState repetidamente;
  4. ES_AWAYMODE_REQUIRED - Esta flag deve ser usada em combinação com a flag ES_CONTINUOUS. Se a máquina estiver configurada para permitir isso, isso significa que a thread requer o modo Away. Quando estiver neste modo o computador irá parecer repousar normalmente, porém a thread irá continuar a ser executada mesmo que o computador seja parcialmente suspenso. Como esta flag dá a falsa impressão de que o computador esta em estado de espera você deve usá-la somente quando for absolutamente necessário.

Obs: Chamando SetThreadExecutionState sem ES_CONTINUOUS simplesmente redefine o cronômetro de inatividade; para manter a tela ou o sistema no estado de trabalho, o segmento deve chamar SetThreadExecutionState periodicamente.

Para poder usar este recurso temos então que declarar a função e as definições das enumerações definidas acima.

Para executar corretamente, em um computador com gerenciamento de energia, aplicações tais como servidores de fax, secretárias eletrônicas, agentes de backup e gerenciamento de rede, devem usar tanto ES_SYSTEM_REQUIRED como ES_CONTINUOUS quando elas processam eventos.

Aplicações multimídia, como players de vídeo e aplicativos de apresentação, deve usar ES_DISPLAY_REQUIRED quando exibirem o vídeo por longos períodos de tempo sem entrada do usuário. Aplicações como processadores de texto, planilhas, navegadores e jogos, não precisam chamar SetThreadExecutionState.

O valor ES_AWAYMODE_REQUIRED deve ser usado somente quando absolutamente necessário por aplicativos de mídia que exigem que o sistema execute tarefas em segundo plano, tais como gravar conteúdo de televisão ou outra mídia de streaming para outros dispositivos, enquanto o sistema parece estar dormindo. Aplicações que não exigem processamento em segundo plano crítico ou que funcionam em computadores portáteis não devem habilitar o modo de espera (AWAY), porque impede a conservação de energia.

Para habilitar o modo AWAY, um aplicativo usa tanto ES_AWAYMODE_REQUIRED como ES_CONTINUOUS; para desativar este modo, um aplicativo chama SetThreadExecutionState usando ES_CONTINUOUS e limpa ES_AWAYMODE_REQUIRED.

Quando este modo é ativado, qualquer operação que iria colocar o computador para dormir o coloca em modo de espera. O computador parece estar dormindo, enquanto o sistema continua a executar tarefas que não exigem entrada do usuário. O modo de espera não afeta o temporizador de inatividade do modo soneca; para evitar que o sistema entre no modo soneca(sleep), quando o temporizador expirar, o aplicativo deve também definir o valor ES_SYSTEM_REQUIRED.

Obs: A função SetThreadExecutionState não pode ser usada para impedir que o usuário ponha o computador para dormir(modo sleep). As As aplicações devem respeitar o desejo do usuário que espera um determinado comportamento quando fecha a tampa de seu laptop ou pressiona o botão de energia.

Criando o projeto VB .NET

Vamos abrir o Visual Basic 2010 Express Edition e criar um novo projeto Windows Forms Application com o nome DesabilitarProtetorTela;

No formulário padrão vamos incluir apenas dois botões de comando: btnDesabilita e btnHabilita.

A primeira coisa que devemos fazer é declarar o namespace System.Runtime.InteropServices:

Imports System.Runtime.InteropServices

A seguir no formulário vamos declarar a função SetThreadExecutionState e as definições das enumerações das flags:

 <DllImport("kernel32.dll")> _
    Private Shared Function SetThreadExecutionState(ByVal esFlags As EXECUTION_STATE) As EXECUTION_STATE
    End Function

<FlagsAttribute()> _
    Enum EXECUTION_STATE As UInteger
        ES_AWAYMODE_REQUIRED =
&H40
        ES_CONTINUOUS =
&H80000000UI
        ES_DISPLAY_REQUIRED =
&H2
        ES_SYSTEM_REQUIRED =
&H1
    End Enum

VB .NET
 [DllImport("kernel32.dll")]
        static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags);

        [FlagsAttribute]
        enum EXECUTION_STATE : uint
        {
            ES_AWAYMODE_REQUIRED = 0x00000040,
            ES_CONTINUOUS = 0x80000000,
            ES_DISPLAY_REQUIRED = 0x00000002,
            ES_SYSTEM_REQUIRED = 0x00000001
        }
C#

A seguir vamos usar a função e as enumerações para conseguir o efeito desejado.

Vamos criar uma rotina para desabilitar o protetor de tela. Fazemos isso invocando a função SetThreadExecutionState usando as enumerações ES_DISPLAY_REQUIRED ou ES_CONTINUOUS, conforme código abaixo:

Public Shared Sub DesativaProtetor()
    SetThreadExecutionState(EXECUTION_STATE.ES_DISPLAY_REQUIRED Or EXECUTION_STATE.ES_CONTINUOUS)
End Sub

Aqui, o método é declarado como estático(Shared) de modo que ele pode ser facilmente chamado a partir do método principal sem criar instâncias se ele for criado em uma classe.

Para ativar novamente o protetor criamos a rotina AtivaProtetor() chamando a função SetThreadExecutionState e usando a enumeração ES_CONTINUOUS. Isso limpa a flag ES_DISPLAY_REQUIRED.

Public Shared Sub AtivaProtetor()
    SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS)
End Sub

A versão para a linguagem C# (Visual C# 2010) as rotinas acima é :

public static void DesativaProtetor()
{
      SetThreadExecutionState(EXECUTION_STATE.ES_DISPLAY_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS);
}

public static void AtivaProtetor()
{
     SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS);
}

Pegue o projeto completo aqui: DesativaProtecaoTelaCSharp.zip e DesabilitarProtetorTelaVBNET.zip

1Ts 4:1 Finalmente, irmãos, vos rogamos e exortamos no Senhor Jesus que, como aprendestes de nós de que maneira deveis andar e agradar a Deus, assim como estais fazendo, nisso mesmo abundeis cada vez mais.

1Ts 4:2 Pois vós sabeis que preceitos vos temos dado pelo Senhor Jesus.

Referências:


José Carlos Macoratti