This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

 

  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.

 

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.