屏幕保护程序是一种特殊的应用程序,如果用户打开了Windows的屏幕保护功能,而且在一特定的时间段内没有任何输入,系统就回自动启动屏幕保护程序。屏幕保护程序有两个作用:
1.防止屏幕长时间显示静态图象而降低荧光介质的寿命。
2.防止用户离开计算机时屏幕上的信息被不相干的人看到。
相应的,屏幕保护程序至少应该实现以下两个功能:
1.动画功能:显示动态的图象。
2.密码校验功能:退出程序时屏蔽一切系统热键(Ctrl+Alt+Del,Alt+Tab,Ctrl+Esc 等,避免用户使用热键关闭程序或切换到其它程序而跳过密码校验),并要求输入授权密码。
我们可以找到不少介绍Windows屏幕保护程序的资料,也可以找到许多制作屏幕保护程序的工具。然而,由于不清楚Windows屏幕保护程序的密码校验功能,所以它们实现的往往只是动画功能,而没有提供密码校验功能。
实际上,Visual C++已经为我们准备好了一个屏幕保护库,使用它,我们可以非常容易的实现Windows屏幕保护程序的一切功能。
介绍Windows屏幕保护库
Windows屏幕保护库为我们提供了
1.WinMain ( )函数:完成程序初始化和消息调度。看到这里,可能有些读者已经想到了:我们不能在MFC中使用Windows屏幕保护库。为什么呢?原因很简单:MFC的底层封装了WinMain( )函数,如果在MFC中使用Windows屏幕保护库,一个程序中就会有两个WinMain( )函数,显然说不过去。因此,我们只有使用Win32 SDK了。
2.DefScreenSaverProc ( )函数:处理键盘、鼠标等消息,实现屏蔽热键及密码校验等功能。
3.一些函数、变量和常量的定义。
大家可以在Visual C++安装目录的Include子目录中找到SCRNSAVE.H文件,通过它,我们可以看到它们具体的定义。
当系统启动一个屏幕保护程序时,WinMain( )函数首先判断系统传递的命令行参数。如果参数指示设置屏幕保护程序,那么WinMain( )函数将会用函数
BOOL WINAPI ScreenSaverConfigureDialog (HWND hDlg,
UINT message,
WPARAM wParam,
LPARAM lParam
);
来创建设置对话框并将用户的输入保存到注册表中,还会用函数
BOOL WINAPI RegisterDialogClasses (HANDLE hInst)来注册设置对话框中的特殊窗口类或自定义控件类,如果没有特殊窗口类和自定义控件类,RegisterDialogClasses( )函数只需简单的返回TRUE值。如果参数指示运行屏幕保护程序,WinMain( )函数会调用一些初始化代码来注册窗口类并建立一个全屏窗口。而发送给屏幕保护程序的消息则由函数
LRESULT WINAPI ScreenSaverProc ( HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam
);
处理。我们可以在ScreenSaverProc( )函数中处理下面几个消息(当然也可以处理其它消息):
WM_CREATE 从注册表中获取屏幕保护程序的设置信息
创建一个计时器
处理其它的初始化工作
WM_TIMER 处理绘制工作
WM_DESTORY 销毁计时器
处理其它销毁工作
ScreenSaverProc( )函数未处理的消息则传递给DefScreenSaverProc( )处理。从这里我们可以看出,我们所要做的只是实现ScreenSaverProc( ),ScreenSaverConfigureDialog( )和
RegisterDialogClasses( )三个函数,而麻烦的密码校验和密码更改已经由DefScreenSaverProc( )函数实现了!剩下的就是编译并与Windows屏幕保护程序库连接了。
必须注意的是,Windows屏幕保护程序库对资源ID有一些特殊的要求。首先,它要求有一个ID为IDS_DESCRIPTION(定义为#define IDS_DESCRIPTION 1,见Visual C++目录的Include\SCRNSAVE.H文件),长度小于25的字符串资源,这个字符串将显示在桌面属性对话框屏幕保护程序列表框中。另一个要求是屏幕保护程序的设置对话框的ID必须为DLG_SCRNSAVECONFIGURE(定义为#define DLG_SCRNSAVECONFIGURE 2003)。
下面我们来看一个屏幕保护程序框架的源程序:
(笔者的开发环境为Windows 98和Visual C++ 6.0,由于笔者没有Windows NT,故未考虑Windows NT下的情况。)
屏幕保护程序框架的源程序
/////////////////////// 主程序 ///////////////////////
#include "windows.h"
#include "resource.h"
#include "ScrnSave.h"
LRESULT CALLBACK ScreenSaverProc(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam
)
{
switch (message)
{
case WM_CREATE:
// 从注册表中获取屏幕保护程序的设置信息
// 创建一个计时器
// 处理其它的初始化工作
return TRUE;
case WM_TIMER:
// 处理绘制工作
return TRUE;
case WM_DESTORY:
// 销毁计时器
// 处理其它销毁工作
return TRUE;
default:
return DefScreenSaverProc(hWnd, message, wParam, lParam);
}
return FALSE;
}
BOOL WINAPI ScreenSaverConfigureDialog (HWND hDlg,
UINT message,
WPARAM wParam,
LPARAM lParam
)
{
switch ( message )
{
case WM_INITDIALOG:
// 创建设置对话框并初始化各控件值
return TRUE;
case WM_COMMAND:
if ( LOWORD( wParam ) == IDOK )
{
// 将用户的输入保存到注册表中
EndDialog( hDlg, LOWORD( wParam ) );
return TRUE;
}
else if( LOWORD( wParam ) == IDCANCEL )
{
EndDialog( hDlg, LOWORD( wParam ) );
return TRUE;
}
break;
}
return FALSE;
}
BOOL WINAPI RegisterDialogClasses (HANDLE hInst)
{
// 注册特殊窗口类或自定义窗口类
return TRUE;
}
///////////////////////// Resource.h ////////////////////////////////
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by Script1.rc
//
#include "scrnsave.h" // 手工加入
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
大家可以在这个屏幕保护程序框架的基础上加入自己的实现。
注意我们必须先创建ID为DLG_SCRNSAVECONFIGURE的对话框资源和ID为IDS_DESCRIPTION的字符串资源,然后将Visual C++产生的Resource.h文件中的对
DLG_SCRNSAVECONFIGURE和IDS_DESCRIPTION的定义删除掉,并在其前部手工加入#include “scrnsave.h”,以保证这些资源能被Windows屏幕保护程序库使用。
编译前(无论是编译Win32 Debug版本还是Win32 Release版本均应做这一步),应先单击Visual C++的Project子菜单中的Settings选项,在弹出的对话框中选择Link选项卡,在其中的Object/library modules编辑框中加入Scrnsave.lib,单击OK,然后就可以编译了。编译完成后,将生成的.EXE改名为.SCR文件,拷贝到Windows系统目录的System子目录中,然后在桌面上单击鼠标右键,选属性,在弹出的对话框中选屏幕保护程序选项卡,并在屏幕保护程序下拉列表框中选中自己的屏幕保护程序,下面就自己去体验吧。
怎么样,用Windows屏幕保护程序库做屏幕保护程序不难吧!看着自己写的屏幕保护程序,感觉很不一样吧!
延伸阅读
文章来源于领测软件测试网 https://www.ltesting.net/