深入浅出屏幕保护程序编程

原创 2001年05月17日 21:43:00
深入浅出屏幕保护程序编程  作者:董晓 发布时间:2001/03/28
 
文章摘要:
  现在V程序画面越来越精美功能越来越强大,可以提供图象,动画,音频,视频等所有的多媒体功能。尽管我们可以很容易获得漂亮的屏幕保护程序,但自己制作屏幕保护程序对用户也许更有吸引力,下文便对如何制作屏幕保护程序做了详细介绍。
       

正文: button_class.GIF  



深入浅出屏幕保护程序编程
  


  读者对屏幕保护程序已经相当熟悉了。去年泰坦尼克号的屏幕保护程序风行了全世界,足见其魅力。有的屏幕保护程序功能十分强大,可以提供图象,动画,音频,视频等所有的多媒体功能。尽管可以很容易获得漂亮的屏幕保护程序,但拥有自己的屏幕保护程序对用户也许更有吸引力。
  VC5.0/6.0是开发屏幕保护程序的好工具。静态链接库SCRNSAVE.LIB对屏幕保护程序提供了支持。SCRNSAVE.LIB包含了建立屏幕保护程序的主程序和缺省功能,用户可以方便地使用SDK进行编程并与之连接。尽管SDK编程相对MFC麻烦,但编写相对简单的屏幕保护程序却相当容易甚至比用MFC编程更简单。
  也可以使用MFC编写屏幕保护程序。但遗憾的是MFC不支持SCRNSAVE.LIB,必须手工完成原来由SCRNSAVE.LIB提供的功能,比较麻烦和不好理解。不过,编写复杂的屏幕保护程序时,MFC对于显示模块和对话框处理可以提供比SDK方便得多的功能。为简单起见先介绍如何使用SDK编写屏幕保护程序。

一. 屏幕保护程序和SCRNSAVE.LIB

  先从开发者的角度对屏幕保护程序说明如下:
  首先,屏幕保护程序是Win32 API 支持一种特殊的应用程序并由系统自动激活。其机制是当条件满足时,系统向当前活动窗口发出字参数 wParam 值为SC_SCREENSAVE 的WM_SYSCOMMAND消息,然后由当前活动窗口执行SYSTEM.INI文件中[boot]区指定的屏幕保护程序。

  屏幕保护程序激活的条件是
  1. 在规定时间内没有鼠标或键盘输入.
  2. 当前的活动窗口是标准的WINDOWS应用程序。因为非WINDOWS应用,不会理睬WM_SYSCOMMAND消息。
  3. 显然,如果当前活动的程序接管了字参数 wParam 值为SC_SCREENSAVE 的WM_SYSCOMMAND 消息并且不传递到 DefWindowProc函数就可以禁止屏幕保护程序。这对某些运行中不愿意被打断的程序如视频播放,光盘刻录程序特别有用。

  其次,可以在控制面板的显示器中选择需要的屏幕保护程序,并可以配置屏幕保护程序的参数。屏幕保护程序应该提供配置屏幕保护程序的对话框。

  再次,屏幕保护程序有特别的输出函数,资源定义和变量声明。SCRNSAVE.LIB包含了建立屏幕保护程序的主程序。屏幕保护程序启动时SCRNSAVE.LIB自动创建一全屏窗口,并描述窗口类为无光标的满黑屏。
  用户编写的屏幕保护程序必须包含三个基本函数ScreenSaverProc,ScreenSaverConfigureDialog 和RegisterDialogClasses 并与SCRNSAVE.LIB连接。
  1.ScreenSaverProc 窗口函数处理特定的消息并把未处理的消息传递给SCRNSAVE.LIB 。ScreenSaverProc 一般处理以下消息:
  WM_CREATE 读取.INI或注册表的初始化数据,设置定时器以及其他初始化操作。
  WM_ERASEBKGND 擦除背景为下一步绘图作准备。
  WM_TIMER 进行绘图输出。用户可以实现自己的动画功能以及其他操作。
  WM_DESTROY 删除定时器以及其他对象
  ScreenSaverProc 把未处理的消息传递到SCRNSAVE.LIB中的 DefScreenSaverProc函数 处理。由它完成许多复杂和关键的操作比如何时激活,何时关闭等,大大方便了屏幕保护程序的编写。
  2.ScreenSaverConfigureDialog函数处理屏幕保护程序配置对话框。该对话框由控制面板的显示器设置程序调用。用户输入的配置数据输出到.INI或注册表中。
  3. RegisterDialogClasses函数登记屏幕保护程序配置对话框的窗口类。如果不使用特殊的窗口或控件,可以简单地返回TRUE。

  另外,编写屏幕保护程序还有一些原则。
  1. 为使控制面板能够识别,屏幕保护程序的扩展名必须改为.SCR并存放在WINDOWS目录下。
  2. 屏幕保护程序的图标(ICON)在资源文件中必须定义为ID_APP。ID_APP由系统的SCRNSAVE.H.定义。
  3. 资源文件中必须包含一描述字符串。该字符串用于控制面板显示屏幕保护程序的名字。它必须位于字符串表的首位。SCRNSAVE.H.定义其ID为1。
  4. 资源文件中屏幕保护程序配置对话框的ID必须为DLG_SCRNSAVECONFIGURE。它由系统的SCRNSAVE.H.定义。

二.编程实例

  1.最小的屏幕保护程序MiniSaver。这是一个仅包含最基本模块的屏幕保护程序,运行时在屏幕上显示一行活动的文字。步骤如下:
  第一步,在VC5.0/6.0中建立32位应用工程(不选MFC WIZARD EXE).建立如下的MiniSaver.CPP文件:
#include
#include
// SCRNSAVE.LIB的头文件
#include "resource.h"
//声明三个基本的函数
LRESULT WINAPI ScreenSaveProc
(HWND,UINT,WPARAM,LPARAM);
BOOL WINAPI ScreenSaveConfigureDialog
(HWND,UINT,WPARAM,LPARAM);
BOOL WINAPI RegisterDialogClasses(HINSTANCE);
//定义三个基本的函数
LRESULT WINAPI ScreenSaverProc
(HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam)
{ HDC hDC;
RECT rc;
static int xpos;//文本的横坐标
static char SlideText[]="欢迎使用屏幕保护程序!";
static UINT timerID;//定时器
switch (message)
{
case WM_CREATE:
xpos=0;
timerID=SetTimer(hWnd,1,250,NULL);//设置定时器
break;

case WM_ERASEBKGND:
//空操作,交由DefScreenSaverProc处理
break;
case WM_TIMER:
hDC=GetDC(hWnd);
//清屏
SetRect(&rc,0,0,GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN))
FillRect(hDC,&rc,GetStockObject(BLACK_BRUSH));
//输出文本
SetTextColor(hDC,RGB(255*rand(),
255*rand(),255*rand()));
SetBkColor(hDC,RGB(0,0,0));
TextOut(hDC,xpos,GetSystemMetrics(SM_CYSCREEN)/2,
SlideText,strlen(SlideText));
//移动文本的横坐标
xpos=(xpos+10)%GetSystemMetrics(SM_CXSCREEN);
ReleaseDC(hWnd,hDC);
break;

case WM_DESTROY:
KillTimer(hWnd,timerID);//删除定时器
PostQuitMessage (0);
return 0;
}
return DefScreenSaverProc
(hWnd,message,wParam,lParam);
}

BOOL WINAPI ScreenSaverConfigureDialog
(HWND hWnd,UINT message,WPARAM wParam,
LPARAM lParam)
{//暂时不需要配置对话框,仅返回FALSE
return FALSE;
}

BOOL WINAPI RegisterDialogClasses
(HINSTANCE hInstance)
{//一般不需要,仅返回TRUE
return TRUE;
}


  第二步,定义资源文件MiniSaver.rc。在VC环境下生成一图标,其ID为ID_APP。向字符串表加入ID为IDS_DESCRIPTION字符串"MiniSaver",并作为字符串表第一项
  第三步,编译连接并将生成的MiniSaver.EXE更名为MiniSaver.SCR拷入WINDOWS目录。注意, 编译前一定要在Project菜单的Setting中的Link选项中加上SCRNSAVE.LIB库。
  第四步,控制面板的显示器设置中选择屏幕保护程序MiniSaver就可以使用了。注意不要急于配置屏幕保护程序,因为MiniSaver还有没提供配置对话框。

  2.较完整的屏幕保护程序MySaver。该屏幕保护程序提供了配置对话框和关于对话框,并且使用了图象显示。读者可以将自己喜爱的图象加到资源中。
  第一步,在VC5.0/6.0中建立32位应用工程(不选MFC WIZARD EXE)并定义资源文件MiniSaver.rc。
    在VC环境下生成一图标,其ID为ID_APP。
    向字符串表加入ID为IDS_DESCRIPTION字符串"MiniSaver",并作为字符串表第一项。加入ID为idsAPPName
    字符串"Screen Saver.MySaver",说明见后面程序。
    加入ID为IDB_BITMAP1的位图
    加入ID为DLG_ABOUT对话框。仅有一ID为IDOK的按钮
    加入ID为ID_APP。此对话的ID由SCRNSAVE.H定义且只能为DLG_SCRNSAVECONFIGURE。其中有ID为IDC_EDIT
    的EDIT控件,ID为IDOK,IDCANCEL和IDABOUT的按钮。
    值得注意的是RESOURCE.H定义的ID_APP和DLG_SCRNSAVECONFIGURE可能与SCRNSAVE.H预定义的值冲突,可
    手动地将RESOURCE.H中的ID_APP设为100,DLG_SCRNSAVECONFIGURE设为2003即可。
  第二步,建立如下的MySaver.CPP文件:
#include #include

#include "resource.h"
//声明三个基本的函数
LRESULT WINAPI ScreenSaveProc
(HWND,UINT,WPARAM,LPARAM);
BOOL WINAPI ScreenSaveConfigureDialog
(HWND,UINT,WPARAM,LPARAM);
BOOL WINAPI RegisterDialogClasses(HINSTANCE);
BOOL WINAPI AboutDialog(HWND,UINT,WPARAM,LPARAM);
//定义全局变量
char szIniFileName[]="control.ini";
//屏幕保护程序配置数据存放在control.ini文件
char szSection[32];
//屏幕保护程序配置数据在control.ini文件位置区名称
char szEntry[]="Slide Text:";
//屏幕保护程序配置数据项名称
char SlideText[256];
//屏幕保护程序配置数据,这里是文本内容
//定义三个基本的函数
LRESULT WINAPI ScreenSaverProc
(HWND hWnd,UINT message, WPARAM wParam,
LPARAM lParam)
{ static HBITMAP hBmp;//位图句柄
HDC hDC,hMemDC;//hMemDC是内存设备,缓存位图。
RECT rc;
static int xpos=0;
static UINT timerID;
switch (message)
{
case WM_CREATE:
//文件位置区名称szSection赋值为资源
idsAPPName。其中hMainInstance为//SCRNSAVE.LIB
定义的屏幕保护程序实例句柄
LoadString(hMainInstance,idsAPPName,
szSection,sizeof(szSection));
strcpy(SlideText,"欢迎使用屏幕保护程序!");
//读control.ini文件中[Screen Saver.MySaver]
区的配置数据到SlideText
GetPrivateProfileString(szSection,szEntry,
SlideText,SlideText,
sizeof(SlideText),szIniFileName);
//取位图
hBmp=LoadBitmap(hMainInstance,
MAKEINTRESOURCE(IDB_BITMAP1));
timerID=SetTimer(hWnd,1,250,NULL);
break;

case WM_ERASEBKGND:
hDC=GetDC(hWnd);
//显示位图
hMemDC=CreateCompatibleDC(hDC);
SelectObject(hMemDC,hBmp);
SetRect(&rc,0,0,GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN)-25);
BitBlt(hDC,rc.top,rc.left,rc.right,rc.bottom,
hMemDC,rc.top,rc.left,SRCCOPY);
//清除底行,为文本显示作准备。
SetRect(&rc,0,GetSystemMetrics(SM_CYSCREEN)-25
GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN));
FillRect(hDC,&rc,GetStockObject(BLACK_BRUSH));
ReleaseDC(hWnd,hDC);
DeleteDC(hMemDC);
return 1;

case WM_TIMER:
hDC=GetDC(hWnd);
//清除底行
SetRect(&rc,0,GetSystemMetrics(SM_CYSCREEN)-25,
GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN));
FillRect(hDC,&rc,GetStockObject(BLACK_BRUSH));
//输出文本
SetTextColor(hDC,RGB(255*rand(),
255*rand(),255*rand()));
SetBkColor(hDC,RGB(0,0,0));
TextOut(hDC,xpos,GetSystemMetrics(SM_CYSCREEN)-25,
SlideText,strlen(SlideText));
xpos=(xpos+10)%GetSystemMetrics(SM_CXSCREEN);
ReleaseDC(hWnd,hDC);
break;

case WM_DESTROY:
DeleteObject(hBmp);
KillTimer(hWnd,timerID);
PostQuitMessage (0);
return 0;
}
return DefScreenSaverProc
(hWnd,message,wParam,lParam);
}

BOOL WINAPI ScreenSaverConfigureDialog
(HWND hWnd,UINT message,WPARAM wParam,
LPARAM lParam)
{ switch (message)
{
case WM_INITDIALOG:
LoadString(hMainInstance,idsAPPName,
szSection,sizeof(szSection));
strcpy(SlideText,"欢迎使用屏幕保护程序!");
GetPrivateProfileString(szSection,
szEntry,SlideText,
SlideText,sizeof(SlideText),szIniFileName);
SetDlgItemText(hWnd,IDC_EDIT,SlideText);
SetFocus(GetDlgItem(hWnd,IDC_EDIT));
return FALSE;

case WM_COMMAND:
switch(wParam)
{
case IDOK:
//取EDIT控件文本数据并写入control.ini文件
GetDlgItemText(hWnd,IDC_EDIT,
SlideText,sizeof(SlideText));
WritePrivateProfileString(szSection,
szEntry,SlideText,szIniFileName);
EndDialog(hWnd,TRUE);
return TRUE;

case IDCANCEL:
EndDialog(hWnd,FALSE);
return TRUE;

case IDABOUT:
//调用ABOUT对话框
DialogBox(hMainInstance,
MAKEINTRESOURCE(DLG_ABOUT),
hWnd,(FARPROC)AboutDialog);
return TRUE;
}
break;
}
return FALSE;
}

BOOL WINAPI RegisterDialogClasses
(HINSTANCE hInstance)
{
return TRUE;
}

BOOL WINAPI AboutDialog
(HWND hWnd,UINT message,WPARAM wParam,
LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;

case WM_COMMAND:
switch(wParam)
{
case IDOK:
EndDialog(hWnd,TRUE);
return TRUE;
}
break;
}
return FALSE;
}

   最后,编译连接并将生成的MiniSaver.EXE更名为MiniSaver.SCR拷入WINDOWS目录。此时可以使用配置对话框了。


作者会员名:heliking

 
版权声明:本文为博主原创文章,未经博主允许不得转载。

Linux下屏保程序

http://www.openswc.com/forum.php?mod=viewthread&tid=560 利用一些便捷的小软件把自己的数码相片做成绚烂多彩的屏保,放在自己的电脑上该是多么惬...
  • openswc
  • openswc
  • 2013年06月16日 10:56
  • 2792

Windows屏幕保护程序的制作

Windows屏幕保护程序的制作 前些日子看了阿卓工作室的一篇关于如何制作屏保程序的文章及其示例,我便想自己做一个玩玩,所以按他说的做,结果不行,所以就在MSDN中搜索了下,得到这么一篇文章...
  • Eternalze
  • Eternalze
  • 2015年06月01日 15:19
  • 2501

全局鼠标键盘事件实现应用程序的自动锁定

全局鼠标键盘事件实现应用程序的自动锁定         我们在进行信息系统开发的时候,有时为了系统数据保密性、安全性得到提升。需要考虑到如果在用户长时间内没有对鼠标及键盘进行操作时,让应用程...
  • anyqu
  • anyqu
  • 2014年08月15日 11:54
  • 646

QT关于屏幕保护程序

首先,要写一个屏保程序,需要一个定时器来统计多长时间没有处理事件进入休眠, 第二,事件处理是一个全局性的,过滤处理事件, //直接上源码吧,自己改改。重写Application #ifn...
  • cqltbe131421
  • cqltbe131421
  • 2017年08月01日 10:56
  • 134

黑客帝国_屏幕保护程序

Hacker empire 申明:本程序资源纯属个人创作,文尾提供程序下载地址。 效果图: 程序思路说明:     1:本源码是在VS2013中编写,在其他版本编译器应该也可以。     2:在...
  • qq_31622605
  • qq_31622605
  • 2017年04月19日 10:47
  • 536

深入浅出Linux工具与编程(socket 函数)

1.   基本套接字函数 (1)socket函数原型 socket(建立一个socket文件描述符) 所需头文件 #include       ...
  • u011347534
  • u011347534
  • 2015年02月13日 14:24
  • 560

win10如何设置或取消屏保密码

进入桌面,点击右键,选择“个性化” 点击左侧列表中的“锁屏界面”,再选择最下方的“屏幕保护程序设置” 在弹出的对话框中,点击“更改电源设置” 在弹出的窗口中选择:“唤醒时需要密码” 接着...
  • u014771464
  • u014771464
  • 2016年03月14日 10:05
  • 10607

Qt实现屏保功能,鼠标一定时间无响应程序进入待机状态

使用Qt实现类似与屏保的功能,当鼠标在一定时间内一直停留在一个位置的时候,程序会自动切入到其他界面(用于显示一些信息),当鼠标移动的时候,屏幕切换回来,效果类似于屏幕保护。 实现想法如下: 想法...
  • u012814360
  • u012814360
  • 2014年01月10日 21:23
  • 1167

mac_ScreenSaver_第1个屏幕保护程序

原文链接:http://cocoadevcentral.com/articles/000088.php written by Brian Christensen Writing a s...
  • u012576807
  • u012576807
  • 2016年06月13日 23:50
  • 617

屏幕取词编程学习总结

屏幕取词的研究 现在词典市场金山词霸占了绝对优势,所以再做字典也没什么前途了。我就是这么认为的,所以我虽然 掌握了这项技术,却没去做字典软件。只做了一个和词霸相似的软件自己用,本来想拿出来做共...
  • bcbobo21cn
  • bcbobo21cn
  • 2017年04月22日 19:05
  • 1343
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深入浅出屏幕保护程序编程
举报原因:
原因补充:

(最多只允许输入30个字)