E_Mail:codehunter@sohu.com 網(wǎng)址:http://codehunter.1yes.net 摘要:本文通過一個(gè)具體的程序演示了Windows下的屏幕保護(hù)程序的實(shí)現(xiàn)過程。 一. 引言 視窗系統(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ì)話框;而“/a”表示調(diào)用密碼設(shè)置對(duì)話框(WinNT中無效)。本 程序盡可能簡(jiǎn)單地實(shí)現(xiàn)一個(gè)全功能的屏保,運(yùn)行Windows的屏保設(shè)置程序時(shí)你既可以修改 密碼(WinNT中無效)又可以設(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ù):得到窗口的客戶區(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ù):訪問或設(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 // 用戶配置文件是否改變標(biāo)記 ); ShowCursor函數(shù):顯示或隱藏光標(biāo) int ShowCursor( BOOL bShow // 鼠標(biāo)可見度標(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. 編寫代碼,具體代碼見第三部分的源程序。 4. 編譯成可執(zhí)行文件,并把文件擴(kuò)展名改為scr。 5. 最后把屏保程序拷貝到windows目錄下就可以測(cè)試了。如果一切正常的話你將會(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ù)覽窗口的客戶區(qū) SetWindowPos(Application->MainForm->Handle,HWND_TOP,0,0,lookrect->right,lookrect->bottom ,SW P_NOZORDER|SWP_NOACTIVATE|SWP_SHOWWINDOW);//將FrmControl的窗口覆蓋屏保預(yù)覽窗口 的客戶區(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ù)的過程 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ì)話框 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) { //把信息寫入注冊(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)
|