编写屏幕保护程序

参考网址:

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 }
原文地址:https://www.cnblogs.com/talenth/p/10647136.html