2012-06-05 15 views
6

Zrobiłem wygaszacz ekranu w .Net 4.0. Zasadniczo po prostu przesuwa bity w obrazie dookoła i wyświetla go za pomocą. Unieważnij timer i przesłonięcie zdarzenia onPaint.Mój wygaszacz ekranu zatrzymuje zawieszenie ekranu, ale nie chcę tego do

Jak na razie działa świetnie - zauważyłem jednak jeden problem z tym.

Zatrzymuje monitor przed zawieszeniem po upłynięciu limitu czasu. Od kiedy go zainstalowałem, mój monitor pozostaje teraz w trybie 24/7.

Chodzi o to, że nie zrobiłem nic, aby powstrzymać funkcje oszczędzania energii - i upewniłem się, że ustawienia oszczędzania energii mojego komputera są ustawione (są). Więc wybrałem inny wygaszacz ekranu, aby upewnić się, że ustawienia wciąż działają. Monitor zawieszony po przekroczeniu limitu czasu.

Co muszę zrobić, aby grać ładnie z zarządzaniem energią? Szukałem tej odpowiedzi w Google i wszystko, co znalazłem, to blokowanie zarządzania energią i nie blokowałem tego wprost! Chcę tylko, żeby zawieszenie było dozwolone, kiedy nadejdzie czas.

Odpowiedz

1

Udało mi się uzyskać program "zagraj miło". Nie wiem, dlaczego to działa, a oryginalny kod nie, ale to nie tylko działa - w rzeczywistości czyni program bardziej "energooszczędnym" przyjaznym, ponieważ redukuje cykle procesora, nie wykonując obliczeń po zawieszeniu ekranu. Krótko mówiąc, przeglądam komunikaty WndProc i sprawdzam, czy monitor jest zawieszony, a po jego odebraniu przerywam odświeżanie, dopóki nie zostanie wznowione (możliwe jest wznowienie i nadal działa wygaszacz ekranu).

zmiany Kod:

// Field Definitions 
    /// <summary> 
    /// Constants that relate to the WndProc messages we wish to intercept and evaluate. 
    /// </summary> 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:FieldNamesMustNotContainUnderscore", Justification = "Standard practice to use this naming style for Win32 API Constants.")] 
    private const int WM_SYSCOMMAND = 0x0112, SC_MONITORPOWER = 0xF170; 

    /// <summary> 
    /// Gets or sets whether we are suspended. Should coincide with whether the display is turned on or not. 
    /// </summary> 
    private bool isSuspended = false; 


    // New overridden method 
    /// <summary> 
    /// Intercepts WndProc messages. We are looking for the screen suspend activity. From it, we will return that we are able to suspend and we ourselves will suspend. 
    /// </summary> 
    /// <param name="m">Message to be checked.</param> 
    protected override void WndProc(ref Message m) 
    { 
     if (m.Msg == WM_SYSCOMMAND) 
     { 
      // The 0x000F bits are used to indicate the specific state and must be ignored to see if this is a monitor power event. 
      if ((m.WParam.ToInt32() & 0xFFF0) == SC_MONITORPOWER) 
      { 
       switch (m.WParam.ToInt32() & 0x000F) 
       { 
        case -1: 
         // Display powering on - resume operation 
#if DEBUG 
         System.Diagnostics.Debug.WriteLine("Display powered on."); 
#endif 
         this.isSuspended = false; 
         break; 
        case 0: 
        case 1: 
        case 2: 
         // Display being powered off - suspend operation 
#if DEBUG 
         System.Diagnostics.Debug.WriteLine("Display suspended"); 
#endif 
         this.isSuspended = true; 
         break; 
        default: 
#if DEBUG 
         System.Diagnostics.Debug.WriteLine(string.Format("Unknown power state: {0}", (m.WParam.ToInt32() & 0x000F).ToString("0"))); 
#endif 
         // Assuming that unknown values mean to power off. This is a WAG. 
         this.isSuspended = true; 
         break; 
       } 
      } 
     } 

     base.WndProc(ref m); 
    } 


    // Change to my refreshing timer. 
    /// <summary> 
    /// Called when the refresh timer ticks. This invalidates the form, forcing it to be redrawn, which creates a framerate for us. 
    /// </summary> 
    /// <param name="sender">Who called this method.</param> 
    /// <param name="e">Event Arguments.</param> 
    private void RefreshTimer_Tick(object sender, EventArgs e) 
    { 
     if (this.isSuspended) 
     { 
      // Program is in suspended mode, so don't do anything this update. 
      return; 
     } 

     // Program is not suspended, so invalidate the client area so it can be painted again. 
     this.Invalidate(); 
    } 

wprowadzeniu tej zmiany zatrzymuje cały przerysowanie kiedy zawieszenia nazywa (i zatrzymuje GDI + obliczenia) i po złożeniu go, wygaszacz ekranu „zachowuje się” z ustawień zarządzania energią.

+3

Bardzo fajnie - jeśli nie masz nic przeciwko, prawdopodobnie użyję tego jako szablonu do zmiany naszej aplikacji monitorującej, która trafia do bazy danych dość mocno, gdy działa, i bezsensownie, więc gdy ekran i tak nie jest wyświetlany. –

+0

Nie mam nic przeciwko, a to już częściowo twój sukces! Dzięki jeszcze raz! – Dracorat

1

Czy przypadkowo pułapkę podkomendy 0xF170 (SC_MONITORPOWER) WM_SYSCOMMAND?

+1

Aby odpowiedzieć na ten komentarz, nie, nie byłem. Jednak rozważałem zrobienie tego i zawieszenie procedury rysowania po otrzymaniu wiadomości. Ta uwaga ostatecznie doprowadziła do rozwiązania, które teraz zamierzam dodać i zaakceptować jako odpowiedź. Mimo to byłeś kluczowym kamieniem milowym na swojej drodze i chciałem cię poinformować, że jak głosowałem na ciebie. – Dracorat

+0

Cieszę się, że mogę chociaż w czymś pomóc;) –

Powiązane problemy