User:Woozle/kscope

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
 * 1) include 
 * 2) include 
 * 3) include "resource.h"
 * 4) include "gtypes.h"
 * 5) include "wgraf.hpp"	/* wpix_rgb */
 * 6) include "k_math.hpp"
 * 7) define MEM_LARGE
 * 8) define FAR_PTRS
 * 9) 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...)
 * 1) include 
 * 2) include 
 * 3) include 
 * 1) include 


 * 1) define WIN_GRAFIX


 * 1) 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 { if (hPen) { HPEN hPenOld = SelectObject(hDC, GetStockObject(NULL_PEN));	/* deselect last pen */ DeleteObject(hPenOld);					/* destroy the last created pen */ } //		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; COLORREF acol = SetPixel(hDC,X,Y,cur_color.wc); SetPixel(hDC,X,Y,cur_color.wc); } else dot_count--; }
 * 1) ifdef x1995feb18 /* PROBABLY UNNECESSARY */
 * 1) endif
 * 1) ifdef _DBG
 * 1) else
 * 1) endif

/*===================================*\			 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); }