用C++Builder 5開(kāi)發(fā)Windows下的屏保
發(fā)表時(shí)間:2023-08-07 來(lái)源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]E_Mail:codehunter@sohu.com網(wǎng)址:http://codehunter.1yes.net摘要:本文通過(guò)一個(gè)具體的程序演示了Windows下的屏幕保護(hù)程序的實(shí)現(xiàn)過(guò)程。一. ...
E_Mail:codehunter@sohu.com
網(wǎng)址:http://codehunter.1yes.net
摘要:本文通過(guò)一個(gè)具體的程序演示了Windows下的屏幕保護(hù)程序的實(shí)現(xiàn)過(guò)程。
一. 引言
視窗系統(tǒng)下的屏幕保護(hù)程序是一個(gè)基于命令行(Command Line)的應(yīng)用程序。當(dāng)屏保
程序被調(diào)用時(shí)操作系統(tǒng)就用具體的命令行執(zhí)行該程序。本文組織和處理了所有的命令行,包
括“/p”,“/s”,“/c”,“/a”,其中“/p”表示讓屏保在預(yù)覽窗口中顯示;“/s”表示真正運(yùn)行
屏保;“/c”表示調(diào)用設(shè)置對(duì)話(huà)框;而“/a”表示調(diào)用密碼設(shè)置對(duì)話(huà)框(WinNT中無(wú)效)。本
程序盡可能簡(jiǎn)單地實(shí)現(xiàn)一個(gè)全功能的屏保,運(yùn)行Windows的屏保設(shè)置程序時(shí)你既可以修改
密碼(WinNT中無(wú)效)又可以設(shè)置圖片顯示的頻率并把頻率數(shù)值保存到注冊(cè)表里。當(dāng)屏保
運(yùn)行時(shí)圖片以你設(shè)置的頻率改變顯示位置。筆者還留了個(gè)作業(yè)給讀者,請(qǐng)看圖1中的選擇圖
片文件夾這個(gè)項(xiàng)目,按下瀏覽按鈕可以設(shè)置圖片的路徑,筆者已經(jīng)實(shí)現(xiàn)了瀏覽按鈕的功能并
把得到的路徑也保存到注冊(cè)表中,并讓屏保啟動(dòng)時(shí)讀picdir的值,picdir等于"no"時(shí)的代碼
筆者已實(shí)現(xiàn)了,picdir不等于"no"時(shí)的代碼由讀者實(shí)現(xiàn)。也就是讓讀者實(shí)現(xiàn)一個(gè)能把picdir
目錄里的圖片輪流顯示的屏保程序。
二. 實(shí)現(xiàn)方法
首先介紹幾個(gè)API函數(shù)。
WinMain函數(shù):
int WINAPI WinMain(
HINSTANCE hInstance, // 當(dāng)前實(shí)例句柄
HINSTANCE hPrevInstance, // 前一個(gè)實(shí)例句柄
LPSTR lpCmdLine, // 指向命令行參數(shù)的指針(本程序要利用的參數(shù))
int nCmdShow // 窗口的狀態(tài)
);
GetWindowLong函數(shù):得到指定窗口信息的函數(shù)
LONG GetWindowLong(
HWND hWnd, //窗口句柄
int nIndex //指定返回的信息
);
SetWindowLong函數(shù):改變窗口屬性
LONG SetWindowLong(
HWND hWnd, //窗口句柄
int nIndex, // 指定要設(shè)定的值的信息
LONG dwNewLong // 新值
);
SetParent函數(shù):改變指定窗口的父窗口
HWND SetParent(
HWND hWndChild, //要改變父窗體的窗口句柄
HWND hWndNewParent //新的父窗體的句柄
);
GetClientRect函數(shù):得到窗口的客戶(hù)區(qū)
BOOL GetClientRect(
HWND hWnd, // 窗口句柄
LPRECT lpRect //RECT結(jié)構(gòu)的地址
);
SetWindowPos函數(shù):改變窗口的大小,位置,頂級(jí)窗口等
BOOL SetWindowPos(
HWND hWnd, // 窗口句柄
HWND hWndInsertAfter, // 布置窗口順序的句柄(Z order)
int X, // horizontal position
int Y, // vertical position
int cx, // width
int cy, // height
UINT uFlags // 窗口位置等標(biāo)記
);
SystemParametersInfo函數(shù):訪(fǎng)問(wèn)或設(shè)置系統(tǒng)級(jí)的參數(shù)
BOOL SystemParametersInfo(
UINT uiAction, // 指定要獲取或設(shè)置的系統(tǒng)參數(shù)
UINT uiParam, // depends on action to be taken
PVOID pvParam, // depends on action to be taken
UINT fWinIni // 用戶(hù)配置文件是否改變標(biāo)記
);
ShowCursor函數(shù):顯示或隱藏光標(biāo)
int ShowCursor(
BOOL bShow // 鼠標(biāo)可見(jiàn)度標(biāo)記
);
GetVersion函數(shù):獲取系統(tǒng)的版本信息
DWORD GetVersion(VOID)
以上API函數(shù)的具體信息可以查找有關(guān)MSSDK文檔。了解了基本函數(shù)后筆者簡(jiǎn)述一
下實(shí)現(xiàn)方法。
1. 新建一工程,增加兩個(gè)窗體,將三個(gè)窗體分別取名為MainForm,FrmConfig,
FrmControl。在MainForm和FrmControl窗體上各添加一個(gè)Timer控件和TImage控件,
把兩窗體的BorderStyle設(shè)為bsNone,背景色設(shè)為黑色。在兩個(gè)窗體的TImage上各加一
張圖片,F(xiàn)rmControl大小設(shè)為:高130像素,寬160像素,Timage的Stretch屬性設(shè)為真
值。FrmConfig的樣式如圖1。
2. 保存工程文件為screensaver.cpp,其它單元分別存為Unitmain.cpp,
Unitcontrol.cpp,Unitconfig.cpp。
3. 編寫(xiě)代碼,具體代碼見(jiàn)第三部分的源程序。
4. 編譯成可執(zhí)行文件,并把文件擴(kuò)展名改為scr。
5. 最后把屏保程序拷貝到windows目錄下就可以測(cè)試了。如果一切正常的話(huà)你將會(huì)看
到圖片在屏幕上以隨機(jī)的位置顯示。
圖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"是指向命令行參數(shù)的指針
{ String StartType;
AnsiString Command=p,temp;
HWND CPWindow =NULL;
if(Command=="")
StartType = "/c";
else
StartType=Command.SubString(1,2);//獲取命令行的前兩個(gè)參數(shù)
try
{
Application->Initialize();
if(StartType=="/c")//啟動(dòng)設(shè)置窗口
Application->CreateForm(__classid(TFrmConfig), &FrmConfig);
else if(StartType=="/s")啟動(dòng)屏保
Application->CreateForm(__classid(TFrmmain), &Frmmain);
else if(StartType=="/p")//預(yù)覽
{
Application->CreateForm(__classid(TFrmControl), &FrmControl);
temp=Command.SubString(3,Command.Length()-2);//獲取命令行中的屏保預(yù)覽窗
口句柄的字符串形式
CPWindow =(long *)temp.ToInt();//將預(yù)覽窗口句柄的字符串形式強(qiáng)制轉(zhuǎn)換為長(zhǎng)整形
指針
RECT *lookrect;//建立一個(gè)RECT結(jié)構(gòu)指針
Long style=GetWindowLong(Application->MainForm->Handle,GWL_STYLE);//獲
取FrmControl窗口的風(fēng)格
style=style WS_CHILD;
SetWindowLong(Application->MainForm->Handle,GWL_STYLE,style);//設(shè)置窗口
為子窗口
SetParent(Application->MainForm->Handle,CPWindow);//設(shè)置屏保預(yù)覽窗口為
FrmControl的父窗口
GetClientRect(CPWindow,lookrect);//獲取屏保預(yù)覽窗口的客戶(hù)區(qū)
SetWindowPos(Application->MainForm->Handle,HWND_TOP,0,0,lookrect->right,lookrect->bottom ,SW
P_NOZORDER SWP_NOACTIVATE SWP_SHOWWINDOW);//將FrmControl的窗口覆蓋屏保預(yù)覽窗口
的客戶(hù)區(qū),并顯示它
}
else if(StartType=="/a")//啟動(dòng)密碼設(shè)置窗口
{
temp=Command.SubString(3,Command.Length()-2);
CPWindow =(long *)temp.ToInt();
//以下是動(dòng)態(tài)調(diào)用mpr.dll里的PwdChangePasswordA函數(shù)的過(guò)程
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);//函數(shù)的調(diào)用
}
}
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);
//時(shí)窗口覆蓋屏幕
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");//檢測(cè)是否密碼保護(hù)
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;設(shè)置定時(shí)器
}
__finally
{
delete Registry;
picdir="no";
}
//檢測(cè)是否運(yùn)行于 NT下
if(Version!=0)
if(PWProtect&&Version>0x80000000)//如果系統(tǒng)要求密碼保護(hù)并此系統(tǒng)為非NT那么把系統(tǒng)設(shè)為屏保
狀態(tài)
SystemParametersInfo(SPI_SCREENSAVERRUNNING, 1, 0, 0);
//使光標(biāo)消失
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;
//顯示光標(biāo),并調(diào)用密碼對(duì)話(huà)框
while(!ShowCursor(True) > 5);
//以下是VerifyScreenSavePwd函數(shù)的動(dòng)態(tài)調(diào)用
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);//退出屏保狀態(tài)
}
//---------------------------------------------------------------------------
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)
{
//把信息寫(xiě)入注冊(cè)表
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();
}
//---------------------------------------------------------------------------
源代碼下載(http://codehunter.1yes.net/download/lucysaver.zip)