User:Woozle/kscope
Jump to navigation
Jump to search
kscope is a screensaver I wrote for Windows 3.11 using Visual C 1.5, but the compiled .exe works in Win95, Win98, and WinXP as well (though in WinXP I can't figure out how to add it to the list of available screensavers).
A screenshot and the compiled .exe are available here.
k3.hpp
/*
FILE : k3.hpp
PURPOSE: header file for k3.cxx
HISTORY:
NWS 1994aug21 began adapting from BOUNCER.H
NWS 1994aug26 adapting unfinished KALEI code to SCTR
NWS 1995feb17 trying to figure out why kscope setup dialog won't load
NWS 1995feb18 done; creating line_drawer object to eliminate DC & PEN conflicts
*/
#include <windows.h>
#include <scrnsave.h>
#include "resource.h"
#include "gtypes.h"
#include "wgraf.hpp" /* wpix_rgb */
#include "k_math.hpp"
#define MEM_LARGE
#define FAR_PTRS
#include "k_model.h" /* fp_void */
void GetIniEntries(void);
void MoveImage(HWND hWnd);
void GetIniSettings(void);
void WriteProfileInt(LPSTR key, LPSTR tag, int i);
extern BOOL FAR PASCAL ScreenSaverConfigureDialog(HWND,UINT,WPARAM,LPARAM);
k3.cpp
/*
FILE : k3.cxx -- kaleidascope screen saver
FUNCTIONS :
ScreenSaverProc()
RegisterDialogClasses()
ScreenSaverConfigureDialog()
HISTORY :
NWS 1994aug21 began adapting from BOUNCER.C
NWS 1994aug26 adapting unfinished KALEI code to SCTR
NWS 1995feb17 migrating sctr back to kaleidascope (it _was_ working...)
*/
#include <assert.h>
#include <memory.h>
#include <math.h>
#define WIN_GRAFIX
#include "k3.hpp"
/* Global used by SCRNSAVE.LIB. Required for all screen savers. */
extern "C" char szAppName[40];
char szAppName[40];
/* Globals specific to this app. */
char szName[] = "Kaleidascope"; /* used by scrnsav library (how?) */
char szSpeed[] = "speed";
/* "kaleidascope" stuff */
char szSegs[] = "#segs";
char szLinks[] = "#links";
char szSoftInc[] = "interval";
char szRandSeed[] = "random seed";
char szClear[] = "clear";
char szPenType[] = "pen type";
char szMoveColors[] = "move colors";
char szColorLinks[] = "color links";
// window classes
char szTestWin[] = "SSTestWin";
/* Externals defined in SCRNSAVE.LIB. Required for all screen savers. */
HINSTANCE _cdecl hMainInstance;
HWND _cdecl hMainWindow;
char _cdecl szIsPassword[22];
char _cdecl szIniFile[MAXFILELEN];
char _cdecl szScreenSaver[22];
char _cdecl szPassword[16];
char _cdecl szDifferentPW[BUFFLEN];
char _cdecl szChangePW[30];
char _cdecl szBadOldPW[BUFFLEN];
char _cdecl szHelpFile[MAXFILELEN];
char _cdecl szNoHelpMemory[BUFFLEN];
UINT _cdecl MyHelpMessage;
HOOKPROC _cdecl fpMessageFilter;
WORD wTimer; // timer id
/* enumerated types used in storage */
enum win_pen_type { /* Windows API pen type */
wpen_solid,
wpen_dash,
wpen_dot,
wpen_dashdot,
wpen_dashdotdot,
wpen_null,
wpen_insideframe
};
enum ks_pen_type { /* kscope pen type */
kpen_solid,
kpen_dash,
kpen_dot,
kpen_dashdot,
kpen_dashdotdot,
kpen_dithered,
kpen_callback,
kpen_software
};
const ks_pen_type highest_api_kpen = kpen_dithered;
/* universal SETUP options */
WORD nSpeed = 10;
flag bPassword;
/* "kaleidascope" options */
WORD nSegs = 1;
WORD nLinks = 200;
ks_pen_type nPenType = kpen_software;
WORD nSoftInc = 24;
WORD nRandSeed = 0;
flag bClearScrn = Yes;
flag bMoveColors = No;
flag bColorLinks = No;
/* common vars & objects */
/* Windows stuff */
gbox scr_box;
int scr_bits; /* screen bits per pixel */
flag scr_pltt; /* screen supports palettes? */
/* other variables */
flag active = No;
gpt start_pt;
/* "kaleidascope" vars & objects */
win_pen_type aPenType; /* actual Windows pen type */
byte penWidth; /* pen width to use */
flag softPen; /* not using an hPen */
/* Windows stuff */
HINSTANCE hInst; /* handle to app instance */
HWND hMsg; /* handle to window for timer messages */
HWND hDlg = 0; /* handle to configuration dialog, if active */
HWND hPenList;
HWND hSoftInc;
HWND hLineDemo; /* handle to line-demo window */
/* other variables */
flag drawing;
flag is_saver = Yes;
gpt new_pt[3];
WORD link,seg;
WORD topSegPoint; /* top point in seg array */
WORD topSegLink; /* top seg for drawing links */
wpix_rgb cur_color;
gloc dot_count;
/* major objects */
struct seg_def {
wpix_rgb color;
gpt point;
};
typedef seg_def asegs[];
asegs* axes; // pointer to axis array
struct line_drawer : public gbox {
/*====DATA====*/
HDC hDC; /* handle to device context for drawing */
HPEN hPen; /* current drawing pen, if any */
/*====CODE====*/
void PenPrep(flag);
void GetColor(COLORREF icolor);
void DoLine();
void CALLBACK LineMethod(int X, int Y);
};
typedef line_drawer* p_line_drawer;
HWND hWnd; /* handle to window for drawing lines */
//HDC call_hDC; /* FUTURE: thunk the line callback */
/* also make cur_color a member */
line_drawer global_line; /* global line-drawer for actual kaleidascope */
typedef void (CALLBACK line_drawer::* LinMeth)(int,int,LPARAM); /* LinMeth: LineDDAProc() */
//struct kprocs {
// union {
// uprocs up;
// LinMeth lm;
// };
//};
//class ckprocs : public kprocs {
// ckprocs() : kprocs() {}
// ckprocs(LinMeth ilm) { lm = ilm; }
//};
/*==============================================================*\
FUNCTION : LineCallback(int,int,proc)
MODEL : LineDDAProc()
\*==============================================================*/
void CALLBACK LineCallback(int X, int Y, LPARAM pclass)
{
((p_line_drawer)pclass) -> LineMethod(X,Y);
}
/*===================================*\
CLASS : line_drawer
PURPOSE: drawing of styled lines
\*===================================*/
/*==============================================================*\
FUNCTION : line_drawer::PenPrep(yes/no)
GLOBALS :
nPenType --> selected pen type from list
aPenType <-- actual Win HPEN to use, if any
softPen <-- Yes = drawing will be done without an HPEN
MEMBERS :
fpCall <-- pointer to instance of callback function
hPen <-- (cleared) handle to pen, if any
\*==============================================================*/
void line_drawer::PenPrep(flag ienter)
{
if (ienter) {
// fpCall = 0;
// fpMeth = 0;
switch (nPenType) {
case kpen_callback: {
// FARPROC fpMeth = MakeProcInstance((FARPROC)LineCallback,hInst);
// old #1
// fpCall = MakeThunk(this,fpMeth);
// fpCall = line_thunk.MakeThunk(this,ckprocs(LineCallback).up);
// old #2
// fpCall = line_thunk.MakeThunk(this,ckprocs(LineCallback).up); /*TEST*/
// old #3
// fpMeth = MakeProcInstance(ckprocs(LineCallback).up.fp, hInst);
// fpCall = line_thunk.MakeThunk(this,cprocs(fpMeth));
/* no break -- also do kpen_software processing */
}
case kpen_software:
softPen = Yes;
aPenType = wpen_null; /* just for clarity */
break;
case kpen_dithered:
softPen = No;
aPenType = wpen_insideframe;
penWidth = 2;
break;
default:
softPen = No;
aPenType = (win_pen_type)nPenType;
penWidth = 0;
}
hPen = 0;
// hPenOld = 0;
} else {
#ifdef x1995feb18 /* PROBABLY UNNECESSARY */
if (hPen) {
HPEN hPenOld = SelectObject(hDC, GetStockObject(NULL_PEN)); /* deselect last pen */
DeleteObject(hPenOld); /* destroy the last created pen */
}
#endif
// line_thunk.FreeThunk();
// if (fpMeth)
// FreeProcInstance(fpMeth);
}
}
/*==============================================================*\
FUNCTION : line_drawer::GetColor()
\*==============================================================*/
void line_drawer::GetColor(COLORREF icolor)
{
cur_color.wc = icolor;
if (!softPen) {
SetBkColor(hDC,RGB(0,0,0));
hPen = CreatePen(aPenType,penWidth,cur_color.wc);
HPEN hPenOld = SelectObject(hDC,hPen);
DeleteObject(hPenOld); /* kill the old pen */
}
}
/*==============================================================*\
FUNCTION : line_drawer::DoLine
ACTION : draw a single line
GLOBALS :
nPenType --> selected type of drawing to do
MEMBERS :
(gbox) --> endpoints of line to draw
\*==============================================================*/
void line_drawer::DoLine()
{
switch (nPenType) {
case kpen_callback:
dot_count = 0;
// call_hDC = hDC; /* TO BE ELIMINATED LATER */
// LineDDA(A.X, A.Y, B.X, B.Y, fpCall, this);
LineDDA(A.X, A.Y, B.X, B.Y, (FARPROC)LineCallback, (LPARAM)(fp_void)this);
break;
case kpen_software: {
float xdiff = X.Diff();
float ydiff = Y.Diff();
// float xydiff = (float)fabs(xdiff) + (float)fabs(ydiff); /* same as callback */
float xydiff = (float)sqrt((xdiff*xdiff) + (ydiff*ydiff));
if (xydiff) {
float xinc = xdiff/xydiff * nSoftInc;
float yinc = ydiff/xydiff * nSoftInc;
float xloc = X.A;
float yloc = Y.A;
int idx, count = (int)(xydiff/nSoftInc)+1;
for (idx=count; idx--; idx>0) {
SetPixel(hDC,(gloc)xloc,(gloc)yloc,cur_color.wc);
xloc += xinc;
yloc += yinc;
};
}
break;
}
default:
SetBkMode(hDC,TRANSPARENT);
MoveTo(hDC, A.X, A.Y);
LineTo(hDC, B.X, B.Y);
}
}
/*==============================================================*\
FUNCTION : line_drawer::LineMethod(int,int)
USAGE : called by ::LineCallback(int,int,LPRARM)
\*==============================================================*/
void CALLBACK line_drawer::LineMethod(int X, int Y)
{
if (!dot_count) {
dot_count = nSoftInc;
#ifdef _DBG
COLORREF acol = SetPixel(hDC,X,Y,cur_color.wc);
#else
SetPixel(hDC,X,Y,cur_color.wc);
#endif
} else
dot_count--;
}
/*===================================*\
SECTION: normal functions
\*===================================*/
/*==============================================================*\
FUNCTION : RegisterDialogClasses
PURPOSE : Entry point for registering window classes
required by configuration dialog box.
INPUT : hWnd -- Handle to window
RETURNS : nothing
\*==============================================================*/
BOOL RegisterDialogClasses(HINSTANCE ihInst)
{
WNDCLASS wc;
hInst = ihInst;
wc.style = 0x0; // Class style(s) (none)
wc.lpfnWndProc = ScreenSaverProc; // Message handler function
wc.cbClsExtra = 0; // No per-class extra data.
wc.cbWndExtra = 0; // No per-window extra data.
wc.hInstance = hInst; // App that owns the class.
wc.hIcon = LoadIcon(hInst,"ID_MAINICON"); // icon to use
wc.hCursor = 0;
wc.hbrBackground = 0; // window must paint background
wc.lpszMenuName = 0; // Name of menu resource in .RC file.
wc.lpszClassName = szTestWin; // Name used in call to CreateWindow.
if (!RegisterClass(&wc)) // register the class
return No; // didn't work
return Yes;
}
/*==============================================================*\
FUNCTIONS : SetSettings
ACTION : copy the settings from the dialog box to the
program variables
\*==============================================================*/
void SetSettings()
{
if (hDlg) {
nSpeed = GetDlgItemInt(hDlg, IDC_SPEED,NULL, No);
nSegs = GetDlgItemInt(hDlg, IDC_NUM_SEGS,NULL, No);
nLinks = GetDlgItemInt(hDlg, IDC_NUM_LINKS,NULL, No);
nSoftInc = GetDlgItemInt(hDlg, IDC_INTERVAL,NULL, No);
nPenType = (ks_pen_type)SendMessage(hPenList,CB_GETCURSEL,0,0);
/* nb don't set random seed from dialog */
bClearScrn = IsDlgButtonChecked(hDlg, IDC_CLEAR_SCRN);
bColorLinks = IsDlgButtonChecked(hDlg, IDC_COLOR_LINKS);
bMoveColors = IsDlgButtonChecked(hDlg, IDC_MOVE_COLORS);
bPassword = IsDlgButtonChecked(hDlg, ID_PASSWORDPROTECTED);
}
WriteProfileInt(szAppName, szSpeed, nSpeed);
WriteProfileInt(szAppName, szSegs, nSegs);
WriteProfileInt(szAppName, szLinks, nLinks);
WriteProfileInt(szAppName, szSoftInc, nSoftInc);
WriteProfileInt(szAppName, szPenType, nPenType);
WriteProfileInt(szAppName, szRandSeed, nRandSeed);
WriteProfileInt(szAppName, szClear, bClearScrn);
WriteProfileInt(szAppName, szColorLinks,bColorLinks);
WriteProfileInt(szAppName, szMoveColors,bMoveColors);
WriteProfileInt(szAppName, szIsPassword,bPassword);
}
/*==============================================================*\
FUNCTION : Prepare(yes/no)
ACTION : start or finish screen saver (e.g. allocate or
deallocate memory, etc.)
\*==============================================================*/
void Prepare(flag ienter)
{
if (ienter) {
p_void mp;
size_t ms;
topSegPoint = nSegs + 2; /* top point # in segment array */
topSegLink = nSegs + 0; /* top segment # for drawing links */
ms = (topSegPoint+1) * sizeof(seg_def); /* figure # of bytes to allocate */
mp = malloc(ms); /* allocate them */
axes = (asegs*)mp; /* recast to segment array */
memset(mp,0,ms); /* clear the array */
if (bMoveColors) { /* if colors are persistent...*/
seg = nSegs;
while (seg > 0) {
seg--;
(*axes)[seg].color.SetRand();
};
}
wTimer = SetTimer(hMsg, ID_TIMER, 0, NULL);
if (!wTimer) {
MessageBox(0,"Couldn't create timer","Error",MB_ICONEXCLAMATION);
return;
}
GetClientRect(hWnd, &scr_box.wr); /* get window size */
global_line.hDC = GetDC(hWnd); /* get window device context */
link = 0; /* go into loop first time */
seg = topSegLink; /* go into loop first time */
srand(nRandSeed);
} else {
free(axes);
/* Destroy any objects we created */
if (wTimer)
KillTimer(hMsg, ID_TIMER);
if (global_line.hDC)
ReleaseDC(hWnd, global_line.hDC);
nRandSeed = rand();
SetSettings(); /* save new random seed */
if (hDlg)
SetDlgItemInt(hDlg,IDC_RAND_SEED,nRandSeed,No);
}
global_line.PenPrep(ienter);
active = ienter;
drawing = No;
}
/*==============================================================*\
FUNCTION : DoLink
ACTION : draw a line with appropriate reflections
\*==============================================================*/
void DoLink(gbox end_pt)
{
gpt scr_ctr = scr_box.Mid();
global_line.A = end_pt.A;
global_line.B = end_pt.B;
global_line.DoLine(); /* X norm, Y norm */
global_line.X.Reflect(scr_ctr.X);
global_line.DoLine(); /* X refl, Y norm */
global_line.Y.Reflect(scr_ctr.Y);
global_line.DoLine(); /* X refl, Y refl */
global_line.X.Reflect(scr_ctr.X);
global_line.DoLine(); /* X norm, Y refl */
}
/*==============================================================*\
FUNCTION : MoveImage
ACTION : Move image around the screen
INPUT : hWnd -- Handle to window
RETURNS : nothing
\*==============================================================*/
static void MoveImage()
{
wpix_rgb color1, color2; /* for color interpolation if (bColorLinks) */
if (active) {
for (word idx = 0; idx < nSpeed; idx++) {
loop: if (!bMoveColors && (seg==0)) {
seg = topSegLink;
} else {
seg++;
if (seg > topSegLink) {
if (link == 0) {
link = nLinks;
/* shift points up the array one notch */
if (bMoveColors) {
for (seg=topSegPoint; seg>0; seg--) {
(*axes)[seg].point = (*axes)[seg-1].point;
}
} else {
for (seg=topSegPoint; seg>0; seg--) {
(*axes)[seg] = (*axes)[seg-1];
}
(*axes)[0].color.SetRand();
}
gpt old_pt = (*axes)[0].point;
gpt new_pt;
do {
new_pt = scr_box.Random();
} while (old_pt.xy == new_pt.xy);
(*axes)[0].point = new_pt;
} else
link--;
seg = 0;
}
}
/* figure current point triplet */
for (int jdx = 2; jdx >= 0; jdx--) {
new_pt[jdx] = (*axes)[seg+jdx].point;
}
if (seg == topSegLink) {
color1.wc = 0;
color2.wc = 0;
} else {
color1 = (*axes)[seg].color;
color2 = (*axes)[seg+1].color;
}
if (!bColorLinks) {
global_line.GetColor(color1.wc);
}
gbox link_line;
gbox interbox;
if (new_pt[0].xy && (new_pt[1].xy || !link)) {
if (new_pt[1].xy && (new_pt[2].xy || !link)) {
float portion = (float)link / (nLinks+1);
interbox.A = new_pt[0];
interbox.B = new_pt[1];
link_line.A = interbox.Interp(portion);
interbox.A = new_pt[1];
interbox.B = new_pt[2];
link_line.B = interbox.Interp(portion);
if (bColorLinks) {
if (seg == topSegLink) {
global_line.GetColor(0);
} else {
global_line.GetColor(color1.Interp(portion,color2.wc));
drawing = Yes;
}
} else if (cur_color.wc)
drawing = Yes;
if (drawing)
DoLink(link_line);
}
}
if (!drawing) /* do all non-visible processing immediately */
goto loop;
}
}
}
/*==============================================================*\
FUNCTION : AboutBoxProc()
ACTION : handles About box
\*==============================================================*/
LONG FAR PASCAL AboutBoxProc(HWND ihWnd, UINT msg, WPARAM wd, LPARAM ld)
{
switch (msg) {
case WM_INITDIALOG:
hWnd = GetDlgItem(ihWnd,IDC_TESTWIN);
hMsg = ihWnd;
Prepare(Yes);
return Yes;
case WM_TIMER:
MoveImage();
return 0;
case WM_COMMAND:
switch (wd) {
case IDOK:
EndDialog(ihWnd,0);
return Yes;
}
case WM_DESTROY:
Prepare(No);
return 0;
}
return 0;
}
/*==============================================================*\
FUNCTION : GetScreenParams
ACTION : get information about the screen device
\*==============================================================*/
void GetScreenParams(HWND ihWnd)
{
HDC scrn_hDC = GetDC(ihWnd);
scr_pltt = (GetDeviceCaps(scrn_hDC,RASTERCAPS) & RC_PALETTE) != 0;
scr_bits = GetDeviceCaps(scrn_hDC,BITSPIXEL);
ReleaseDC(ihWnd,scrn_hDC);
}
/*==============================================================*\
FUNCTION : DoLineTest()
ACTION : demonstrate the selected pen type at various angles
\*==============================================================*/
void DoLineTest()
{
PAINTSTRUCT far ps;
HDC hDemoDC = BeginPaint(hLineDemo,&ps);
assert(hDemoDC);
gbox demo_box;
line_drawer local_line;
local_line.hDC = hDemoDC; /* set line's DC to line demo area */
local_line.PenPrep(Yes);
local_line.GetColor(RGB(0x0ff, 0x0ff, 0x0ff));
GetClientRect(hLineDemo, &demo_box.wr); /* get window size */
FillRect(hDemoDC,&demo_box.wr,(HBRUSH)GetStockObject(BLACK_BRUSH));
gloc line_siz;
if (demo_box.X.Size() < demo_box.Y.Size())
line_siz = demo_box.X.Size();
else
line_siz = demo_box.Y.Size();
line_siz /= 2;
local_line.A = demo_box.Mid();
float idx_dec = ((float)_PI) * 0.05f;
for (float idx = (float)_PI * 2.0f; idx > 0.0; idx-=idx_dec) {
local_line.Y.FitB((gloc)(sin(idx) * (float)line_siz));
local_line.X.FitB((gloc)(cos(idx) * (float)line_siz));
local_line.DoLine();
}
// ValidateRect(hLineDemo,0); /* don't repaint over line demo */
local_line.PenPrep(No);
EndPaint(hDlg,&ps); // finished with painting
}
/*==============================================================*\
FUNCTION : ScreenSaverConfigureDialog
MODEL : DialogProc()
PURPOSE : Dialog box function for configuration dialog.
INPUT : hWnd -- Handle to window
RETURNS : nothing
\*==============================================================*/
BOOL FAR PASCAL __export ScreenSaverConfigureDialog(HWND ihDlg, UINT msg, WPARAM wd, LPARAM ld)
{
static HWND hIDOK;
static HWND hSetPassword;
HWND hTest;
switch (msg) {
case WM_INITDIALOG:
hDlg = ihDlg;
hPenList = GetDlgItem(hDlg,IDC_PEN_TYPE); /* get handle for pen-type list */
hSoftInc = GetDlgItem(hDlg,IDC_INTERVAL);
hLineDemo = GetDlgItem(hDlg,IDC_LINE_TEST); /* get line-demo control */
GetIniEntries();
GetIniSettings();
SetDlgItemInt (hDlg,IDC_SPEED,nSpeed,No);
SetDlgItemInt (hDlg,IDC_NUM_SEGS,nSegs,No);
SetDlgItemInt (hDlg,IDC_NUM_LINKS,nLinks,No);
SetDlgItemInt (hDlg,IDC_RAND_SEED,nRandSeed,No);
SetDlgItemInt (hDlg,IDC_INTERVAL,nSoftInc,No);
SendMessage(hPenList,CB_ADDSTRING,0,(LPARAM)(char far*)"Solid");
SendMessage(hPenList,CB_ADDSTRING,0,(LPARAM)(char far*)"Dash");
SendMessage(hPenList,CB_ADDSTRING,0,(LPARAM)(char far*)"Dot");
SendMessage(hPenList,CB_ADDSTRING,0,(LPARAM)(char far*)"Dash-dot");
SendMessage(hPenList,CB_ADDSTRING,0,(LPARAM)(char far*)"Dash-dot-dot");
SendMessage(hPenList,CB_ADDSTRING,0,(LPARAM)(char far*)"Dithered");
SendMessage(hPenList,CB_ADDSTRING,0,(LPARAM)(char far*)"Callback");
SendMessage(hPenList,CB_ADDSTRING,0,(LPARAM)(char far*)"Software");
SendMessage(hPenList,CB_SETCURSEL,nPenType,0);
CheckDlgButton (hDlg,IDC_CLEAR_SCRN,bClearScrn);
CheckDlgButton (hDlg,IDC_COLOR_LINKS,bColorLinks);
CheckDlgButton (hDlg,IDC_MOVE_COLORS,bMoveColors);
SendDlgItemMessage (hDlg,ID_PASSWORDPROTECTED, BM_SETCHECK, bPassword, NULL);
hSetPassword = GetDlgItem(hDlg, ID_SETPASSWORD);
EnableWindow(hSetPassword, bPassword);
hIDOK = GetDlgItem(hDlg, IDOK);
return TRUE;
case WM_DESTROY:
hDlg = 0;
return FALSE;
case WM_PAINT: {
if (nPenType > highest_api_kpen) {
ShowWindow(hSoftInc,SW_SHOW);
} else {
ShowWindow(hSoftInc,SW_HIDE);
}
DoLineTest();
return No;
}
case WM_COMMAND:
switch (wd) {
case IDOK:
SetSettings();
EndDialog(hDlg, TRUE);
return TRUE;
case IDCANCEL:
EndDialog(hDlg, FALSE);
return TRUE;
case ID_TEST:
is_saver = No;
SetSettings(); /* save current settings to ini file */
hTest = CreateWindow(
szTestWin,
"Kaleidascope",
WS_CAPTION | WS_MAXIMIZEBOX | WS_MINIMIZEBOX |
WS_SYSMENU | WS_THICKFRAME | WS_OVERLAPPED,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
hDlg,0,hInst,0);
ShowWindow(hTest,SW_SHOWNA);
return TRUE;
case ID_ABOUT: {
FARPROC fpDialog;
fpDialog = MakeProcInstance((FARPROC)AboutBoxProc,hInst);
SetSettings();
DialogBox(hInst,MAKEINTRESOURCE(IDD_ABOUTBOX),hDlg,fpDialog);
FreeProcInstance(fpDialog);
break;
}
case ID_SETPASSWORD: {
FARPROC fpDialog;
fpDialog = MakeProcInstance((FARPROC)DlgChangePassword,hMainInstance);
if(!fpDialog)
return FALSE;
DialogBox(hMainInstance, MAKEINTRESOURCE(DLG_CHANGEPASSWORD), hDlg, fpDialog);
FreeProcInstance(fpDialog);
SendMessage(hDlg, WM_NEXTDLGCTL, hIDOK, 1l);
break;
}
case ID_PASSWORDPROTECTED:
bPassword ^= 1;
CheckDlgButton(hDlg, wd, bPassword);
EnableWindow(hSetPassword, bPassword);
break;
case IDC_PEN_TYPE: {
if ((ld & 0x00080000) && !(ld & 0x00010000)) {
ks_pen_type oldPenType = nPenType;
nPenType = (ks_pen_type)SendMessage(hPenList,CB_GETCURSEL,0,0);
// if (nPenType != oldPenType) {
if (nPenType > highest_api_kpen)
ShowWindow(hSoftInc,SW_SHOW);
else
ShowWindow(hSoftInc,SW_HIDE);
InvalidateRect(hLineDemo,0,No);
DoLineTest();
// }
}
} break;
case IDC_RAND_SEED:
nRandSeed = GetDlgItemInt(hDlg, IDC_RAND_SEED,NULL, No);
break;
}
break;
}
return FALSE;
}
/*==============================================================*\
FUNCTION : GetIniSettings
ACTION : Get initial settings from WIN.INI
INPUT : hWnd -- Handle to window
RETURNS : nothing
\*==============================================================*/
static void GetIniSettings()
{
nSpeed = GetPrivateProfileInt(szAppName, szSpeed, nSpeed, szIniFile);
nSegs = GetPrivateProfileInt(szAppName, szSegs, nSegs, szIniFile);
nLinks = GetPrivateProfileInt(szAppName, szLinks, nLinks, szIniFile);
nSoftInc = GetPrivateProfileInt(szAppName, szSoftInc, nSoftInc, szIniFile);
nRandSeed = GetPrivateProfileInt(szAppName, szRandSeed, nRandSeed, szIniFile);
nPenType =
(ks_pen_type)GetPrivateProfileInt(szAppName, szPenType, nPenType, szIniFile);
bClearScrn = GetPrivateProfileInt(szAppName, szClear, bClearScrn, szIniFile);
bColorLinks = GetPrivateProfileInt(szAppName, szColorLinks, bColorLinks,szIniFile);
bMoveColors = GetPrivateProfileInt(szAppName, szMoveColors, bMoveColors,szIniFile);
bPassword = GetPrivateProfileInt(szAppName, szIsPassword, FALSE, szIniFile);
}
/*==============================================================*\
FUNCTION : ScreenSaverProc
PURPOSE : Main entry point for screen saver messages.
USAGE : This function is required for all screen savers.
RETURNS : depends on input message
\*==============================================================*/
LONG FAR PASCAL __export ScreenSaverProc(HWND ihWnd, UINT msg, WPARAM wd, LPARAM ld)
{
hWnd = ihWnd;
hMsg = ihWnd;
switch (msg) {
case WM_CREATE:
GetScreenParams(ihWnd);
if (scr_bits > 8) /* if hiColor display...*/
bColorLinks = Yes; /* default is "move colors" = on */
GetIniEntries(); /* Load the strings from the STRINGTABLE */
GetIniSettings(); /* Load the initial bounce settings. */
Prepare(Yes);
GetScreenParams(hWnd);
break;
case WM_DESTROY:
active = No;
Prepare(No);
break;
case WM_ERASEBKGND:
if (bClearScrn) {
FillRect((HDC)wd,&scr_box.wr,(HBRUSH)GetStockObject(BLACK_BRUSH));
}
active = Yes;
return 0L;
case WM_TIMER:
MoveImage();
break;
case WM_SIZE:
GetClientRect(ihWnd, &scr_box.wr); /* get window size */
ReleaseDC(ihWnd,global_line.hDC); /* release old device context */
global_line.hDC = GetDC(ihWnd); /* get new device context */
if (bClearScrn) {
FillRect(global_line.hDC,&scr_box.wr,(HBRUSH)GetStockObject(BLACK_BRUSH));
}
break;
case WM_SYSCOMMAND:
if (wd == SC_SCREENSAVE)
is_saver = Yes;
break;
}
if (is_saver)
return DefScreenSaverProc(ihWnd,msg,wd,ld);
else
return DefWindowProc(ihWnd,msg,wd,ld);
}
/*==============================================================*\
FUNCTION : WriteProfileInt
ACTION : Write an unsigned integer value to CONTROL.INI.
INPUT :
name - szSection - [section] name in .INI file
szKey - key= in .INI file
i - value for key above
RETURNS : nothing
\*==============================================================*/
static void WriteProfileInt(LPSTR szSection, LPSTR szKey, int i)
{
char achBuf[40];
/* write out as unsigned because GetPrivateProfileInt() can't
* cope with signed values!
*/
wsprintf(achBuf, "%u", i);
WritePrivateProfileString(szSection, szKey, achBuf, szIniFile);
}
/*==============================================================*\
FUNCTION : GetIniEntries()
\*==============================================================*/
void GetIniEntries(void)
{
//Load Common Strings from stringtable...
LoadString(hMainInstance, idsIsPassword, szIsPassword, 22);
LoadString(hMainInstance, idsIniFile, szIniFile, MAXFILELEN);
LoadString(hMainInstance, idsScreenSaver, szScreenSaver, 22);
LoadString(hMainInstance, idsPassword, szPassword, 16);
LoadString(hMainInstance, idsDifferentPW, szDifferentPW, BUFFLEN);
LoadString(hMainInstance, idsChangePW, szChangePW, 30);
LoadString(hMainInstance, idsBadOldPW, szBadOldPW, 255);
LoadString(hMainInstance, idsHelpFile, szHelpFile, MAXFILELEN);
LoadString(hMainInstance, idsNoHelpMemory, szNoHelpMemory, BUFFLEN);
}