Windows 屏幕保護程序本質是基於命令行參數的應用程序。系統調用時傳遞特定參數:
| 參數 | 含義 |
|---|---|
| /p | 預覽模式:在指定窗口句柄中顯示預覽 |
| /s | 正常運行:全屏執行屏保 |
| /c | 配置模式:顯示設置對話框 |
| /a | 密碼設置:顯示密碼修改對話框 (WinNT 無效) |
WinMain:程序入口,解析 lpCmdLine 參數GetWindowLong/SetWindowLong:獲取/設置窗口屬性 (GWL_STYLE、GWL_EXSTYLE)SetParent:改變窗口父子關係 (預覽模式關鍵)GetClientRect:獲取客戶區矩形SetWindowPos:調整窗口大小、位置、Z 序 (HWND_TOPMOST 置頂)SystemParametersInfo:系統參數讀寫 (SPI_GETSCREENSAVERRUNNING、SPI_SETSCREENSAVEACTIVE)ShowCursor:顯示/隱藏鼠標光標GetVersion:獲取系統版本區分 9x/NTint WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
String cmdLine = lpCmdLine;
cmdLine = cmdLine.LowerCase();
if (cmdLine.Pos("/p") == 1) {
// 預覽模式:lpCmdLine 格式 "/p HWND"
HWND hParent = StrToInt(cmdLine.SubString(4, cmdLine.Length()-3).c_str());
return RunPreviewMode(hParent);
}
else if (cmdLine.Pos("/s") == 1) {
return RunScreenSaver();
}
else if (cmdLine.Pos("/c") == 1) {
return ShowConfigDialog();
}
else if (cmdLine.Pos("/a") == 1) {
return ShowPasswordDialog();
}
return 0;
}
int RunPreviewMode(HWND hParent) {
// 創建預覽窗口
HWND hPreview = CreateWindowEx(0, "STATIC", "", WS_CHILD | WS_VISIBLE | SS_BITMAP,
0, 0, 0, 0, hParent, NULL, hInstance, NULL);
// 設置為父窗口子窗口
SetParent(hPreview, hParent);
// 獲取父窗口客戶區並調整大小
RECT rect;
GetClientRect(hParent, &rect);
SetWindowPos(hPreview, NULL, 0, 0, rect.right, rect.bottom, SWP_NOZORDER);
// 繪製預覽內容...
return 0;
}
int RunScreenSaver() {
// 創建全屏窗口
HWND hWnd = CreateWindowEx(WS_EX_TOPMOST, "SCREENSAVER_CLASS", "",
WS_POPUP | WS_VISIBLE, 0, 0,
GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
NULL, NULL, hInstance, NULL);
// 隱藏鼠標
ShowCursor(FALSE);
// 設置屏保運行標誌
SystemParametersInfo(SPI_SETSCREENSAVERRUNNING, TRUE, NULL, 0);
// 消息循環 + 繪製邏輯
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
// 處理鍵盤/鼠標消息退出
if (msg.message == WM_KEYDOWN || msg.message == WM_MOUSEMOVE || msg.message == WM_LBUTTONDOWN) {
// 但需忽略初始移動...
PostQuitMessage(0);
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
ShowCursor(TRUE);
SystemParametersInfo(SPI_SETSCREENSAVERRUNNING, FALSE, NULL, 0);
return 0;
}
設置項目示例:圖片切換頻率 (毫秒)、圖片目錄路徑。存儲位置:
HKEY_CURRENT_USER\Software\MyScreenSaver
Interval (DWORD) = 5000
PicDir (String) = "C:\Pictures\"
Win9x:調用系統密碼對話框 (MSSCP.DLL)
WinNT/2000+:系統管理密碼,屏保無權修改,通常禁用此功能或提示用戶設置系統鎖屏密碼。
ScreenSaver.cpp:主入口、參數分發、窗口類註冊PreviewWnd.cpp/h:預覽窗口類SaverWnd.cpp/h:全屏窗口類、繪製邏輯、動畫計時器ConfigDlg.cpp/h:設置對話框 (頻率、路徑、預覽)Registry.cpp/h:注冊表讀寫封裝Resource.rc:圖標、光標、位圖資源.scr 副檔名C:\Windows\System32\ 或 C:\Windows\已實現:目錄瀏覽按鈕、路徑存儲、PicDir="no" 時默認動畫。
待實現:PicDir!="no" 時掃描目錄圖片 (jpg/bmp/png)、按間隔輪播顯示、支持縮放/居中/拉伸模式。