zoukankan      html  css  js  c++  java
  • 编写屏幕保护程序

    参考网址:

    https://blog.csdn.net/xylary/article/details/1737627

    https://www.windows-commandline.com/configure-screensaver-command-line/

    https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-systemparametersinfow

    一 编写屏幕保护程序

    微软已经写了一个静态类库ScrnSav.lib, 只要包含头文件, 实现几个接口就可以做出一个屏保来, 相关代码如下:

    注意: 屏幕保护程序实际是个exe, 但是使用的时候要把exe改成scr, 并且放在 windowssystem32 或者windowssyswow64目录下

     1 #include <Windows.h>
     2 #include <ScrnSave.h>
     3 
     4 #ifdef UNICODE
     5 #pragma comment(lib, "ScrnSavw.lib")
     6 #else
     7 #pragma comment(lib, "ScrnSave.lib")
     8 #endif
     9 #pragma comment(lib,"comctl32.lib")
    10 
    11 extern "C" LRESULT WINAPI ScreenSaverProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    12 {
    13     switch (message)
    14     {// 省略的代码
    15     default:
    16         return DefScreenSaverProc(hWnd, message, wParam, lParam);
    17     }
    18     return 0;
    19 }
    20 
    21 extern "C" BOOL WINAPI ScreenSaverConfigureDialog(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    22 {//暂时不需要配置对话框,仅返回FALSE
    23     return FALSE;
    24 }
    25 
    26 extern "C" BOOL WINAPI RegisterDialogClasses(HANDLE hInstance)
    27 {//一般不需要,仅返回TRUE 
    28     return TRUE;
    29 }

    二  设置屏保

     1 拷贝文件到系统目录

     2 设置注册表, 这个大多数是给系统重启后初始化屏保逻辑的初始参数

    3 调用SystemParametersInfo api给各窗口发消息, 因为屏保的部分逻辑已经运行在当前已经运行的窗口程序中了, 需要调用此api给窗口发消息更新这些参数

    代码如下:

      1 #include <windows.h>
      2 #include <strsafe.h>
      3 #include <iostream>
      4 
      5 bool GetScreenSaverRunning(bool &isRunning)
      6 {
      7     bool result = false;
      8     try
      9     {
     10         BOOL BRun = TRUE;
     11         BOOL ret = SystemParametersInfoW(SPI_GETSCREENSAVERRUNNING, NULL, &BRun, 0);
     12         if (ret)
     13         {
     14             isRunning = BRun ? true : false;
     15             result = true;
     16         }
     17     }
     18     catch (...)
     19     {
     20         result = false;
     21     }
     22     return result;
     23 }
     24 bool GetScreenSaverActive(bool &active)
     25 {
     26     bool result = false;
     27     try
     28     {
     29         BOOL bActive = TRUE;
     30         BOOL ret = SystemParametersInfoW(SPI_GETSCREENSAVEACTIVE, NULL, &bActive, 0);
     31         if (ret)
     32         {
     33             active = bActive ? true : false;
     34             result = true;
     35         }
     36     }
     37     catch (...)
     38     {
     39         result = false;
     40     }
     41     return result;
     42 }
     43 bool SetScreenSaverActive(bool active)
     44 {
     45     bool result = false;
     46     try
     47     {
     48         BOOL ret = FALSE;
     49         if (active)
     50             ret = SystemParametersInfoW(SPI_SETSCREENSAVEACTIVE, TRUE, NULL, SPIF_SENDWININICHANGE);
     51         else
     52             ret = SystemParametersInfoW(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, SPIF_SENDWININICHANGE);
     53 
     54         result = ret ? true : false;
     55     }
     56     catch (...)
     57     {
     58         result = false;
     59     }
     60     return result;
     61 }
     62 
     63 //screenSaveTimeoutSeconds, 单位是秒
     64 bool SetScreenSaver(const wchar_t *scrFile, UINT screenSaveTimeoutSeconds)
     65 {
     66     if (!scrFile || !screenSaveTimeoutSeconds)
     67         return false;
     68 
     69     bool result = false;
     70     HRESULT hr = S_OK;
     71     LSTATUS status = ERROR_SUCCESS;
     72     BOOL ret2 = FALSE;
     73     wchar_t buffer[MAX_PATH] = { 0 };
     74     DWORD accessmask = KEY_SET_VALUE;
     75     HKEY root = NULL;
     76     DWORD charLen = 0;
     77     do
     78     {
     79         // copy到系统路径
     80         BOOL isWOW64 = FALSE;
     81         IsWow64Process(GetCurrentProcess(), &isWOW64);
     82 
     83         UINT ret = 0;
     84         if (isWOW64)
     85             ret = GetSystemWow64DirectoryW(buffer, MAX_PATH);
     86         else
     87             ret = GetSystemDirectoryW(buffer, MAX_PATH);
     88         if(ret ==0 || ret >MAX_PATH)
     89             break;
     90         
     91         hr = StringCchCatW(buffer, MAX_PATH, L"\aaa.scr");
     92         if(hr != S_OK)
     93             break;
     94 
     95         ret2 = CopyFile(scrFile, buffer, FALSE);
     96         if(!ret2)
     97         {
     98             wchar_t buffer2[MAX_PATH] = { 0 };
     99             hr =StringCchPrintfW(buffer2, MAX_PATH, L"%s1",buffer);
    100             if(hr != S_OK)
    101                 break;
    102 
    103             ret2 =MoveFileExW(buffer, buffer2, MOVEFILE_REPLACE_EXISTING);
    104             if (!ret2)
    105                 break;
    106 
    107             ret2 = MoveFileExW(buffer2, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
    108             if(!ret2)
    109                 break;
    110 
    111             ret2 = CopyFile(scrFile, buffer, FALSE);
    112             if (!ret2)
    113                 break;
    114         }
    115 
    116         status = RegOpenKeyExW(HKEY_CURRENT_USER, L"Control Panel", 0, accessmask, &root);
    117         if(status != ERROR_SUCCESS)
    118             break;
    119 
    120         // 设置屏保程序
    121         charLen = (DWORD)((wcslen(buffer) + 1) * sizeof(wchar_t));
    122         status = RegSetKeyValueW(root, L"Desktop", L"SCRNSAVE.EXE", REG_SZ, buffer, charLen);
    123         if (status != ERROR_SUCCESS)
    124             break;
    125 
    126         // 设置超时时间
    127         // 仅设置注册表不会立即生效, 要给其他程序发消息才能立即生效
    128         hr = StringCchPrintfW(buffer, MAX_PATH, L"%u", screenSaveTimeoutSeconds);
    129         if(hr !=S_OK)
    130             break;
    131 
    132         charLen = (DWORD)((wcslen(buffer) + 1) * sizeof(wchar_t));
    133         status = RegSetKeyValueW(root, L"Desktop", L"ScreenSaveTimeOut", REG_SZ, buffer, charLen);
    134         if(status != ERROR_SUCCESS)
    135             break;
    136 
    137         try
    138         {
    139             ret2 = SystemParametersInfoW(SPI_SETSCREENSAVETIMEOUT, screenSaveTimeoutSeconds, NULL, SPIF_SENDWININICHANGE);
    140             if (!ret2)
    141                 break;
    142         }
    143         catch (...)
    144         {
    145             break;
    146         }
    147 
    148         // 设置恢复时显示登录界面
    149         // 仅设置注册表会立即生效, 但是设置界面跟注册表里的值不一致
    150         hr = StringCchPrintfW(buffer, MAX_PATH, L"%u", 1);
    151         if(hr != S_OK)
    152             break;
    153 
    154         charLen = (DWORD)((wcslen(buffer) + 1) * sizeof(wchar_t));
    155         status = RegSetKeyValueW(root, L"Desktop", L"ScreenSaverIsSecure", REG_SZ, buffer, charLen);
    156         if(status !=ERROR_SUCCESS)
    157             break;
    158 
    159         try
    160         {
    161             BOOL bSecurite = TRUE;
    162             ret2 = SystemParametersInfoW(SPI_SETSCREENSAVESECURE, bSecurite, NULL, SPIF_SENDWININICHANGE);
    163             if (!ret2)
    164                 break;
    165         }
    166         catch (...)
    167         {
    168             break;
    169         }
    170 
    171         // 设置屏保开关
    172         // 仅设置注册表不会立即生效, 要给其他程序发消息才能立即生效
    173         hr = StringCchPrintfW(buffer, MAX_PATH, L"%u", 1);
    174         if(hr != S_OK)
    175             break;
    176 
    177         charLen = (DWORD)((wcslen(buffer) + 1) * sizeof(wchar_t));
    178         status = RegSetKeyValueW(root, L"Desktop", L"ScreenSaveActive", REG_SZ, buffer, charLen);
    179         if (status != ERROR_SUCCESS)
    180             break;
    181 
    182         SetScreenSaverActive(true);
    183 
    184         result = true;
    185     } while (false);
    186 
    187 
    188     return result;
    189 }
    190 int main(int argc, char **argv, char **env)
    191 {
    192      SetScreenSaver(L"aaa.exe",60);
    193     system("pause");
    194     return 0;
    195 }
  • 相关阅读:
    InstallShield自定义对话框模板代码(转)
    破解汇编知识(转)
    Openrowset数据库远程操作
    SQL类似sleep延时语句
    C#结束线程
    JavaScript中相应ActiveX事件
    Visual C# .NET 命令行编辑器
    AfxBeginThread
    atoi,atol,strtod,strtol,strtoul类型转换(转)
    SQLServer PadLeft,PadRight
  • 原文地址:https://www.cnblogs.com/talenth/p/10647136.html
Copyright © 2011-2022 走看看