Issue 47 May 1, 2008 | ||
How to Write a Screen Saver Screen savers have a long, venerable history. It seems we've never been satisfied with just blanking the screen; we need fish to swim around or take journeys through star systems. These days, most CRT monitors are designed to prevent burn-in through improved phosphor coating, and LCD monitors aren't susceptible to burn-in at all. But screen savers still have plenty of useful purposes. They can show the current time and weather conditions, analyze data in the search for intelligent life, decode genomes, and present RSS feeds. Screen savers are also used for advertising purposes or to present "dashboard" type information for business managers. On Windows-based operating systems, a screen saver is just like any other program. The only difference is that instead of an extension of ".exe" they have an extension of ".scr" - in fact, you could just change the extension of any program on your computer to ".scr" and it will become a screen saver. Yes, even Revolution standalone programs created with Studio or Enterprise. There's a little bit more to it than that, though. We want a proper screen saver to integrate well with the Display Properties control panel in Windows, and otherwise behave in the ways a screen saver ought to. Fortunately, it's a piece of cake with Revolution. Screen Saver Basics When a file has the extension ".scr" Windows gives it a special context menu (the one that appears when you right-click the icon). The new commands are Test, Configure, and Install. Test will show the screen saver as if it was triggered by idle time. Configure will bring up the screen saver's "Options" panel, if it has one. And Install will register the file with Windows so it appears in the list of screen savers when you open Display Properties. I suggest as you are developing and testing your own screen saver, you don't use the Install option, as this will create multiple instances of the screen saver in the Display Properties list that will be hard to remove. Instead, just copy each iteration into C:\Windows\System32 directly, over-writing any previous versions, and Windows will find it there just fine. Getting Started So fire up your copy of Revolution and follow along. We'll start with a brand-new stack. Quitting the Screen Saver
on mouseDown
if the environment is "development" then
pass mouseDown
else
ssShutDown
end if
end mouseDown
on rawKeyDown
if the environment is "development" then
pass rawKeyDown
else
ssShutDown
end if
end rawKeyDown
on mouseMove
if the environment is "development" then
pass mouseMove
else
ssShutDown
end if
end mouseMove
Now, I've already been a little clever here. I don't want the stack to quit while I'm working on it, so I check to see whether I'm in the IDE or not. If the system property "environment" is "development" then I just pass the message along as if my handler wasn't there. Otherwise I call "ssShutDown" which will be a handler in the stack script. Here's what that looks like:
on ssShutDown
if the environment is not "development" then
-- cancel messages
put the pendingMessages into stopList
repeat for each line stopMessage in stopList
cancel item 1 of stopMessage
end repeat
-- exit application
quit
else
beep
end if
end ssShutDown
Again, I don't want the stack to close while I'm working on it, so I check the environment variable. I might be calling this handler under other conditions and I just don't want it to quit and cause me to lose my work. Another important addition here is canceling all pending messages. Leaving a stray message or two lying around when trying to quit is a sure way to find your program still listed in the Task Manager, still hogging memory and system resources, and generally being regarded as sloppy. Anything else I will need to do when shutting down the screen saver can be handled from here. We can actually try this out as our first attempt. Save it as a standalone application for Windows and drop it into the System32 folder. Go to the Screen Saver tab of Display Properties and you'll see it listed. Click on it, and then click "Test." You'll see your stack pop up. When you move your mouse over it, it should disappear. I have a stack that quits properly, what to do next? Inside Screen Savers We see three elements here: A preview image in the mini-monitor, a Settings button, and a Preview button. How can our Rev stack handle these various situations? To figure this out, I'm going to add a little bit of code to our vanilla screen saver stack. First I add a one-line field to the stack. Then I add the following code to the stack script:
on startUp
put $1 into fld 1
end startup
No, I haven't gotten myself mixed up with BASIC, $1 is a special variable that contains the command line parameters used to launch a program. Since a screen saver is just a normal program that is started by the system when it's idle, I figured this was the most natural way for Windows to tell the screen saver what it should be doing. Save as a standalone, change the extension to .scr, and drop it into the System32 folder to see what happens. (By the way, the name used in the Screen Saver menu is the name you assign in the General tab of the Standalone Application Settings dialog box.) You'll discover that when you first open the Display Properties panel and select your screen saver from the drop-down, your screen saver immediately pops up with "/p" in the field. This is because Windows is calling your screen saver in order to render the preview in the little monitor... the p stands for "preview." Move your mouse over your stack. It goes away. Now click the "Settings" button. Your stack comes up with something like, "/c:7998344" in the field. You can bet the c stands for configure. Who knows what the number is for. (Remember I said I wasn't going to read any stuffy documentation on this!) Move your mouse over the stack to make it disappear again. And finally, click the "Preview" button. Your stack pops up with "/s" in the field. Aha, s must mean, "save screen." Eureka. As a final exercise, set the sleep time to one minute and wait. Your stack will come up again in 60 seconds with the "/s" option showing. What we learned in this step is that the Windows Display Properties control panel will open your stack with one of three command-line switches: p for preview, c for configuration, and s for screen saving. Punting on Preview Three Stacks in One
The way I decided to handle this was to use substacks. I'll leave the "main" stack just so I have something to call home, and I'll create two sub stacks, "display" and "config." I'm not exactly sure what my screen saver will look like yet, so I'll just create a simple dialog with basic options. Here's what mine ended up looking like: Notice that I set the decorations so there was no close box. Next, I created a "display" substack and set the decorations to none, with a black background. (I'm not going to provide a screen shot of that, you'll just have to imagine it.) I moved the mouseDown, mouseMove, and rawKeyDown handlers from the first card of the main stack to the first card of the display substack, because that's the one that will have to be dismissed by mouse/keyboard activity. I kept the ssShutDown handler in the main stack script. Then I wired OK and Cancel to simply call ssShutDown for the time being. The main thing now was to have the program operate in three different ways depending on the command line parameters. So I put the following into the main stack script:
on startUp
lock screen
hide stack "ScreenSaver"
hide stack "config"
hide stack "display"
ssInit $1
end startUp
on ssInit startupType
switch startupType
case "/p"
ssSilent
break
case "/s"
ssSave
break
default
ssConfigure
end switch
end ssInit
on ssSilent
unlock screen
quit
end ssSilent
on ssConfigure
go stack "config"
show stack "config"
unlock screen
end ssConfigure
on ssSave
go stack "display"
show stack "display"
unlock screen
end ssSave
The case statement defaults to configure mode because I found that no command line parameter is placed in $1 when choosing "Settings" from the Explorer context menu, and we would want to account for this possibility anyway. Now, when you test your screen saver, you'll see the stack opens in three modes:
Saving Settings Saving the Screen For the animation, I didn't want to have a crushing burden on the CPU, so I used the "send in [time]" technique along with move. The sample stack, which you can use as a template for your own screen savers can be found here I hope you enjoyed learning how to make a screen saver with Revolution. We'd enjoy learning how you've used this technique. |