  | 
   Screensaver Framework 
   Submitted by  |   
  
  
A simple screensaver framework which implements much of
the Windows fluff that's required of a screensaver.
This leaves you to do the interesting OpenGL/DirectX rendering.
See the readme in the zip.
--  
Cheers, 
Roc (CyberFrog) 8:)
 | 
 
 
 
Currently browsing [ScreensaverWrapper.zip] (11,763 bytes) - [TestScreensaver.cpp] - (7,922 bytes)
 
 #include "stdafx.h"
#include "screensaver.h"
  class CTestScreensaver : public CScreensaverApp
{
public:
  	CTestScreensaver();
	virtual ~CTestScreensaver();
  	// Accessors
	bool	isFullscreen() const		{ return isFullscreen_; }
	bool	isActive() const			{ return isActive_; }
  protected:
  	// Methods inherited from base class.
	// Required for fullscreen rendering.
	virtual HWND doCreateFullscreen();
	virtual void doRenderFullscreen();
	virtual void doDestroyFullscreen();
	virtual void doRestoreFullscreen();
  	// Required for preview rendering.
	virtual HWND doCreatePreview( HWND hParentWnd );
	virtual void doRenderPreview();
	virtual void doDestroyPreview();
	virtual void doRestorePreview();
  	// Required for configuration
	virtual void doRunConfiguration();
  	// Required for registering the application
	// settings.  Typically, a company name.
	virtual LPCTSTR	applicationRegistryKey() const;
  private:
  	// Canonical form revoked
	CTestScreensaver( const CTestScreensaver ©Me );
	CTestScreensaver &operator =( const CTestScreensaver ©Me );
  	// Helpers
	bool		createWindow( bool fullscreen,HWND hParentWnd );
	LPCTSTR		registerClass();
	void		renderFrame();
  	// The window procedure is our friend
	friend LRESULT CALLBACK WndProc( HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam );
  	// Data members
	HWND	hRenderWnd_;
	bool	isFullscreen_;
	bool	isActive_;
  };
  // We need an application instance
CTestScreensaver	theApp;
  // Our screensaver will need a window procedure.  This is it.
LRESULT CALLBACK WndProc( HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam )
{
	switch( msg ) 
	{
		case WM_CREATE:
		{
			CTestScreensaver	*pApp=(CTestScreensaver *)AfxGetApp();
			ASSERT( pApp );
  			// Hide mouse if fullscreen
			if ( pApp->isFullscreen() )
			{
				::ShowCursor( FALSE );
			}
  			// Window should always on the top 
			::SetWindowPos( hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE );
			break;
		}
		case WM_LBUTTONDOWN:
		case WM_RBUTTONDOWN:
		case WM_MBUTTONDOWN:
		case WM_KEYDOWN:
		case WM_SYSKEYDOWN:
		{
			// Any sort of keyboard or mouse action
			// closes our screensaver.
			::SendMessage( hWnd,WM_CLOSE,0,0 );
			break;
		}
		case WM_CLOSE:
		{
			// It's all over.
			::DestroyWindow( hWnd );
			break;
		}
		case WM_DESTROY:
		{
			CTestScreensaver	*pApp=(CTestScreensaver *)AfxGetApp();
			ASSERT( pApp );
  			// Ensure we are properly shutdown
			if ( pApp->isFullscreen() )
			{
				pApp->doDestroyFullscreen();
			}
			else
			{
				pApp->doDestroyPreview();
			}
  			// Show mouse if we were in fullscreen mode
			if ( pApp->isFullscreen() )
			{
				::ShowCursor( TRUE );
			}
  			// Ensure the app knows that the window has gone
			pApp->hRenderWnd_=NULL;
			break;
		}
		case WM_PAINT:
		{
			// Very rudimentary painting.
			static size_t	frameCounter=0;
			PAINTSTRUCT		ps;
			HDC				hDC=::BeginPaint( hWnd,&ps );
			TCHAR			szBuff[256];
			wsprintf( szBuff,_T("Frame: %u"),++frameCounter );
			::FillRect( hDC,&ps.rcPaint,(HBRUSH)::GetStockObject(BLACK_BRUSH) );
			::TextOut( hDC,0,0,szBuff,lstrlen(szBuff) );
			::EndPaint( hWnd,&ps );
			break;
		}
		default:
			return ::DefWindowProc( hWnd,msg,wParam,lParam );
   }
     return 0;
}
  // Implementation
CTestScreensaver::CTestScreensaver() :
	CScreensaverApp(),
	hRenderWnd_( NULL ),
	isFullscreen_( false ),
	isActive_( false )
{
	// Ctor
}
  // virtual
CTestScreensaver::~CTestScreensaver()
{
	// Dtor.
	// We should have already shut down properly
	ASSERT( hRenderWnd_==NULL );
	ASSERT( !isActive_ );
}
  bool CTestScreensaver::createWindow( bool fullscreen,HWND hParentWnd )
{
	ASSERT( hRenderWnd_==NULL );
	LPCTSTR		lpszClassName=registerClass();
	const DWORD	dwStyles=(fullscreen ? WS_POPUP : WS_CHILD) | WS_VISIBLE;
	const int	x=0;
	const int	y=0;
	int			width, height;
	if ( fullscreen )
	{
		width	= ::GetSystemMetrics( SM_CXSCREEN );
		height	= ::GetSystemMetrics( SM_CYSCREEN );
	}
	else
	{
		RECT	r;
		ASSERT( hParentWnd!=NULL );
		::GetClientRect( hParentWnd,&r );
		width	= r.right;
		height	= r.bottom;
	}
  	hRenderWnd_ = ::CreateWindow( lpszClassName,_T(""),dwStyles,x,y,width,height,hParentWnd,NULL,::AfxGetInstanceHandle(),NULL );
  	return (hRenderWnd_!=NULL);
}
  LPCTSTR CTestScreensaver::registerClass()
{
	// We must only ever register the class once
	static bool		hasBeenRegistered=false;
	static LPCTSTR	lpszClassName=_T("TestScreensaverClass");
	if ( !hasBeenRegistered )
	{
		WNDCLASSEX		wc;
		
		ZeroMemory( &wc,sizeof(wc) );
		wc.cbSize			= sizeof(wc);
		wc.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
		wc.lpfnWndProc		= (WNDPROC) WndProc;
		wc.cbClsExtra		= 0;
		wc.cbWndExtra		= 0;
		wc.hInstance		= ::AfxGetInstanceHandle();
		wc.hIcon			= NULL;
		wc.hCursor			= ::LoadCursor(NULL, IDC_ARROW);
		wc.hbrBackground	= NULL;
		wc.lpszMenuName		= NULL;
		wc.lpszClassName	= lpszClassName;
  		ATOM	atom=::RegisterClassEx( &wc );
		ASSERT( atom!=0 );
  		hasBeenRegistered=true;
	}
  	return lpszClassName;
}
  void CTestScreensaver::renderFrame()
{
	ASSERT( hRenderWnd_ );
	ASSERT( isActive_ );
  	// Render the Direct3D or OpenGL frame here.
	// For our purposes, we simply invalidate
	// the client area and have WM_PAINT sort it
	// out.  Only cause a frame to be rendered
	// every second though.
	static clock_t	lastClock=0;
	clock_t			thisClock=clock();
	if ( thisClock-lastClock>1000 )
	{
		::InvalidateRect( hRenderWnd_,NULL,FALSE );
		::UpdateWindow( hRenderWnd_ );
  		lastClock=thisClock;
	}
}
  // virtual
LPCTSTR CTestScreensaver::applicationRegistryKey() const
{
	return _T("TestCompanyName");
}
  // virtual
HWND CTestScreensaver::doCreateFullscreen()
{
	// Create a window for fullscreen rendering
	HWND	result=(createWindow(true,NULL) ? hRenderWnd_ : NULL);
  	if ( result!=NULL )
	{
		// Now's the time to create Direct3D or OpenGL.
		// If everything is okay, set the isActive_ flag
		// to say that the sub-system is activated.
		isActive_=true;
	}
  	return result;
}
  // virtual
void CTestScreensaver::doRenderFullscreen()
{
	// Called to render a frame.
	renderFrame();
}
  // virtual
void CTestScreensaver::doRestoreFullscreen()
{
	// Called if the device has been lost
	// e.g. after a power off on monitor
	// and should be restored.
}
  // virtual
void CTestScreensaver::doDestroyFullscreen()
{
	// If we're active, shutdown any Direct3D
	// or OpenGL objects.  Do NOT destroy
	// the window - this is done automatically.
	if ( isActive_ )
	{
		isActive_=false;
	}
}
  // virtual
HWND CTestScreensaver::doCreatePreview( HWND hParentWnd )
{
	// Create a window for Preview rendering
	HWND	result=(createWindow(false,hParentWnd) ? hRenderWnd_ : NULL);
  	if ( result!=NULL )
	{
		// Now's the time to create Direct3D or OpenGL.
		// If everything is okay, set the isActive_ flag
		// to say that the sub-system is activated.
		isActive_=true;
	}
  	return result;
}
  // virtual
void CTestScreensaver::doRenderPreview()
{
	// Called to render a frame.
	renderFrame();
}
  // virtual
void CTestScreensaver::doRestorePreview()
{
	// Called if the device has been lost
	// e.g. after a power off on monitor
	// and should be restored.
}
  // virtual
void CTestScreensaver::doDestroyPreview()
{
	// If we're active, shutdown any Direct3D
	// or OpenGL objects.  Do NOT destroy
	// the window - this is done automatically.
	if ( isActive_ )
	{
		isActive_=false;
	}
}
  // virtual
void CTestScreensaver::doRunConfiguration()
{
	// Pull up a dialog to alter your
	// screensaver's settings.
	// You must also persist them in the registry
	// yourself.
	::MessageBox( NULL,_T("This should be a configuration dialog!"),_T("TestScreensaver"),MB_OK );
}   |  
  
 | 
 
  
Currently browsing [ScreensaverWrapper.zip] (11,763 bytes) - [screensaver.h] - (3,555 bytes)
 
 // screensaver.h : main header file for the SCREENSAVER application
//
#if !defined(AFX_SCREENSAVER_H__F42F12B4_728D_11D3_B3DD_00A0C90F8EDC__INCLUDED_)
#define AFX_SCREENSAVER_H__F42F12B4_728D_11D3_B3DD_00A0C90F8EDC__INCLUDED_
  #if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#ifndef __AFXWIN_H__
	#error include 'stdafx.h' before including this file for PCH
#endif
  /////////////////////////////////////////////////////////////////////////////
// CScreensaverApp:
//
// This ABC forms the basis of the Screensaver skeleton.  You should derive
// a concrete class from this base and implement the pure virtual functions
// to carry out the necessary implementation of your screensaver.
//
class CScreensaverApp : public CWinApp
{
public:
  	virtual ~CScreensaverApp();
  // Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CScreensaverApp)
public:
	virtual BOOL InitInstance();
	//}}AFX_VIRTUAL
// Implementation
public:
	//{{AFX_MSG(CScreensaverApp)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
  protected:
  	// We can only be created by concrete classes
	CScreensaverApp();
  	// Concretes of this class MUST override these pure virtuals.
	// The virtuals are broken down into groups based upon their
	// requirement.
	// These are for fullscreen operation.
	// Initialise fullscreen mode (typically creates a window)
	// and return the HWND.  If there is an error, return NULL.
	// The render call is made once per frame.
	// If the monitor power is lost, the doRestoreFullscreen()
	// method is called.  This should re-create any device
	// objects as required.
	virtual HWND doCreateFullscreen() = 0;
	virtual void doRenderFullscreen() = 0;
	virtual void doDestroyFullscreen() = 0;
	virtual void doRestoreFullscreen() = 0;
  	// These are for running any configuration dialog
	// and for the persistence mechanism for screensaver
	// settings.  In running the configuration, the
	// client should automatically persist any settings
	// it needs.
	virtual void doRunConfiguration() = 0;
  	// These are for running the preview mode.
	// The client should use the parent HWND to
	// create a child window of the same dimensions
	// and render to that target.  It is ASSUMED
	// that this will be a windowed and not fullscreen
	// render target.
	// The render call is made once per frame.
	// If the monitor power is lost, the doRestorePreview()
	// method is called.  This should re-create any device
	// objects as required.
	virtual HWND doCreatePreview( HWND hParentWnd ) = 0;
	virtual void doRenderPreview() = 0;
	virtual void doDestroyPreview() = 0;
	virtual void doRestorePreview() = 0;
  	// Return the name to use for the registry stub key.
	// Typically, this would be the name of the company.
	virtual LPCTSTR	applicationRegistryKey() const = 0;
  private:
  	// Canonical form revoked
	CScreensaverApp( const CScreensaverApp ©Me );
	CScreensaverApp &operator =( const CScreensaverApp ©Me );
  	// Internal methods
	void	runScreensaver();
	void	runConfiguration();
	void	runPreview( HWND hParentWnd );
	void	runChangePassword();
	bool	verifyPassword( HWND hParentWnd );
	HWND	createHelperWindow();
  };
  /////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_SCREENSAVER_H__F42F12B4_728D_11D3_B3DD_00A0C90F8EDC__INCLUDED_)
   |  
  
 | 
 
  
Currently browsing [ScreensaverWrapper.zip] (11,763 bytes) - [StdAfx.cpp] - (213 bytes)
 
 // stdafx.cpp : source file that includes just the standard includes
//	screensaver.pch will be the pre-compiled header
//	stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
 
 
     |  
  
 | 
 
  
Currently browsing [ScreensaverWrapper.zip] (11,763 bytes) - [StdAfx.h] - (999 bytes)
 
 // stdafx.h : include file for standard system include files,
//  or project specific include files that are used frequently, but
//      are changed infrequently
//
#if !defined(AFX_STDAFX_H__F42F12B6_728D_11D3_B3DD_00A0C90F8EDC__INCLUDED_)
#define AFX_STDAFX_H__F42F12B6_728D_11D3_B3DD_00A0C90F8EDC__INCLUDED_
  #if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions
#include <afxdtctl.h>		// MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>			// MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
  //{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__F42F12B6_728D_11D3_B3DD_00A0C90F8EDC__INCLUDED_)
   |  
  
 | 
 
  
Currently browsing [ScreensaverWrapper.zip] (11,763 bytes) - [screensaver.cpp] - (11,985 bytes)
 
 // screensaver.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "screensaver.h"
  #ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
  /////////////////////////////////////////////////////////////////////////////
// CScreensaverApp
BEGIN_MESSAGE_MAP(CScreensaverApp, CWinApp)
	//{{AFX_MSG_MAP(CScreensaverApp)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()
  /////////////////////////////////////////////////////////////////////////////
// CScreensaverApp construction
CScreensaverApp::CScreensaverApp()
{
	// Place all significant initialization in InitInstance
}
  // virtual
CScreensaverApp::~CScreensaverApp()
{
	// Intentionally empty
}
  /////////////////////////////////////////////////////////////////////////////
// CScreensaverApp initialization
BOOL CScreensaverApp::InitInstance()
{
	// Standard initialization
	// If you are not using these features and wish to reduce the size
	//  of your final executable, you should remove from the following
	//  the specific initialization routines you do not need.
#ifdef _AFXDLL
	Enable3dControls();			// Call this when using MFC in a shared DLL
#else
	Enable3dControlsStatic();	// Call this when linking to MFC statically
#endif
  	// Change the registry key under which our settings are stored.
	SetRegistryKey( applicationRegistryKey() );
  	// When we are invoked, there are a number of command line parameters
	// which govern how we are to operate.  They are as follows:
	//
	//		/s			- Run the screensaver in fullscreen mode
	//		/c			- Run any configuration settings
	//		/a			- Change the password
	//		/p <HWND>	- Run the screensaver in preview mode with HWND
	//					  being the parent window we are to run within.
	//
	// As a special debugging aid, we can test the preview option
	// by running the screensaver in a debugger using /testpreview.
	// In this case, the app will create a parent window internally
	// solely to test the preview.  To test fullscreen, simply supply
	// the /s switch as normal.
	// Determine the command line parameters
	CString		cmdLine=m_lpCmdLine;
	cmdLine.MakeLower();
	if ( cmdLine.Find(_T("/s")) != -1 )
	{
		// Run screensaver proper
		runScreensaver();
	}
	else if ( cmdLine.Find(_T("/c")) != -1 )
	{
		// Run configuration
		runConfiguration();
	}
	else if ( cmdLine.Find(_T("/a")) != -1 )
	{
		// Run password change
		runChangePassword();
	}
	else if ( cmdLine.Find(_T("/testpreview")) != -1 )
	{
		// Run the preview but in test mode.
		// For this, we need to create a
		// window to act as the parent of
		// the screensaver.
		HWND	hParentWnd=createHelperWindow();
		ASSERT( ::IsWindow(hParentWnd) );
		runPreview( hParentWnd );
		::DestroyWindow( hParentWnd );
	}
	else if ( cmdLine.Find(_T("/p")) != -1 )
	{
		// Run preview but we need to extract the HWND
		// of the parent window
		const int	index=cmdLine.Find( _T("/p") );
		ASSERT( index!=-1 );
  		// We don't bother checking that the parent window is
		// invalid - the preview method will verify and early
		// out if there's a problem.  For debugging, we just
		// do a sanity check
		HWND		hParentWnd=(HWND)atoi( cmdLine.Mid(index+3) );
		ASSERT( ::IsWindow(hParentWnd) );
		runPreview( hParentWnd );
	}
	else
	{
		TRACE( "CScreensaverApp::InitInstance() Unrecognised command line parameters: '%s'\n",(LPCTSTR)cmdLine );
		ASSERT( false );
	}
  	return FALSE;
}
  void CScreensaverApp::runScreensaver()
{
	// This will run the screensaver in fullscreen mode.
	// We simply handle the drudgery here and defer the
	// actual work to the concrete class.
	MSG			msg;
	int			originalSPISetting;
	bool		isPowerOn=true;
  	// Allow the client to initialise itself
	HWND		hWnd=doCreateFullscreen();
	if ( hWnd!=NULL )
	{
		// We should be initialised okay so let Windows
		// know that a screensaver is running.
		::SystemParametersInfo( SPI_SCREENSAVERRUNNING,true,&originalSPISetting,0 );
  		// Process whilst we have a valid window
		while ( ::IsWindow(hWnd) || !verifyPassword(hWnd) )
		{
			// Only render if we have still got power
			if ( isPowerOn )
				doRenderFullscreen();
  			// Operate a standard message pump
			while ( ::PeekMessage(&msg,NULL,0,0,PM_REMOVE) )
			{
				// For Win98 and Win2K systems, we could have the
				// monitor powered off.  If this happens, Direct3D/OpenGL
				// can loose their surfaces, etc.
				if ( _winver >= 0x0400 )
				{
					if ( msg.message==WM_SYSCOMMAND && msg.wParam==SC_MONITORPOWER )
					{
						// We've lost power
						isPowerOn=false;
					}
					else if ( msg.message==WM_PAINT )
					{
						// If we get this and power was off, let the
						// client know that surfaces need to be
						// restored
						if ( !isPowerOn )
						{
							doRestoreFullscreen();
							isPowerOn=true;
						}
					}
				}
  				// The normal translate and despatch stuff
				PreTranslateMessage( &msg );
				TranslateMessage( &msg );
				DispatchMessage( &msg );
			}
		}
  		// Ensure the window is destroyed
		if ( ::IsWindow(hWnd) )
		{
			::SendMessage( hWnd,WM_CLOSE,0,0 );
		}
		ASSERT( !::IsWindow(hWnd) );
  		// Prepare for the end.
		// Restore Windows' view of what was running
		::SystemParametersInfo( SPI_SCREENSAVERRUNNING,false,&originalSPISetting,0 );
  		// Allow the client to perform an orderly shutdown
		doDestroyFullscreen();
	}
}
  void CScreensaverApp::runConfiguration()
{
	// Nothing really clever here - simply delegate to client
	doRunConfiguration();
}
  void CScreensaverApp::runPreview( HWND hParentWnd )
{
	// This will run the preview mode.
	// As in the case of fullscreen, we handle alot
	// of the mudane stuff here and delegate the
	// juicy bits to the client.
	MSG			msg;
	bool		isPowerOn=true;
  	// Verify the parent window
	if ( !::IsWindow(hParentWnd) )
	{
		TRACE( "CScreensaverApp::runPreview() Parent window is invalid!\n" );
		return;
	}
  	// Wait for the parent window to become visible
	while ( ::IsWindow(hParentWnd) && !::IsWindowVisible(hParentWnd) )
	{
		// Pump away
		while ( ::PeekMessage(&msg,hParentWnd,0,0,PM_REMOVE) )
		{
			PreTranslateMessage( &msg );
			TranslateMessage( &msg );
			DispatchMessage( &msg );
		}
	}
  	// Allow the client to initialise itself
	HWND		hWnd=doCreatePreview( hParentWnd );
	if ( hWnd!=NULL )
	{
		// Process whilst we have a valid window
		while ( ::IsWindow(hParentWnd) && ::IsWindowVisible(hParentWnd) && ::IsWindow(hWnd) )
		{
			// Only render if we have still got power
			if ( isPowerOn )
				doRenderPreview();
  			// Operate a standard message pump
			while ( ::PeekMessage(&msg,NULL,0,0,PM_REMOVE) )
			{
				// For Win98 and Win2K systems, we could have the
				// monitor powered off.  If this happens, Direct3D/OpenGL
				// can loose their surfaces, etc.
				if ( _winver >= 0x0400 )
				{
					if ( msg.message==WM_SYSCOMMAND && msg.wParam==SC_MONITORPOWER )
					{
						// We've lost power
						isPowerOn=false;
					}
					else if ( msg.message==WM_PAINT )
					{
						// If we get this and power was off, let the
						// client know that surfaces need to be
						// restored
						if ( !isPowerOn )
						{
							doRestorePreview();
							isPowerOn=true;
						}
					}
				}
  				// The normal translate and despatch stuff
				PreTranslateMessage( &msg );
				TranslateMessage( &msg );
				DispatchMessage( &msg );
			}
		}
  		// Ensure the window is destroyed
		if ( ::IsWindow(hWnd) )
		{
			::SendMessage( hWnd,WM_CLOSE,0,0 );
		}
		ASSERT( !::IsWindow(hWnd) );
  		// Allow the client to perform an orderly shutdown
		doDestroyPreview();
	}
}
  void CScreensaverApp::runChangePassword()
{
	// We need to dynamically link to the password DLL since
	// it contains the function to change the screensaver
	// password.
	HINSTANCE	hInst=::LoadLibrary( _T("MPR.DLL") );
	if ( hInst==NULL )
	{
		TRACE( "CScreensaverApp::runChangePassword() Failed to load MPR.DLL\n" );
	}
	else
	{
		// Get hold of the correct function
		typedef VOID (WINAPI *PSWCHANGER)( LPCSTR lpRegKey,HWND hWnd,UINT nReserved1,UINT nReserved2 );
		PSWCHANGER	pswChanger=(PSWCHANGER)::GetProcAddress( hInst,_T("PwdChangePasswordA") );
		if ( pswChanger==NULL )
		{
			TRACE( "CScreensaverApp::runChangePassword() Failed to get address of PwdChangePasswordA\n" );
		}
		else
		{
			// Change the password
			pswChanger( _T("SCRSAVE"),::GetDesktopWindow(),0,0 );
		}
  		// Free the library
		::FreeLibrary( hInst );
	}
}
  bool CScreensaverApp::verifyPassword( HWND hParentWnd )
{
	// This method will optionally bring up the password
	// verification dialog and verify the password
	bool	result=false;
  	// If we're running on WinNT, it will handle the password
	// verification for us so we don't need to bother with
	// anything
	OSVERSIONINFO		osv; 
	ZeroMemory( &osv,sizeof(osv) );
	osv.dwOSVersionInfoSize=sizeof(osv); 
	::GetVersionEx( &osv );
	if ( osv.dwPlatformId==VER_PLATFORM_WIN32_NT )
	{
		result=true;
	}
	else
	{
		// Use the password control panel applet
		HINSTANCE	hInst=::LoadLibrary( _T("PASSWORD.CPL") );
		if ( hInst==NULL )
		{
			TRACE( "CScreensaver::verifyPassword() Failed to load PASSWORD.CPL\n" );
		}
		else
		{
			// Get hold of the password verification function
			typedef BOOL (WINAPI *PSWVERIFY)( HWND hWnd );
			PSWVERIFY		pswVerify=(PSWVERIFY)::GetProcAddress( hInst,_T("VerifyScreenSavePwd") );
			if ( pswVerify==NULL )
			{
				TRACE( "CScreensaver::verifyPassword() Failed to get address of VerifyScreenSavePwd\n" );
			}
			else
			{
				::ShowCursor( TRUE );
  				result = (pswVerify(hParentWnd)==TRUE);
  				::ShowCursor( FALSE );
			}
  			// Release the library
			::FreeLibrary( hInst );
		}
	}
  	return result;
}
  // Test preview window procedure.  Nothing special, really.
LRESULT CALLBACK PreviewHelperWndProc( HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam )
{
	switch( msg ) 
	{
		case WM_PAINT:
		{
			// Just draw a black background
			PAINTSTRUCT		ps;
			HDC				hDC=::BeginPaint( hWnd,&ps );
			::FillRect( hDC,&ps.rcPaint,(HBRUSH)::GetStockObject(BLACK_BRUSH) );
			::EndPaint( hWnd,&ps );
			break;
		}
		default:
			return ::DefWindowProc( hWnd,msg,wParam,lParam );
   }
     return 0;
}
  HWND CScreensaverApp::createHelperWindow()
{
	// We need to create a little window
	// to serve as the parent to a preview
	// test.
	static bool		hasBeenRegistered=false;
	static LPCTSTR	lpszClassName=_T("ScreensaverPreviewHelperClass");
	if ( !hasBeenRegistered )
	{
		WNDCLASSEX		wc;
		
		ZeroMemory( &wc,sizeof(wc) );
		wc.cbSize			= sizeof(wc);
		wc.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
		wc.lpfnWndProc		= (WNDPROC) PreviewHelperWndProc;
		wc.cbClsExtra		= 0;
		wc.cbWndExtra		= 0;
		wc.hInstance		= ::AfxGetInstanceHandle();
		wc.hIcon			= NULL;
		wc.hCursor			= ::LoadCursor(NULL, IDC_ARROW);
		wc.hbrBackground	= NULL;
		wc.lpszMenuName		= NULL;
		wc.lpszClassName	= lpszClassName;
  		ATOM	atom=::RegisterClassEx( &wc );
		ASSERT( atom!=0 );
  		hasBeenRegistered=true;
	}
  	// Choose a size that befits the current resolution
	const int	xScreen=::GetSystemMetrics( SM_CXSCREEN );
	const int	yScreen=::GetSystemMetrics( SM_CYSCREEN );
  	// Set the width and height to a quarter that of the screen
	const int	w=xScreen / 4;
	const int	h=yScreen / 4;
  	// Centre the window
	const int	x=(xScreen - w) / 2;
	const int	y=(yScreen - h) / 2;
  	// Create the window.
	LPCTSTR		lpszTitle=_T("Screensaver Preview Test");
	DWORD		dwStyles=WS_CAPTION;
	HWND		result=::CreateWindow( lpszClassName,lpszTitle,dwStyles,x,y,w,h,NULL,NULL,::AfxGetInstanceHandle(),NULL );
	ASSERT( ::IsWindow(result) );
	::ShowWindow( result,SW_SHOW );
  	return result;
}   |  
  
 | 
 
 
 
The zip file viewer built into the Developer Toolbox made use
of the zlib library, as well as the zlibdll source additions.
 
 
 |