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.
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
On Error Resume Next
hWnd& = GetDesktopWindow()
Call SendMessage(hWnd&, WM_SYSCOMMAND, SC_SCREENSAVE, 0&)
gf_StartScreenSaver = (Err.Number = 0)
Microsoft also has a sample in Visual Basic 6:
#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&
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&
Private Sub Command1_Click()
Dim result As Long
result = SendMessage(Form1.hWnd, WM_SYSCOMMAND, _
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)
Public Shared Sub Main()
Catch ex As Exception
MsgBox("Error: " & ex.Message)
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
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.
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.