Seite 1 von 2

Energiesparmodus / Bildschirm Abschaltung ?

Verfasst: 15.10.2015 10:54
von tft
Hallo alle zusammen,

wie es manchmal so ist beim Coden. Bestimmte Fehler kommen bei einem selber manchmal einfach nicht vor.
Dann grübelt man tage lang und kommt auf eine Lösung die echt behämmert ist. Ich habe folgende Situation.

Ich bin ANIME Liebhaber und habe dazu einen speziellen Player Programmiert, damit die Serien Teile die ich aus
dem Internet als Stream aufzeichne, in einem Stück und ohne In/Outro oder der nervigen Werbe Unterbrechung
angeschaut werden können. ( Hauptsächlich wegen der Kinder). Einigen freunde fanden das toll und ich gab Ihnen
den Player.

Nun das Problem: Es gibt Leute die den Energiesparmodus oder einen Bildschirmschoner im Hintergrund laufen
haben. Was zu dem Problem führt , das solange man die Videos schaut, meistens auch keine Aktionen mit der Maus
oder der Tastatur stattfinden was zu Aktivierung des Bildschirmschoner oder der Energiespar-Modus führt.

Das möchte ich verhindern. Da ich aber mit MSN aus Fremdsprachen technischen Gründen nicht schlau werde.
Bitte ich euch um Hilfe.

Da der Windows MediaPlayer das Abschalten verhindert muss es irgendwie eine Möglichkeit geben das mittel Windows API
zu lösen.

Danke für eure Zeit.

Gruss TFT

PS: Das Bewegen der Mause in Zeitlichen Intervallen funktioniert nicht auf allen systemen.

Re: Energiesparmodus / Bildschirm Abschaltung ?

Verfasst: 15.10.2015 11:08
von mhs
Dazu hab ich folgendes gefunden:
The active application receives the WM_SYSCOMMAND message with the wParam parameter set to the SC_SCREENSAVE value, but it does not pass the message to the DefWindowProc function.
D.h. du kannst es mal so probieren:
  • SetWindowCallback für dein Playerfenster
  • Im Callback die WM_SYSCOMMAND Nachricht abfangen und auf den Parameter SC_SCREENSAVE überprüfen
  • Wenn der Screensaver unterdrückt werden soll, gibst du die Nachricht nicht weiter und beendest du das Callback mit ProcedureReturn #False

Re: Energiesparmodus / Bildschirm Abschaltung ?

Verfasst: 15.10.2015 12:05
von RSBasic
Du kannst genau für solche Zwecke den Standby-Plan temporär deaktivieren und zwar mit der WinAPI-Funktion "SetThreadExecutionState_()".

Beispielcode: http://www.rsbasic.de/aktualisierung/wi ... ivieren.pb
tft hat geschrieben:PS: Das Bewegen der Mause in Zeitlichen Intervallen funktioniert nicht auf allen systemen.
Das hört sich so an, als ob du nach einer Crossplattformlösung suchst oder? Vielleicht kann jemand für dich zusätzlich eine Linux- und MacOS-Lösung posten, aber ohne API ist das nicht möglich. Außer die Workaround-Lösung, die du bereits genannt hast bezüglich der automatischen Mausbewegung, wobei das ja auch API ist.

Re: Energiesparmodus / Bildschirm Abschaltung ?

Verfasst: 15.10.2015 21:33
von tft
Hallo ...
danke erstmal für die schnelle Antwort.

@RSBasic

dein Funktions Aufruf funktioniert genau wie er soll. Habe ich dankender weise bereits eingebaut. Bedauerlicherweise funktioniert das nur am PC.
Das Surface Pro ... bei dem ich das besagte Problem erst bemerkt habe ist aber der Meinung das die Systemeinstellung egal ist und schaltet den Bildschirm
trotzdem ab. Ich nehme an das es sich dabei um eine Energie Sparmaßnahme handelt die nur Aktiv ist wenn das Pad keine direkte Stromzufuhr hat und
höchst warscheinlich über das BIOS gesteuert wird. leider kann ich den angepassten Player nicht im EXE Format auf meinen Stick laden um Ihn dem Pad
zu kopieren. Der Zugriff auch die Exe wird mit einem Datei Fehler Quittiert. Darum kümmere ich mich dann später. Hat aber irgendwas mit dem System
Aufruf zu tun, denn wenn ich den rausnehme geht es wieder. Aber das wird schon ......

@mhs

Ich habe im Forfeld schonmal was mit diesem Callback versucht. Aber ich bekomme das nicht zum laufen. Selbst das Hilfe-Beispiel funktioniert nicht.
Ich wollte nämlich den Close Botton abfangen um noch Daten zu speichern und im falle eines Herunterfahren des Rechners noch eine Requester ausgeben.
Das mit dem Close Botten mache ich jetzt über das normale msg. Aber der Shutdown läst sich nicht abfangen. Es ist auch so das die PlayRutine für das Video
dann ebenfals keine Bilder mehr auf den Screen bringt. Mein Code wird daher wohl defekt sein.

Code: Alles auswählen

Procedure WinCallback(hWnd, uMsg, wParam, lParam) 
  ; Windows füllt die Parameter automatisch, welche wir im Callback verwenden...
  Shared Quit.b 
  DebugLog(Str(hwnd)+" "+Str(umsg)+" "+Str(wparam)+" "+Str(lparam))
  If uMsg = #WM_SIZE 
    Select wParam 
      Case #SIZE_MINIMIZED 
        DebugLog("Fenster wurde minimiert")
      Case #SIZE_RESTORED 
        DebugLog("Fenster wurde wiederhergestellt")
      Case #SIZE_MAXIMIZED 
        DebugLog("Fenster wurde maximiert")
    EndSelect 
  ElseIf uMsg =  #WM_QUERYENDSESSION ; unter W8 scheint das nicht mer zu funktionieren
    If MessageRequester( "Windows Shutdown", "Windows wirklich beenden?",  #MB_YESNO ) = #PB_MessageRequester_Yes     
      Quit.b = 1 
      ProcedureReturn #True 
    Else 
      ProcedureReturn #False 
    EndIf 
  EndIf 
  
  ProcedureReturn #PB_ProcessPureBasicEvents 
EndProcedure 
das die Procedure abgearbeitet wird sehe ich an der 1.DebugLog Funktion
aber keine der anderen kommt. Und ehe das grundsätzlich nicht läuft wird es schwer das
richtig abzufangen . Ich denke die letzte Zeile ist das Problem. Aber so habe ich das aus der Hilfe

Gruss TFT

Re: Energiesparmodus / Bildschirm Abschaltung ?

Verfasst: 15.10.2015 21:44
von RSBasic
Hallo tft,

mit dem Surface Pro kenne ich mich leider nicht aus, aber ich denke, es hat damit zu tun, dass auf dem Tablet nicht alle WinAPIs unterstützt werden.
Auf der von mir verlinkten MSDN-Seite steht ganz unten folgendes:
MSDN hat geschrieben:Minimum supported client: Windows XP [desktop apps only]
Deshalb geht es glaube ich nicht. Außerdem hat das Tablet sowieso seine eigene Energieverwaltung, aber keine Ahnung, wie man das unterdrücken kann.

Re: Energiesparmodus / Bildschirm Abschaltung ?

Verfasst: 16.10.2015 08:09
von mhs
Das Surface Pro bzw. generell alle Windows Tablets (außer welche mit Windows RT) sind normalen Notebooks gleichzusetzen. Das Betriebssystem ist dabei ein ganz normales Windows 8.1/10 welches auch auf normalen PCs installiert wird, deswegen funktionieren auch alle WinAPIs.

Das Verhalten von WM_QUERYENDSESSION und WM_ENDSESSION hat sich mit Vista geändert, so dass ein einfaches ProcedureReturn #False nicht mehr ausreicht um das Herunterfahren zu verhindern, wenn das Flag ENDSESSION_CLOSEAPP gesetzt ist. Und das ist soweit ich weiß der Fall, wenn der Anwender selbst auf Abmelden oder Herunterfahren klickt. In so einem Fall muss zusätzlich mit ShutdownBlockReasonCreate ein Grund generiert werden, warum das Herunterfahren unterbrochen wird. Dann erscheint allerdings der bekannte Bildschirm, dass das Herunterfahren wegen Anwendung XY nicht durchgeführt werden kann.

Das Abfangen des Bildschirmschoners funktioniert aber auch mit Windows 8 noch genauso:

Code: Alles auswählen

Procedure WinCallback(hWnd, uMsg, wParam, lParam) 
  
  Select uMsg
  
    Case #WM_SYSCOMMAND
    
      If wParam = #SC_SCREENSAVE
        Debug "Bildschirmschoner verhindert"
        ProcedureReturn #False
      EndIf

  EndSelect

  ProcedureReturn #PB_ProcessPureBasicEvents 

EndProcedure 


If OpenWindow(0, 0, 0, 300, 300, "Test", #PB_Window_SystemMenu) 
  
  SetWindowCallback(@WinCallback())
  
  Repeat 
    
  Until WaitWindowEvent() = #PB_Event_CloseWindow 
  
EndIf

Re: Energiesparmodus / Bildschirm Abschaltung ?

Verfasst: 16.10.2015 12:38
von tft
Hallo,

also danke nochmal für eure Mühe. Bildschirmschoner und Energiesparmodus lassen sich so gut handhaben.
Nur eine Sache ist blöd. Wenn ich SetWindowCallBack benutze funktionieren die MOVI befehle nicht mehr.
Das decodierte Bild wird nicht angezeigt.

Gruss TFT

Re: Energiesparmodus / Bildschirm Abschaltung ?

Verfasst: 16.10.2015 16:19
von GPI
RSBasic hat geschrieben:Beispielcode: http://www.rsbasic.de/aktualisierung/wi ... ivieren.pb
Das ganze kann man etwas zusammenkürzen (oder ich mach gerade einen Fehler). Mir missfällt auch, das man eine DLL öffnet, die Adresse raussucht und dann wieder schließt. Müsste die Adresse dann nicht eigentlich ungültig werden? Die Konstanten sind -zumindest in der Beta10) auch schon in PB drin.

Code: Alles auswählen

Import "kernel32.lib"
  SetThreadExecutionState(esFlags)
EndImport

If OpenWindow(0, 0, 0, 500, 400, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ButtonGadget(1, 10, 10, 200, 20, "Standby-Plan deaktivieren", 0)
  ButtonGadget(2, WindowWidth(0)-210, 10, 200, 20, "Standby-Plan aktivieren", 0)
  
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 1
            Debug SetThreadExecutionState(#ES_CONTINUOUS | #ES_SYSTEM_REQUIRED | #ES_AWAYMODE_REQUIRED | #ES_DISPLAY_REQUIRED);Falls 0, dann Fehler
          Case 2
            Debug SetThreadExecutionState(#ES_CONTINUOUS);Falls 0, dann Fehler
        EndSelect
      Case #PB_Event_CloseWindow
        End
    EndSelect
  ForEver
EndIf

Re: Energiesparmodus / Bildschirm Abschaltung ?

Verfasst: 18.10.2015 10:37
von tft
Hallo,

also diese Variante funktioniert auch.

DAnke ... TFT

Re: Energiesparmodus / Bildschirm Abschaltung ?

Verfasst: 18.10.2015 20:19
von edel
GPI hat geschrieben:
RSBasic hat geschrieben:Beispielcode: http://www.rsbasic.de/aktualisierung/wi ... ivieren.pb
Das ganze kann man etwas zusammenkürzen (oder ich mach gerade einen Fehler). Mir missfällt auch, das man eine DLL öffnet, die Adresse raussucht und dann wieder schließt. Müsste die Adresse dann nicht eigentlich ungültig werden? Die Konstanten sind -zumindest in der Beta10) auch schon in PB drin.
Diese DLL wird immer geladen, daher kann man sie auch gar nicht freigeben. Es wird lediglich der von PB reservierte Speicher wieder freigegeben. So funktioniert der Aufruf der Funktion immer. Aber schoen ist etwas anderes ;)

Der Code zeigt, dass PB hier immer das gleiche Handle bekommt.

Code: Alles auswählen

Debug OpenLibrary(0, "Kernel32.dll")
Debug OpenLibrary(1, "Kernel32.dll")
Debug OpenLibrary(2, "Kernel32.dll")
Debug OpenLibrary(3, "Kernel32.dll")
Debug OpenLibrary(4, "Kernel32.dll")