windows-nt/Source/XPSP1/NT/shell/osshell/control/scrnsave/default/scrnsave.c
2020-09-26 16:20:57 +08:00

406 lines
11 KiB
C

/*
* SCRNSAVE.C - default screen saver.
*
* this app makes a IdleWild screen saver compatible with the windows 3.1
* screen saver interface.
*
* Usage: SCRNSAVE.EXE saver.iw [/s] [/c]
*
* the IdleWild screen saver 'saver.iw' will be loaded and told to
* screen save. if '/c' is specifed the savers configure dialog will
* be shown.
*
* when the screen saver terminates SCRNSAVE.EXE will terminate too.
*
* if the saver.iw is not specifed or refuses to load then a
* builtin 'blackness' screen saver will be used.
*
* Restrictions:
*
* because only one screen saver is loaded, (not all the screen savers
* like IdleWild.exe does) the random screen saver will not work correctly
*
* History:
* 10/15/90 ToddLa stolen from SOS.C by BradCh
* 6/17/91 stevecat ported to NT Windows
*
*/
#include <string.h>
#define WIN31 /* For topmost windows */
#include <windows.h>
#include "strings.h"
#include <stdlib.h>
#define BUFFER_LEN 255
CHAR szAppName[BUFFER_LEN];
CHAR szNoConfigure[BUFFER_LEN];
#define THRESHOLD 3
#define abs(x) ( (x)<0 ? -(x) : (x) )
//
// private stuff in IWLIB.DLL
//
HANDLE hIdleWildDll;
CHAR szIdleWildDll[] = "IWLIB.DLL";
SHORT (*FInitScrSave) (HANDLE, HWND);
VOID (*TermScrSave) (VOID);
VOID (*ScrBlank) (SHORT);
VOID (*ScrSetIgnore) (SHORT);
SHORT (*ScrLoadServer) (CHAR *);
SHORT (*ScrSetServer) (CHAR *);
VOID (*ScrInvokeDlg) (HANDLE, HWND);
HANDLE hMainInstance = NULL;
HWND hwndApp = NULL;
HWND hwndActive = NULL;
HWND hwndPreview = NULL;
BOOL fBlankNow = FALSE;
BOOL fIdleWild = FALSE;
//SHORT wmScrSave = -1;
// changed to what I believe it should be
UINT wmScrSave = 0xffffffff;
typedef LONG (*LPWNDPROC)(); // pointer to a window procedure
BOOL FInitIdleWild (LPSTR szCmdLine);
BOOL FTermIdleWild (VOID);
BOOL FInitApp (HANDLE hInstance, LPSTR szCmdLine, WORD sw);
BOOL FTermApp (VOID);
BOOL FInitDefault (VOID);
LRESULT DefaultProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
int __cdecl main (USHORT argc, CHAR **argv)
{
HANDLE hInstance;
HANDLE hPrev = NULL;
LPSTR szCmdLine = GetCommandLine();
WORD sw = SW_SHOWNORMAL;
MSG msg;
hInstance = GetModuleHandle (NULL);
hMainInstance = hInstance;
// If we're already running another instance, get out
if (hPrev != NULL)
return FALSE;
if (!FInitApp (hInstance, szCmdLine, sw))
{
//MessageBox (NULL, "Cannot initialize!", szAppName, MB_OK);
return FALSE;
}
while (GetMessage (&msg, NULL, 0, 0))
{
//
// IWLIB.DLL will brodcast a message when the screen saving
// is done.
//
if (msg.message == wmScrSave && msg.wParam == FALSE)
break;
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return FTermApp ();
}
BOOL FTermApp (VOID)
{
////FTermDefault ();
FTermIdleWild ();
return TRUE;
}
BOOL FInitApp (HANDLE hInstance, LPSTR szCmdLine, WORD sw)
{
LPSTR lpch, lpT;
LoadString(hMainInstance, idsAppName, szAppName, BUFFER_LEN);
LoadString(hMainInstance, idsNoConfigure, szNoConfigure, BUFFER_LEN);
//=================================================================
// on NT, szCmdLine's first string includes its own name, remove this
// to make it exactly like the windows command line.
if (*szCmdLine)
{
lpT = strchr(szCmdLine, ' '); // skip self name
if (lpT)
{
szCmdLine = lpT;
while (*szCmdLine == ' ')
szCmdLine++; // skip spaces to end or first cmd
}
else
{
szCmdLine += strlen(szCmdLine); // point to NULL
}
}
//=====================================================================
//
// parse command line looking for switches
//
for (lpch = szCmdLine; *lpch != '\0'; lpch += 1)
{
if (*lpch == '/' || *lpch == '-')
{
if (lpch[1] == 's' || lpch[1] == 'S')
fBlankNow = TRUE;
if (lpch[1] == 'c' || lpch[1] == 'C')
hwndActive = GetActiveWindow ();
if (lpch[1] == 'p' || lpch[1] == 'P')
{
fBlankNow = TRUE;
hwndPreview = (HWND)IntToPtr(atoi(lpch+2));
break;
}
lpch[0] = ' ';
lpch[1] = ' ';
}
}
//
// try to load the IdleWild screen saver, if none specifed or
// we are unable to load it then use the default one.
//
if (FInitIdleWild (szCmdLine))
{
if (fBlankNow)
{
ScrSetIgnore (1);
ScrBlank (TRUE);
}
else
{
ScrInvokeDlg (hMainInstance, hwndActive);
PostQuitMessage (0);
}
}
else if (!fBlankNow || !FInitDefault ())
{
MessageBox (hwndActive, szNoConfigure, szAppName, MB_OK | MB_ICONEXCLAMATION);
PostQuitMessage (0);
}
return TRUE;
}
//
// run-time link to IWLIB.DLL
//
BOOL FInitIdleWild (LPSTR szCmdLine)
{
OFSTRUCT of;
while (*szCmdLine == ' ')
szCmdLine++;
if (*szCmdLine == 0)
return FALSE;
if (-1 == OpenFile(szIdleWildDll, &of, OF_EXIST | OF_SHARE_DENY_NONE) ||
-1 == OpenFile(szCmdLine, &of, OF_EXIST | OF_SHARE_DENY_NONE))
return FALSE;
if ((hIdleWildDll = LoadLibrary (szIdleWildDll)) == NULL)
return FALSE;
FInitScrSave = (SHORT (*) (HANDLE, HWND))GetProcAddress (hIdleWildDll, "FInitScrSave" );
TermScrSave = (VOID (*) (VOID)) GetProcAddress (hIdleWildDll, "TermScrSave" );
ScrBlank = (VOID (*) (SHORT)) GetProcAddress (hIdleWildDll, "ScrBlank" );
ScrSetIgnore = (VOID (*) (SHORT)) GetProcAddress (hIdleWildDll, "ScrSetIgnore" );
ScrLoadServer = (SHORT (*) (CHAR *)) GetProcAddress (hIdleWildDll, "ScrLoadServer");
ScrSetServer = (SHORT (*) (CHAR *)) GetProcAddress (hIdleWildDll, "ScrSetServer" );
ScrInvokeDlg = (VOID (*) (HANDLE, HWND)) GetProcAddress (hIdleWildDll, "ScrInvokeDlg" );
//
// must be a invalid dll?
//
if (!FInitScrSave || !TermScrSave)
{
FreeLibrary (hIdleWildDll);
return FALSE;
}
//
// init iwlib.dll
//
if (!FInitScrSave (hMainInstance, NULL)) // NULL hwnd???
{
FreeLibrary (hIdleWildDll);
return FALSE;
}
//
// load the screen saver on the command line.
// if the load fails, abort
//
if (!ScrLoadServer (szCmdLine))
{
TermScrSave ();
FreeLibrary (hIdleWildDll);
return FALSE;
}
wmScrSave = RegisterWindowMessage ("SCRSAVE"); // REVIEW: for win 3.1
fIdleWild = TRUE;
return TRUE;
}
BOOL FTermIdleWild (VOID)
{
if (fIdleWild)
{
TermScrSave ();
FreeLibrary (hIdleWildDll);
}
return TRUE;
}
//
// init the default screen saver
//
BOOL FInitDefault (VOID)
{
WNDCLASS cls;
HWND hwnd;
HDC hdc;
RECT rc;
OSVERSIONINFO osvi;
BOOL bWin2000 = FALSE;
cls.style = 0;
cls.lpfnWndProc = DefaultProc;
cls.cbClsExtra = 0;
cls.cbWndExtra = 0;
cls.hInstance = hMainInstance;
cls.hIcon = NULL;
if (hwndPreview == NULL)
{
cls.hCursor = NULL;
}
else
{
cls.hCursor = LoadCursor(NULL,IDC_ARROW);
}
cls.hbrBackground = GetStockObject (BLACK_BRUSH);
cls.lpszMenuName = NULL;
cls.lpszClassName = szAppName;
if (!RegisterClass (&cls))
return FALSE;
//
// Make sure we use the entire virtual desktop size for multiple
// displays
//
hdc = GetDC(NULL);
GetClipBox(hdc, &rc);
ReleaseDC(NULL, hdc);
// On Win2000 Terminal Services we must detect the case where a remotte session
// is on the disconnected desktop, because in this case GetClipBox() returns
// an empty rect.
if (IsRectEmpty(&rc)) {
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (GetVersionEx (&osvi)){
if ((osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) && (osvi.dwMajorVersion >= 5)) {
bWin2000 = TRUE;
}
}
if (bWin2000 && GetSystemMetrics(SM_REMOTESESSION)) {
rc.left = 0;
rc.top = 0;
rc.right = GetSystemMetrics(SM_CXVIRTUALSCREEN);
rc.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
}
}
hwnd = CreateWindowEx (WS_EX_TOPMOST, szAppName, szAppName,
WS_VISIBLE | ((hwndPreview == NULL) ? WS_POPUP : WS_CHILD),
rc.left,
rc.top,
rc.right - rc.left,
rc.bottom - rc.top,
hwndPreview, NULL,
hMainInstance, NULL);
return hwnd != NULL;
}
LRESULT DefaultProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static POINT ptLast;
POINT ptMouse;
switch (msg)
{
case WM_CREATE:
GetCursorPos (&ptLast);
break;
case WM_DESTROY:
PostQuitMessage (0);
break;
case WM_ACTIVATE:
case WM_ACTIVATEAPP:
if (wParam)
break;
case WM_LBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_KEYDOWN:
case WM_CHAR:
if (hwndPreview == NULL)
{
PostMessage (hwnd, WM_CLOSE, 0, 0L);
}
break;
case WM_MOUSEMOVE:
if (hwndPreview == NULL)
{
GetCursorPos (&ptMouse);
if (abs (ptMouse.x - ptLast.x) + abs (ptMouse.y - ptLast.y) > THRESHOLD)
PostMessage (hwnd, WM_CLOSE, 0, 0L);
}
break;
case WM_SETCURSOR:
if (hwndPreview == NULL)
{
SetCursor (NULL);
return 0L;
}
break;
}
return DefWindowProc (hwnd, msg, wParam, lParam);
}