C++开发屏保.txt
上传用户:zhh515
上传日期:2022-06-18
资源大小:5k
文件大小:18k
源码类别:

屏幕保护

开发平台:

Visual C++

  1. 一. 引言
  2. 视窗系统下的屏幕保护程序是一个基于命令行(Command Line)的应用程序。当屏保
  3. 程序被调用时操作系统就用具体的命令行执行该程序。本文组织和处理了所有的命令行,包
  4. 括“/p”,“/s”,“/c”,“/a”,其中“/p”表示让屏保在预览窗口中显示;“/s”表示真正运行
  5. 屏保;“/c”表示调用设置对话框;而“/a”表示调用密码设置对话框(WinNT中无效)。本
  6. 程序尽可能简单地实现一个全功能的屏保,运行Windows的屏保设置程序时你既可以修改
  7. 密码(WinNT中无效)又可以设置图片显示的频率并把频率数值保存到注册表里。当屏保
  8. 运行时图片以你设置的频率改变显示位置。笔者还留了个作业给读者,请看图1中的选择图
  9. 片文件夹这个项目,按下浏览按钮可以设置图片的路径,笔者已经实现了浏览按钮的功能并
  10. 把得到的路径也保存到注册表中,并让屏保启动时读picdir的值,picdir等于"no"时的代码
  11. 笔者已实现了,picdir不等于"no"时的代码由读者实现。也就是让读者实现一个能把picdir
  12. 目录里的图片轮流显示的屏保程序。
  13. 二. 实现方法
  14. 首先介绍几个API函数。
  15. WinMain函数:
  16. int WINAPI WinMain(
  17.         HINSTANCE hInstance, // 当前实例句柄
  18.     HINSTANCE hPrevInstance, // 前一个实例句柄
  19.     LPSTR lpCmdLine, // 指向命令行参数的指针(本程序要利用的参数)
  20.     int nCmdShow  // 窗口的状态
  21.    );
  22. GetWindowLong函数:得到指定窗口信息的函数
  23.     LONG GetWindowLong(
  24.          HWND hWnd, //窗口句柄
  25.          int nIndex  //指定返回的信息
  26.        );
  27. SetWindowLong函数:改变窗口属性
  28.     LONG SetWindowLong(
  29.     HWND hWnd, //窗口句柄
  30.     int nIndex, // 指定要设定的值的信息
  31.     LONG dwNewLong  // 新值
  32.    );
  33. SetParent函数:改变指定窗口的父窗口
  34.    HWND SetParent(
  35.     HWND hWndChild, //要改变父窗体的窗口句柄
  36.     HWND hWndNewParent  //新的父窗体的句柄
  37.    );
  38. GetClientRect函数:得到窗口的客户区
  39.     BOOL GetClientRect(
  40.     HWND hWnd, // 窗口句柄
  41.     LPRECT lpRect  //RECT结构的地址
  42.    );
  43. SetWindowPos函数:改变窗口的大小,位置,顶级窗口等
  44. BOOL SetWindowPos(
  45. HWND hWnd, // 窗口句柄
  46.     HWND hWndInsertAfter, // 布置窗口顺序的句柄(Z order)
  47.     int X, // horizontal position
  48.     int Y, // vertical position
  49.     int cx, // width
  50.     int cy, // height
  51.     UINT uFlags  // 窗口位置等标记
  52.    );
  53. SystemParametersInfo函数:访问或设置系统级的参数
  54.     BOOL SystemParametersInfo(
  55.     UINT uiAction, // 指定要获取或设置的系统参数
  56.     UINT uiParam, // depends on action to be taken
  57.     PVOID pvParam, // depends on action to be taken
  58.     UINT fWinIni  // 用户配置文件是否改变标记
  59.    );
  60. ShowCursor函数:显示或隐藏光标
  61. int ShowCursor(
  62. BOOL bShow  // 鼠标可见度标记  
  63.    );
  64. GetVersion函数:获取系统的版本信息
  65. DWORD GetVersion(VOID)
  66. 以上API函数的具体信息可以查找有关MSSDK文档。了解了基本函数后笔者简述一
  67. 下实现方法。
  68. 1. 新建一工程,增加两个窗体,将三个窗体分别取名为MainForm,FrmConfig,
  69. FrmControl。在MainForm和FrmControl窗体上各添加一个Timer控件和TImage控件,
  70. 把两窗体的BorderStyle设为bsNone,背景色设为黑色。在两个窗体的TImage上各加一
  71. 张图片,FrmControl大小设为:高130像素,宽160像素,Timage的Stretch属性设为真
  72. 值。FrmConfig的样式如图1。
  73. 2. 保存工程文件为screensaver.cpp,其它单元分别存为Unitmain.cpp,
  74. Unitcontrol.cpp,Unitconfig.cpp。
  75. 3. 编写代码,具体代码见第三部分的源程序。
  76. 4. 编译成可执行文件,并把文件扩展名改为scr。
  77. 5. 最后把屏保程序拷贝到windows目录下就可以测试了。如果一切正常的话你将会看
  78. 到图片在屏幕上以随机的位置显示。
  79.                                     图1
  80. 三. 源代码
  81. 以下是本程序的所有的源代码,其中screensaver.cpp, Unitmain.cpp是核心代码。
  82. /*{*******************************}*/
  83. /*{***** screensaver.cpp  ****}*/
  84. /*{*******************************}*/
  85. //---------------------------------------------------------------------------
  86. #include 
  87. #pragma hdrstop
  88. USERES("screensaver.res");
  89. USEFORM("Unitmain.cpp", Frmmain);
  90. USEFORM("Unitconfig.cpp", FrmConfig);
  91. USEFORM("Unitcontrol.cpp", FrmControl);
  92. //---------------------------------------------------------------------------
  93. WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR p, int)//“p"是指向命令行参数的指针
  94. { String StartType;
  95.   AnsiString Command=p,temp;
  96.   HWND CPWindow =NULL;
  97.   if(Command=="")
  98.    StartType = "/c";
  99.   else
  100.    StartType=Command.SubString(1,2);//获取命令行的前两个参数
  101.         try
  102.         {
  103.                  Application->Initialize();
  104.                  if(StartType=="/c")//启动设置窗口
  105.                    Application->CreateForm(__classid(TFrmConfig), &FrmConfig);
  106.                  else if(StartType=="/s")启动屏保
  107.                    Application->CreateForm(__classid(TFrmmain), &Frmmain);
  108.                  else if(StartType=="/p")//预览
  109.                   {
  110.                    Application->CreateForm(__classid(TFrmControl), &FrmControl);
  111.                    temp=Command.SubString(3,Command.Length()-2);//获取命令行中的屏保预览窗
  112. 口句柄的字符串形式
  113.                    CPWindow =(long *)temp.ToInt();//将预览窗口句柄的字符串形式强制转换为长整形
  114. 指针
  115.                    RECT *lookrect;//建立一个RECT结构指针
  116.                    Long style=GetWindowLong(Application->MainForm->Handle,GWL_STYLE);//获
  117. 取FrmControl窗口的风格
  118.                    style=style|WS_CHILD;
  119.                    SetWindowLong(Application->MainForm->Handle,GWL_STYLE,style);//设置窗口
  120. 为子窗口
  121.                    SetParent(Application->MainForm->Handle,CPWindow);//设置屏保预览窗口为
  122. FrmControl的父窗口
  123.                    GetClientRect(CPWindow,lookrect);//获取屏保预览窗口的客户区
  124.                    
  125. SetWindowPos(Application->MainForm->Handle,HWND_TOP,0,0,lookrect->right,lookrect->bottom ,SW
  126. P_NOZORDER|SWP_NOACTIVATE|SWP_SHOWWINDOW);//将FrmControl的窗口覆盖屏保预览窗口
  127. 的客户区,并显示它
  128.                    }
  129.                  else if(StartType=="/a")//启动密码设置窗口
  130.                   {
  131.                    temp=Command.SubString(3,Command.Length()-2);
  132.                    CPWindow =(long *)temp.ToInt();
  133.                   //以下是动态调用mpr.dll里的PwdChangePasswordA函数的过程
  134.                    typedef UINT(CALLBACK *FUN)(LPSTR,HWND,UINT,UINT);
  135.                    HINSTANCE hDll=LoadLibrary("mpr.DLL");
  136.                    FUN myfun;
  137.                    if(hDll!=NULL)
  138.                     {
  139.                      myfun=(FUN)GetProcAddress(hDll,"PwdChangePasswordA");
  140.                      if(!myfun)FreeLibrary(hDll);
  141.                      else
  142.                      myfun("SCRSAVE", CPWindow, 0, 0);//函数的调用
  143.                     }
  144.                   }
  145.                  Application->Run();
  146.         }
  147.         catch (Exception &exception)
  148.         {
  149.                  Application->ShowException(&exception);
  150.         }
  151.         return 0;
  152. }
  153. //---------------------------------------------------------------------------
  154. /*{*******************************}*/
  155. /*{*****   Unitmain.h     ****}*/
  156. /*{*******************************}*/
  157. //---------------------------------------------------------------------------
  158. #ifndef UnitmainH
  159. #define UnitmainH
  160. //---------------------------------------------------------------------------
  161. #include 
  162. #include 
  163. #include 
  164. #include 
  165. #include 
  166. #include 
  167. #include 
  168. //---------------------------------------------------------------------------
  169. class TFrmmain : public TForm
  170. {
  171. __published: // IDE-managed Components
  172.         TTimer *Timer1;
  173.         TImage *Image1;
  174.         void __fastcall FormCreate(TObject *Sender);
  175.         void __fastcall FormKeyDown(TObject *Sender, WORD &Key,
  176.           TShiftState Shift);
  177.         void __fastcall FormMouseDown(TObject *Sender, TMouseButton Button,
  178.           TShiftState Shift, int X, int Y);
  179.         void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose);
  180.         void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
  181.         void __fastcall Image1MouseDown(TObject *Sender,
  182.           TMouseButton Button, TShiftState Shift, int X, int Y);
  183.         void __fastcall Image1MouseMove(TObject *Sender, TShiftState Shift,
  184.           int X, int Y);
  185.         void __fastcall Timer1Timer(TObject *Sender);
  186. private: // User declarations
  187.        DWORD PWProtect;
  188.        DWORD Version;
  189.        String picdir;
  190.        int frequence;
  191. public: // User declarations
  192.         __fastcall TFrmmain(TComponent* Owner);
  193. };
  194. //---------------------------------------------------------------------------
  195. extern PACKAGE TFrmmain *Frmmain;
  196. //---------------------------------------------------------------------------
  197. #endif
  198. //---------------------------------------------------------------------------
  199. /*{*******************************}*/
  200. /*{*****  Unitmain.cpp   ****}*/
  201. /*{*******************************}*/
  202. //---------------------------------------------------------------------------
  203. #include 
  204. #pragma hdrstop
  205. #include 
  206. #include "Unitmain.h"
  207. #include 
  208. //---------------------------------------------------------------------------
  209. #pragma package(smart_init)
  210. #pragma resource "*.dfm"
  211. TFrmmain *Frmmain;
  212. //---------------------------------------------------------------------------
  213. __fastcall TFrmmain::TFrmmain(TComponent* Owner)
  214.         : TForm(Owner)
  215. {
  216. }
  217. //---------------------------------------------------------------------------
  218. void __fastcall TFrmmain::FormCreate(TObject *Sender)
  219. {
  220.     //使窗口成为最顶层的窗口
  221.     SetWindowPos(this->Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
  222.     //时窗口覆盖屏幕
  223.     this->Width=Screen->Width;
  224.     this->Height=Screen->Height;
  225.     this->Top=0;
  226.     this->Left=0;
  227.     Version=GetVersion();
  228.     TRegistry *Registry = new TRegistry;
  229.   try
  230.   {
  231.     if(Version>0x80000000){
  232.     Registry->RootKey =HKEY_CURRENT_USER;
  233.     Registry->OpenKey("\Control Panel\Desktop",false);
  234.     PWProtect=Registry->ReadInteger("ScreenSaveUsePassword");//检测是否密码保护
  235.     Registry->CloseKey();}
  236.     Registry->RootKey =HKEY_CURRENT_USER;
  237.     Registry->OpenKey("\Software\CODEHUNTER", true);
  238.     picdir=Registry->ReadString("PicDir");//得到图片目录
  239.     frequence=Registry->ReadInteger("frequence");//得到图像显示的频率
  240.     if(picdir=="")picdir="no";
  241.     if(frequence<0||frequence>6)
  242.      frequence=2;
  243.     Timer1->Interval=1000*frequence;设置定时器
  244.   }
  245.   __finally
  246.   {
  247.     delete Registry;
  248.     picdir="no";
  249.   }
  250.     //检测是否运行于 NT下
  251.     if(Version!=0)
  252.     if(PWProtect&&Version>0x80000000)//如果系统要求密码保护并此系统为非NT那么把系统设为屏保
  253. 状态
  254.      SystemParametersInfo(SPI_SCREENSAVERRUNNING, 1, 0, 0);
  255.     //使光标消失
  256.     while (!ShowCursor(false)< -5);
  257. }
  258. //---------------------------------------------------------------------------
  259. void __fastcall TFrmmain::FormKeyDown(TObject *Sender, WORD &Key,
  260.       TShiftState Shift)
  261. {
  262. this->Close();
  263. }
  264. //---------------------------------------------------------------------------
  265. void __fastcall TFrmmain::FormMouseDown(TObject *Sender,
  266.       TMouseButton Button, TShiftState Shift, int X, int Y)
  267. {
  268. this->Close();
  269. }
  270. //---------------------------------------------------------------------------
  271. void __fastcall TFrmmain::FormCloseQuery(TObject *Sender, bool &CanClose)
  272. {
  273. if (PWProtect && Version>0x80000000)
  274.       {
  275.         bool PassChck;
  276.        //显示光标,并调用密码对话框
  277.         while(!ShowCursor(True) > 5);
  278.        //以下是VerifyScreenSavePwd函数的动态调用
  279.         typedef UINT(CALLBACK *FUN)(HWND);
  280.                    HINSTANCE hDll=LoadLibrary("password.cpl");
  281.                    FUN myfun;
  282.                    if(hDll!=NULL)
  283.                     {
  284.                      myfun=(FUN)GetProcAddress(hDll,"VerifyScreenSavePwd");
  285.                      if(!myfun)FreeLibrary(hDll);
  286.                      else
  287.                      PassChck=myfun(this->Handle);
  288.                     }
  289.         if(PassChck == false)
  290.           {
  291.             while(!ShowCursor(False) < -5);
  292.             CanClose = false;
  293.            }
  294.       }
  295. }
  296. //---------------------------------------------------------------------------
  297. void __fastcall TFrmmain::FormClose(TObject *Sender, TCloseAction &Action)
  298. {
  299. while(!ShowCursor(True) > 5);
  300.     if(PWProtect&&Version>0x80000000)
  301.         SystemParametersInfo(SPI_SCREENSAVERRUNNING, 0, 0, 0);//退出屏保状态
  302. }
  303. //---------------------------------------------------------------------------
  304. void __fastcall TFrmmain::Image1MouseDown(TObject *Sender,
  305.       TMouseButton Button, TShiftState Shift, int X, int Y)
  306. {
  307. this->Close();
  308. }
  309. //---------------------------------------------------------------------------
  310. void __fastcall TFrmmain::Image1MouseMove(TObject *Sender,
  311.       TShiftState Shift, int X, int Y)
  312. {   static int MouseMoves=0;
  313.     MouseMoves = MouseMoves + 1;
  314.     if(MouseMoves >4)
  315.      {
  316.      this->Close();
  317.      MouseMoves = 0 ;
  318.      }
  319. }
  320. //---------------------------------------------------------------------------
  321. void __fastcall TFrmmain::Timer1Timer(TObject *Sender)
  322. {
  323. if(picdir=="no")
  324. {
  325. int i ;
  326. randomize();
  327. i=rand()%2;
  328. if(i==0)
  329. i=-1;
  330. else
  331. i=1;
  332. Image1->Top=i*(rand()%this->Height);
  333. Image1->Left=i*(rand()%this->Width);
  334. }
  335. }
  336. //---------------------------------------------------------------------------
  337. /*{*******************************}*/
  338. /*{*****   Unitcontrol.h   ****}*/
  339. /*{*******************************}*/
  340. //---------------------------------------------------------------------------
  341. #ifndef UnitcontrolH
  342. #define UnitcontrolH
  343. //---------------------------------------------------------------------------
  344. #include 
  345. #include 
  346. #include 
  347. #include 
  348. #include 
  349. #include 
  350. #include 
  351. //---------------------------------------------------------------------------
  352. class TFrmControl : public TForm
  353. {
  354. __published: // IDE-managed Components
  355.         TImage *Image1;
  356.         TTimer *Timer1;
  357.         void __fastcall Timer1Timer(TObject *Sender);
  358.         void __fastcall FormCreate(TObject *Sender);
  359. private: // User declarations
  360. public: // User declarations
  361.         __fastcall TFrmControl(TComponent* Owner);
  362. };
  363. //---------------------------------------------------------------------------
  364. extern PACKAGE TFrmControl *FrmControl;
  365. //---------------------------------------------------------------------------
  366. #endif
  367. //---------------------------------------------------------------------------
  368. /*{*******************************}*/
  369. /*{*****   Unitcontrol.cpp ****}*/
  370. /*{*******************************}*/
  371. //---------------------------------------------------------------------------
  372. #include 
  373. #pragma hdrstop
  374. #include "Unitcontrol.h"
  375. //---------------------------------------------------------------------------
  376. #pragma package(smart_init)
  377. #pragma resource "*.dfm"
  378. TFrmControl *FrmControl;
  379. //---------------------------------------------------------------------------
  380. __fastcall TFrmControl::TFrmControl(TComponent* Owner)
  381.         : TForm(Owner)
  382. {
  383. }
  384. //---------------------------------------------------------------------------
  385. void __fastcall TFrmControl::Timer1Timer(TObject *Sender)
  386. {
  387. int i ;
  388. randomize();
  389. i=rand()%2;
  390. if(i==0)
  391. i=-1;
  392. else
  393. i=1;
  394. Image1->Top=i*(rand()%this->Height);
  395. Image1->Left=i*(rand()%this->Width);
  396. }
  397. //---------------------------------------------------------------------------
  398. void __fastcall TFrmControl::FormCreate(TObject *Sender)
  399. {
  400. Image1->Top=0;
  401. Image1->Left=0;
  402. Image1->Height=this->Height ;
  403. Image1->Width=this->Width ;
  404. }
  405. //---------------------------------------------------------------------------
  406. /*{*******************************}*/
  407. /*{*****    Unitconfig.h   ****}*/
  408. /*{*******************************}*/
  409. //---------------------------------------------------------------------------
  410. #ifndef UnitconfigH
  411. #define UnitconfigH
  412. //---------------------------------------------------------------------------
  413. #include 
  414. #include 
  415. #include 
  416. #include 
  417. #include 
  418. #include 
  419. #include 
  420. #include 
  421. //---------------------------------------------------------------------------
  422. class TFrmConfig : public TForm
  423. {
  424. __published: // IDE-managed Components
  425.         TPanel *Panel1;
  426.         TButton *Button1;
  427.         TPanel *Panel2;
  428.         TLabel *Label1;
  429.         TTrackBar *TrackBar1;
  430.         TLabel *Label2;
  431.         TLabel *Label3;
  432.         TLabel *Label4;
  433.         TButton *Button2;
  434.         void __fastcall Button1Click(TObject *Sender);
  435.         void __fastcall Button2Click(TObject *Sender);
  436. private: // User declarations
  437.   AnsiString picdir;
  438.   int frequence;
  439. public: // User declarations
  440.         __fastcall TFrmConfig(TComponent* Owner);
  441. };
  442. //---------------------------------------------------------------------------
  443. extern PACKAGE TFrmConfig *FrmConfig;
  444. //---------------------------------------------------------------------------
  445. #endif
  446. //---------------------------------------------------------------------------
  447. /*{*******************************}*/
  448. /*{*****   Unitconfig.cpp  ****}*/
  449. /*{*******************************}*/
  450. //---------------------------------------------------------------------------
  451. #include 
  452. #pragma hdrstop
  453. #include "Unitconfig.h"
  454. //---------------------------------------------------------------------------
  455. #pragma package(smart_init)
  456. #pragma resource "*.dfm"
  457. TFrmConfig *FrmConfig;
  458. //---------------------------------------------------------------------------
  459. __fastcall TFrmConfig::TFrmConfig(TComponent* Owner)
  460.         : TForm(Owner)
  461. {
  462. }
  463. //---------------------------------------------------------------------------
  464. void __fastcall TFrmConfig::Button1Click(TObject *Sender)
  465. {
  466. if(SelectDirectory("Select Picture Dir","",picdir))
  467.    Panel2->Caption=picdir;
  468. }
  469. //---------------------------------------------------------------------------
  470. void __fastcall TFrmConfig::Button2Click(TObject *Sender)
  471. {
  472. //把信息写入注册表
  473. if(picdir=="") picdir="no";
  474. this->frequence=TrackBar1->Position;
  475. TRegistry *Reg = new TRegistry;
  476.   try
  477.    {
  478.     Reg->RootKey = HKEY_CURRENT_USER;
  479.     if (Reg->OpenKey("\Software\CODEHUNTER", true))
  480.     {
  481.       Reg->WriteString("PicDir",picdir);
  482.       Reg->WriteInteger("frequence",frequence);
  483.       Reg->CloseKey();
  484.     }
  485.   }
  486.   __finally
  487.   {
  488.     delete Reg;
  489.   }
  490. this->Close();
  491. }
  492. //---------------------------------------------------------------------------
  493.                                                                   
  494. 源代码下载(http://codehunter.1yes.net/download/lucysaver.zip)