Building a Screen Saver in Visual Basic

A Screen Saver is a program that Windows will run after a certain period of inactivity. The particular Screen Saver program and inactivity time period is configured as part of the Display setup in the Control Panel. Windows keeps track of keyboard and mouse activity and starts the Screen Saver program after no activity has been detected for the specified time period. A Windows screen saver program is simply an executable file, but an .EXE that has a number of specific requirements.


This example will build a Screen Saver that will display a series of graphics. These pictures can be displayed in sequential or random order. This application can also change the background color of the form randomly. In order to do this, you must use the random number generator and the timer control. This exercise will also step through some of the system options related to screen savers using the command line options.

Build the User Interface

Your Main form should have the following properties:

BorderStyle None No Border
ControlBox False No Caption, No Buttons
Icon None Highlight (Icon) and press Delete
ShowInTaskBar False Will not show up in the task bar at the bottom
WindowState Maximized Fill the entire desktop
AutoRedraw False No need for Windows to keep the screen contents

The Image Box should be sized so that it will nicely display the pictures you have selected and you should set the Stretch property to True. You can customize this at a later time, so for now just make the image fairly large.

 

Add a Control Array of Image Boxes

Initialize the picture property of each of the elements in the Image Box control array

Add a Timer Control

A Timer Control can execute code at regular intervals by firing the Timer event. The control is invisible to the user.

Set the Timer properties

This will cause tmrChange_Timer to fire every 5000ms. which is every 5 seconds

Programming the Timer

The Screen Saver is designed to repeatedly cycle through and display the series of pictures held in the control array of image boxes. To make the programming easier, we can user the UBound and LBound functions. and a static count variable to stay within the bounds of the array and keep track of what picture should display next.

Private Sub tmrChange_Timer()
    Static intCounter As Integer

    intCounter = intCounter + 1

    If intCounter > imgPictures.UBound Then
        intCounter = imgPictures.LBound
    End If

    imgImage.Picture = imgPictures(intCounter).Picture

End Sub


You can now run the program and see how it works.

Probably, the first thing you notice about this program is that the Image Box is not centered in the form. This is kind of difficult to do at design time with the WindowState of the form set to Maximized. This task can be performed at run time.

Private Function Center(c As Control) As Integer
    c.Move (Screen.Width - c.Width) / 2, (Screen.Height - c.Height) / 2

End Function

This function will center a control on the form using the Move method. The first parameter sets c.Left and the second parameter sets c.Top. Calling the function at Form_Activate and running the program should give you better results.

Private Sub Form_Activate()
    Dim rc As Integer

    rc = Center(imgImage)

End Sub

This function will work with any form control.

The program works, but it does not yet function as a screen saver.


Programming the Screen Saver Events

In order for the application to function as Screen Saver, it must terminate upon mouse or keyboard activity. These activities can be monitored in the following (and other) event handlers.

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
    Unload Me
End Sub

Private Sub Form_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)
    Static intCount As Integer

    If intCount < 10 Then
        intCount = intCount + 1
        Exit Sub
    End If

    Unload Me

End Sub

Form_MouseMove is fired when the Form is loaded, so a static variable and a counter handles this situation, and in addition, makes the program a bit less sensitive to mouse movements.

Go ahead and run the program to see that the these monitors terminate the programs.


Other Screen Saver Features

That Annoying Cursor

Use an API function to hide the cursor. The ShowCursor function accepts a Boolean value to Turn On or Turn Off the cursor. Turn it off in Form_Load, but be sure to turn it back on in Form_Unload when you exit.

Private Declare Function ShowCursor Lib "user32" (ByVal bShow As Long) As Long

Private Sub Form_Load()
    Dim rc As Integer
    rc = ShowCursor(False)
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Dim rc As Integer
    rc = ShowCursor(True)
End Sub

Run the program now, and the cursor should not be visible.

Control Panel / Display Properties

If you look at the configuration dialog for the Screen Saver setup, there are a number of features, like Password Protection, Screen Saver Settings, and Preview.

When these options are selected, Windows invokes the Screen Saver program, but passes a Command Line parameter to tell the application what option was selected.

/s Show the Screen Saver
/c Display the Settings Dialog
/a Display the Password Change Dialog
/p Preview the Screen Saver

While we will not discuss the Preview option, checking the Command Line parameter and displaying the proper dialog can be programmed in the Main subroutine.

Public Sub Main()
    Dim strOption As String

    If App.PrevInstance Then
        Exit Sub
    End If

    strOption = Left$(Command, 2)

'     If strOption = "/p" Then
'         MsgBox "Preview"
'         frmMain.Show
'         Exit Sub
'     End If

    If strOption = "/c" Then
        MsgBox "Sorry, this Screen Saver has nothing to configure"
        Exit Sub
    End If

    If strOption = "/a" Then
        MsgBox "Sorry, Password Protection is not supported"
        Exit Sub
    End If

    If strOption = "/s" Then
        frmMain.Show
        Exit Sub
    End If

End Sub

Sub Main checks what is being passes on the Command line. In VB, the Command object contains the contents of the Command Line. Depending on the switch that is set by Windows when the Screen Saver is invoked, the program acts a little differently. As none of the switches are supported, a dialog box is displayed informing the user. Only the '/s' is used, as this is the switch that calls for the Screen Saver to be run directly.

After you add this change (and change the Startup Object to Sub Main), you must simulate this switch to continue testing.

Under the Project Properties, click on the Make tab. In the Command Line Arguments box, type "/s" (no quotes).

 

Create the Screen Saver Executable

To create the Screen Saver program, select File | Make .EXE. Change to the Windows Directory, and change the extension on the executable from .EXE to .SCR

Once you've created the SCR file, you should be able to go to the Display option of the Control Panel and select your Screen Saver from the list displayed. Set the Wait period to 1 minute, and then just sit back.

Here is an example of a Screen Saver written in VB that is similar to the one described in this lesson

Download an example


Creating a Test Application

You can start a screen saver from VB application (provided, of course, you have a screen saver enabled).

Const WM_SYSCOMMAND = &H112&
Const SC_SCREENSAVE = &HF140&

Declare Function SendMessage _

            Lib "user32" Alias "SendMessageA" _
                    (ByVal hWnd As Long, _

                    ByVal wMsg As Long,
                    ByVal wParam As Long, _
                     ByVal lParam As Long)         As Long

Call SendMessage(frmMain.hWnd, WM_SYSCOMMAND, SC_SCREENSAVE, 0&)

Place this code in a Command Button click event on any form, and when you press the button, the Screen Saver will run immediately.

Download this example