|
|
//-----------------------------------------------------------------------------
// File: Text3D.cpp
//
// Desc: Fun screen saver.
//
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#include <Windows.h>
#include <d3d8.h>
#include <d3dx8.h>
#include <d3dsaver.h>
#include <d3d8rgbrast.h>
#include <time.h>
#include <commdlg.h>
#include <commctrl.h>
#include "Text3D.h"
#include "Resource.h"
#include "dxutil.h"
CTextScreensaver* g_pMyTextScreensaver = NULL;
#define BUF_SIZE 255
TCHAR g_szSectName[BUF_SIZE]; TCHAR g_szFname[BUF_SIZE];
//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: Entry point to the program. Initializes everything, and goes into a
// message-processing loop. Idle time is used to render the scene.
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT ) { HRESULT hr; CTextScreensaver textSS;
if( FAILED( hr = textSS.Create( hInst ) ) ) { textSS.DisplayErrorMsg( hr ); return 0; }
return textSS.Run(); }
//-----------------------------------------------------------------------------
// Name: LoadTextureFromResource()
// Desc:
//-----------------------------------------------------------------------------
HRESULT LoadTextureFromResource( LPDIRECT3DDEVICE8 pd3dDevice, TCHAR* strRes, TCHAR* strResType, LPDIRECT3DTEXTURE8* ppTex ) { HRESULT hr; HMODULE hModule = NULL; HRSRC rsrc; HGLOBAL hgData; LPVOID pvData; DWORD cbData;
rsrc = FindResource( hModule, strRes, strResType ); if( rsrc != NULL ) { cbData = SizeofResource( hModule, rsrc ); if( cbData > 0 ) { hgData = LoadResource( hModule, rsrc ); if( hgData != NULL ) { pvData = LockResource( hgData ); if( pvData != NULL ) { if( FAILED( hr = D3DXCreateTextureFromFileInMemory( pd3dDevice, pvData, cbData, ppTex ) ) ) { return hr; } } } } } if( *ppTex == NULL) return E_FAIL;
return S_OK; }
//-----------------------------------------------------------------------------
// Name: CTextScreensaver()
// Desc: Constructor
//-----------------------------------------------------------------------------
CTextScreensaver::CTextScreensaver() { g_pMyTextScreensaver = this;
LoadString( NULL, IDS_DESCRIPTION, m_strWindowTitle, 200 ); InitCommonControls(); ZeroMemory( m_DeviceObjects, sizeof(m_DeviceObjects) ); m_hFont = NULL; m_bUseDepthBuffer = TRUE; m_dwMinDepthBits = 16; m_floatrect.xSize = 0.0f; lstrcpy( m_strRegPath, TEXT("Software\\Microsoft\\Screensavers\\Text3D") );
m_fAngleX = 0.0f; m_fAngleY = 0.0f; m_fAngleZ = 0.0f;
m_dwMeshUpdateCounter = 0;
srand((UINT)time(NULL)); // seed random number generator
}
//-----------------------------------------------------------------------------
// Name: RegisterSoftwareDevice()
// Desc: This can register the D3D8RGBRasterizer or any other
// pluggable software rasterizer.
//-----------------------------------------------------------------------------
HRESULT CTextScreensaver::RegisterSoftwareDevice() { m_pD3D->RegisterSoftwareDevice( D3D8RGBRasterizer );
return S_OK; }
//-----------------------------------------------------------------------------
// Name: FrameMove()
// Desc: Called once per frame, the call is the entry point for animating
// the scene.
//-----------------------------------------------------------------------------
HRESULT CTextScreensaver::FrameMove() { DWORD tick = GetTickCount(); DWORD elapsed = tick - m_dwLastTick; m_dwLastTick = tick;
// update floatrect
RECT rcBounceBounds;
if( m_floatrect.xSize == 0.0f ) { // Initialize floatrect
RECT rcBounds; DWORD dwParentWidth; DWORD dwParentHeight;
rcBounds = m_rcRenderTotal;
dwParentWidth = rcBounds.right - rcBounds.left; dwParentHeight = rcBounds.bottom - rcBounds.top;
FLOAT sizeFact; FLOAT sizeScale; DWORD size;
sizeScale = m_dwSize / 10.0f; sizeFact = 0.25f + (0.75f * sizeScale); // range 25-100%
size = (DWORD) (sizeFact * ( dwParentWidth > dwParentHeight ? dwParentHeight : dwParentWidth ) );
if( size > dwParentWidth ) size = dwParentWidth; if( size > dwParentHeight ) size = dwParentHeight;
// Start floatrect centered on first RenderUnit's screen
if( !m_bWindowed ) { INT iMonitor = m_RenderUnits[0].iMonitor; rcBounds = m_Monitors[iMonitor].rcScreen; } m_floatrect.xMin = rcBounds.left + ((rcBounds.right - rcBounds.left) - size) / 2.0f; m_floatrect.yMin = rcBounds.top + ((rcBounds.bottom - rcBounds.top) - size) / 2.0f; m_floatrect.xSize = (FLOAT)size; m_floatrect.ySize = (FLOAT)size;
m_floatrect.xVel = 0.01f * (FLOAT) size; if( rand() % 2 == 0 ) m_floatrect.xVel = -m_floatrect.xVel;
m_floatrect.yVel = 0.01f * (FLOAT) size; if( rand() % 2 == 0 ) m_floatrect.yVel = -m_floatrect.yVel; }
rcBounceBounds = m_rcRenderTotal;
FLOAT xMinOld = m_floatrect.xMin; FLOAT yMinOld = m_floatrect.yMin;
m_floatrect.xMin += m_floatrect.xVel * 20.0f * m_fElapsedTime; m_floatrect.yMin += m_floatrect.yVel * 20.0f * m_fElapsedTime; if( m_floatrect.xVel < 0 && m_floatrect.xMin < rcBounceBounds.left || m_floatrect.xVel > 0 && (m_floatrect.xMin + m_floatrect.xSize) > rcBounceBounds.right ) { m_floatrect.xMin = xMinOld; // undo last move
m_floatrect.xVel = -m_floatrect.xVel; // change direction
} if( m_floatrect.yVel < 0 && m_floatrect.yMin < rcBounceBounds.top || m_floatrect.yVel > 0 && (m_floatrect.yMin + m_floatrect.ySize) > rcBounceBounds.bottom ) { m_floatrect.yMin = yMinOld; // undo last move
m_floatrect.yVel = -m_floatrect.yVel; // change direction
}
UpdateAngles( elapsed );
if ( m_bDisplayTime ) { if ( UpdateTimeString( m_szDisplayString ) ) { m_dwMeshUpdateCounter++; // provoke a mesh update at render tiem
} }
return S_OK; }
//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Called once per frame, the call is the entry point for 3d
// rendering. This function sets up render states, clears the
// viewport, and renders the scene.
//-----------------------------------------------------------------------------
HRESULT CTextScreensaver::Render() { D3DVIEWPORT8 vp;
// First, clear the entire back buffer to the background color
vp.X = 0; vp.Y = 0; vp.Width = m_rcRenderCurDevice.right - m_rcRenderCurDevice.left; vp.Height = m_rcRenderCurDevice.bottom - m_rcRenderCurDevice.top; vp.MinZ = 0.0f; vp.MaxZ = 1.0f; m_pd3dDevice->SetViewport( &vp ); m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0L );
// Now determine what part of the floatrect, if any, intersects the current screen
RECT rcFloatThisScreen; RECT rcFloatThisScreenClipped;
rcFloatThisScreen.left = (INT)m_floatrect.xMin; rcFloatThisScreen.top = (INT)m_floatrect.yMin; rcFloatThisScreen.right = rcFloatThisScreen.left + (INT)m_floatrect.xSize; rcFloatThisScreen.bottom = rcFloatThisScreen.top + (INT)m_floatrect.ySize;
if( !IntersectRect(&rcFloatThisScreenClipped, &rcFloatThisScreen, &m_rcRenderCurDevice) ) { return S_OK; // no intersection, so nothing further to render on this screen
}
// Convert rcFloatThisScreen from screen to window coordinates
OffsetRect(&rcFloatThisScreen, -m_rcRenderCurDevice.left, -m_rcRenderCurDevice.top); OffsetRect(&rcFloatThisScreenClipped, -m_rcRenderCurDevice.left, -m_rcRenderCurDevice.top);
// Now set up the viewport to render to the clipped rect
vp.X = rcFloatThisScreenClipped.left; vp.Y = rcFloatThisScreenClipped.top; vp.Width = rcFloatThisScreenClipped.right - rcFloatThisScreenClipped.left; vp.Height = rcFloatThisScreenClipped.bottom - rcFloatThisScreenClipped.top; vp.MinZ = 0.0f; vp.MaxZ = 1.0f; m_pd3dDevice->SetViewport( &vp ); // m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0L );
// Now set up the projection matrix to only render the onscreen part of the
// rect to the viewport
D3DXMATRIX matProj; FLOAT l,r,b,t; l = -0.8f; r = 0.8f; b = 0.8f; t = -0.8f; FLOAT cxUnclipped = (rcFloatThisScreen.right + rcFloatThisScreen.left) / 2.0f; FLOAT cyUnclipped = (rcFloatThisScreen.bottom + rcFloatThisScreen.top) / 2.0f; l *= (rcFloatThisScreenClipped.left - cxUnclipped) / (rcFloatThisScreen.left - cxUnclipped); r *= (rcFloatThisScreenClipped.right - cxUnclipped) / (rcFloatThisScreen.right - cxUnclipped); t *= (rcFloatThisScreenClipped.top - cyUnclipped) / (rcFloatThisScreen.top - cyUnclipped); b *= (rcFloatThisScreenClipped.bottom - cyUnclipped) / (rcFloatThisScreen.bottom - cyUnclipped); D3DXMatrixPerspectiveOffCenterLH( &matProj, l, r, t, b, 1.0f, 50.0f ); m_pd3dDevice->SetTransform( D3DTS_PROJECTION , &matProj );
// Mesh updates happen in Render() instead of FrameMove() since they
// are per-device
if( m_pDeviceObjects->m_dwMeshUpdateCounter != m_dwMeshUpdateCounter ) { BuildTextMesh( m_szDisplayString ); m_pDeviceObjects->m_dwMeshUpdateCounter = m_dwMeshUpdateCounter; }
m_pd3dDevice->BeginScene();
// Set world matrix
D3DXMATRIX rotx,roty,rotz,trans,trans2; D3DXMatrixTranslation( &trans , m_fTextOffsetX , m_fTextOffsetY , 0.25f ); D3DXMatrixRotationX( &rotx , m_fAngleX ); D3DXMatrixRotationY( &roty , m_fAngleY ); D3DXMatrixRotationZ( &rotz , m_fAngleZ ); D3DXMatrixTranslation( &trans2, 0, 0, 1.5f + (m_fTextMaxX - m_fTextMinX) ); m_matWorld = trans * rotx * roty * rotz * trans2; m_pd3dDevice->SetTransform( D3DTS_WORLDMATRIX(0) , &m_matWorld );
// Set other per-frame states
SetPerFrameStates();
// Draw mesh
m_pDeviceObjects->m_pObject->DrawSubset( 0 );
m_pd3dDevice->EndScene();
return S_OK; }
//-----------------------------------------------------------------------------
// Name: RestoreDeviceObjects()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CTextScreensaver::RestoreDeviceObjects() { HRESULT rc;
// Set up sensible view matrix
D3DXMatrixLookAtLH( &m_matView , &D3DXVECTOR3(0,0,0) , &D3DXVECTOR3(0,0,1) , &D3DXVECTOR3(0,1,0) ); m_pd3dDevice->SetTransform( D3DTS_VIEW , &m_matView );
// Set some basic renderstates
m_pd3dDevice->SetRenderState( D3DRS_ZENABLE , TRUE ); m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE , D3DZB_TRUE ); m_pd3dDevice->SetRenderState( D3DRS_ZFUNC , D3DCMP_LESSEQUAL ); m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE , TRUE ); m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE , m_bSpecular );
// Create the GDI font object
LONG h = m_Font.lfHeight; m_Font.lfHeight = 100; m_hFont = CreateFontIndirect( &m_Font ); m_Font.lfHeight = h; if ( m_hFont == NULL ) return E_FAIL;
// Initialise time string
if ( m_bDisplayTime ) UpdateTimeString( m_szDisplayString );
// Make mesh for text string
if ( FAILED(rc = BuildTextMesh( m_szDisplayString )) ) return rc;
// Update offsets for mesh
m_fTextOffsetX = (m_fTextMinX + m_fTextMaxX) * -0.5f; m_fTextOffsetY = (m_fTextMinY + m_fTextMaxY) * -0.5f;
// Load appropriate texture (if any)
switch ( m_SurfType ) { case color: m_pDeviceObjects->m_pTexture = NULL; break;
case environment: if ( m_bUseCustomEnvironment ) { m_pDeviceObjects->m_pTexture = CreateTextureFromFile( m_szCustomEnvironment ); } if ( m_pDeviceObjects->m_pTexture == NULL ) { LoadTextureFromResource( m_pd3dDevice, MAKEINTRESOURCE(IDB_SPHEREMAP), TEXT("JPG"), &m_pDeviceObjects->m_pTexture ); } break;
case texture: if ( m_bUseCustomTexture ) { m_pDeviceObjects->m_pTexture = CreateTextureFromFile( m_szCustomTexture ); } if ( m_pDeviceObjects->m_pTexture == NULL ) { LoadTextureFromResource( m_pd3dDevice, MAKEINTRESOURCE(IDB_TEXTURE), TEXT("JPG"), &m_pDeviceObjects->m_pTexture ); } break;
default: return E_FAIL; }
// Set per-frame states
SetPerFrameStates();
m_dwLastTick = GetTickCount();
return S_OK; }
//**********************************************************************************
VOID CTextScreensaver::SetPerFrameStates() { m_pd3dDevice->SetTexture( 0 , m_pDeviceObjects->m_pTexture );
// Set up texture pipeline
if ( m_SurfType == color ) { m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_COLOROP , D3DTOP_SELECTARG1 ); m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_COLORARG1 , D3DTA_DIFFUSE ); m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_COLORARG2 , D3DTA_DIFFUSE ); } else { m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_COLOROP , D3DTOP_MODULATE ); m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_COLORARG1 , D3DTA_TEXTURE ); m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_COLORARG2 , D3DTA_DIFFUSE ); } m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_ALPHAOP , D3DTOP_DISABLE ); m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_MAGFILTER , D3DTEXF_LINEAR ); m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_MINFILTER , D3DTEXF_LINEAR ); m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_MIPFILTER , D3DTEXF_LINEAR ); m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_ADDRESSU , D3DTADDRESS_WRAP ); m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_ADDRESSV , D3DTADDRESS_WRAP ); m_pd3dDevice->SetTextureStageState( 1 , D3DTSS_COLOROP , D3DTOP_DISABLE ); m_pd3dDevice->SetTextureStageState( 1 , D3DTSS_ALPHAOP , D3DTOP_DISABLE );
// Set up lighting
m_pd3dDevice->SetRenderState( D3DRS_LIGHTING , TRUE ); if ( !m_bSpecular ) m_pd3dDevice->SetRenderState( D3DRS_AMBIENT , 0x646464 ); else m_pd3dDevice->SetRenderState( D3DRS_AMBIENT , 0x464646 ); D3DLIGHT8 light; light.Type = D3DLIGHT_DIRECTIONAL; light.Diffuse = D3DXCOLOR(1,1,1,0); light.Specular = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); light.Ambient = D3DXCOLOR(0,0,0,0); light.Direction = D3DXVECTOR3(0.5,-0.5,1); light.Position = D3DXVECTOR3(0,0,0); light.Range = 10000; light.Falloff = light.Attenuation0 = light.Attenuation1 = light.Attenuation2 = 0; light.Phi = light.Theta = 0; m_pd3dDevice->SetLight( 0 , &light ); m_pd3dDevice->LightEnable( 0 , TRUE );
// Set up material
D3DMATERIAL8 mat; if ( m_SurfType == color ) { DWORD dwColor; if( m_bUseCustomColor ) dwColor = m_SurfaceColor; else dwColor = 0x00777777;
mat.Diffuse.r = FLOAT(dwColor&0xff)/255.0f; mat.Diffuse.g = FLOAT((dwColor>>8)&0xff)/255.0f; mat.Diffuse.b = FLOAT((dwColor>>16)&0xff)/255.0f; } else { mat.Diffuse = D3DXCOLOR(1,1,1,0); } mat.Ambient = mat.Diffuse; mat.Specular = D3DXCOLOR(1.0f,1.0f,1.0f,0); mat.Emissive = D3DXCOLOR(0,0,0,0); mat.Power = 5; m_pd3dDevice->SetMaterial( &mat );
// Set up texture coordinate generation if we're environment mapping or just force to passthrough
if ( m_SurfType == environment ) { m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_TEXCOORDINDEX , D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR ); m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_TEXTURETRANSFORMFLAGS , D3DTTFF_COUNT2 );
D3DXMATRIX envmat; D3DXMatrixIdentity( &envmat );
envmat._11 = envmat._22 = 0.5f; envmat._31 = envmat._32 = 0.5f; m_pd3dDevice->SetTransform( D3DTS_TEXTURE0 , &envmat ); } else { D3DXMATRIX matWorldView; D3DXMATRIX matWorldViewInv;
matWorldView = m_matWorld * m_matView; D3DXMatrixInverse( &matWorldViewInv, NULL, &matWorldView ); m_pd3dDevice->SetTransform( D3DTS_TEXTURE0, &matWorldViewInv ); m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_TEXCOORDINDEX , D3DTSS_TCI_CAMERASPACEPOSITION ); m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_TEXTURETRANSFORMFLAGS , D3DTTFF_COUNT2 ); }
m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE , FALSE ); m_pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE , FALSE ); m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE , m_bSpecular ); m_pd3dDevice->SetRenderState( D3DRS_WRAP0 , D3DWRAP_U|D3DWRAP_V ); m_pd3dDevice->SetRenderState( D3DRS_POINTSPRITEENABLE , FALSE );
m_pd3dDevice->SetTexture( 0, m_pDeviceObjects->m_pTexture ); }
//-----------------------------------------------------------------------------
// Name: InvalidateDeviceObjects()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CTextScreensaver::InvalidateDeviceObjects() { SAFE_RELEASE(m_pDeviceObjects->m_pTexture); SAFE_RELEASE(m_pDeviceObjects->m_pObject); return S_OK; }
//-----------------------------------------------------------------------------
// Name: ConfirmDevice()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CTextScreensaver::ConfirmDevice(D3DCAPS8* pCaps, DWORD dwBehavior, D3DFORMAT fmtBackBuffer) { // Need D3DVTXPCAPS_TEXGEN for D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR
if( ( ( dwBehavior & D3DCREATE_HARDWARE_VERTEXPROCESSING ) || ( dwBehavior & D3DCREATE_MIXED_VERTEXPROCESSING ) ) && ( pCaps->VertexProcessingCaps & D3DVTXPCAPS_TEXGEN ) == 0 ) { return E_FAIL; }
return S_OK; }
//-----------------------------------------------------------------------------
// Name: SetDevice()
// Desc:
//-----------------------------------------------------------------------------
VOID CTextScreensaver::SetDevice( UINT iDevice ) { m_pDeviceObjects = &m_DeviceObjects[iDevice]; }
//***************************************************************************************
IDirect3DTexture8* CTextScreensaver::CreateTextureFromFile( const TCHAR* filename ) { IDirect3DTexture8* texture; if ( FAILED(D3DXCreateTextureFromFile( m_pd3dDevice , filename , &texture )) ) return NULL; else return texture; }
//***************************************************************************************
HRESULT CTextScreensaver::BuildTextMesh( const TCHAR* text ) { // Release any old text mesh we built
SAFE_RELEASE(m_pDeviceObjects->m_pObject);
// Create temporary DC and select the correct font into it
HDC hdc = CreateDC( TEXT("DISPLAY") , NULL , NULL , NULL ); SelectObject( hdc , m_hFont );
TCHAR szText[MAX_DISPLAY_STRING+1]; lstrcpyn( szText, text, MAX_DISPLAY_STRING+1 );
// Build new mesh
FLOAT max_deviation = 5.0f / FLOAT(m_dwMeshQuality+10); GLYPHMETRICSFLOAT metrics[MAX_DISPLAY_STRING+1]; HRESULT rc; rc = D3DXCreateText( m_pd3dDevice , hdc , szText , max_deviation, 0.5f , &m_pDeviceObjects->m_pObject , NULL, metrics ); if( FAILED( rc ) ) { // We might have failed because the string had no glyphs, so try
// the default text instead
LoadString( NULL, IDS_DEFAULTTEXT, szText, MAX_DISPLAY_STRING ); rc = D3DXCreateText( m_pd3dDevice , hdc , szText , max_deviation, 0.5f , &m_pDeviceObjects->m_pObject , NULL, metrics ); }
// Delete temporary DC
DeleteDC( hdc ); if ( FAILED(rc) ) return rc;
// Compute the bounding box for the mesh by stepping through the glyph metrics structures
int len = lstrlen( szText ); m_fTextMinX = 1000000; m_fTextMaxX = -1000000; m_fTextMinY = 1000000; m_fTextMaxY = -1000000; FLOAT originx = 0; FLOAT originy = 0; GLYPHMETRICSFLOAT* pglyph = metrics; for ( int i = 0 ; i < len ; i++ , pglyph++ ) { if ( (pglyph->gmfptGlyphOrigin.x + originx) < m_fTextMinX ) m_fTextMinX = (pglyph->gmfptGlyphOrigin.x + originx); if ( (pglyph->gmfptGlyphOrigin.x + originx + pglyph->gmfBlackBoxX) > m_fTextMaxX ) m_fTextMaxX = (pglyph->gmfptGlyphOrigin.x + originx + pglyph->gmfBlackBoxX);
if ( (pglyph->gmfptGlyphOrigin.y + originy) > m_fTextMaxY ) m_fTextMaxY = (pglyph->gmfptGlyphOrigin.y + originy); if ( (pglyph->gmfptGlyphOrigin.y + originy - pglyph->gmfBlackBoxY) < m_fTextMinY ) m_fTextMinY = (pglyph->gmfptGlyphOrigin.y + originy - pglyph->gmfBlackBoxY);
originx += pglyph->gmfCellIncX; originy += pglyph->gmfCellIncY; }
return S_OK; }
//*********************************************************************************
VOID CTextScreensaver::UpdateAngles( DWORD elapsed ) { static FLOAT x,y,z,t; const FLOAT pi2 = 3.1415926536f * 2.0f;
FLOAT inc = FLOAT(elapsed * m_dwRotationSpeed);
switch ( m_RotType ) { case spin: y += inc * 0.00002f; break;
case seesaw: t += inc * 0.000025f; y = (FLOAT(sin((t * pi2))) * 0.17f) + 1.0f; break;
case wobble: t += inc * 0.000025f; y = (FLOAT(sin((t * pi2))) * 0.17f) + 1.0f; z = (FLOAT(cos((t * pi2))) * 0.09f) + 1.0f; break;
case tumble: x += inc * 0.000004f; y += inc * 0.000018f; z += inc * 0.000007f; break; }
x = x - int(x); y = y - int(y); z = z - int(z);
m_fAngleX = x * pi2; m_fAngleY = y * pi2; m_fAngleZ = z * pi2; }
//***************************************************************************************
BOOL CTextScreensaver::UpdateTimeString( TCHAR* string ) { TCHAR str[MAX_DISPLAY_STRING+1];
GetTimeFormat( LOCALE_USER_DEFAULT, 0, NULL, NULL, str, MAX_DISPLAY_STRING+1 );
if ( lstrcmp( string , str ) ) { lstrcpy( string , str ); return TRUE; }
return FALSE; }
//-----------------------------------------------------------------------------
// Name: ReadSettings()
// Desc:
//-----------------------------------------------------------------------------
VOID CTextScreensaver::ReadSettings() { HKEY hkey; DWORD dwType = REG_DWORD; DWORD dwLength = sizeof(DWORD);
// Defaults
LoadString( NULL, IDS_DEFAULTTEXT, m_szDisplayString, MAX_DISPLAY_STRING ); m_Font.lfHeight = 96; m_Font.lfWidth = 0; m_Font.lfEscapement = 0; m_Font.lfOrientation = 0; m_Font.lfWeight = 0; m_Font.lfItalic = 0; m_Font.lfUnderline = 0; m_Font.lfStrikeOut = 0; m_Font.lfCharSet = DEFAULT_CHARSET; m_Font.lfOutPrecision = OUT_DEFAULT_PRECIS; m_Font.lfClipPrecision = OUT_DEFAULT_PRECIS; m_Font.lfQuality = DEFAULT_QUALITY; m_Font.lfPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE; LoadString( NULL, IDS_FONT, m_Font.lfFaceName, LF_FACESIZE ); m_bDisplayTime = FALSE; m_dwMeshQuality = 500; m_SurfType = SurfType(environment); m_bSpecular = TRUE; m_dwRotationSpeed = 10; m_dwSize = 10; m_RotType = RotType(spin); m_SurfaceColor = 0x00777777; m_bUseCustomColor = FALSE; m_bUseCustomTexture = FALSE; m_bUseCustomEnvironment = FALSE; lstrcpy( m_szCustomTexture, TEXT("") ); lstrcpy( m_szCustomEnvironment, TEXT("") );
// Read OpenGL settings first, so OS upgrade cases work
ss_ReadSettings();
if( ERROR_SUCCESS == RegCreateKeyEx( HKEY_CURRENT_USER, m_strRegPath, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL ) ) { dwLength = (MAX_DISPLAY_STRING + 1) * sizeof(TCHAR); RegQueryValueEx( hkey, TEXT("DisplayString"), NULL, &dwType, (BYTE*)m_szDisplayString, &dwLength );
dwLength = sizeof(DWORD); RegQueryValueEx( hkey, TEXT("FontHeight"), NULL, &dwType, (BYTE*)&m_Font.lfHeight, &dwLength );
RegQueryValueEx( hkey, TEXT("FontWeight"), NULL, &dwType, (BYTE*)&m_Font.lfWeight, &dwLength ); RegQueryValueEx( hkey, TEXT("FontItalic"), NULL, &dwType, (BYTE*)&m_Font.lfItalic, &dwLength ); RegQueryValueEx( hkey, TEXT("FontCharSet"), NULL, &dwType, (BYTE*)&m_Font.lfCharSet, &dwLength ); RegQueryValueEx( hkey, TEXT("FontPitchFamily"), NULL, &dwType, (BYTE*)&m_Font.lfPitchAndFamily, &dwLength );
dwLength = sizeof(m_Font.lfFaceName); RegQueryValueEx( hkey, TEXT("FontFace"), NULL, &dwType, (BYTE*)m_Font.lfFaceName, &dwLength );
dwLength = sizeof(DWORD); RegQueryValueEx( hkey, TEXT("DisplayTime"), NULL, &dwType, (BYTE*)&m_bDisplayTime, &dwLength );
RegQueryValueEx( hkey, TEXT("MeshQuality"), NULL, &dwType, (BYTE*)&m_dwMeshQuality, &dwLength ); if ( m_dwMeshQuality > 1000 ) m_dwMeshQuality = 1000;
RegQueryValueEx( hkey, TEXT("SurfaceType"), NULL, &dwType, (BYTE*)&m_SurfType, &dwLength );
RegQueryValueEx( hkey, TEXT("Specular"), NULL, &dwType, (BYTE*)&m_bSpecular, &dwLength ); RegQueryValueEx( hkey, TEXT("RotationSpeed"), NULL, &dwType, (BYTE*)&m_dwRotationSpeed, &dwLength ); RegQueryValueEx( hkey, TEXT("Size"), NULL, &dwType, (BYTE*)&m_dwSize, &dwLength ); if( m_dwSize < 1 ) m_dwSize = 1; if( m_dwSize > 10 ) m_dwSize = 10; RegQueryValueEx( hkey, TEXT("RotationStyle"), NULL, &dwType, (BYTE*)&m_RotType, &dwLength ); RegQueryValueEx( hkey, TEXT("SurfaceColor"), NULL, &dwType, (BYTE*)&m_SurfaceColor, &dwLength ); RegQueryValueEx( hkey, TEXT("UseCustomColor"), NULL, &dwType, (BYTE*)&m_bUseCustomColor, &dwLength ); RegQueryValueEx( hkey, TEXT("UseCustomTexture"), NULL, &dwType, (BYTE*)&m_bUseCustomTexture, &dwLength ); RegQueryValueEx( hkey, TEXT("UseCustomEnvironment"), NULL, &dwType, (BYTE*)&m_bUseCustomEnvironment, &dwLength ); dwLength = sizeof(m_szCustomTexture); RegQueryValueEx( hkey, TEXT("CustomTexture"), NULL, &dwType, (BYTE*)m_szCustomTexture, &dwLength ); dwLength = sizeof(m_szCustomEnvironment); RegQueryValueEx( hkey, TEXT("CustomEnvironment"), NULL, &dwType, (BYTE*)m_szCustomEnvironment, &dwLength );
ReadScreenSettings( hkey );
RegCloseKey( hkey ); } }
//-----------------------------------------------------------------------------
// Name: ss_ReadSettings()
// Desc:
//-----------------------------------------------------------------------------
VOID CTextScreensaver::ss_ReadSettings() { int options; int optMask = 1;
// Get registry settings
if( ss_RegistrySetup( IDS_SAVERNAME, IDS_INIFILE ) ) { // get demo type
int demoType = ss_GetRegistryInt( IDS_DEMOTYPE, 0 ); if( demoType == 1 ) { m_bDisplayTime = TRUE; }
// get rotation style
m_RotType = (RotType) (ss_GetRegistryInt( IDS_ROTSTYLE, 0 ) + 1); // add 1
if( m_RotType == 1 ) // 1==none,2=right,3=right,4=random->spin
m_RotType = none; if( m_RotType > 3 ) m_RotType = spin;
// get tesselation
m_dwMeshQuality = ss_GetRegistryInt( IDS_TESSELATION, 0 ); // 0-100
m_dwMeshQuality = m_dwMeshQuality*10 + 1; // 1-1000
if ( m_dwMeshQuality > 1000 ) m_dwMeshQuality = 1000;
// get size
m_dwSize = ss_GetRegistryInt( IDS_SIZE, 0 ); // 0-100
m_dwSize = (unsigned) ( ((m_dwSize / 100.0f) * 90.0f + 10.0f) / 10.0f ); // 1-10
// get speed
m_dwRotationSpeed = ss_GetRegistryInt( IDS_SPEED, 0 ); // 0-100
m_dwRotationSpeed = (unsigned) ( ((m_dwRotationSpeed / 100.0f) * 190.0f + 10.0f) / 10.0f ); // 1-20
// get font, attributes, and charset
ss_GetRegistryString( IDS_FONT_REG, TEXT(""), m_Font.lfFaceName, LF_FACESIZE );
options = ss_GetRegistryInt( IDS_FONT_ATTRIBUTES, 0 ); if( options >= 0 ) { optMask = 1; m_Font.lfWeight = ((options & optMask) != 0) ? FW_BOLD : FW_NORMAL; optMask <<=1; m_Font.lfItalic = ((options & optMask) != 0) ? (BYTE) 1 : 0; }
m_Font.lfCharSet = (BYTE)ss_GetRegistryInt( IDS_CHARSET, 0 );
// get display string
ss_GetRegistryString( IDS_TEXT, TEXT(""), m_szDisplayString, MAX_DISPLAY_STRING );
m_SurfType = (SurfType) ss_GetRegistryInt( IDS_SURFSTYLE, color ); if( m_SurfType >= 1 ) m_SurfType = texture;
// Is there a texture specified in the registry that overrides the default?
ss_GetRegistryString( IDS_TEXTURE, NULL, m_szCustomTexture, MAX_PATH ); if( lstrlen( m_szCustomTexture ) > 0 ) { m_bUseCustomTexture = TRUE; } } }
//-----------------------------------------------------------------------------
// Name: ss_GetRegistryString()
// Desc:
//-----------------------------------------------------------------------------
BOOL CTextScreensaver::ss_RegistrySetup( int section, int file ) { if( LoadString(m_hInstance, section, g_szSectName, BUF_SIZE) && LoadString(m_hInstance, file, g_szFname, BUF_SIZE) ) { TCHAR pBuffer[100]; DWORD dwRealSize = GetPrivateProfileSection( g_szSectName, pBuffer, 100, g_szFname ); if( dwRealSize > 0 ) return TRUE; } return FALSE; }
//-----------------------------------------------------------------------------
// Name: ss_GetRegistryInt()
// Desc:
//-----------------------------------------------------------------------------
int CTextScreensaver::ss_GetRegistryInt( int name, int iDefault ) { TCHAR szItemName[BUF_SIZE];
if( LoadString( m_hInstance, name, szItemName, BUF_SIZE ) ) return GetPrivateProfileInt(g_szSectName, szItemName, iDefault, g_szFname);
return 0; }
//-----------------------------------------------------------------------------
// Name: ss_GetRegistryString()
// Desc:
//-----------------------------------------------------------------------------
VOID CTextScreensaver::ss_GetRegistryString( int name, LPTSTR lpDefault, LPTSTR lpDest, int bufSize ) { TCHAR szItemName[BUF_SIZE];
if( LoadString( m_hInstance, name, szItemName, BUF_SIZE ) ) GetPrivateProfileString(g_szSectName, szItemName, lpDefault, lpDest, bufSize, g_szFname);
return; }
//-----------------------------------------------------------------------------
// Name: DoConfig()
// Desc:
//-----------------------------------------------------------------------------
VOID CTextScreensaver::DoConfig() { ReadSettings(); DialogBox( NULL, MAKEINTRESOURCE( IDD_SETTINGS ), m_hWndParent, SettingsDialogProcStub ); }
INT_PTR CALLBACK CTextScreensaver::SettingsDialogProcStub( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam ) { return g_pMyTextScreensaver->SettingsDialogProc( hDlg, message, wParam, lParam ); };
BOOL CTextScreensaver::SettingsDialogProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam ) { switch ( message ) { case WM_INITDIALOG: InitItems( hDlg ); return FALSE;
case WM_COMMAND: switch ( HIWORD(wParam) ) { case BN_CLICKED: { switch( LOWORD(wParam) ) { case IDOK: ExtractAndWriteSettings( hDlg ); EndDialog( hDlg, TRUE ); break;
case IDCANCEL: ReadSettings(); EndDialog( hDlg, FALSE ); break;
case IDC_SELECT_FONT: SelectFont( hDlg ); break;
case IDC_RADIO_TIME: EnableWindow( GetDlgItem( hDlg , IDC_DISPLAY_STRING ) , FALSE ); break;
case IDC_RADIO_TEXT: EnableWindow( GetDlgItem( hDlg , IDC_DISPLAY_STRING ) , TRUE ); break;
case IDC_RADIO_COLOR: case IDC_RADIO_TEXTURE: case IDC_RADIO_REFLECTION: case IDC_USE_CUSTOM_COLOR: case IDC_USE_CUSTOM_TEXTURE: case IDC_USE_CUSTOM_ENVIRONMENT: { if( IsDlgButtonChecked( hDlg, IDC_RADIO_COLOR ) ) m_SurfType = color; else if( IsDlgButtonChecked( hDlg, IDC_RADIO_TEXTURE ) ) m_SurfType = texture; else if( IsDlgButtonChecked( hDlg, IDC_RADIO_REFLECTION ) ) m_SurfType = environment; EnableTextureWindows( hDlg , SurfType(m_SurfType) ); } break;
case IDC_SURFACE_COLOR: SelectSurfaceColor( hDlg ); break;
case IDC_BROWSE_TEXTURE: SelectCustomTexture( hDlg ); break;
case IDC_BROWSE_ENVIRONMENT: SelectCustomEnvironment( hDlg ); break;
case IDC_SCREENSETTINGS: DoScreenSettingsDialog( hDlg ); break; } } break;
case EN_CHANGE: if ( LOWORD(wParam) == IDC_DISPLAY_STRING ) { GetDlgItemText( hDlg , IDC_DISPLAY_STRING , m_szDisplayString , MAX_DISPLAY_STRING ); } break; } return FALSE; }
return FALSE; }
VOID CTextScreensaver::InitItems( HWND hDlg ) { TCHAR sz[100];
// Set the limit of the text box
SendDlgItemMessage( hDlg, IDC_DISPLAY_STRING, EM_SETLIMITTEXT, MAX_DISPLAY_STRING, 0 );
// Set the text string
SetDlgItemText( hDlg, IDC_DISPLAY_STRING, m_szDisplayString );
// Set the radio button for time/text display
if ( m_bDisplayTime ) { EnableWindow( GetDlgItem( hDlg, IDC_DISPLAY_STRING ), FALSE ); CheckRadioButton( hDlg, IDC_RADIO_TIME, IDC_RADIO_TEXT, IDC_RADIO_TIME ); } else { EnableWindow( GetDlgItem( hDlg, IDC_DISPLAY_STRING ), TRUE ); CheckRadioButton( hDlg, IDC_RADIO_TIME, IDC_RADIO_TEXT, IDC_RADIO_TEXT ); }
switch( m_SurfType ) { case color: CheckRadioButton( hDlg, IDC_RADIO_COLOR, IDC_RADIO_REFLECTION, IDC_RADIO_COLOR ); break; case texture: CheckRadioButton( hDlg, IDC_RADIO_COLOR, IDC_RADIO_REFLECTION, IDC_RADIO_TEXTURE ); break; case environment: CheckRadioButton( hDlg, IDC_RADIO_COLOR, IDC_RADIO_REFLECTION, IDC_RADIO_REFLECTION ); break; }
// Check/uncheck the specular box
SendDlgItemMessage( hDlg, IDC_SPECULAR, BM_SETCHECK, m_bSpecular ? BST_CHECKED : BST_UNCHECKED, 0 );
// Enable/disable surface color button
EnableWindow( GetDlgItem( hDlg, IDC_SURFACE_COLOR ), m_SurfType == color );
// Check/uncheck the custom texture boxes
SendDlgItemMessage( hDlg, IDC_USE_CUSTOM_COLOR, BM_SETCHECK, m_bUseCustomColor ? BST_CHECKED : BST_UNCHECKED, 0 ); SendDlgItemMessage( hDlg, IDC_USE_CUSTOM_TEXTURE, BM_SETCHECK, m_bUseCustomTexture ? BST_CHECKED : BST_UNCHECKED, 0 ); SendDlgItemMessage( hDlg, IDC_USE_CUSTOM_ENVIRONMENT, BM_SETCHECK, m_bUseCustomEnvironment ? BST_CHECKED : BST_UNCHECKED, 0 );
// Enable all the texture windows as appropriate
EnableTextureWindows( hDlg, m_SurfType );
// Fill the rotation style combo box
LoadString( NULL, IDS_NONE, sz, 100 ); SendDlgItemMessage( hDlg, IDC_ROTATION_STYLE, CB_ADDSTRING, 0, (LPARAM) sz ); LoadString( NULL, IDS_SPIN, sz, 100 ); SendDlgItemMessage( hDlg, IDC_ROTATION_STYLE, CB_ADDSTRING, 0, (LPARAM) sz ); LoadString( NULL, IDS_SEESAW, sz, 100 ); SendDlgItemMessage( hDlg, IDC_ROTATION_STYLE, CB_ADDSTRING, 0, (LPARAM) sz ); LoadString( NULL, IDS_WOBBLE, sz, 100 ); SendDlgItemMessage( hDlg, IDC_ROTATION_STYLE, CB_ADDSTRING, 0, (LPARAM) sz ); LoadString( NULL, IDS_TUMBLE, sz, 100 ); SendDlgItemMessage( hDlg, IDC_ROTATION_STYLE, CB_ADDSTRING, 0, (LPARAM) sz );
// Set the current rotation style selection
SendDlgItemMessage( hDlg, IDC_ROTATION_STYLE, CB_SETCURSEL, m_RotType, 0 );
// Set up the rotation speed slider
SendDlgItemMessage( hDlg, IDC_ROTATION_SPEED, TBM_SETRANGE, TRUE, MAKELONG(1,20) ); SendDlgItemMessage( hDlg, IDC_ROTATION_SPEED, TBM_SETPOS, TRUE, m_dwRotationSpeed );
// Set up the resolution slider
SendDlgItemMessage( hDlg, IDC_RESOLUTION, TBM_SETRANGE, TRUE, MAKELONG(1,10) ); SendDlgItemMessage( hDlg, IDC_RESOLUTION, TBM_SETPOS, TRUE, m_dwMeshQuality / 100 );
// Set up the size slider
SendDlgItemMessage( hDlg, IDC_VIEWPORTSIZE, TBM_SETRANGE, TRUE, MAKELONG(1,10) ); SendDlgItemMessage( hDlg, IDC_VIEWPORTSIZE, TBM_SETPOS, TRUE, m_dwSize ); }
VOID CTextScreensaver::ExtractAndWriteSettings( HWND hDlg ) { LRESULT ret; HKEY hkey = NULL;
m_bSpecular = IsDlgButtonChecked( hDlg, IDC_SPECULAR );
m_bUseCustomColor = IsDlgButtonChecked( hDlg, IDC_USE_CUSTOM_COLOR ); m_bUseCustomTexture = IsDlgButtonChecked( hDlg, IDC_USE_CUSTOM_TEXTURE ); m_bUseCustomEnvironment = IsDlgButtonChecked( hDlg, IDC_USE_CUSTOM_ENVIRONMENT );
if ( (ret = SendDlgItemMessage( hDlg, IDC_ROTATION_STYLE, CB_GETCURSEL, 0, 0 )) != CB_ERR ) m_RotType = RotType(ret);
m_dwSize = (DWORD)SendDlgItemMessage( hDlg, IDC_VIEWPORTSIZE, TBM_GETPOS, 0, 0 ); m_dwRotationSpeed = (DWORD)SendDlgItemMessage( hDlg, IDC_ROTATION_SPEED, TBM_GETPOS, 0, 0 ); m_dwMeshQuality = 100 * (DWORD)SendDlgItemMessage( hDlg, IDC_RESOLUTION, TBM_GETPOS, 0, 0 );
GetDlgItemText( hDlg, IDC_DISPLAY_STRING, m_szDisplayString, MAX_DISPLAY_STRING + 1 );
if ( IsDlgButtonChecked( hDlg, IDC_RADIO_TIME ) ) m_bDisplayTime = TRUE; else m_bDisplayTime = FALSE;
if( ERROR_SUCCESS == RegCreateKeyEx( HKEY_CURRENT_USER, m_strRegPath, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL ) ) { WriteScreenSettings( hkey ); RegSetValueEx( hkey, TEXT("SurfaceType"), NULL, REG_DWORD, (BYTE*)&m_SurfType, sizeof(DWORD) ); RegSetValueEx( hkey, TEXT("Specular"), NULL, REG_DWORD, (BYTE*)&m_bSpecular, sizeof(DWORD) ); RegSetValueEx( hkey, TEXT("SurfaceColor"), NULL, REG_DWORD, (BYTE*)&m_SurfaceColor, sizeof(DWORD) ); RegSetValueEx( hkey, TEXT("CustomTexture"), NULL, REG_SZ, (BYTE*)&m_szCustomTexture, (lstrlen(m_szCustomTexture) + 1) * sizeof(TCHAR) ); RegSetValueEx( hkey, TEXT("CustomEnvironment"), NULL, REG_SZ, (BYTE*)&m_szCustomEnvironment, (lstrlen(m_szCustomEnvironment) + 1) * sizeof(TCHAR) ); RegSetValueEx( hkey, TEXT("UseCustomColor"), NULL, REG_DWORD, (BYTE*)&m_bUseCustomColor, sizeof(DWORD) ); RegSetValueEx( hkey, TEXT("UseCustomTexture"), NULL, REG_DWORD, (BYTE*)&m_bUseCustomTexture, sizeof(DWORD) ); RegSetValueEx( hkey, TEXT("UseCustomEnvironment"), NULL, REG_DWORD, (BYTE*)&m_bUseCustomEnvironment, sizeof(DWORD) ); RegSetValueEx( hkey, TEXT("MeshQuality"), NULL, REG_DWORD, (BYTE*)&m_dwMeshQuality, sizeof(DWORD) ); RegSetValueEx( hkey, TEXT("Size"), NULL, REG_DWORD, (BYTE*)&m_dwSize, sizeof(DWORD) ); RegSetValueEx( hkey, TEXT("RotationSpeed"), NULL, REG_DWORD, (BYTE*)&m_dwRotationSpeed, sizeof(DWORD) ); RegSetValueEx( hkey, TEXT("RotationStyle"), NULL, REG_DWORD, (BYTE*)&m_RotType, sizeof(DWORD) ); RegSetValueEx( hkey, TEXT("DisplayString"), NULL, REG_SZ, (BYTE*)&m_szDisplayString, (lstrlen(m_szDisplayString) + 1) * sizeof(TCHAR) ); RegSetValueEx( hkey, TEXT("DisplayTime"), NULL, REG_DWORD, (BYTE*)&m_bDisplayTime, sizeof(DWORD) ); RegSetValueEx( hkey, TEXT("FontWeight"), NULL, REG_DWORD, (BYTE*)&m_Font.lfWeight, sizeof(DWORD) ); RegSetValueEx( hkey, TEXT("FontHeight"), NULL, REG_DWORD, (BYTE*)&m_Font.lfHeight, sizeof(DWORD) ); RegSetValueEx( hkey, TEXT("FontItalic"), NULL, REG_DWORD, (BYTE*)&m_Font.lfItalic, sizeof(DWORD) ); RegSetValueEx( hkey, TEXT("FontCharSet"), NULL, REG_DWORD, (BYTE*)&m_Font.lfCharSet, sizeof(DWORD) ); RegSetValueEx( hkey, TEXT("FontPitchFamily"), NULL, REG_DWORD, (BYTE*)&m_Font.lfPitchAndFamily, sizeof(DWORD) ); RegSetValueEx( hkey, TEXT("FontFace"), NULL, REG_SZ, (BYTE*)&m_Font.lfFaceName, (lstrlen(m_Font.lfFaceName) + 1) * sizeof(TCHAR) ); RegCloseKey( hkey ); } }
//***************************************************************************************
VOID CTextScreensaver::SelectSurfaceColor( HWND hDlg ) { static COLORREF cust_colors[16];
CHOOSECOLOR choose; choose.lStructSize = sizeof(choose); choose.hwndOwner = hDlg; choose.hInstance = HWND(m_hInstance); choose.rgbResult = m_SurfaceColor; choose.lpCustColors = cust_colors; choose.Flags = CC_ANYCOLOR|CC_FULLOPEN|CC_RGBINIT; choose.lCustData = 0; choose.lpfnHook = NULL; choose.lpTemplateName = NULL;
if ( ChooseColor( &choose ) ) m_SurfaceColor = choose.rgbResult; }
//***************************************************************************************
VOID CTextScreensaver::SelectFont( HWND hDlg ) { CHOOSEFONT choose;
choose.lStructSize = sizeof(choose); choose.hwndOwner = hDlg; choose.hDC; choose.iPointSize = 720; choose.lpLogFont = &m_Font; choose.Flags = CF_TTONLY|CF_FORCEFONTEXIST|CF_NOVERTFONTS|CF_SCREENFONTS|CF_INITTOLOGFONTSTRUCT|CF_ENABLETEMPLATE; choose.lpTemplateName = MAKEINTRESOURCE(DLG_SELECT_FONT); choose.hInstance = m_hInstance;
if ( ChooseFont( &choose ) ) m_Font = *choose.lpLogFont; }
//***************************************************************************************
VOID CTextScreensaver::SelectCustomTexture( HWND hDlg ) { TCHAR fn[MAX_PATH] = TEXT("\0"); TCHAR strTitle[100]; LoadString( NULL, IDS_OPENTEXTURETITLE, strTitle, 100 );
lstrcpy( fn, m_szCustomTexture );
TCHAR filter[200]; LoadString( NULL, IDS_FILEFILTER, filter, 200); for( TCHAR* pch = filter; *pch != TEXT('\0'); pch++ ) { if( *pch == TEXT('#') ) *pch = TEXT('\0'); }
TCHAR szWindowsDir[MAX_PATH+1]; if( 0 == GetWindowsDirectory( szWindowsDir, MAX_PATH+1 ) ) szWindowsDir[0] = TEXT('\0');
OPENFILENAME ofn; memset( &ofn , 0 , sizeof(ofn) ); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hDlg; ofn.hInstance = m_hInstance; ofn.lpstrFilter = filter; ofn.nFilterIndex = 1; ofn.lpstrFile = fn; ofn.nMaxFile = sizeof(fn); ofn.lpstrTitle = strTitle; ofn.Flags = OFN_ENABLESIZING|OFN_FILEMUSTEXIST; ofn.lpstrDefExt = TEXT("mid"); if( lstrlen( fn ) == 0 ) ofn.lpstrInitialDir = szWindowsDir;
if ( GetOpenFileName( &ofn ) ) lstrcpy( m_szCustomTexture , ofn.lpstrFile ); }
//***************************************************************************************
VOID CTextScreensaver::SelectCustomEnvironment( HWND hDlg ) { TCHAR fn[MAX_PATH] = TEXT("\0"); TCHAR strTitle[100]; LoadString( NULL, IDS_OPENENVIRONMENTMAPTITLE, strTitle, 100 );
TCHAR filter[200]; LoadString( NULL, IDS_FILEFILTER, filter, 200); for( TCHAR* pch = filter; *pch != TEXT('\0'); pch++ ) { if( *pch == TEXT('#') ) *pch = TEXT('\0'); }
TCHAR szWindowsDir[MAX_PATH+1]; if( 0 == GetWindowsDirectory( szWindowsDir, MAX_PATH+1 ) ) szWindowsDir[0] = TEXT('\0');
OPENFILENAME ofn; memset( &ofn , 0 , sizeof(ofn) ); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hDlg; ofn.hInstance = m_hInstance; ofn.lpstrFilter = filter; ofn.nFilterIndex = 1; ofn.lpstrFile = fn; ofn.nMaxFile = sizeof(fn); ofn.lpstrTitle = strTitle; ofn.Flags = OFN_ENABLESIZING|OFN_FILEMUSTEXIST; ofn.lpstrDefExt = TEXT("mid"); if( lstrlen( fn ) == 0 ) ofn.lpstrInitialDir = szWindowsDir;
if ( GetOpenFileName( &ofn ) ) lstrcpy( m_szCustomEnvironment , ofn.lpstrFile ); }
//***************************************************************************************
VOID CTextScreensaver::EnableTextureWindows( HWND hDlg , SurfType sel ) { HWND use_color = GetDlgItem( hDlg , IDC_USE_CUSTOM_COLOR ); HWND use_texture = GetDlgItem( hDlg , IDC_USE_CUSTOM_TEXTURE ); HWND use_environ = GetDlgItem( hDlg , IDC_USE_CUSTOM_ENVIRONMENT ); HWND browse_color = GetDlgItem( hDlg , IDC_SURFACE_COLOR ); HWND browse_texture = GetDlgItem( hDlg , IDC_BROWSE_TEXTURE ); HWND browse_environ = GetDlgItem( hDlg , IDC_BROWSE_ENVIRONMENT );
BOOL color_checked = IsDlgButtonChecked( hDlg , IDC_USE_CUSTOM_COLOR ); BOOL texture_checked = IsDlgButtonChecked( hDlg , IDC_USE_CUSTOM_TEXTURE ); BOOL environment_checked = IsDlgButtonChecked( hDlg , IDC_USE_CUSTOM_ENVIRONMENT );
switch ( sel ) { case environment: EnableWindow( use_color , FALSE ); EnableWindow( use_texture , FALSE ); EnableWindow( use_environ , TRUE ); EnableWindow( browse_color , FALSE ); EnableWindow( browse_texture , FALSE ); EnableWindow( browse_environ , environment_checked ); break;
case texture: EnableWindow( use_color , FALSE ); EnableWindow( use_texture , TRUE ); EnableWindow( use_environ , FALSE ); EnableWindow( browse_color , FALSE ); EnableWindow( browse_texture , texture_checked ); EnableWindow( browse_environ , FALSE ); break;
case color: default: EnableWindow( use_color , TRUE ); EnableWindow( use_texture , FALSE ); EnableWindow( use_environ , FALSE ); EnableWindow( browse_color , color_checked ); EnableWindow( browse_texture , FALSE ); EnableWindow( browse_environ , FALSE ); break; } }
|