65.9K
CodeProject is changing. Read more.
Home

ScreenSaverNow: Starts the Screensaver

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.08/5 (7 votes)

Oct 19, 2005

2 min read

viewsIcon

64648

downloadIcon

779

A utility that starts the screensaver.

Sample Image - ScreenSaverNow.gif

Introduction

Since I work in a company, when I leave my desk I like to lock my computer, as a good security practice. I used to do this by typing the Windows+L key combination. But this brings up that ugly default dialog box. I'd much rather start the screensaver and have it configured so the machine will be blocked when the screensaver is interrupted.

The problem is: how to start the screensaver in a handy way? This utility, ScreenSaverNow, does this.

Background

My search for a utility to start the screensaver was not very successful. I wouldn't pay US$ 20 for a program just to do that. And I didn't want some memory-resident thing using resources and notification area space unnecessarily. So I decided to build my own program.

Finding instructions on how to do this was not so easy either. I couldn't find anything about this on the .NET Framework documentation. After wading through a lot of irrelevant search results, I found some Visual Basic 6 code to do it using the Windows API:

Declare Function GetDesktopWindow Lib "user32" () As Long
Public Declare Function SendMessage Lib "user32" _
    Alias "SendMessageA" (ByVal hWnd As Long, ByVal _
    wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

Public Const WM_SYSCOMMAND As Long = &H112&
Public Const SC_SCREENSAVE As Long = &HF140&

Function gf_StartScreenSaver() As Boolean
    Dim hWnd&
    On Error Resume Next
    hWnd& = GetDesktopWindow()
    Call SendMessage(hWnd&, WM_SYSCOMMAND, SC_SCREENSAVE, 0&)
    gf_StartScreenSaver = (Err.Number = 0)
End Function

Microsoft also has a sample in Visual Basic 6:

[general declarations]
#If Win32 Then
    Private 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
    Const WM_SYSCOMMAND = &H112&
    Const SC_SCREENSAVE = &HF140&
#Else
    Private Declare Function SendMessage Lib "User" (ByVal _ hWnd
        As Integer, ByVal wMsg As Integer, ByVal wParam As _ Integer,
        lParam As Any) As Long
    Const WM_SYSCOMMAND = &H112
    Const SC_SCREENSAVE = &HF140&
#End If

Private Sub Command1_Click()
    Dim result As Long
    result = SendMessage(Form1.hWnd, WM_SYSCOMMAND, _
        SC_SCREENSAVE, 0&)
End Sub

There was nothing for .NET. So I decided to convert these examples from Visual Basic 6 to Visual Basic .NET.

Using the code

This is the source code for ScreenSaverNow:

Public Class Main

    Private Declare Function GetDesktopWindow Lib "user32" () As Integer
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
        (ByVal hWnd As Integer, ByVal wMsg As Integer, _
        ByVal wParam As Integer, ByRef lParam As Integer) As Integer

    Const WM_SYSCOMMAND As Integer = &H112
    Const SC_SCREENSAVE As Integer = &HF140

    Private Shared Sub StartScreenSaver()
        Dim hWnd As Integer
        hWnd = GetDesktopWindow()
        SendMessage(hWnd, WM_SYSCOMMAND, SC_SCREENSAVE, 0)
    End Sub

    Public Shared Sub Main()
        Try
            StartScreenSaver()
        Catch ex As Exception
            MsgBox("Error: " & ex.Message)
        End Try
    End Sub

End Class

The two Declare statements declare the Windows API functions that will be called. The two Const statements are just predefined values that the API expects.

StartScreenSaver is the main method. It uses the GetDesktopWindow API function to get the handle for the Windows Desktop window. Then the WM_SYSCOMMAND message is sent to that window with the SC_SCREENSAVE parameter.

When Windows processes this message, it starts the default screensaver. If the screensaver is configured, in the Display Properties dialog box, for password protection, Windows will guarantee that the workstation will be locked when the screensaver is interrupted.

Finally, the Sub Main just runs the main method.

Points of Interest

First of all, this information is not so easy to discover nowadays as we don't look up the Windows API so much anymore and we expect that the .NET Framework will encapsulate anything we want to do on the underlying Windows system. Not quite.

Second, this was a great exercise on how to leverage old-school Visual Basic API calling on a .NET project. I consider it a great thing that backward compatibility remains and that we can still use the Windows API if and when we need to.

References

History

  • October 19, 2005
    • Initial revision.