PDA

View Full Version : Deactivate Screensaver/Power States while game is running



Grendelus
28-12-2006, 10:04 AM
I've coded a simple dll in delphi in order to deactivate the screensaver when my game is running.
I can use the function _enableSSaver to activate it back when I am done, but in case of a ctrl+alt+del or a crash the screensaver won't go back to normal.
I've seen there are some tags initialization/finalization but I don't know how to use them. Is there a way to make it that the screensaver is always enabled when the dll is unloaded (freed)?

Here is my code:

library screenhndl;

uses
Windows,
Messages,
SysUtils;

function _disableSSaver : pchar; stdcall;
begin
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE,0,0,0 );
SystemParametersInfo(SPI_SETPOWEROFFACTIVE,0,0,0);
SystemParametersInfo(SPI_SETLOWPOWERACTIVE,0,0,0);
end;

function _enableSSaver : pchar; stdcall;
begin
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE,1,0,0 );
SystemParametersInfo(SPI_SETPOWEROFFACTIVE,1,0,0);
SystemParametersInfo(SPI_SETLOWPOWERACTIVE,1,0,0);
end;


exports _disableSSaver;
exports _enableSSaver;
begin end.

JSoftware
28-12-2006, 01:59 PM
I seem to recall reading somewhere that calling changeresolution with the flag cds_fullscreen will block screensavers and power options, eg. sleep, hibernate, etc.

WILL
28-12-2006, 03:13 PM
Hey, not bad. Though I think a better solution may be to have the game 'kick' the system's input queue every so often instead.

What happens when you simply set and reset these values instead of 'permanently' setting them at the start and reseting them at the end of your game? Would that result in such a 'kick' as I'm referring to?

Huehnerschaender
28-12-2006, 03:19 PM
I hope you test the settings before you use your DLL calls... Otherwise, the player will have the screensaver and those other stuff enabled after he played your game, even if it was disabled before :)

Greetings,
Dirk

jasonf
28-12-2006, 03:27 PM
I hope you test the settings before you use your DLL calls... Otherwise, the player will have the screensaver and those other stuff enabled after he played your game, even if it was disabled before :)

..or the Screensaver will be disabled if the game crashes and doesn't clean up properly.

Probably be better to find a less destructive way of preventing the screensaver from kicking in.

Grendelus
29-12-2006, 08:30 AM
I seem to recall reading somewhere that calling changeresolution with the flag cds_fullscreen will block screensavers and power options, eg. sleep, hibernate, etc.

You are talking about exclusive mode?

The fact is that with the initialization and finalization tags you can automatically unload a dll and its functions even when the game has been forced quit (ctrl+alt+del) or crashed.

But I don't know how to use them. Anyone that can apply it to the code above.

JSoftware
29-12-2006, 10:39 AM
no actually I was talking about ChangeDisplaySettings :wink:

czar
29-12-2006, 11:22 PM
procedure WMSysCommand(var Msg : TWMSysCommand); message WM_SYSCOMMAND;


// SWITCH OFF THE SCREENSAVER AND THE MONITOR POWER SAVER IF THEY TRY TO CUT IN
procedure TForm1.WMSysCommand(var Msg : TWMSysCommand);
begin
//catch the message and turn it off
if (Msg.CmdType = SC_MONITORPOWER) or (Msg.CmdType = SC_SCREENSAVE) then
begin
Msg.Result := -1;
end
else
inherited;///Otherwise do whatever is supposed to be done
end;



That does the trick

Clootie
30-12-2006, 12:06 AM
There is also another way:

type
EXECUTION_STATE = DWORD;
const
ES_SYSTEM_REQUIRED = DWORD($00000001);
ES_DISPLAY_REQUIRED = DWORD($00000002);
ES_USER_PRESENT = DWORD($00000004);
ES_CONTINUOUS = DWORD($80000000);

function SetThreadExecutionState(esFlags: EXECUTION_STATE): EXECUTION_STATE; stdcall; external kernel32;

......
SetThreadExecutionState(ES_DISPLAY_REQUIRED or ES_CONTINUOUS); // this will fix current state and disable screensaver

Grendelus
31-12-2006, 10:11 AM
Will it be compatible with most versions of the Windows including Vista?

tux
31-12-2006, 12:10 PM
Client Requires: Windows Vista, Windows XP, or Windows 2000 Professional.
Server Requires: Windows Server "Longhorn", Windows Server 2003, or Windows 2000 Server.

from http://msdn2.microsoft.com/en-us/library/aa373208.aspx

Grendelus
02-01-2007, 12:29 PM
The SetThreadExecutionState function cannot be used to prevent the user from putting the computer in standby mode. Applications should respect that the user expects a certain behavior when they close the lid on their laptop or press the power button.

This function does not stop the screen saver from executing either.

Uh, I tried the above code, but it seems it indeed doesn't prevent the screensaver from popping in.

czar
02-01-2007, 05:49 PM
Did u try my code?

I have never had any problems with it.

Clootie
02-01-2007, 07:41 PM
The SetThreadExecutionState function cannot be used to prevent the user from putting the computer in standby mode. Applications should respect that the user expects a certain behavior when they close the lid on their laptop or press the power button.

This function does not stop the screen saver from executing either.

Uh, I tried the above code, but it seems it indeed doesn't prevent the screensaver from popping in.

Are you sure that you are not misinterpretting documentation?

Multimedia applications, such as video players and presentation applications, must use ES_DISPLAY_REQUIRED when they display video for long periods of time without user input.

Grendelus
04-01-2007, 11:51 AM
library setthread;

uses
Windows,
Messages;

type
EXECUTION_STATE = DWORD;

const
ES_SYSTEM_REQUIRED = DWORD($00000001);
ES_DISPLAY_REQUIRED = DWORD($00000002);
ES_USER_PRESENT = DWORD($00000004);
ES_CONTINUOUS = DWORD($80000000);

function SetThreadExecutionState(esFlags: EXECUTION_STATE): EXECUTION_STATE; stdcall; external kernel32;

function Xclusive : pchar; stdcall;
begin
SetThreadExecutionState(ES_DISPLAY_REQUIRED or ES_CONTINUOUS);
end;

exports Xclusive;
begin end.

When I tried to implement into a dll it does not work. :(
I MUST be doing something wrong here.

Grendelus
29-01-2007, 11:42 AM
Has anyone got any workarounds to this? :)

Sly
29-01-2007, 10:28 PM
Did you try czar's code? Every application that is currently running gets notified when the screen saver is about to become active, or power save is about to be enabled, and the application has a chance to stop it.

Use czar's code along with Clootie's code and you should be covered from all angles.

Grendelus
30-01-2007, 02:37 PM
Problem is that I want it implemented in a dll, and don't know what are equivalents for TForm1, Msg etc... :(

EDIT: I found this while googling, looks a lot like czar's code.

Disabling screen saver temporarily
If you want to turn off the screen saver while your program is running, you don't have to disable the Windows screen saver at all. Just define the following method to handle the appropriate Windows message:


procedure TForm1.AppMessage (var Msg: TMsg; var Handled: boolean);
begin
if (Msg.Message = WM_SYSCOMMAND) and (Msg.wParam = SC_SCREENSAVE) then
Handled := true;
end;

{On the form's OnCreate event, assign}

Application.OnMessage := AppMessage;

Problem again is that I don't know how I am supposed to substitute Application.OnMessage and the like in the dll...

*is it me or the pascal tags do not work?[/code]