• 4976阅读
  • 0回复

用C++Builder 5开发Windows下的屏保[wolf] [复制链接]

上一主题 下一主题
离线XChinux
 

只看楼主 倒序阅读 楼主  发表于: 2005-07-30
摘要:本文通过一个具体的程序演示了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, //窗口句柄
    int nIndex //指定返回的信息
  );
SetWindowLong函数:改变窗口属性
LONG SetWindowLong(
HWND hWnd, //窗口句柄
int nIndex, // 指定要设定的值的信息
LONG dwNewLong // 新值
);
SetParent函数:改变指定窗口的父窗口
HWND SetParent(
HWND hWndChild, //要改变父窗体的窗口句柄
HWND hWndNewParent //新的父窗体的句柄
);
GetClientRect函数:得到窗口的客户区
BOOL GetClientRect(
HWND hWnd, // 窗口句柄
LPRECT lpRect //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 ****}*/
/*{*******************************}*/
//---------------------------------------------------------------------------
#include
#pragma hdrstop
USERES("screensaver.res");
USEFORM("Unitmain.cpp", Frmmain);
USEFORM("Unitconfig.cpp", FrmConfig);
USEFORM("Unitcontrol.cpp", FrmControl);
//---------------------------------------------------------------------------
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();
        //以下是动态调用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;
}
//---------------------------------------------------------------------------
/*{*******************************}*/
/*{*****   Unitmain.h   ****}*/
/*{*******************************}*/
//---------------------------------------------------------------------------

#ifndef UnitmainH
#define UnitmainH
//---------------------------------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
//---------------------------------------------------------------------------
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);
};
//---------------------------------------------------------------------------
extern PACKAGE TFrmmain *Frmmain;
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
/*{*******************************}*/
/*{***** Unitmain.cpp   ****}*/
/*{*******************************}*/
//---------------------------------------------------------------------------
#include
#pragma hdrstop
#include
#include "Unitmain.h"
#include
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TFrmmain *Frmmain;
//---------------------------------------------------------------------------
__fastcall TFrmmain::TFrmmain(TComponent* Owner)
  : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TFrmmain::FormCreate(TObject *Sender)
{
//使窗口成为最顶层的窗口
SetWindowPos(this->Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
//时窗口覆盖屏幕
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";
}
//检测是否运行于 NT下
if(Version!=0)
if(PWProtect&&Version>0x80000000)//如果系统要求密码保护并此系统为非NT那么把系统设为屏保
状态
SystemParametersInfo(SPI_SCREENSAVERRUNNING, 1, 0, 0);
//使光标消失
while (!ShowCursor(false)< -5);
}
//---------------------------------------------------------------------------
void __fastcall TFrmmain::FormKeyDown(TObject *Sender, WORD &Key,
  TShiftState Shift)
{
this->Close();
}
//---------------------------------------------------------------------------
void __fastcall TFrmmain::FormMouseDown(TObject *Sender,
  TMouseButton Button, TShiftState Shift, int X, int Y)
{
this->Close();
}
//---------------------------------------------------------------------------
void __fastcall TFrmmain::FormCloseQuery(TObject *Sender, bool &CanClose)
{
if (PWProtect && Version>0x80000000)
  {
  bool PassChck;
  //显示光标,并调用密码对话框
  while(!ShowCursor(True) > 5);
  //以下是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;
    }
  }
}
//---------------------------------------------------------------------------

void __fastcall TFrmmain::FormClose(TObject *Sender, TCloseAction &Action)
{
while(!ShowCursor(True) > 5);
if(PWProtect&&Version>0x80000000)
  SystemParametersInfo(SPI_SCREENSAVERRUNNING, 0, 0, 0);//退出屏保状态
}
//---------------------------------------------------------------------------
void __fastcall TFrmmain::Image1MouseDown(TObject *Sender,
  TMouseButton Button, TShiftState Shift, int X, int Y)
{
this->Close();
}
//---------------------------------------------------------------------------
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 ;
}
}
//---------------------------------------------------------------------------
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);
}
}
//---------------------------------------------------------------------------
/*{*******************************}*/
/*{*****   Unitcontrol.h   ****}*/
/*{*******************************}*/
//---------------------------------------------------------------------------
#ifndef UnitcontrolH
#define UnitcontrolH
//---------------------------------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
//---------------------------------------------------------------------------
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);
};
//---------------------------------------------------------------------------
extern PACKAGE TFrmControl *FrmControl;
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
/*{*******************************}*/
/*{*****   Unitcontrol.cpp ****}*/
/*{*******************************}*/
//---------------------------------------------------------------------------
#include
#pragma hdrstop
#include "Unitcontrol.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TFrmControl *FrmControl;
//---------------------------------------------------------------------------
__fastcall TFrmControl::TFrmControl(TComponent* Owner)
  : TForm(Owner)
{
}
//---------------------------------------------------------------------------
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);
}
//---------------------------------------------------------------------------
void __fastcall TFrmControl::FormCreate(TObject *Sender)
{
Image1->Top=0;
Image1->Left=0;
Image1->Height=this->Height ;
Image1->Width=this->Width ;
}
//---------------------------------------------------------------------------
/*{*******************************}*/
/*{*****   Unitconfig.h   ****}*/
/*{*******************************}*/
//---------------------------------------------------------------------------
#ifndef UnitconfigH
#define UnitconfigH
//---------------------------------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
#include
//---------------------------------------------------------------------------
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);
};
//---------------------------------------------------------------------------
extern PACKAGE TFrmConfig *FrmConfig;
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
/*{*******************************}*/
/*{*****   Unitconfig.cpp ****}*/
/*{*******************************}*/
//---------------------------------------------------------------------------
#include
#pragma hdrstop
#include "Unitconfig.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TFrmConfig *FrmConfig;
//---------------------------------------------------------------------------
__fastcall TFrmConfig::TFrmConfig(TComponent* Owner)
  : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TFrmConfig::Button1Click(TObject *Sender)
{
if(SelectDirectory("Select Picture Dir","",picdir))
Panel2->Caption=picdir;
}
//---------------------------------------------------------------------------
void __fastcall TFrmConfig::Button2Click(TObject *Sender)
{
//把信息写入注册表
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();
}
//---------------------------------------------------------------------------
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
快速回复
限100 字节
 
上一个 下一个