406 lines
11 KiB
C
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);
|
||
|
}
|