Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Detect when screensaver activates

Posted on 1998-07-21
15
Medium Priority
?
339 Views
Last Modified: 2010-04-04
Seems to be my day asking questions - but with the help of E-E my programming has come on leaps and bounds and the encouragement of my school IT Manager means that I'm busily writing quite-handy ( :) ) little apps during these long summer holidays (tough life, eh?)

I had the idea of an app that detected when the screensaver activated, waited a few minutes and then if the screensaver hadn't turned off, logged-off the user to stop people forgetting to log-off and consequently having trouble logging on the next day.

I had a look at SystemParametersInfo, with GETSCREENSAVERACTIVE (which is great for disabling c-a-d) but this only seems to find out whether screen-saving is enabled in display control panel....

TIA,

Ed
0
Comment
Question by:edmoore
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 5
  • 4
  • +1
15 Comments
 

Author Comment

by:edmoore
ID: 1358350
Just to make it clear - I'm asking how to implement the idea I suggested.  Maybe I was a bit vague - maybe it's just me?
0
 
LVL 4

Expert Comment

by:erajoj
ID: 1358351
Hi Ed,
a simple solution is to make your own screensaver and then invoke whatever screensaver you want to see on screen from within it.
A screensaver is just an EXE-file with another extension (SCR) and can be executed in the ordinary way (createprocess...).
The idea is that your (nonvisual) screensaver would get the handle of the visual screensaver and run a loop to detect if the process attached to the handle is stopped.
If not it would log off in the ordinary way (ExitWindowsEx...) after the desired time.
Not the most beautiful solution, but easy enough to implement in 15-20 mins or so...
If you need further assistance; mail me...

Regards,
/// John
0
 
LVL 6

Expert Comment

by:Holger101497
ID: 1358352
erajoj: It takes a lot more to write a "good" screen saver than just renaming it!
For one thing, it must make sure it covers the task bar, it should provide a "config-dialog" when "Configure" is clicked and last but definitely not least, it should display a litttle preview in the desktop-properties window (in the little monitor). I spent more than 2 of hours writing one (a very simplistic one) two weeks ago and I have a good URL abut it... maybe I'll post it if I can find it...

But apart from that:
edmoore, I'm pretty optimistic I can help you find a solution, but I don't have the time right now to write a working program...

Here's something from the Delphi FAQ:
How do I turn the Windows Screen Saver on in code?

 Answer:

 The following function tests to see if the WIndows Screen Saver is
 available, and if so, turns it on:

 function TurnScreenSaverOn : bool;
 var
   b : bool;
 begin
   result := false;
   if SystemParametersInfo(SPI_GETSCREENSAVEACTIVE,
                           0,
                           @b,
                           0) <> true then exit;
   if not b then exit;
   PostMessage(GetDesktopWindow, WM_SYSCOMMAND, SC_SCREENSAVE, 0);
   result := true;
 end;

but I guess you already knew that, right?

The truly interesting part is from Delphi\Source\RTL\Win\WINDOWS.PAS:
const
  { Parameter for SystemParametersInfo() }
  {$EXTERNALSYM SPI_GETBEEP}
  SPI_GETBEEP = 1;
.
  {$EXTERNALSYM SPI_GETSCREENSAVEACTIVE}
  SPI_GETSCREENSAVEACTIVE = $10;
. (now this is the good part :-)
  {$EXTERNALSYM SPI_SCREENSAVERRUNNING}
  SPI_SCREENSAVERRUNNING = 97;
.

That should do it, shouldn't it?? I would imagine that
 SystemParametersInfo(SPI_GETSCREENSAVERRUNNING,
                           0,
                           @b,
                           0) <> true then exit;
returns what you're looking for in b :-))))

Good luck and let me know if that's all you need so I can post an "official answer" :-))
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:edmoore
ID: 1358353
OK, Holger, thanks - that's great.  Post it as an answer and collect your points!

Ed
0
 
LVL 3

Expert Comment

by:vladika
ID: 1358354
function IsScreenSaverRunning: LongBool;
var Dummy: Integer;
begin
  SystemParametersInfo(SPI_SCREENSAVERRUNNING, 1, @Result, 0);
  SystemParametersInfo(SPI_SCREENSAVERRUNNING, Integer(Result), @Dummy, 0);
end;

Reject if you want.

0
 
LVL 3

Expert Comment

by:vladika
ID: 1358355
Edmore, Holger !

SORRY!!! Reject my answer!!!

0
 

Author Comment

by:edmoore
ID: 1358356
"Rejection" sounds like such a strong term - sorry vladika - your answer was very helpful as well, but I had already promised the points to Holger.  Shame E-E doesn't let you give two "corrects"! (now there's an idea....)

Ed
0
 
LVL 6

Accepted Solution

by:
Holger101497 earned 200 total points
ID: 1358357
ok, here it is - the "official answer" - solution see below/above.

Two "corrects" might be a good idea if they are different answers, but basically, vladika's answer is the same as mine (guess he didn't see it until after he posted his answer).
vladika: What does your second line do?
0
 
LVL 3

Expert Comment

by:vladika
ID: 1358358
After first line I set SPI_SCREENSAVERRUNNING = 1

My second line restore previous SPI_SCREENSAVERRUNNING value
I must do it, isn't it? :)

0
 
LVL 6

Expert Comment

by:Holger101497
ID: 1358359
Why do you have to restore something you don't change?
Ed doesn't want to start the screen saver, he just want to DETECT IF it is running. The state of the screen saver should not be changed and therefore, nothing has to be restored either...
0
 
LVL 3

Expert Comment

by:vladika
ID: 1358360
You are mistaken.

> Why do you have to restore something you don't change?
I change by
  SystemParametersInfo(SPI_SCREENSAVERRUNNING, 1, @Result, 0);
I set SPI_SCREENSAVERRUNNING = 1
and previous SPI_SCREENSAVERRUNNING value went into Result.
Previous value maybe 0, maybe 1.
So, I must restore this value.

And I restore it by
  SystemParametersInfo(SPI_SCREENSAVERRUNNING, Integer(Result), @Dummy, 0);

If you did not restore previous state, you will have some by-effect.
For example disabling CTRL-ALT-DEL, maybe more...

0
 
LVL 6

Expert Comment

by:Holger101497
ID: 1358361
ok, *might* be true, but I'll have to check the API when I'm back home. The code I posted is from the official Delphi FAQ:
  if SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0, @b, 0) <> true then exit;
  if not b then exit;
  PostMessage(GetDesktopWindow, WM_SYSCOMMAND, SC_SCREENSAVE, 0);

Following your point, this code would first disable the screen saver before trying to turn it on - strange, huh?

Now I don't say you're wrong before checking... but it would be a serious problem... I guess ed wants to check for the status of the screen saver in a timer and he'd probably be very unhappy if the screen saver is turned off/off and back on/off every 30 seconds :-)))
Also, why would we have the PostMessage(GetDesktopWindow, WM_SYSCOMMAND, SC_SCREENSAVE, 0); command??

Let's hear ed's opinion - I guess he's tried the code already and it sounded like it worked.
If you're right, he'd notice right away because the screen saver wouldn't work any more (being turned off as soon as the function is called)

P.S.: Just a formality: SPI_SCREENSAVERRUNNING is a constant and it's value is 97
0
 
LVL 3

Expert Comment

by:vladika
ID: 1358362
> Following your point, this code would first disable the screen saver before trying to turn it on - strange, huh?
No, It is not my point.

SPI_GETSCREENSAVEACTIVE only query whether screen saving is enabled or not.
SPI_SETSCREENSAVEACTIVE only set the state of the screen saver. (not running it)

BUT!!!
SPI_SCREENSAVERRUNNING query and set params at the same time!!!

Also I think you will not find SPI_SCREENSAVERRUNNING description in API.
I found in API only that SPI_SCREENSAVERRUNNING is internal parameter and all.

0
 

Author Comment

by:edmoore
ID: 1358363
OK, I got it to work but Delphi 2 didn't like SPI_SCREENSAVERRUNNING (wasn't listed in the windows.pas Holger came up with either - maybe that's D3?) but when I stuck 97 in instead it worked fine...

Incidentally, what do think is the best way to first, keep checking if the screensaver is on, and then wait say 10 minutes.  I was going to use a timer, but are they particularly resource-intensive?

Ed
0
 
LVL 6

Expert Comment

by:Holger101497
ID: 1358364
As far as I know, a timer is the best way to wait for a longer time and Borland probably implemented them very efficiently by using the windows-functions that are available - they use a "windows timer event" - whatever that is.

The only way of waiting without a timer looks like this:

procedure Delay(ms : longint);
 var TheTime : LongInt;
 begin
   TheTime := GetTickCount + ms;
   while GetTickCount < TheTime do
     Application.ProcessMessages;
 end;

but I really can't imagine that that's more efficient, since the loop keeps going and going and going... I think if you set your timer interval to 20000 ms or so, that should be quite ok. Check the ressource-meter and I'm pretty sure your process will have less than 1% CPU-time (if you use NT, you can check CPU time for individual programs)
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Video by: ITPro.TV
In this episode Don builds upon the troubleshooting techniques by demonstrating how to properly monitor a vSphere deployment to detect problems before they occur. He begins the show using tools found within the vSphere suite as ends the show demonst…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
Suggested Courses

704 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question