2 * PROJECT: ReactOS Screen Saver Library
3 * LICENSE: GPL v2 or any later version
4 * FILE: lib/sdk/scrnsave/scrnsave.c
5 * PURPOSE: Library for writing screen savers, compatible with MS' scrnsave.lib
6 * PROGRAMMERS: Anders Norlander <anorland@hem2.passagen.se>
7 * Colin Finck <mail@colinfinck.de>
18 // Screen Saver window class
19 #define CLASS_SCRNSAVE TEXT("WindowsScreenSaverClass")
22 HWND hMainWindow
= NULL
;
23 BOOL fChildPreview
= FALSE
;
24 HINSTANCE hMainInstance
;
25 TCHAR szName
[TITLEBARNAMELEN
];
26 TCHAR szAppName
[APPNAMEBUFFERLEN
];
27 TCHAR szIniFile
[MAXFILELEN
];
28 TCHAR szScreenSaver
[22];
29 TCHAR szHelpFile
[MAXFILELEN
];
30 TCHAR szNoHelpMemory
[BUFFLEN
];
33 // Local house keeping
36 static int ISSPACE(TCHAR c
)
38 return (c
== ' ' || c
== '\t');
41 #define ISNUM(c) ((c) >= '0' && c <= '9')
43 static ULONG_PTR
_toulptr(const TCHAR
*s
)
56 for (n
= 1; p
>= s
; p
--, n
*= 10)
57 res
+= (*p
- '0') * n
;
62 // This function takes care of *must* do tasks, like terminating screen saver
63 static LRESULT WINAPI
SysScreenSaverProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
68 // Mouse is not supposed to move from this position
69 GetCursorPos(&pt_orig
);
89 return ScreenSaverProc(hWnd
, uMsg
, wParam
, lParam
);
92 LRESULT WINAPI
DefScreenSaverProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
94 // Don't do any special processing when in preview mode
96 return DefWindowProc(hWnd
, uMsg
, wParam
, lParam
);
105 // wParam is FALSE, so the screensaver is losing the focus.
106 PostMessage(hWnd
, WM_CLOSE
, 0, 0);
114 if (pt
.x
== pt_orig
.x
&& pt
.y
== pt_orig
.y
)
125 // Send a WM_CLOSE to close the screen saver (allows the screensaver author to do clean-up tasks)
126 PostMessage(hWnd
, WM_CLOSE
, 0, 0);
134 return DefWindowProc(hWnd
, uMsg
, wParam
, lParam
);
137 // Registers the screen saver window class
138 static BOOL
RegisterScreenSaverClass(void)
142 cls
.hIcon
= LoadIcon(hMainInstance
, MAKEINTATOM(ID_APP
));
143 cls
.lpszClassName
= CLASS_SCRNSAVE
;
144 cls
.hbrBackground
= (HBRUSH
)GetStockObject(BLACK_BRUSH
);
145 cls
.hInstance
= hMainInstance
;
146 cls
.style
= CS_VREDRAW
| CS_HREDRAW
| CS_SAVEBITS
| CS_PARENTDC
;
147 cls
.lpfnWndProc
= (WNDPROC
)SysScreenSaverProc
;
149 return RegisterClass(&cls
) != 0;
152 static void LaunchConfig(void)
154 // Only show the dialog if the RegisterDialogClasses function succeeded.
155 // This is the same behaviour as MS' scrnsave.lib.
156 if( RegisterDialogClasses(hMainInstance
) )
157 DialogBox(hMainInstance
, MAKEINTRESOURCE(DLG_SCRNSAVECONFIGURE
), GetForegroundWindow(), (DLGPROC
) ScreenSaverConfigureDialog
);
160 static int LaunchScreenSaver(HWND hParent
)
166 if (!RegisterScreenSaverClass())
168 MessageBox(NULL
, TEXT("RegisterClass() failed"), NULL
, MB_ICONHAND
);
172 // A slightly different approach needs to be used when displaying in a preview window
176 GetClientRect(hParent
, &rc
);
181 rc
.right
= GetSystemMetrics(SM_CXVIRTUALSCREEN
);
182 rc
.bottom
= GetSystemMetrics(SM_CYVIRTUALSCREEN
);
186 // Create the main screen saver window
187 hMainWindow
= CreateWindowEx(hParent
? 0 : WS_EX_TOPMOST
, CLASS_SCRNSAVE
,
188 TEXT("SCREENSAVER"), style
,
189 0, 0, rc
.right
, rc
.bottom
, hParent
, NULL
,
190 hMainInstance
, NULL
);
195 // Display window and start pumping messages
196 ShowWindow(hMainWindow
, SW_SHOW
);
200 while (GetMessage(&msg
, NULL
, 0, 0))
201 DispatchMessage(&msg
);
206 // Screen Saver entry point
207 int APIENTRY
_tWinMain(HINSTANCE hInst
, HINSTANCE hPrevInst
, LPTSTR CmdLine
, int nCmdShow
)
211 UNREFERENCED_PARAMETER(nCmdShow
);
212 UNREFERENCED_PARAMETER(hPrevInst
);
214 hMainInstance
= hInst
;
216 // Parse the arguments
217 for (p
= CmdLine
; *p
; p
++)
223 // Start the screen saver
224 return LaunchScreenSaver(NULL
);
229 // Start the screen saver in preview mode
231 fChildPreview
= TRUE
;
233 while (ISSPACE(*++p
));
234 hParent
= (HWND
) _toulptr(p
);
236 if (hParent
&& IsWindow(hParent
))
237 return LaunchScreenSaver(hParent
);
243 // Display the configuration dialog