http://www.developer.com/

Back to article

Quickstart Guide to Screensavers


November 19, 2002

Need to knock together a seasonal screensaver? Perhaps you want to get in on corporate branding by ensuring all idle office monitors display your animated company logo? Or heck, maybe you just fancy having a little fun by throwing all your juicy holiday snapshots into one neat .SCR file?

If so, you'd better step right up—'cause our Quickstart guide has all the code you need. From setting the form properties to prompting for a password, disabling CTRL-ALT-DEL through to displaying your application in the screensaver preview window. Yup, it's all here ready for you to use—right here, right now.

We're here with the facts—and just the facts—so fire up your printer as we open our doors to the wonderful world of screensavers...

Screensavers are technically very similar to regular Visual Basic applications. The only real difference is the file extension, SCR as opposed to EXE.

Your screensaver could contain anything from a simple static company logo through to flying animations, a mini noughts-and-crosses through to a full-blown shoot-'em-up game. You create these just as you would any regular application, though with screensavers you typically place all the graphics and related functionality on one form.

First off, try creating a test project by following through our instructions for Setting Up your Form, Compiling Your Screensaver and Running your Screensaver. Then run through our extra sections to Determine the Mode, moving on later to Previewing your Screensaver. You might also want to find out about Changing the Password and Verifying the Password, plus you'll probably be interested in techniques such as Hiding the Cursor, Disabling Task Keys and Checking for Mouse Movement.

Setting Up your Form

Before creating a screensaver, you need to define a few key form properties.

  • Set the following properties on your screensaver form:
BackgroundBlack, usually
BorderStyle0 None
WindowState2 Maximised
ShowInTaskbarTrue

Compiling your Screensaver

You can compile any regular project into a screensaver.

  • Click 'File'
  • Select 'Make <ProjectName>.exe'
  • When the 'Make Project' box appears, change the '.exe' extension to '.scr'
  • Hit 'OK'

Running your Screensaver

You can run a screensaver from the Control Panel's Display applet or by simply double-clicking on it within Windows Explorer. This section deals with handling it via the Display applet.

  • Compile your Screensaver to the Windows directory
  • Click 'Start', 'Settings', 'Control Panel'
  • Double-click the 'Display' icon
  • Select the 'Screensaver' tab and choose your screensaver from the list
  • Hit the 'Preview' button

Note: Your screensaver may simply 'popup' before you hit the Preview button. If this occurs, you need to add code to handle the passed screensaver arguments. You do this by first Determining the Mode, then responding accordingly. We'll deal with this in the next section.

When your screensaver application is run (by, say, the Display applet or Windows itself) numerous arguments are passed to it, depending on what the calling application wants it to do. You can extract command-line arguments by analysing the string returned by the Command function.

Here's a list of arguments you may encounter, along with what they are asking your screensaver to do:

/pDisplay a preview of your screensaver (followed by a handle to the preview window)
/cDisplay any settings for your screensaver (followed by a handle to the Display Properties window)
/pDisplay a preview of your screensaver (followed by a handle to the preview window)
/sDisplay full screensaver
/aShow change password dialog box (followed by a handle to the Display Properties window)

Determining the Mode

To determine the screensaver mode, you need to analyse any passed arguments.

  • Use the following code to determine which mode you are currently in, preferably placing it into your Sub Main:
If Left(Command, 2) = "/p" Then' Run "Previewing your Screensaver" codeElseIf Left(Command, 2) = "/c" ThenMsgBox "Settings Dialog Box (If Required) Goes Here"ElseIf Left(Command, 2) = "/s" ThenMyScreensaverForm.ShowElseIf Left(Command, 2) = "/a" Then' Run "Changing the Password" codeEnd If

Previewing your screensaver means recreating a smaller version of it in the 'Preview' panel in the Display applet. This is not as difficult as it sounds and simply requires you to copy-and-paste a chunk of code.

Previewing your Screensaver

  • Add the following code to a module in your screensaver application:
Private Type RECT   Left As Long   Top As Long   Right As Long   Bottom As LongEnd TypePrivate Const WS_CHILD = &H40000000Private Const GWL_STYLE = (-16)Private Const GWL_HWNDPARENT = (-8)Private Const HWND_TOP = 0&Private Const SWP_NOZORDER = &H4Private Const SWP_NOACTIVATE = &H10Private Const SWP_SHOWWINDOW = &H40Declare Function GetClientRect Lib "user32" _    (ByVal hwnd As Long, lpRect As RECT) As LongDeclare Function GetWindowLong Lib "user32" _    Alias "GetWindowLongA" (ByVal hwnd As Long, _    ByVal nIndex As Long) As LongDeclare Sub SetWindowPos Lib "user32" (ByVal _    hwnd As Long, ByVal hWndInsertAfter As Long, _    ByVal X As Long, ByVal Y As Long, ByVal _    cx As Long, ByVal cy As Long, ByVal wFlags As Long)Declare Function SetWindowLong Lib "user32" _    Alias "SetWindowLongA" (ByVal hwnd As Long, _    ByVal nIndex As Long, ByVal dwNewLong As Long) As LongDeclare Function SetParent Lib "user32" _    (ByVal hWndChild As Long, _    ByVal hWndNewParent As Long) As LongPublic Sub DoPreviewMode(PreviewForm As Form)        Dim lngStyle As Long, dispHWND As Long, DispRec As RECT        dispHWND = CLng(Right(Command, Len(Command) - 3))        Load PreviewForm    GetClientRect dispHWND, DispRec    lngStyle = GetWindowLong(PreviewForm.hwnd, GWL_STYLE)    lngStyle = lngStyle Or WS_CHILD ' Append "WS_CHILD"    SetWindowLong PreviewForm.hwnd, GWL_STYLE, lngStyle    SetParent PreviewForm.hwnd, dispHWND    SetWindowLong PreviewForm.hwnd, GWL_HWNDPARENT, dispHWND    SetWindowPos PreviewForm.hwnd, HWND_TOP, 0&, 0&, _        DispRec.Right, DispRec.Bottom, _        SWP_NOZORDER Or SWP_NOACTIVATE Or SWP_SHOWWINDOW        End Sub
  • When a preview is requested (see Determining the Mode), run the DoPreviewMode method, passing it your form to preview as an argument

Your screensaver needs to handle passwords. This section will deal with allowing the user to change their password. We will later look at prompting the user for a password, plus verifying its authenticity.

Changing the Password

  • Add the following code to a module in your screensaver application:
Declare Function PwdChangePassword& Lib "mpr" _    Alias "PwdChangePasswordA" (ByVal lpcRegkeyname$, _    ByVal hwnd&, ByVal uiReserved1&, ByVal uiReserved2&)        Public Sub ChangePassword()    Dim dispHWND As Long    ' Get handle of the Display Properties window    dispHWND = CLng(Right(Command, Len(Command) - 3))        ' Call the change password screen    Call PwdChangePassword("SCRSAVE", dispHWND, 0, 0)End Sub
  • When a password change is requested (see Determining the Mode), run the ChangePassword method

Your actual screensaver needs to be able to handle user responses. When the mouse moves, it needs to quit or prompt for a password. The cursor should be invisible and the task keys should be disabled. This section handles these issues.

Hiding the Cursor

  • Add the following API declaration to a module in your screensaver application:
Declare Function ShowCursor Lib "user32" _    (ByVal bShow As Long) As Long
  • Pass the ShowCursor API call a True or False to show or hide the cursor, respectively. For example, this code hides the cursor: Call ShowCursor(False)

Disabling Task Keys

Task key combinations, such as CTRL-ALT-DEL, ALT-TAB and CTRL-F4, should be disabled when your screensaver starts, then re-enabled when it quits.

  • Add the following code to a module in your screensaver application:
Private Const SPI_SCREENSAVERRUNNING = 97&Declare Function SystemParametersInfo Lib "user32" _    Alias "SystemParametersInfoA" (ByVal uAction As _    Long, ByVal uParam As Long, lpvParam As Any, ByVal _    fuWinIni As Long) As LongPublic Sub EnableTaskKeys(Enabled As Boolean)If Enabled = False Then    'Disable CTRL+ALT+DELETE    SystemParametersInfo SPI_SCREENSAVERRUNNING, 1&, 0&, 0Else    ' Enable CTRL+ALT+DELETE    SystemParametersInfo SPI_SCREENSAVERRUNNING, 0&, 0&, 0End IfEnd Sub
  • To use this code, run the EnableTaskKeys method, passing a True or False argument to enable or disable the task keys respectively. For example, to enable the task keys, run: EnableTaskKeys (True)

Checking for Mouse Movement

You need to monitor mouse movement in your screensaver, so you know when to either quit or prompt for a password.

  • Add the following code behind the MouseMove event of your Form:
Static intMoveCount As IntegerIntMoveCount = intMoveCount + 1If intMoveCount > 5 Then Unload MyScreenSaverForm

As your screensaver form is unloading, you need to check whether the password is enabled and if so, prompt the user for it.

  • Add the following code behind the Unload event of your Form:
' Check password is enabledIf IsPasswordEnabled = True Then' If so, show cursorCall ShowCursor(True)' Verify passwordIf VerifyScreenSavePwd(Me.hwnd) = False Then' If incorrect, forget the UnloadCancel = TrueCall ShowCursor(False)Exit SubEnd IfEnd If' But if no password enabled' or password is correct,' it's time to clean up before leavingCall EnableCtrlAltDelete(True)Call ShowCursor(True)
  • Add the following supporting code to a module in your screensaver application:
' Password checkPublic Function VerifyScreenSavePwd Lib _    "password.cpl" (ByVal hwnd&) As Boolean' Registry API functionsPrivate Const HKEY_CURRENT_USER = &H80000001Public Const REG_DWORD As Long = 4Declare Function RegOpenKey Lib "advapi32.dll" _    Alias "RegOpenKeyA" (ByVal hKey As Long, ByVal _    lpSubKey As String, phkResult As Long) As LongDeclare Function RegQueryValueEx Lib "advapi32.dll" _    Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal _    lpValueName As String, ByVal lpReserved As Long, _    lpType As Long, ByVal lpData As String, lpcbData _    As Long) As LongDeclare Function RegCloseKey Lib "advapi32.dll" _    (ByVal hKey As Long) As LongPublic Function IsPasswordEnabled() As Boolean    ' Checks registry to see if password is enabled    If ReadRegistry(HKEY_CURRENT_USER, "Control Panel\Desktop", _        "ScreenSaveUsePassword") = 1 Then                IsPasswordEnabled = True            End If        End FunctionPrivate Function ReadRegistry(ByVal Group _    As Long, ByVal Section As String, ByVal Key _    As String) As String    ' Reads from the registry    Dim lResult As Long, lKeyValue As Long, _    lDataTypeValue As Long, lValueLength As Long, _    sValue As String, td As Double        On Error Resume Next        lResult = RegOpenKey(Group, Section, lKeyValue)    sValue = Space$(2048)    lValueLength = Len(sValue)    lResult = RegQueryValueEx(lKeyValue, Key, 0&, _    lDataTypeValue, sValue, lValueLength)        If (lResult = 0) And (Err.Number = 0) Then               If lDataTypeValue = REG_DWORD Then                        td = Asc(Mid$(sValue, 1, 1)) + &H100& * _                Asc(Mid$(sValue, 2, 1)) + &H10000 * _                Asc(Mid$(sValue, 3, 1)) + &H1000000 * _                CDbl(Asc(Mid$(sValue, 4, 1)))                      sValue = Format$(td, "000")              End If              sValue = Left$(sValue, lValueLength - 1)        Else              sValue = "Not Found"        End If        lResult = RegCloseKey(lKeyValue)    ReadRegistry = sValueEnd Function

Top Tip: If when in preview mode, your application is prompting you for a password, try adding an 'IsRunning' global boolean to your screensaver. Then, when your application runs the full screensaver (see Determining the Mode), set this variable to True. In the Unload event of your form, check for this if it is True, prompt for a password. Otherwise, you'll be in preview mode and can simply ignore it. You can also detect whether the screensaver is running is by using a SystemParametersInfo API call.

That's all for this Quickstart Guide to Screensavers!

Join us again soon for more printable reference guides to the most popular programming activities with facts. And just the facts.

So until next time - Goodbye!

Sitemap | Contact Us

Thanks for your registration, follow us on our social networks to keep up-to-date