Creating Screen Savers Using MSVC ++

Page 2

This page discusses the various functions that your screen saver is expected to perform.


I've had enough! I want to go home

I want to see the first page

Skip straight to the screen saver windows


PREVENTING MULTIPLE SCREEN SAVER EXECUTIONS

When Windows thinks it is time to launch a screen saver, it sends the current foreground program a message to indicate it is considering starting a screen saver. If the program does nothing with this message, a screen saver will be started. The program can instead examine the message and decide if the screen saver should be started or not. It can just throw away the message, which will prevent Windows starting the screen saver.

This mechanism allows programs to stop screen savers from starting, for example lengthy image rendering programs that know they are going to be busy for a long time. But it also means that screen savers could be started multiple times if they do not handle this message, because the message will get sent even if the current program already is the screen saver!

Your screen saver should intercept this message, then cause it to be thrown away, because it knows the screen saver (i.e. itself) is already running.

The message that is sent is "WM_SYSCOMMAND" with the parameter set to "SC_SCREENSAVE".


SCREEN SAVER PASSWORDS

Windows 95

The "standard" Windows 95 screen savers use a shared screen saver password, kept encrypted in the registry. Turning password protection on will apply to any of the screen savers when selected, not just to the currently selected one. Similarly, choosing a new password changes the value that all of the screen savers will use.

If you want to write your own screen saver, you obviously will want to use the same password that the "standard" screen savers use. Microsoft’s official line is that you cannot do this, but have to provide your own password mechanism, unique to your screen saver. However, you can use the "standard" password by taking advantage of two undocumented functions :

These functions and files are always available with Windows 95, and can be used by any program even though they are not documented.

‘PwdChangePasswordA’ displays the standard dialog box to allow changing the screen saver password. Your screen saver should use this function when it is started with "/a".

‘VerifyScreenSavePwd’ displays the standard dialog box requesting a screen saver password to be entered, and returns a value to indicate if a correct password was entered. Your screen saver should use this function when running in full-screen mode, screen saver password protection is enabled, and user input (mouse or keyboard) is detected. The screen saver should not terminate until a correct password is entered.

You can tell if password protection is on by examining the value of "ScreenSaveUsePassword" in the registry key "Control Panel\Desktop" for HKEY_CURRENT_USER. Windows automatically maintains this value to indicate whether you have screen saver password protection turned on or not (using Control Panel's "Display Properties" screen saver window).

Details on how to incorporate support for password protection in your screen saver are given in the pages about constructing your code.

Windows NT

With Windows NT, your screen saver program does not have to do anything at all about password protection. It is all handled by NT without having to involve the screen savers.

NT uses the logon password as the screen saver password.


Preventing Alt-Tab and Ctrl-Alt-Del

When you are using screen saver password protection, you do not want anyone to be able to access your desktop unless they enter a correct password. If the press a key or use the mouse, the "password request" dialog box is displayed. If they enter a correct password, the screen saver terminates. If they do not enter a correct password, the screen saver keeps running.

However, if they are astute, they could do press Alt-Tab to switch to another program, use Ctrl-Alt-Del to forcibly terminate the screen saver, bring up the start menu, and so on. Obviously, you do not want them to be able to do this.

Windows allows your program to disable use of Alt-Tab, Ctrl-Alt-Del and so on, by using the ‘SystemsParameterInfo’ API and setting the undocumented SPI_SCREENSAVERRUNNING to 1. You should do this sometime before the "password request" dialog box is displayed, and set it back to 0 sometime before your screen saver terminates.

You can either set the SPI_SCREENSAVERRUNNING parameter to 1 right from when your screen saver starts, and set it back to 0 just before terminating, or just have it set while the "password request" dialog box is being displayed. My recommendation is to only set it around use of the "password request" dialog box, so that it does not permanently disable Alt-Tab and Ctrl-Alt-Del if the screen saver terminates in error.

If you are not using screen saver password protection, there is no problem with users being able to enter Alt-Tab or Ctrl-Alt-Del sequences etc., because as soon as they press any key (including Ctrl and Alt), the screen saver terminates.

This problem only applies to Windows 95 and not to Windows NT. This is because Windows NT manages password protection without involving your screen saver. NT runs your screen saver in a separate desktop window, and handles all the security issues itself.


Disabling the Mouse Cursor

When your screen saver is running, you should disable the mouse cursor so that it cannot be seen.

The best way to do this is to use the ‘ShowCursor(FALSE)’ API call to hide the cursor. You should use ‘ShowCursor(TRUE)’ to display the cursor again just before the screen saver terminates, and just before showing the "password request" dialog box.

It is also possible to set the screen saver window’s cursor to be a "null cursor" (i.e. all pixels transparent) before it is displayed, but this would prevent the cursor from showing up when the "password request" dialog box was displayed, unless you use the 'SetCursor' API call to change it and trap the mouse move events (to keep resetting the cursor). You can also use 'SetCursor' to set the cursor to NULL, but also have to trap mouse move events to prevent the cursor getting set back when the mouse is moved.

My screen savers use 'ShowCursor', because it is easy to implement.


Modifying the Desktop

Most screen savers cover the desktop with their own window, but there are some screen savers that seem to modify the appearance of the desktop. For example, dividing the desktop into squares and shuffling it around, or making the desktop appear to melt.

The screen savers do this by making a copy of the entire desktop when they start, and then adjusting this copy. They are not really altering the desktop itself.

This is possible under Windows 95, where the screen saver can get direct access to the desktop. However, with Windows NT, screen savers are run in a separate desktop, which just consists of the wallpaper background. You can see this if you turn on screen saver password protection, then look when you are prompted to enter your password. The background behind the dialog box is just the wallpaper.

Therefore, if you want to write a screen saver that appears to modify the desktop appearance, it will only work with Windows 95.


Using the Registry

If your screen saver has values that can be configured (e.g. to change the appearance or control the speed), or wants to be able to store and retrieve values (e.g. to indicate where it is up to), then the values should be stored in the registry.

The standard recommendation is to use a registry key of the following form :


Microsoft’s standard screen savers use :

If you want to be modern and up to date, you should use the proper 'registry' API calls to create the registry key and to save and retrieve configuration values. The alternative is to use the older 'profile' API calls, but get them to use the registry instead of ".ini" files.

In the days before the registry existed (i.e. Windows 3.1), programs kept configuration information in ".ini" files. The 'profile' API calls allowed values to be saved to and read from the ".ini" files. Modern programs should use the registry instead of ".ini" files. For compatibility, programs can still use the 'profile' API calls, but divert them to use the registry.

The 'registry' API calls and 'profile' API calls are explained next.

Registry API’s

To create a registry key or open a key for update, use :


To create or update a value within the registry key, use :


To close the registry key, use :

Profile API’s

These are the alternative to using the 'registry' API’s. You can divert them to use the registry by using the 'SetRegistryKey' API call.

You might be persuaded to use these because the call to ‘SetRegistryKey’ is automatically generated by App Wizard when you create a MFC application. I use the 'profile' API's, but it is probably better to use the proper 'registry' API calls.

The 'profile' API calls are implemented as methods of the CWinApp class, and the application name becomes part of the registry key that is used, as explained below.

Specify the registry key using :

This API causes the other ‘profile’ API’s to use the registry instead of the ".ini" file. The registry key will be :

The application name value is taken from the m_lpszAppName member of your CWinApp object. This can be set up by creating a resource string with id AFX_IDS_APP_TITLE, or by explicitly copying a value into m_lpszAppName. Otherwise, the application name will be the same as your generated screen saver file name (without the ‘.scr’ extension).

The company value can be whatever you like. I use my initial and surname.

To  store values in the registry use :

These two API’s write a value to the registry key "HKEY_CURRENT_USER\Software\\\

".

To retrieve values from the registry use :

The is specified by you, and is returned if the value does not exist within the registry key.

If you use the 'profile' API's and want to access the configuration values in methods that are not part of the application class, you will need to link to the application object. For example, you may want to do this so that the full-screen window can read the configuration values. Luckily, the MFC App Wizard generates the application object as a global variable, so other classes can access it by setting up an 'extern' link to it. How to do this is shown in the pages on constructing the code.


Next | Previous | Home

1