topical media & game development
hush-src-multi-GamePlayer-dxutil.cpp / cpp
//-----------------------------------------------------------------------------
// File: DXUtil.cpp
//
// Desc: Shortcut macros and functions for using DirectX objects
//
// Copyright (c) Microsoft Corporation. All rights reserved
//-----------------------------------------------------------------------------
ifndef STRICT
define STRICT
endif // !STRICT
include <stdafx.h>
include <windows.h>
include <mmsystem.h>
include <tchar.h>
include <stdio.h>
include <stdarg.h>
include <DXUtil.h>
ifdef UNICODE
typedef HINSTANCE (WINAPI* LPShellExecute)(HWND hwnd, LPCWSTR lpOperation, LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd);
else
typedef HINSTANCE (WINAPI* LPShellExecute)(HWND hwnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, INT nShowCmd);
endif
ifndef UNDER_CE
//-----------------------------------------------------------------------------
// Name: DXUtil_GetDXSDKMediaPathCch()
// Desc: Returns the DirectX SDK media path
// cchDest is the size in TCHARs of strDest. Be careful not to
// pass in sizeof(strDest) on UNICODE builds.
//-----------------------------------------------------------------------------
HRESULT DXUtil_GetDXSDKMediaPathCch( TCHAR* strDest, int cchDest )
{
if( strDest == NULL || cchDest < 1 )
return E_INVALIDARG;
lstrcpy( strDest, TEXT("") );
// Open the appropriate registry key
HKEY hKey;
LONG lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
_T("Software\\Microsoft\\DirectX SDK"),
0, KEY_READ, &hKey );
if( ERROR_SUCCESS != lResult )
return E_FAIL;
DWORD dwType;
DWORD dwSize = cchDest * sizeof(TCHAR);
lResult = RegQueryValueEx( hKey, _T("DX9J3SDK Samples Path"), NULL,
&dwType, (BYTE*)strDest, &dwSize );
strDest[cchDest-1] = 0; // RegQueryValueEx doesn't NULL term if buffer too small
RegCloseKey( hKey );
if( ERROR_SUCCESS != lResult )
return E_FAIL;
const TCHAR* strMedia = _T("\\Media\\");
if( lstrlen(strDest) + lstrlen(strMedia) < cchDest )
_tcscat( strDest, strMedia );
else
return E_INVALIDARG;
return S_OK;
}
endif // !UNDER_CE
ifndef UNDER_CE
//-----------------------------------------------------------------------------
// Name: DXUtil_FindMediaFileCch()
// Desc: Returns a valid path to a DXSDK media file
// cchDest is the size in TCHARs of strDestPath. Be careful not to
// pass in sizeof(strDest) on UNICODE builds.
//-----------------------------------------------------------------------------
HRESULT DXUtil_FindMediaFileCch( TCHAR* strDestPath, int cchDest, TCHAR* strFilename )
{
HRESULT hr;
HANDLE file;
TCHAR* strShortNameTmp = NULL;
TCHAR strShortName[MAX_PATH];
int cchPath;
if( NULL==strFilename || NULL==strDestPath || cchDest < 1 )
return E_INVALIDARG;
lstrcpy( strDestPath, TEXT("") );
lstrcpy( strShortName, TEXT("") );
// Build full path name from strFileName (strShortName will be just the leaf filename)
cchPath = GetFullPathName(strFilename, cchDest, strDestPath, &strShortNameTmp);
if ((cchPath == 0) || (cchDest <= cchPath))
return E_FAIL;
if( strShortNameTmp )
lstrcpyn( strShortName, strShortNameTmp, MAX_PATH );
// first try to find the filename given a full path
file = CreateFile( strDestPath, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, 0, NULL );
if( INVALID_HANDLE_VALUE != file )
{
CloseHandle( file );
return S_OK;
}
// next try to find the filename in the current working directory (path stripped)
file = CreateFile( strShortName, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, 0, NULL );
if( INVALID_HANDLE_VALUE != file )
{
_tcsncpy( strDestPath, strShortName, cchDest );
strDestPath[cchDest-1] = 0; // _tcsncpy doesn't NULL term if it runs out of space
CloseHandle( file );
return S_OK;
}
// last, check if the file exists in the media directory
if( FAILED( hr = DXUtil_GetDXSDKMediaPathCch( strDestPath, cchDest ) ) )
return hr;
if( lstrlen(strDestPath) + lstrlen(strShortName) < cchDest )
lstrcat( strDestPath, strShortName );
else
return E_INVALIDARG;
file = CreateFile( strDestPath, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, 0, NULL );
if( INVALID_HANDLE_VALUE != file )
{
CloseHandle( file );
return S_OK;
}
// On failure, just return the file as the path
_tcsncpy( strDestPath, strFilename, cchDest );
strDestPath[cchDest-1] = 0; // _tcsncpy doesn't NULL term if it runs out of space
return HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND );
}
endif // !UNDER_CE
//-----------------------------------------------------------------------------
// Name: DXUtil_ReadStringRegKeyCch()
// Desc: Helper function to read a registry key string
// cchDest is the size in TCHARs of strDest. Be careful not to
// pass in sizeof(strDest) on UNICODE builds.
//-----------------------------------------------------------------------------
HRESULT DXUtil_ReadStringRegKeyCch( HKEY hKey, TCHAR* strRegName, TCHAR* strDest,
DWORD cchDest, TCHAR* strDefault )
{
DWORD dwType;
DWORD cbDest = cchDest * sizeof(TCHAR);
if( ERROR_SUCCESS != RegQueryValueEx( hKey, strRegName, 0, &dwType,
(BYTE*)strDest, &cbDest ) )
{
_tcsncpy( strDest, strDefault, cchDest );
strDest[cchDest-1] = 0;
if( dwType != REG_SZ )
return E_FAIL;
return S_OK;
}
return E_FAIL;
}
//-----------------------------------------------------------------------------
// Name: DXUtil_WriteStringRegKey()
// Desc: Helper function to write a registry key string
//-----------------------------------------------------------------------------
HRESULT DXUtil_WriteStringRegKey( HKEY hKey, TCHAR* strRegName,
TCHAR* strValue )
{
if( NULL == strValue )
return E_INVALIDARG;
DWORD cbValue = ((DWORD)_tcslen(strValue)+1) * sizeof(TCHAR);
if( ERROR_SUCCESS != RegSetValueEx( hKey, strRegName, 0, REG_SZ,
(BYTE*)strValue, cbValue ) )
return E_FAIL;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: DXUtil_ReadIntRegKey()
// Desc: Helper function to read a registry key int
//-----------------------------------------------------------------------------
HRESULT DXUtil_ReadIntRegKey( HKEY hKey, TCHAR* strRegName, DWORD* pdwDest,
DWORD dwDefault )
{
DWORD dwType;
DWORD dwLength = sizeof(DWORD);
if( ERROR_SUCCESS != RegQueryValueEx( hKey, strRegName, 0, &dwType,
(BYTE*)pdwDest, &dwLength ) )
{
*pdwDest = dwDefault;
if( dwType != REG_DWORD )
return E_FAIL;
return S_OK;
}
return E_FAIL;
}
//-----------------------------------------------------------------------------
// Name: DXUtil_WriteIntRegKey()
// Desc: Helper function to write a registry key int
//-----------------------------------------------------------------------------
HRESULT DXUtil_WriteIntRegKey( HKEY hKey, TCHAR* strRegName, DWORD dwValue )
{
if( ERROR_SUCCESS != RegSetValueEx( hKey, strRegName, 0, REG_DWORD,
(BYTE*)&dwValue, sizeof(DWORD) ) )
return E_FAIL;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: DXUtil_ReadBoolRegKey()
// Desc: Helper function to read a registry key BOOL
//-----------------------------------------------------------------------------
HRESULT DXUtil_ReadBoolRegKey( HKEY hKey, TCHAR* strRegName, BOOL* pbDest,
BOOL bDefault )
{
DWORD dwType;
DWORD dwLength = sizeof(BOOL);
if( ERROR_SUCCESS != RegQueryValueEx( hKey, strRegName, 0, &dwType,
(BYTE*)pbDest, &dwLength ) )
{
*pbDest = bDefault;
if( dwType != REG_DWORD )
return E_FAIL;
return S_OK;
}
return E_FAIL;
}
//-----------------------------------------------------------------------------
// Name: DXUtil_WriteBoolRegKey()
// Desc: Helper function to write a registry key BOOL
//-----------------------------------------------------------------------------
HRESULT DXUtil_WriteBoolRegKey( HKEY hKey, TCHAR* strRegName, BOOL bValue )
{
if( ERROR_SUCCESS != RegSetValueEx( hKey, strRegName, 0, REG_DWORD,
(BYTE*)&bValue, sizeof(BOOL) ) )
return E_FAIL;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: DXUtil_ReadGuidRegKey()
// Desc: Helper function to read a registry key guid
//-----------------------------------------------------------------------------
HRESULT DXUtil_ReadGuidRegKey( HKEY hKey, TCHAR* strRegName, GUID* pGuidDest,
GUID& guidDefault )
{
DWORD dwType;
DWORD dwLength = sizeof(GUID);
if( ERROR_SUCCESS != RegQueryValueEx( hKey, strRegName, 0, &dwType,
(LPBYTE) pGuidDest, &dwLength ) )
{
*pGuidDest = guidDefault;
if( dwType != REG_BINARY )
return E_FAIL;
return S_OK;
}
return E_FAIL;
}
//-----------------------------------------------------------------------------
// Name: DXUtil_WriteGuidRegKey()
// Desc: Helper function to write a registry key guid
//-----------------------------------------------------------------------------
HRESULT DXUtil_WriteGuidRegKey( HKEY hKey, TCHAR* strRegName, GUID guidValue )
{
if( ERROR_SUCCESS != RegSetValueEx( hKey, strRegName, 0, REG_BINARY,
(BYTE*)&guidValue, sizeof(GUID) ) )
return E_FAIL;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: DXUtil_Timer()
// Desc: Performs timer opertations. Use the following commands:
// TIMER_RESET - to reset the timer
// TIMER_START - to start the timer
// TIMER_STOP - to stop (or pause) the timer
// TIMER_ADVANCE - to advance the timer by 0.1 seconds
// TIMER_GETABSOLUTETIME - to get the absolute system time
// TIMER_GETAPPTIME - to get the current time
// TIMER_GETELAPSEDTIME - to get the time that elapsed between
// TIMER_GETELAPSEDTIME calls
//-----------------------------------------------------------------------------
FLOAT __stdcall DXUtil_Timer( TIMER_COMMAND command )
{
static BOOL m_bTimerInitialized = FALSE;
static BOOL m_bUsingQPF = FALSE;
static BOOL m_bTimerStopped = TRUE;
static LONGLONG m_llQPFTicksPerSec = 0;
// Initialize the timer
if( FALSE == m_bTimerInitialized )
{
m_bTimerInitialized = TRUE;
// Use QueryPerformanceFrequency() to get frequency of timer. If QPF is
// not supported, we will timeGetTime() which returns milliseconds.
LARGE_INTEGER qwTicksPerSec;
m_bUsingQPF = QueryPerformanceFrequency( &qwTicksPerSec );
if( m_bUsingQPF )
m_llQPFTicksPerSec = qwTicksPerSec.QuadPart;
}
if( m_bUsingQPF )
{
static LONGLONG m_llStopTime = 0;
static LONGLONG m_llLastElapsedTime = 0;
static LONGLONG m_llBaseTime = 0;
double fTime;
double fElapsedTime;
LARGE_INTEGER qwTime;
// Get either the current time or the stop time, depending
// on whether we're stopped and what command was sent
if( m_llStopTime != 0 && command != TIMER_START && command != TIMER_GETABSOLUTETIME)
qwTime.QuadPart = m_llStopTime;
else
QueryPerformanceCounter( &qwTime );
// Return the elapsed time
if( command == TIMER_GETELAPSEDTIME )
{
fElapsedTime = (double) ( qwTime.QuadPart - m_llLastElapsedTime ) / (double) m_llQPFTicksPerSec;
m_llLastElapsedTime = qwTime.QuadPart;
return (FLOAT) fElapsedTime;
}
// Return the current time
if( command == TIMER_GETAPPTIME )
{
double fAppTime = (double) ( qwTime.QuadPart - m_llBaseTime ) / (double) m_llQPFTicksPerSec;
return (FLOAT) fAppTime;
}
// Reset the timer
if( command == TIMER_RESET )
{
m_llBaseTime = qwTime.QuadPart;
m_llLastElapsedTime = qwTime.QuadPart;
m_llStopTime = 0;
m_bTimerStopped = FALSE;
return 0.0f;
}
// Start the timer
if( command == TIMER_START )
{
if( m_bTimerStopped )
m_llBaseTime += qwTime.QuadPart - m_llStopTime;
m_llStopTime = 0;
m_llLastElapsedTime = qwTime.QuadPart;
m_bTimerStopped = FALSE;
return 0.0f;
}
// Stop the timer
if( command == TIMER_STOP )
{
m_llStopTime = qwTime.QuadPart;
m_llLastElapsedTime = qwTime.QuadPart;
m_bTimerStopped = TRUE;
return 0.0f;
}
// Advance the timer by 1/10th second
if( command == TIMER_ADVANCE )
{
m_llStopTime += m_llQPFTicksPerSec/10;
return 0.0f;
}
if( command == TIMER_GETABSOLUTETIME )
{
fTime = qwTime.QuadPart / (double) m_llQPFTicksPerSec;
return (FLOAT) fTime;
}
return -1.0f; // Invalid command specified
}
else
{
// Get the time using timeGetTime()
static double m_fLastElapsedTime = 0.0;
static double m_fBaseTime = 0.0;
static double m_fStopTime = 0.0;
double fTime;
double fElapsedTime;
// Get either the current time or the stop time, depending
// on whether we're stopped and what command was sent
if( m_fStopTime != 0.0 && command != TIMER_START && command != TIMER_GETABSOLUTETIME)
fTime = m_fStopTime;
else
fTime = GETTIMESTAMP() * 0.001;
// Return the elapsed time
if( command == TIMER_GETELAPSEDTIME )
{
fElapsedTime = (double) (fTime - m_fLastElapsedTime);
m_fLastElapsedTime = fTime;
return (FLOAT) fElapsedTime;
}
// Return the current time
if( command == TIMER_GETAPPTIME )
{
return (FLOAT) (fTime - m_fBaseTime);
}
// Reset the timer
if( command == TIMER_RESET )
{
m_fBaseTime = fTime;
m_fLastElapsedTime = fTime;
m_fStopTime = 0;
m_bTimerStopped = FALSE;
return 0.0f;
}
// Start the timer
if( command == TIMER_START )
{
if( m_bTimerStopped )
m_fBaseTime += fTime - m_fStopTime;
m_fStopTime = 0.0f;
m_fLastElapsedTime = fTime;
m_bTimerStopped = FALSE;
return 0.0f;
}
// Stop the timer
if( command == TIMER_STOP )
{
m_fStopTime = fTime;
m_fLastElapsedTime = fTime;
m_bTimerStopped = TRUE;
return 0.0f;
}
// Advance the timer by 1/10th second
if( command == TIMER_ADVANCE )
{
m_fStopTime += 0.1f;
return 0.0f;
}
if( command == TIMER_GETABSOLUTETIME )
{
return (FLOAT) fTime;
}
return -1.0f; // Invalid command specified
}
}
//-----------------------------------------------------------------------------
// Name: DXUtil_ConvertAnsiStringToWideCch()
// Desc: This is a UNICODE conversion utility to convert a CHAR string into a
// WCHAR string.
// cchDestChar is the size in TCHARs of wstrDestination. Be careful not to
// pass in sizeof(strDest)
//-----------------------------------------------------------------------------
HRESULT DXUtil_ConvertAnsiStringToWideCch( WCHAR* wstrDestination, const CHAR* strSource,
int cchDestChar )
{
if( wstrDestination==NULL || strSource==NULL || cchDestChar < 1 )
return E_INVALIDARG;
int nResult = MultiByteToWideChar( CP_ACP, 0, strSource, -1,
wstrDestination, cchDestChar );
wstrDestination[cchDestChar-1] = 0;
if( nResult == 0 )
return E_FAIL;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: DXUtil_ConvertWideStringToAnsi()
// Desc: This is a UNICODE conversion utility to convert a WCHAR string into a
// CHAR string.
// cchDestChar is the size in TCHARs of strDestination
//-----------------------------------------------------------------------------
HRESULT DXUtil_ConvertWideStringToAnsiCch( CHAR* strDestination, const WCHAR* wstrSource,
int cchDestChar )
{
if( strDestination==NULL || wstrSource==NULL || cchDestChar < 1 )
return E_INVALIDARG;
int nResult = WideCharToMultiByte( CP_ACP, 0, wstrSource, -1, strDestination,
cchDestChar*sizeof(CHAR), NULL, NULL );
strDestination[cchDestChar-1] = 0;
if( nResult == 0 )
return E_FAIL;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: DXUtil_ConvertGenericStringToAnsi()
// Desc: This is a UNICODE conversion utility to convert a TCHAR string into a
// CHAR string.
// cchDestChar is the size in TCHARs of strDestination
//-----------------------------------------------------------------------------
HRESULT DXUtil_ConvertGenericStringToAnsiCch( CHAR* strDestination, const TCHAR* tstrSource,
int cchDestChar )
{
if( strDestination==NULL || tstrSource==NULL || cchDestChar < 1 )
return E_INVALIDARG;
ifdef _UNICODE
return DXUtil_ConvertWideStringToAnsiCch( strDestination, tstrSource, cchDestChar );
else
strncpy( strDestination, tstrSource, cchDestChar );
strDestination[cchDestChar-1] = '\0';
return S_OK;
endif
}
//-----------------------------------------------------------------------------
// Name: DXUtil_ConvertGenericStringToWide()
// Desc: This is a UNICODE conversion utility to convert a TCHAR string into a
// WCHAR string.
// cchDestChar is the size in TCHARs of wstrDestination. Be careful not to
// pass in sizeof(strDest)
//-----------------------------------------------------------------------------
HRESULT DXUtil_ConvertGenericStringToWideCch( WCHAR* wstrDestination, const TCHAR* tstrSource,
int cchDestChar )
{
if( wstrDestination==NULL || tstrSource==NULL || cchDestChar < 1 )
return E_INVALIDARG;
ifdef _UNICODE
wcsncpy( wstrDestination, tstrSource, cchDestChar );
wstrDestination[cchDestChar-1] = L'\0';
return S_OK;
else
return DXUtil_ConvertAnsiStringToWideCch( wstrDestination, tstrSource, cchDestChar );
endif
}
//-----------------------------------------------------------------------------
// Name: DXUtil_ConvertAnsiStringToGeneric()
// Desc: This is a UNICODE conversion utility to convert a CHAR string into a
// TCHAR string.
// cchDestChar is the size in TCHARs of tstrDestination. Be careful not to
// pass in sizeof(strDest) on UNICODE builds
//-----------------------------------------------------------------------------
HRESULT DXUtil_ConvertAnsiStringToGenericCch( TCHAR* tstrDestination, const CHAR* strSource,
int cchDestChar )
{
if( tstrDestination==NULL || strSource==NULL || cchDestChar < 1 )
return E_INVALIDARG;
ifdef _UNICODE
return DXUtil_ConvertAnsiStringToWideCch( tstrDestination, strSource, cchDestChar );
else
strncpy( tstrDestination, strSource, cchDestChar );
tstrDestination[cchDestChar-1] = '\0';
return S_OK;
endif
}
//-----------------------------------------------------------------------------
// Name: DXUtil_ConvertAnsiStringToGeneric()
// Desc: This is a UNICODE conversion utility to convert a WCHAR string into a
// TCHAR string.
// cchDestChar is the size in TCHARs of tstrDestination. Be careful not to
// pass in sizeof(strDest) on UNICODE builds
//-----------------------------------------------------------------------------
HRESULT DXUtil_ConvertWideStringToGenericCch( TCHAR* tstrDestination, const WCHAR* wstrSource,
int cchDestChar )
{
if( tstrDestination==NULL || wstrSource==NULL || cchDestChar < 1 )
return E_INVALIDARG;
ifdef _UNICODE
wcsncpy( tstrDestination, wstrSource, cchDestChar );
tstrDestination[cchDestChar-1] = L'\0';
return S_OK;
else
return DXUtil_ConvertWideStringToAnsiCch( tstrDestination, wstrSource, cchDestChar );
endif
}
ifndef UNDER_CE
//-----------------------------------------------------------------------------
// Name: DXUtil_LaunchReadme()
// Desc: Finds and opens the readme.txt for this sample
//-----------------------------------------------------------------------------
VOID DXUtil_LaunchReadme( HWND hWnd )
{
bool bSuccess = false;
bool bFound = false;
TCHAR strReadmePath[1024];
TCHAR strExeName[MAX_PATH];
TCHAR strExePath[MAX_PATH];
TCHAR* strLastSlash = NULL;
lstrcpy( strReadmePath, TEXT("") );
lstrcpy( strExePath, TEXT("") );
lstrcpy( strExeName, TEXT("") );
// Get the exe name, and exe path
GetModuleFileName( NULL, strExePath, MAX_PATH );
strExePath[MAX_PATH-1]=0;
strLastSlash = _tcsrchr( strExePath, TEXT('\\') );
if( strLastSlash )
{
lstrcpyn( strExeName, &strLastSlash[1], MAX_PATH );
strExeName[MAX_PATH-1]=0;
// Chop the exe name from the exe path
*strLastSlash = 0;
// Chop the .exe from the exe name
strLastSlash = _tcsrchr( strExeName, TEXT('.') );
if( strLastSlash )
*strLastSlash = 0;
}
if( !bFound )
{
// Search in "\%EXE_DIR%\..%EXE_NAME%". This matchs the DirectX SDK layout
_tcscpy( strReadmePath, strExePath );
strLastSlash = _tcsrchr( strReadmePath, TEXT('\\') );
if( strLastSlash )
*strLastSlash = 0;
lstrcat( strReadmePath, TEXT("\\") );
lstrcat( strReadmePath, strExeName );
lstrcat( strReadmePath, TEXT("\\readme.txt") );
if( GetFileAttributes( strReadmePath ) != 0xFFFFFFFF )
bFound = TRUE;
}
if( !bFound )
{
// Search in "\%EXE_DIR%\"
_tcscpy( strReadmePath, strExePath );
lstrcat( strReadmePath, TEXT("\\readme.txt") );
if( GetFileAttributes( strReadmePath ) != 0xFFFFFFFF )
bFound = TRUE;
}
if( !bFound )
{
// Search in "\%EXE_DIR%\.."
_tcscpy( strReadmePath, strExePath );
strLastSlash = _tcsrchr( strReadmePath, TEXT('\\') );
if( strLastSlash )
*strLastSlash = 0;
lstrcat( strReadmePath, TEXT("\\readme.txt") );
if( GetFileAttributes( strReadmePath ) != 0xFFFFFFFF )
bFound = TRUE;
}
if( !bFound )
{
// Search in "\%EXE_DIR%\..\.."
_tcscpy( strReadmePath, strExePath );
strLastSlash = _tcsrchr( strReadmePath, TEXT('\\') );
if( strLastSlash )
*strLastSlash = 0;
strLastSlash = _tcsrchr( strReadmePath, TEXT('\\') );
if( strLastSlash )
*strLastSlash = 0;
lstrcat( strReadmePath, TEXT("\\readme.txt") );
if( GetFileAttributes( strReadmePath ) != 0xFFFFFFFF )
bFound = TRUE;
}
if( bFound )
{
// GetProcAddress for ShellExecute, so we don't have to include shell32.lib
// in every project that uses dxutil.cpp
LPShellExecute pShellExecute = NULL;
HINSTANCE hInstShell32 = LoadLibrary(TEXT(<shell32.dll>));
if (hInstShell32 != NULL)
{
ifdef UNICODE
pShellExecute = (LPShellExecute)GetProcAddress(hInstShell32, _TWINCE("ShellExecuteW"));
else
pShellExecute = (LPShellExecute)GetProcAddress(hInstShell32, _TWINCE("ShellExecuteA"));
endif
if( pShellExecute != NULL )
{
if( pShellExecute( hWnd, TEXT("open"), strReadmePath, NULL, NULL, SW_SHOW ) > (HINSTANCE) 32 )
bSuccess = true;
}
FreeLibrary(hInstShell32);
}
}
if( !bSuccess )
{
// Tell the user that the readme couldn't be opened
MessageBox( hWnd, TEXT("Could not find readme.txt"),
TEXT("DirectX SDK Sample"), MB_ICONWARNING | MB_OK );
}
}
endif // !UNDER_CE
//-----------------------------------------------------------------------------
// Name: DXUtil_Trace()
// Desc: Outputs to the debug stream a formatted string with a variable-
// argument list.
//-----------------------------------------------------------------------------
VOID DXUtil_Trace( TCHAR* strMsg, ... )
{
if defined(DEBUG) | defined(_DEBUG)
TCHAR strBuffer[512];
va_list args;
va_start(args, strMsg);
_vsntprintf( strBuffer, 512, strMsg, args );
va_end(args);
OutputDebugString( strBuffer );
else
UNREFERENCED_PARAMETER(strMsg);
endif
}
//-----------------------------------------------------------------------------
// Name: DXUtil_ConvertStringToGUID()
// Desc: Converts a string to a GUID
//-----------------------------------------------------------------------------
HRESULT DXUtil_ConvertStringToGUID( const TCHAR* strSrc, GUID* pGuidDest )
{
UINT aiTmp[10];
if( _stscanf( strSrc, TEXT("{%8X-%4X-%4X-%2X%2X-%2X%2X%2X%2X%2X%2X}"),
&pGuidDest->Data1,
&aiTmp[0], &aiTmp[1],
&aiTmp[2], &aiTmp[3],
&aiTmp[4], &aiTmp[5],
&aiTmp[6], &aiTmp[7],
&aiTmp[8], &aiTmp[9] ) != 11 )
{
ZeroMemory( pGuidDest, sizeof(GUID) );
return E_FAIL;
}
else
{
pGuidDest->Data2 = (USHORT) aiTmp[0];
pGuidDest->Data3 = (USHORT) aiTmp[1];
pGuidDest->Data4[0] = (BYTE) aiTmp[2];
pGuidDest->Data4[1] = (BYTE) aiTmp[3];
pGuidDest->Data4[2] = (BYTE) aiTmp[4];
pGuidDest->Data4[3] = (BYTE) aiTmp[5];
pGuidDest->Data4[4] = (BYTE) aiTmp[6];
pGuidDest->Data4[5] = (BYTE) aiTmp[7];
pGuidDest->Data4[6] = (BYTE) aiTmp[8];
pGuidDest->Data4[7] = (BYTE) aiTmp[9];
return S_OK;
}
}
//-----------------------------------------------------------------------------
// Name: DXUtil_ConvertGUIDToStringCch()
// Desc: Converts a GUID to a string
// cchDestChar is the size in TCHARs of strDest. Be careful not to
// pass in sizeof(strDest) on UNICODE builds
//-----------------------------------------------------------------------------
HRESULT DXUtil_ConvertGUIDToStringCch( const GUID* pGuidSrc, TCHAR* strDest, int cchDestChar )
{
int nResult = _sntprintf( strDest, cchDestChar, TEXT("{%0.8X-%0.4X-%0.4X-%0.2X%0.2X-%0.2X%0.2X%0.2X%0.2X%0.2X%0.2X}"),
pGuidSrc->Data1, pGuidSrc->Data2, pGuidSrc->Data3,
pGuidSrc->Data4[0], pGuidSrc->Data4[1],
pGuidSrc->Data4[2], pGuidSrc->Data4[3],
pGuidSrc->Data4[4], pGuidSrc->Data4[5],
pGuidSrc->Data4[6], pGuidSrc->Data4[7] );
if( nResult < 0 )
return E_FAIL;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CArrayList constructor
// Desc:
//-----------------------------------------------------------------------------
CArrayList::CArrayList( ArrayListType Type, UINT BytesPerEntry )
{
if( Type == AL_REFERENCE )
BytesPerEntry = sizeof(void*);
m_ArrayListType = Type;
m_pData = NULL;
m_BytesPerEntry = BytesPerEntry;
m_NumEntries = 0;
m_NumEntriesAllocated = 0;
}
//-----------------------------------------------------------------------------
// Name: CArrayList destructor
// Desc:
//-----------------------------------------------------------------------------
CArrayList::~CArrayList( void )
{
if( m_pData != NULL )
delete[] m_pData;
}
//-----------------------------------------------------------------------------
// Name: CArrayList::Add
// Desc: Adds pEntry to the list.
//-----------------------------------------------------------------------------
HRESULT CArrayList::Add( void* pEntry )
{
if( m_BytesPerEntry == 0 )
return E_FAIL;
if( m_pData == NULL || m_NumEntries + 1 > m_NumEntriesAllocated )
{
void* pDataNew;
UINT NumEntriesAllocatedNew;
if( m_NumEntriesAllocated == 0 )
NumEntriesAllocatedNew = 16;
else
NumEntriesAllocatedNew = m_NumEntriesAllocated * 2;
pDataNew = new BYTE[NumEntriesAllocatedNew * m_BytesPerEntry];
if( pDataNew == NULL )
return E_OUTOFMEMORY;
if( m_pData != NULL )
{
CopyMemory( pDataNew, m_pData, m_NumEntries * m_BytesPerEntry );
delete[] m_pData;
}
m_pData = pDataNew;
m_NumEntriesAllocated = NumEntriesAllocatedNew;
}
if( m_ArrayListType == AL_VALUE )
CopyMemory( (BYTE*)m_pData + (m_NumEntries * m_BytesPerEntry), pEntry, m_BytesPerEntry );
else
*(((void**)m_pData) + m_NumEntries) = pEntry;
m_NumEntries++;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CArrayList::Remove
// Desc: Remove the item at Entry in the list, and collapse the array.
//-----------------------------------------------------------------------------
void CArrayList::Remove( UINT Entry )
{
// Decrement count
m_NumEntries--;
// Find the entry address
BYTE* pData = (BYTE*)m_pData + (Entry * m_BytesPerEntry);
// Collapse the array
MoveMemory( pData, pData + m_BytesPerEntry, ( m_NumEntries - Entry ) * m_BytesPerEntry );
}
//-----------------------------------------------------------------------------
// Name: CArrayList::GetPtr
// Desc: Returns a pointer to the Entry'th entry in the list.
//-----------------------------------------------------------------------------
void* CArrayList::GetPtr( UINT Entry )
{
if( m_ArrayListType == AL_VALUE )
return (BYTE*)m_pData + (Entry * m_BytesPerEntry);
else
return *(((void**)m_pData) + Entry);
}
//-----------------------------------------------------------------------------
// Name: CArrayList::Contains
// Desc: Returns whether the list contains an entry identical to the
// specified entry data.
//-----------------------------------------------------------------------------
bool CArrayList::Contains( void* pEntryData )
{
for( UINT iEntry = 0; iEntry < m_NumEntries; iEntry++ )
{
if( m_ArrayListType == AL_VALUE )
{
if( memcmp( GetPtr(iEntry), pEntryData, m_BytesPerEntry ) == 0 )
return true;
}
else
{
if( GetPtr(iEntry) == pEntryData )
return true;
}
}
return false;
}
//-----------------------------------------------------------------------------
// Name: BYTE helper functions
// Desc: cchDestChar is the size in BYTEs of strDest. Be careful not to
// pass use sizeof() if the strDest is a string pointer.
// eg.
// TCHAR* sz = new TCHAR[100]; // sizeof(sz) == 4
// TCHAR sz2[100]; // sizeof(sz2) == 200
//-----------------------------------------------------------------------------
HRESULT DXUtil_ConvertAnsiStringToWideCb( WCHAR* wstrDestination, const CHAR* strSource, int cbDestChar )
{
return DXUtil_ConvertAnsiStringToWideCch( wstrDestination, strSource, cbDestChar / sizeof(WCHAR) );
}
HRESULT DXUtil_ConvertWideStringToAnsiCb( CHAR* strDestination, const WCHAR* wstrSource, int cbDestChar )
{
return DXUtil_ConvertWideStringToAnsiCch( strDestination, wstrSource, cbDestChar / sizeof(CHAR) );
}
HRESULT DXUtil_ConvertGenericStringToAnsiCb( CHAR* strDestination, const TCHAR* tstrSource, int cbDestChar )
{
return DXUtil_ConvertGenericStringToAnsiCch( strDestination, tstrSource, cbDestChar / sizeof(CHAR) );
}
HRESULT DXUtil_ConvertGenericStringToWideCb( WCHAR* wstrDestination, const TCHAR* tstrSource, int cbDestChar )
{
return DXUtil_ConvertGenericStringToWideCch( wstrDestination, tstrSource, cbDestChar / sizeof(WCHAR) );
}
HRESULT DXUtil_ConvertAnsiStringToGenericCb( TCHAR* tstrDestination, const CHAR* strSource, int cbDestChar )
{
return DXUtil_ConvertAnsiStringToGenericCch( tstrDestination, strSource, cbDestChar / sizeof(TCHAR) );
}
HRESULT DXUtil_ConvertWideStringToGenericCb( TCHAR* tstrDestination, const WCHAR* wstrSource, int cbDestChar )
{
return DXUtil_ConvertWideStringToGenericCch( tstrDestination, wstrSource, cbDestChar / sizeof(TCHAR) );
}
HRESULT DXUtil_ReadStringRegKeyCb( HKEY hKey, TCHAR* strRegName, TCHAR* strDest, DWORD cbDest, TCHAR* strDefault )
{
return DXUtil_ReadStringRegKeyCch( hKey, strRegName, strDest, cbDest / sizeof(TCHAR), strDefault );
}
HRESULT DXUtil_ConvertGUIDToStringCb( const GUID* pGuidSrc, TCHAR* strDest, int cbDestChar )
{
return DXUtil_ConvertGUIDToStringCch( pGuidSrc, strDest, cbDestChar / sizeof(TCHAR) );
}
ifndef UNDER_CE
HRESULT DXUtil_GetDXSDKMediaPathCb( TCHAR* szDest, int cbDest )
{
return DXUtil_GetDXSDKMediaPathCch( szDest, cbDest / sizeof(TCHAR) );
}
HRESULT DXUtil_FindMediaFileCb( TCHAR* szDestPath, int cbDest, TCHAR* strFilename )
{
return DXUtil_FindMediaFileCch( szDestPath, cbDest / sizeof(TCHAR), strFilename );
}
endif // !UNDER_CE
(C) Æliens
20/2/2008
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.