TITLE:Screen Savers in MultiValue Environment
ISSUE:Multi-Value Solutions Nov'98
More and more people are integrating their MultiValue system on to Windows workstations. For those who have moved to Windows workstations, you found that you have lost some basic control over the workstation that you had with dumb terminals.
With dumb terminals, the IS department could control what people had access to and how the data moved through the system. They had control over what people could load on the system, or what they could use the system for.
With Windows terminals, the IS department loses these controls. As more and more employees learn how to work with Windows, they start playing with settings on the Windows workstations at work. They also start loading their own applications or games.
Not only do you have these problems you now have other people in the company that that know how to do these things. With a little searching or playing they may be able to access accounting information just by using the same computer that accounting uses when no one is around to control the access.
The question comes up on how to regain control over the workstations. There are a lot of things that can and need to be done. One is to use screen savers.
All Windows systems come with default screen savers. However, most are more playful than functional. In this article I'm going to show you how to make screen savers useful to the IS department.
All screen savers have a password option that requires the user to input a password before the screen saver disappears. The one problem is that the password exists on the local machine and is a generic overall password that is easily pass around to other coworkers. It also doesn't allow you the ability to control the time of the day and the days of the week the user may use the system.
Now imagine having a screen saver that validates a user name and password against information on the host system. In this article I'm going to show you how to make one. This program requires a little bit of knowledge of Visual Basic as well as Visual Basic hooks into the MultiValue database, eg: Winlink32, Pic-Lan, D3 Objects, or UniObjects.
Due to the length of this topic, I'll have to cover how to do this in more than one article.
For starters, create a new Visual Basic "Standard EXE" project. You need 2 form -- Savemain and frmLogin -- and one module. In this article, I'll cover the main code needed to make the screen saver function in Windows.
Due the complexity of some of the API code, I will not cover the actual detail on how each one of the APIs are used. The code supplied in this article is to be placed in the VB module.
Here is a basic description of what each routine in this set of code does.
Main() = used when the program is started. It decides what part of the routine to use with the switch Windows uses when the program is run.
cleanup_and_end() = runs right before the screen saver stops the program. It is used to clean up any open variables or system settings that need to be reset.
start_screensaver() = starts the screen saver. It launches the Savemain form that is displayed when the screen save is active.
Check_password() = sets the local screen saver password. This routine is run when the user tries to set the screen saver password in the Control Panel. In this example, if the user tries to do this, it displays a message saying the function is not available.
start_preview_box() = when displaying the screen saver in the Control Panel, there is a preview window that allows the user to see what the screen saver looks like when it is running.
run_configuration() = some screen savers allow users to configure what they do. For example, the speed or color of the information being displayed on the screen. For this example, the routine displays a message saying that there is no configuration screen.
Set_TFS() = this routine disables or enables the ctrl-alt-del keys so the user can't reset the computer to get around the screen saver.
GetVersion32() = gets the current version of the Windows OS the screen saver is running on. There are some options that work differently on Windows NT than Windows 95.
' Constants List
Public Const WS_CHILD = &H40000000
Public Const GWL_STYLE = (-16)
Public Const GWL_HWNDPARENT = (-8)
Public Const HWND_TOP = 0&
Public Const SWP_NOZORDER = &H4
Public Const SWP_NOACTIVATE = &H10
Public Const SWP_SHOWWINDOW = &H40
Public Const SPI_SCREENSAVERRUNNING = 97&
' ScreenSaver Running Modes
Public Const RM_NORMAL = 1
Public Const RM_CONFIGURE = 2
Public Const RM_PASSWORD = 3
Public Const RM_PREVIEW = 4
' API call to turn mouse cursor on / off
Declare Function ShowCursor Lib "user32" (ByVal bShow As Long) As Long 'Version info
Private OsVers As OsVersionInfo
dwVersionInfoSize As Long
dwMajorVersion As Long
dwMinorVersion As Long
dwBuildNumber As Long
dwPlatform As Long
szCSDVersion As String * 128
Private Declare Function GetVersionEx& Lib "kernel32" Alias "GetVersionExA" (lpStruct As OsVersionInfo) ' API calls required to talk to the preview window
Declare Function GetClientRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
Declare Function IsWindowVisible Lib "user32" (ByVal hwnd As Long) As Long
Declare 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)
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, _
ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, _
ByVal nIndex As Long) As Long
Public Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, _
ByVal uParam As Long, lpvParam As Any, ByVal fuWinIni As Long) As Long
' Public variable fields
Public CurrOS As String ' Name of operating system, 95 or NT
Public PWMode As Integer ' Screensaver password enabled flag
Public RunMode As Long
Public DispRec As RECT ' Rectangle values of display form
' Private variable fields
Private dispHWND, style As Long '
Types Public Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
' Ensure that only one instance of this screensaver is running
Randomize ' Seed the random number generator - may be required
' Check the command line arguments
If Left(Command$, 2) = "/p" Then
' The command-line argument /p is used to launch the preview box
RunMode = RM_PREVIEW start_preview_box
ElseIf Left(Command$, 2) = "/c" Then
' The command-line argument /c is used to launch the screen saver
in setup mode RunMode = RM_CONFIGURE run_configuration
ElseIf Left(Command$, 2) = "/s" Or Command$ = "" And Not
' The command-line argument /s is used to launch the screen saver
in normal operating mode RunMode = RM_NORMAL start_screensaver
ElseIf Left(Command$, 2) = "/a" Then
' The command-line argument /a is used to launch the password mode
RunMode = RM_PASSWORD Check_password
Public Sub cleanup_and_end() ' Public exit - can be called from forms etc.
On Error Resume Next
ShowCursor True ' Unhide the mouse cursor
Set_TFS "enable" ' Restore CTL+ALT+DEL
End ' Endex here
Private Sub start_screensaver()
On Error GoTo saver_error
ShowCursor True ' Hide the mouse cursor
' Get the O/S name using function in SysInfo code module
' Get the PW flag using a function in the ellreg code module.
CurrOS = GetVersion32 ' Find out the operating system, 95 or NT
' Find out if the user has enabled passwords for this screen saver If
CurrOS = "95" Then PWMode = 1 Set_TFS "disable" ' Stop CTL+ALT+DEL
Savemain.Show ' Start the screensaver Exit Sub
MsgBox "The screensaver has failed" & vbCrLf & vbCrLf &
Err.Description, vbOKOnly, "Saver"
Private Sub Check_password()
MsgBox "The password change not available.", vbOKOnly, "PW"
Private Sub start_preview_box()
On Error GoTo preview_error
' Convert preview window handle to long type
dispHWND = CLng(Right$(Command$, Len(Command$) - 3))
' Load up the preview form
GetClientRect dispHWND, DispRec ' Get Preview Box Rectangle dimensions
style = GetWindowLong(Savemain.hwnd, GWL_STYLE) ' Get current window
style style = style Or WS_CHILD ' Append "WS_CHILD" style to the hWnd window style
SetWindowLong Savemain.hwnd, GWL_STYLE, style ' Add new style to window
SetParent Savemain.hwnd, dispHWND ' Set preview form into preview window
' Save the hWnd Parent in hWnd's window struct.
SetWindowLong Savemain.hwnd, GWL_HWNDPARENT, dispHWND
SetWindowPos Savemain.hwnd, HWND_TOP, 0&, 0&, DispRec.Right, DispRec.Bottom, _
SWP_NOZORDER Or SWP_NOACTIVATE Or SWP_SHOWWINDOW
preview_error: ' No error messages when in preview mode - looks messy End
Private Sub run_configuration()
MsgBox "This screensaver has no configuration options", vbOKOnly, "Setup"
Public Sub Set_TFS(Command As String)
' Disable three finger salute (TFS) on Win 95.
' Call when you don't want people breaking past the screensaver
' when passwords are enabled. Command can be "enable" or "disable". '
Example - Set_TFS "enable" If PWMode = 1 And CurrOS = "95" Then
' only diable the Ctrl-Alt-Del When in Win95 or Win98
If LCase(Command) = "disable" Then
SystemParametersInfo SPI_SCREENSAVERRUNNING, 1&, 0&, 0&
If LCase(Command) = "enable" Then
SystemParametersInfo SPI_SCREENSAVERRUNNING, 0&, 0&, 0&
Public Function GetVersion32() As String
' Call to get the 32 Bit O/S ID. Returned values are either "95" or
' "NT" or "Unknown"
' Example - MyString = GetVersion32 '
OsVers.dwVersionInfoSize = 148& GetVersionEx OsVers If
OsVers.dwPlatform = 1& Then
GetVersion32 = "95"
ElseIf OsVers.dwPlatform = 2& Then
GetVersion32 = "NT"
GetVersion32 = "Unknown"