分享
 
 
 

用C++Builder 5开发Windows下的屏保

王朝c/c++·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

E_Mail:codehunter@sohu.com

摘要:本文通过一个具体的程序演示了Windows下的屏幕保护程序的实现过程。

一. 引言

视窗系统下的屏幕保护程序是一个基于命令行(Command Line)的应用程序。当屏保

程序被调用时操作系统就用具体的命令行执行该程序。本文组织和处理了所有的命令行,包

括“/p”,“/s”,“/c”,“/a”,其中“/p”表示让屏保在预览窗口中显示;“/s”表示真正运行

屏保;“/c”表示调用设置对话框;而“/a”表示调用密码设置对话框(WinNT中无效)。本

程序尽可能简单地实现一个全功能的屏保,运行Windows的屏保设置程序时你既可以修改

密码(WinNT中无效)又可以设置图片显示的频率并把频率数值保存到注册表里。当屏保

运行时图片以你设置的频率改变显示位置。笔者还留了个作业给读者,请看图1中的选择图

片文件夹这个项目,按下浏览按钮可以设置图片的路径,笔者已经实现了浏览按钮的功能并

把得到的路径也保存到注册表中,并让屏保启动时读picdir的值,picdir等于"no"时的代码

笔者已实现了,picdir不等于"no"时的代码由读者实现。也就是让读者实现一个能把picdir

目录里的图片轮流显示的屏保程序。

二. 实现方法

首先介绍几个API函数。

WinMain函数:

int WINAPI WinMain(

HINSTANCE hInstance, // 当前实例句柄

HINSTANCE hPrevInstance, // 前一个实例句柄

LPSTR lpCmdLine, // 指向命令行参数的指针(本程序要利用的参数)

int nCmdShow // 窗口的状态

);

GetWindowLong函数:得到指定窗口信息的函数

LONG GetWindowLong(

HWND hWnd, file://窗口句柄

int nIndex file://指定返回的信息

);

SetWindowLong函数:改变窗口属性

LONG SetWindowLong(

HWND hWnd, file://窗口句柄

int nIndex, // 指定要设定的值的信息

LONG dwNewLong // 新值

);

SetParent函数:改变指定窗口的父窗口

HWND SetParent(

HWND hWndChild, file://要改变父窗体的窗口句柄

HWND hWndNewParent file://新的父窗体的句柄

);

GetClientRect函数:得到窗口的客户区

BOOL GetClientRect(

HWND hWnd, // 窗口句柄

LPRECT lpRect file://RECT结构的地址

);

SetWindowPos函数:改变窗口的大小,位置,顶级窗口等

BOOL SetWindowPos(

HWND hWnd, // 窗口句柄

HWND hWndInsertAfter, // 布置窗口顺序的句柄(Z order)

int X, // horizontal position

int Y, // vertical position

int cx, // width

int cy, // height

UINT uFlags // 窗口位置等标记

);

SystemParametersInfo函数:访问或设置系统级的参数

BOOL SystemParametersInfo(

UINT uiAction, // 指定要获取或设置的系统参数

UINT uiParam, // depends on action to be taken

PVOID pvParam, // depends on action to be taken

UINT fWinIni // 用户配置文件是否改变标记

);

ShowCursor函数:显示或隐藏光标

int ShowCursor(

BOOL bShow // 鼠标可见度标记

);

GetVersion函数:获取系统的版本信息

DWORD GetVersion(VOID)

以上API函数的具体信息可以查找有关MSSDK文档。了解了基本函数后笔者简述一

下实现方法。

1. 新建一工程,增加两个窗体,将三个窗体分别取名为MainForm,FrmConfig,

FrmControl。在MainForm和FrmControl窗体上各添加一个Timer控件和TImage控件,

把两窗体的BorderStyle设为bsNone,背景色设为黑色。在两个窗体的TImage上各加一

张图片,FrmControl大小设为:高130像素,宽160像素,Timage的Stretch属性设为真

值。FrmConfig的样式如图1。

2. 保存工程文件为screensaver.cpp,其它单元分别存为Unitmain.cpp,

Unitcontrol.cpp,Unitconfig.cpp。

3. 编写代码,具体代码见第三部分的源程序。

4. 编译成可执行文件,并把文件扩展名改为scr。

5. 最后把屏保程序拷贝到windows目录下就可以测试了。如果一切正常的话你将会看

到图片在屏幕上以随机的位置显示。

图1

三. 源代码

以下是本程序的所有的源代码,其中screensaver.cpp, Unitmain.cpp是核心代码。

/*{*******************************}*/

/*{***** screensaver.cpp ****}*/

/*{*******************************}*/

file://---------------------------------------------------------------------------

#include

#pragma hdrstop

USERES("screensaver.res");

USEFORM("Unitmain.cpp", Frmmain);

USEFORM("Unitconfig.cpp", FrmConfig);

USEFORM("Unitcontrol.cpp", FrmControl);

file://---------------------------------------------------------------------------

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR p, int)//“p"是指向命令行参数的指针

{ String StartType;

AnsiString Command=p,temp;

HWND CPWindow =NULL;

if(Command=="")

StartType = "/c";

else

StartType=Command.SubString(1,2);//获取命令行的前两个参数

try

{

Application->Initialize();

if(StartType=="/c")//启动设置窗口

Application->CreateForm(__classid(TFrmConfig), &FrmConfig);

else if(StartType=="/s")启动屏保

Application->CreateForm(__classid(TFrmmain), &Frmmain);

else if(StartType=="/p")//预览

{

Application->CreateForm(__classid(TFrmControl), &FrmControl);

temp=Command.SubString(3,Command.Length()-2);//获取命令行中的屏保预览窗

口句柄的字符串形式

CPWindow =(long *)temp.ToInt();//将预览窗口句柄的字符串形式强制转换为长整形

指针

RECT *lookrect;//建立一个RECT结构指针

Long style=GetWindowLong(Application->MainForm->Handle,GWL_STYLE);//获

取FrmControl窗口的风格

style=style|WS_CHILD;

SetWindowLong(Application->MainForm->Handle,GWL_STYLE,style);//设置窗口

为子窗口

SetParent(Application->MainForm->Handle,CPWindow);//设置屏保预览窗口为

FrmControl的父窗口

GetClientRect(CPWindow,lookrect);//获取屏保预览窗口的客户区

SetWindowPos(Application->MainForm->Handle,HWND_TOP,0,0,lookrect->right,lookrect->bottom ,SW

P_NOZORDER|SWP_NOACTIVATE|SWP_SHOWWINDOW);//将FrmControl的窗口覆盖屏保预览窗口

的客户区,并显示它

}

else if(StartType=="/a")//启动密码设置窗口

{

temp=Command.SubString(3,Command.Length()-2);

CPWindow =(long *)temp.ToInt();

file://以下是动态调用mpr.dll里的PwdChangePasswordA函数的过程

typedef UINT(CALLBACK *FUN)(LPSTR,HWND,UINT,UINT);

HINSTANCE hDll=LoadLibrary("mpr.DLL");

FUN myfun;

if(hDll!=NULL)

{

myfun=(FUN)GetProcAddress(hDll,"PwdChangePasswordA");

if(!myfun)FreeLibrary(hDll);

else

myfun("SCRSAVE", CPWindow, 0, 0);//函数的调用

}

}

Application->Run();

}

catch (Exception &exception)

{

Application->ShowException(&exception);

}

return 0;

}

file://---------------------------------------------------------------------------

/*{*******************************}*/

/*{***** Unitmain.h ****}*/

/*{*******************************}*/

file://---------------------------------------------------------------------------

#ifndef UnitmainH

#define UnitmainH

file://---------------------------------------------------------------------------

#include

#include

#include

#include

#include

#include

#include

file://---------------------------------------------------------------------------

class TFrmmain : public TForm

{

__published: // IDE-managed Components

TTimer *Timer1;

TImage *Image1;

void __fastcall FormCreate(TObject *Sender);

void __fastcall FormKeyDown(TObject *Sender, WORD &Key,

TShiftState Shift);

void __fastcall FormMouseDown(TObject *Sender, TMouseButton Button,

TShiftState Shift, int X, int Y);

void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose);

void __fastcall FormClose(TObject *Sender, TCloseAction &Action);

void __fastcall Image1MouseDown(TObject *Sender,

TMouseButton Button, TShiftState Shift, int X, int Y);

void __fastcall Image1MouseMove(TObject *Sender, TShiftState Shift,

int X, int Y);

void __fastcall Timer1Timer(TObject *Sender);

private: // User declarations

DWORD PWProtect;

DWORD Version;

String picdir;

int frequence;

public: // User declarations

__fastcall TFrmmain(TComponent* Owner);

};

file://---------------------------------------------------------------------------

extern PACKAGE TFrmmain *Frmmain;

file://---------------------------------------------------------------------------

#endif

file://---------------------------------------------------------------------------

/*{*******************************}*/

/*{***** Unitmain.cpp ****}*/

/*{*******************************}*/

file://---------------------------------------------------------------------------

#include

#pragma hdrstop

#include

#include "Unitmain.h"

#include

file://---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TFrmmain *Frmmain;

file://---------------------------------------------------------------------------

__fastcall TFrmmain::TFrmmain(TComponent* Owner)

: TForm(Owner)

{

}

file://---------------------------------------------------------------------------

void __fastcall TFrmmain::FormCreate(TObject *Sender)

{

file://使窗口成为最顶层的窗口

SetWindowPos(this->Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);

file://时窗口覆盖屏幕

this->Width=Screen->Width;

this->Height=Screen->Height;

this->Top=0;

this->Left=0;

Version=GetVersion();

TRegistry *Registry = new TRegistry;

try

{

if(Version>0x80000000){

Registry->RootKey =HKEY_CURRENT_USER;

Registry->OpenKey("\\Control Panel\\Desktop",false);

PWProtect=Registry->ReadInteger("ScreenSaveUsePassword");//检测是否密码保护

Registry->CloseKey();}

Registry->RootKey =HKEY_CURRENT_USER;

Registry->OpenKey("\\Software\\CODEHUNTER", true);

picdir=Registry->ReadString("PicDir");//得到图片目录

frequence=Registry->ReadInteger("frequence");//得到图像显示的频率

if(picdir=="")picdir="no";

if(frequence<0||frequence>6)

frequence=2;

Timer1->Interval=1000*frequence;设置定时器

}

__finally

{

delete Registry;

picdir="no";

}

file://检测是否运行于 NT下

if(Version!=0)

if(PWProtect&&Version>0x80000000)//如果系统要求密码保护并此系统为非NT那么把系统设为屏保

状态

SystemParametersInfo(SPI_SCREENSAVERRUNNING, 1, 0, 0);

file://使光标消失

while (!ShowCursor(false)< -5);

}

file://---------------------------------------------------------------------------

void __fastcall TFrmmain::FormKeyDown(TObject *Sender, WORD &Key,

TShiftState Shift)

{

this->Close();

}

file://---------------------------------------------------------------------------

void __fastcall TFrmmain::FormMouseDown(TObject *Sender,

TMouseButton Button, TShiftState Shift, int X, int Y)

{

this->Close();

}

file://---------------------------------------------------------------------------

void __fastcall TFrmmain::FormCloseQuery(TObject *Sender, bool &CanClose)

{

if (PWProtect && Version>0x80000000)

{

bool PassChck;

file://显示光标,并调用密码对话框

while(!ShowCursor(True) > 5);

file://以下是VerifyScreenSavePwd函数的动态调用

typedef UINT(CALLBACK *FUN)(HWND);

HINSTANCE hDll=LoadLibrary("password.cpl");

FUN myfun;

if(hDll!=NULL)

{

myfun=(FUN)GetProcAddress(hDll,"VerifyScreenSavePwd");

if(!myfun)FreeLibrary(hDll);

else

PassChck=myfun(this->Handle);

}

if(PassChck == false)

{

while(!ShowCursor(False) < -5);

CanClose = false;

}

}

}

file://---------------------------------------------------------------------------

void __fastcall TFrmmain::FormClose(TObject *Sender, TCloseAction &Action)

{

while(!ShowCursor(True) > 5);

if(PWProtect&&Version>0x80000000)

SystemParametersInfo(SPI_SCREENSAVERRUNNING, 0, 0, 0);//退出屏保状态

}

file://---------------------------------------------------------------------------

void __fastcall TFrmmain::Image1MouseDown(TObject *Sender,

TMouseButton Button, TShiftState Shift, int X, int Y)

{

this->Close();

}

file://---------------------------------------------------------------------------

void __fastcall TFrmmain::Image1MouseMove(TObject *Sender,

TShiftState Shift, int X, int Y)

{ static int MouseMoves=0;

MouseMoves = MouseMoves + 1;

if(MouseMoves >4)

{

this->Close();

MouseMoves = 0 ;

}

}

file://---------------------------------------------------------------------------

void __fastcall TFrmmain::Timer1Timer(TObject *Sender)

{

if(picdir=="no")

{

int i ;

randomize();

i=rand()%2;

if(i==0)

i=-1;

else

i=1;

Image1->Top=i*(rand()%this->Height);

Image1->Left=i*(rand()%this->Width);

}

}

file://---------------------------------------------------------------------------

/*{*******************************}*/

/*{***** Unitcontrol.h ****}*/

/*{*******************************}*/

file://---------------------------------------------------------------------------

#ifndef UnitcontrolH

#define UnitcontrolH

file://---------------------------------------------------------------------------

#include

#include

#include

#include

#include

#include

#include

file://---------------------------------------------------------------------------

class TFrmControl : public TForm

{

__published: // IDE-managed Components

TImage *Image1;

TTimer *Timer1;

void __fastcall Timer1Timer(TObject *Sender);

void __fastcall FormCreate(TObject *Sender);

private: // User declarations

public: // User declarations

__fastcall TFrmControl(TComponent* Owner);

};

file://---------------------------------------------------------------------------

extern PACKAGE TFrmControl *FrmControl;

file://---------------------------------------------------------------------------

#endif

file://---------------------------------------------------------------------------

/*{*******************************}*/

/*{***** Unitcontrol.cpp ****}*/

/*{*******************************}*/

file://---------------------------------------------------------------------------

#include

#pragma hdrstop

#include "Unitcontrol.h"

file://---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TFrmControl *FrmControl;

file://---------------------------------------------------------------------------

__fastcall TFrmControl::TFrmControl(TComponent* Owner)

: TForm(Owner)

{

}

file://---------------------------------------------------------------------------

void __fastcall TFrmControl::Timer1Timer(TObject *Sender)

{

int i ;

randomize();

i=rand()%2;

if(i==0)

i=-1;

else

i=1;

Image1->Top=i*(rand()%this->Height);

Image1->Left=i*(rand()%this->Width);

}

file://---------------------------------------------------------------------------

void __fastcall TFrmControl::FormCreate(TObject *Sender)

{

Image1->Top=0;

Image1->Left=0;

Image1->Height=this->Height ;

Image1->Width=this->Width ;

}

file://---------------------------------------------------------------------------

/*{*******************************}*/

/*{***** Unitconfig.h ****}*/

/*{*******************************}*/

file://---------------------------------------------------------------------------

#ifndef UnitconfigH

#define UnitconfigH

file://---------------------------------------------------------------------------

#include

#include

#include

#include

#include

#include

#include

#include

file://---------------------------------------------------------------------------

class TFrmConfig : public TForm

{

__published: // IDE-managed Components

TPanel *Panel1;

TButton *Button1;

TPanel *Panel2;

TLabel *Label1;

TTrackBar *TrackBar1;

TLabel *Label2;

TLabel *Label3;

TLabel *Label4;

TButton *Button2;

void __fastcall Button1Click(TObject *Sender);

void __fastcall Button2Click(TObject *Sender);

private: // User declarations

AnsiString picdir;

int frequence;

public: // User declarations

__fastcall TFrmConfig(TComponent* Owner);

};

file://---------------------------------------------------------------------------

extern PACKAGE TFrmConfig *FrmConfig;

file://---------------------------------------------------------------------------

#endif

file://---------------------------------------------------------------------------

/*{*******************************}*/

/*{***** Unitconfig.cpp ****}*/

/*{*******************************}*/

file://---------------------------------------------------------------------------

#include

#pragma hdrstop

#include "Unitconfig.h"

file://---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TFrmConfig *FrmConfig;

file://---------------------------------------------------------------------------

__fastcall TFrmConfig::TFrmConfig(TComponent* Owner)

: TForm(Owner)

{

}

file://---------------------------------------------------------------------------

void __fastcall TFrmConfig::Button1Click(TObject *Sender)

{

if(SelectDirectory("Select Picture Dir","",picdir))

Panel2->Caption=picdir;

}

file://---------------------------------------------------------------------------

void __fastcall TFrmConfig::Button2Click(TObject *Sender)

{

file://把信息写入注册表

if(picdir=="") picdir="no";

this->frequence=TrackBar1->Position;

TRegistry *Reg = new TRegistry;

try

{

Reg->RootKey = HKEY_CURRENT_USER;

if (Reg->OpenKey("\\Software\\CODEHUNTER", true))

{

Reg->WriteString("PicDir",picdir);

Reg->WriteInteger("frequence",frequence);

Reg->CloseKey();

}

}

__finally

{

delete Reg;

}

this->Close();

}

file://---------------------------------------------------------------------------

源代码下载(http://codehunter.1yes.net/download/lucysaver.zip)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有