参考网址:
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, 并且放在 windows\system32 或者windows\syswow64目录下
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