1 /* 2 * Star field screensaver 3 * 4 * Copyright 2011 Carlo Bramini 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #define WIN32_LEAN_AND_MEAN 22 #include <windows.h> 23 #include <tchar.h> 24 #include <commctrl.h> 25 #include <shellapi.h> 26 27 #include "resource.h" 28 #include "settings.h" 29 30 #define SIZEOF(_v) (sizeof(_v) / sizeof(*_v)) 31 32 // Options for the starfield 33 SSSTARS Settings; 34 35 // Factory default settings. 36 static const SSSTARS FactoryDefaults = { 37 MAX_STARS, 38 20, 39 ROTATION_PERIODIC, 40 41 TRUE, 42 TRUE, 43 TRUE, 44 TRUE 45 }; 46 47 static const DWORD RotoStrings[] = { 48 IDS_ROTATION_NONE, 49 IDS_ROTATION_LINEAR, 50 IDS_ROTATION_PERIODIC 51 }; 52 53 static DWORD QueryDWORD(HKEY hKey, LPCTSTR pszValueName, DWORD Default) 54 { 55 DWORD dwData, dwType, cbData; 56 LONG lRes; 57 58 dwType = REG_DWORD; 59 cbData = sizeof(DWORD); 60 61 lRes = RegQueryValueEx( 62 hKey, 63 pszValueName, 64 NULL, 65 &dwType, 66 (LPBYTE)&dwData, 67 &cbData); 68 69 if (lRes != ERROR_SUCCESS || dwType != REG_DWORD) 70 return Default; 71 72 return dwData; 73 } 74 75 static void SaveDWORD(HKEY hKey, LPCTSTR pszValueName, DWORD dwValue) 76 { 77 RegSetValueEx(hKey, pszValueName, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(dwValue)); 78 } 79 80 81 void LoadSettings(void) 82 { 83 HKEY hKey; 84 LONG lRes; 85 86 Settings = FactoryDefaults; 87 88 lRes = RegCreateKeyEx( 89 HKEY_CURRENT_USER, 90 _T("Software\\Microsoft\\ScreenSavers\\Ssstars"), 91 0, 92 _T(""), 93 0, 94 KEY_READ, 95 NULL, 96 &hKey, 97 NULL); 98 99 if (lRes != ERROR_SUCCESS) 100 return; 101 102 Settings.uiNumStars = QueryDWORD(hKey, _T("NumberOfStars"), Settings.uiNumStars); 103 Settings.uiSpeed = QueryDWORD(hKey, _T("Speed"), Settings.uiSpeed); 104 Settings.uiRotation = QueryDWORD(hKey, _T("TypeOfRotation"), Settings.uiRotation); 105 106 Settings.bDoBlending = QueryDWORD(hKey, _T("DoBlending"), Settings.bDoBlending); 107 Settings.bFinePerspective = QueryDWORD(hKey, _T("FinePerspective"), Settings.bFinePerspective); 108 Settings.bEnableFiltering = QueryDWORD(hKey, _T("EnableFiltering"), Settings.bEnableFiltering); 109 Settings.bSmoothShading = QueryDWORD(hKey, _T("SmoothShading"), Settings.bSmoothShading); 110 111 // Check the number of stars to be in range 112 if (Settings.uiNumStars < MIN_STARS) 113 Settings.uiNumStars = MIN_STARS; 114 else 115 if (Settings.uiNumStars > MAX_STARS) 116 Settings.uiNumStars = MAX_STARS; 117 118 // Check the speed to be in range 119 if (Settings.uiSpeed < MIN_SPEED) 120 Settings.uiSpeed = MIN_SPEED; 121 else 122 if (Settings.uiSpeed > MAX_SPEED) 123 Settings.uiSpeed = MAX_SPEED; 124 125 // Check type of rotation to be in range 126 if (Settings.uiRotation != ROTATION_NONE && 127 Settings.uiRotation != ROTATION_LINEAR && 128 Settings.uiRotation != ROTATION_PERIODIC) 129 Settings.uiRotation = ROTATION_PERIODIC; 130 131 RegCloseKey(hKey); 132 } 133 134 void SaveSettings(void) 135 { 136 HKEY hKey; 137 LONG lRes; 138 139 lRes = RegCreateKeyEx( 140 HKEY_CURRENT_USER, 141 _T("Software\\Microsoft\\ScreenSavers\\Ssstars"), 142 0, 143 _T(""), 144 0, 145 KEY_WRITE, 146 NULL, 147 &hKey, 148 NULL); 149 150 if (lRes != ERROR_SUCCESS) 151 return; 152 153 SaveDWORD(hKey, _T("NumberOfStars"), Settings.uiNumStars); 154 SaveDWORD(hKey, _T("Speed"), Settings.uiSpeed); 155 SaveDWORD(hKey, _T("TypeOfRotation"), Settings.uiRotation); 156 157 SaveDWORD(hKey, _T("DoBlending"), Settings.bDoBlending); 158 SaveDWORD(hKey, _T("FinePerspective"), Settings.bFinePerspective); 159 SaveDWORD(hKey, _T("EnableFiltering"), Settings.bEnableFiltering); 160 SaveDWORD(hKey, _T("SmoothShading"), Settings.bSmoothShading); 161 162 RegCloseKey(hKey); 163 } 164 165 static void SetupControls(HWND hWnd) 166 { 167 TCHAR Strings[256]; 168 HINSTANCE hInstance; 169 UINT x, gap; 170 LOGFONT lf; 171 HFONT hFont; 172 HBITMAP hCosmos; 173 HDC hDC, hMemDC; 174 HGDIOBJ hOldBmp, hOldFnt; 175 SIZE sizeReactOS; 176 SIZE sizeStarfield; 177 BITMAP bm; 178 179 hInstance = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE); 180 181 SendDlgItemMessage(hWnd, IDC_SLIDER_NUM_OF_STARS, TBM_SETRANGE, FALSE, MAKELPARAM(MIN_STARS, MAX_STARS)); 182 183 SendDlgItemMessage(hWnd, IDC_SLIDER_SPEED, TBM_SETRANGE, FALSE, MAKELPARAM(1, 100)); 184 185 for (x = 0; x < ROTATION_ITEMS; x++) 186 { 187 LoadString(hInstance, RotoStrings[x], Strings, sizeof(Strings)/sizeof(TCHAR)); 188 SendDlgItemMessage(hWnd, IDC_COMBO_ROTATION, CB_ADDSTRING, 0, (LPARAM)Strings); 189 } 190 191 hCosmos = LoadImage(hInstance, MAKEINTRESOURCE(IDB_COSMOS), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE); 192 193 hDC = GetDC(hWnd); 194 hMemDC = CreateCompatibleDC(hDC); 195 196 // Create the font for the title 197 ZeroMemory(&lf, sizeof(lf)); 198 199 lf.lfWeight = FW_THIN; 200 lf.lfCharSet = ANSI_CHARSET; 201 lf.lfQuality = PROOF_QUALITY; 202 lf.lfHeight = 36; 203 _tcscpy(lf.lfFaceName, _T("Tahoma")); 204 205 hFont = CreateFontIndirect(&lf); 206 207 hOldBmp = SelectObject(hMemDC, hCosmos); 208 hOldFnt = SelectObject(hMemDC, hFont); 209 210 SetBkMode(hMemDC, TRANSPARENT); 211 SetTextColor(hMemDC, RGB(0xFF, 0xFF, 0xFF)); 212 213 x = LoadString(hInstance, IDS_DESCRIPTION, Strings, sizeof(Strings)/sizeof(TCHAR)); 214 215 GetTextExtentPoint32(hMemDC, _T("ReactOS"), 7, &sizeReactOS); 216 GetTextExtentPoint32(hMemDC, Strings, x, &sizeStarfield); 217 218 GetObject(hCosmos, sizeof(BITMAP), &bm); 219 220 gap = bm.bmHeight - sizeReactOS.cy - sizeStarfield.cy; 221 222 TextOut(hMemDC, 16, gap * 2 / 5, _T("ReactOS"), 7); 223 TextOut(hMemDC, 16, gap * 3 / 5 + sizeReactOS.cy, Strings, x); 224 225 SelectObject(hMemDC, hOldBmp); 226 SelectObject(hMemDC, hOldFnt); 227 228 DeleteObject(hFont); 229 230 DeleteDC(hMemDC); 231 ReleaseDC(hWnd, hDC); 232 233 SendDlgItemMessage(hWnd, IDC_IMAGE_COSMOS, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hCosmos); 234 } 235 236 static void ApplySettings(HWND hWnd) 237 { 238 SendDlgItemMessage(hWnd, IDC_SLIDER_NUM_OF_STARS, TBM_SETPOS, TRUE, Settings.uiNumStars); 239 SetDlgItemInt(hWnd, IDC_TEXT_NUM_OF_STARS, Settings.uiNumStars, FALSE); 240 241 SendDlgItemMessage(hWnd, IDC_SLIDER_SPEED, TBM_SETPOS, TRUE, Settings.uiSpeed); 242 SetDlgItemInt(hWnd, IDC_TEXT_SPEED, Settings.uiSpeed, FALSE); 243 244 SendDlgItemMessage(hWnd, IDC_COMBO_ROTATION, CB_SETCURSEL, (WPARAM)Settings.uiRotation, 0); 245 246 SendDlgItemMessage(hWnd, IDC_CHECK_DOBLENDING, BM_SETCHECK, (WPARAM)Settings.bDoBlending, 0); 247 SendDlgItemMessage(hWnd, IDC_CHECK_PERSPECTIVE, BM_SETCHECK, (WPARAM)Settings.bFinePerspective, 0); 248 SendDlgItemMessage(hWnd, IDC_CHECK_FILTERING, BM_SETCHECK, (WPARAM)Settings.bEnableFiltering, 0); 249 SendDlgItemMessage(hWnd, IDC_CHECK_SHADING, BM_SETCHECK, (WPARAM)Settings.bSmoothShading, 0); 250 } 251 252 static void ReadSettings(HWND hWnd) 253 { 254 Settings.uiNumStars = SendDlgItemMessage(hWnd, IDC_SLIDER_NUM_OF_STARS, TBM_GETPOS, 0, 0); 255 SetDlgItemInt(hWnd, IDC_TEXT_NUM_OF_STARS, Settings.uiNumStars, FALSE); 256 257 Settings.uiSpeed = SendDlgItemMessage(hWnd, IDC_SLIDER_SPEED, TBM_GETPOS, 0, 0); 258 SetDlgItemInt(hWnd, IDC_TEXT_SPEED, Settings.uiSpeed, FALSE); 259 260 Settings.uiRotation = SendDlgItemMessage(hWnd, IDC_COMBO_ROTATION, CB_GETCURSEL, 0, 0); 261 262 Settings.bDoBlending = SendDlgItemMessage(hWnd, IDC_CHECK_DOBLENDING, BM_GETCHECK, 0, 0); 263 Settings.bFinePerspective = SendDlgItemMessage(hWnd, IDC_CHECK_PERSPECTIVE, BM_GETCHECK, 0, 0); 264 Settings.bEnableFiltering = SendDlgItemMessage(hWnd, IDC_CHECK_FILTERING, BM_GETCHECK, 0, 0); 265 Settings.bSmoothShading = SendDlgItemMessage(hWnd, IDC_CHECK_SHADING, BM_GETCHECK, 0, 0); 266 } 267 268 static BOOL OnCommandAbout(HWND hWnd) 269 { 270 HINSTANCE hInstance; 271 HICON hIcon; 272 TCHAR szAppName[256]; 273 TCHAR szAuthor[256]; 274 TCHAR szLicense[1024]; 275 276 hInstance = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE); 277 278 hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_STARFIELD)); 279 280 LoadString(hInstance, IDS_DESCRIPTION, szAppName, SIZEOF(szAppName)); 281 LoadString(hInstance, IDS_AUTHOR, szAuthor, SIZEOF(szAuthor)); 282 LoadString(hInstance, IDS_LICENSE, szLicense, SIZEOF(szLicense)); 283 284 _tcscat(szAppName, _T("#")); 285 _tcscat(szAppName, szAuthor); 286 287 ShellAbout(hWnd, szAppName, szLicense, hIcon); 288 289 return TRUE; 290 } 291 292 // 293 // Dialogbox procedure for Configuration window 294 // 295 BOOL CALLBACK ScreenSaverConfigureDialog(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 296 { 297 switch (uMsg) { 298 case WM_INITDIALOG: 299 LoadSettings(); 300 SetupControls(hDlg); 301 ApplySettings(hDlg); 302 return TRUE; 303 304 case WM_COMMAND: 305 switch (LOWORD( wParam )) { 306 307 case IDOK: 308 // Write configuration 309 SaveSettings(); 310 311 // Fall down... 312 case IDCANCEL: 313 EndDialog( hDlg, LOWORD( wParam )); 314 return TRUE; 315 316 case IDC_BUTTON_ABOUT: 317 return OnCommandAbout(hDlg); 318 } 319 320 case WM_HSCROLL: 321 ReadSettings(hDlg); 322 return TRUE; 323 324 } 325 326 return FALSE; 327 } 328 329 BOOL WINAPI RegisterDialogClasses(HANDLE hInst) 330 { 331 InitCommonControls(); 332 333 return TRUE; 334 } 335 336