📄 dxutmisc.cpp
字号:
//--------------------------------------------------------------------------------------
// File: DXUTMisc.cpp
//
// Shortcut macros and functions for using DX objects
//
// Copyright (c) Microsoft Corporation. All rights reserved
//--------------------------------------------------------------------------------------
#include "dxstdafx.h"
//--------------------------------------------------------------------------------------
// Global/Static Members
//--------------------------------------------------------------------------------------
CDXUTResourceCache& DXUTGetGlobalResourceCache()
{
// Using an accessor function gives control of the construction order
static CDXUTResourceCache cache;
return cache;
}
CDXUTTimer* DXUTGetGlobalTimer()
{
// Using an accessor function gives control of the construction order
static CDXUTTimer timer;
return &timer;
}
//--------------------------------------------------------------------------------------
// Internal functions forward declarations
//--------------------------------------------------------------------------------------
bool DXUTFindMediaSearchTypicalDirs( WCHAR* strSearchPath, int cchSearch, LPCWSTR strLeaf, WCHAR* strExePath, WCHAR* strExeName, LPCWSTR strMediaDir );
bool DXUTFindMediaSearchParentDirs( WCHAR* strSearchPath, int cchSearch, WCHAR* strStartAt, WCHAR* strLeafName );
//--------------------------------------------------------------------------------------
CDXUTTimer::CDXUTTimer()
{
m_bUsingQPF = false;
m_bTimerStopped = true;
m_llQPFTicksPerSec = 0;
m_llStopTime = 0;
m_llLastElapsedTime = 0;
m_llBaseTime = 0;
// Use QueryPerformanceFrequency() to get frequency of timer.
LARGE_INTEGER qwTicksPerSec;
m_bUsingQPF = (bool) (QueryPerformanceFrequency( &qwTicksPerSec ) != 0);
m_llQPFTicksPerSec = qwTicksPerSec.QuadPart;
}
//--------------------------------------------------------------------------------------
void CDXUTTimer::Reset()
{
if( !m_bUsingQPF )
return;
// Get either the current time or the stop time
LARGE_INTEGER qwTime;
if( m_llStopTime != 0 )
qwTime.QuadPart = m_llStopTime;
else
QueryPerformanceCounter( &qwTime );
m_llBaseTime = qwTime.QuadPart;
m_llLastElapsedTime = qwTime.QuadPart;
m_llStopTime = 0;
m_bTimerStopped = FALSE;
}
//--------------------------------------------------------------------------------------
void CDXUTTimer::Start()
{
if( !m_bUsingQPF )
return;
// Get either the current time or the stop time
LARGE_INTEGER qwTime;
if( m_llStopTime != 0 )
qwTime.QuadPart = m_llStopTime;
else
QueryPerformanceCounter( &qwTime );
if( m_bTimerStopped )
m_llBaseTime += qwTime.QuadPart - m_llStopTime;
m_llStopTime = 0;
m_llLastElapsedTime = qwTime.QuadPart;
m_bTimerStopped = FALSE;
}
//--------------------------------------------------------------------------------------
void CDXUTTimer::Stop()
{
if( !m_bUsingQPF )
return;
if( !m_bTimerStopped )
{
// Get either the current time or the stop time
LARGE_INTEGER qwTime;
if( m_llStopTime != 0 )
qwTime.QuadPart = m_llStopTime;
else
QueryPerformanceCounter( &qwTime );
m_llStopTime = qwTime.QuadPart;
m_llLastElapsedTime = qwTime.QuadPart;
m_bTimerStopped = TRUE;
}
}
//--------------------------------------------------------------------------------------
void CDXUTTimer::Advance()
{
if( !m_bUsingQPF )
return;
m_llStopTime += m_llQPFTicksPerSec/10;
}
//--------------------------------------------------------------------------------------
double CDXUTTimer::GetAbsoluteTime()
{
if( !m_bUsingQPF )
return -1.0;
// Get either the current time or the stop time
LARGE_INTEGER qwTime;
if( m_llStopTime != 0 )
qwTime.QuadPart = m_llStopTime;
else
QueryPerformanceCounter( &qwTime );
double fTime = qwTime.QuadPart / (double) m_llQPFTicksPerSec;
return fTime;
}
//--------------------------------------------------------------------------------------
double CDXUTTimer::GetTime()
{
if( !m_bUsingQPF )
return -1.0;
// Get either the current time or the stop time
LARGE_INTEGER qwTime;
if( m_llStopTime != 0 )
qwTime.QuadPart = m_llStopTime;
else
QueryPerformanceCounter( &qwTime );
double fAppTime = (double) ( qwTime.QuadPart - m_llBaseTime ) / (double) m_llQPFTicksPerSec;
return fAppTime;
}
//--------------------------------------------------------------------------------------
double CDXUTTimer::GetElapsedTime()
{
if( !m_bUsingQPF )
return -1.0;
// Get either the current time or the stop time
LARGE_INTEGER qwTime;
if( m_llStopTime != 0 )
qwTime.QuadPart = m_llStopTime;
else
QueryPerformanceCounter( &qwTime );
double fElapsedTime = (double) ( qwTime.QuadPart - m_llLastElapsedTime ) / (double) m_llQPFTicksPerSec;
m_llLastElapsedTime = qwTime.QuadPart;
return fElapsedTime;
}
//--------------------------------------------------------------------------------------
bool CDXUTTimer::IsStopped()
{
return m_bTimerStopped;
}
//--------------------------------------------------------------------------------------
// Returns the DirectX SDK media path
// cchDest is the size in WCHARs of strDest. Be careful not to
// pass in sizeof(strDest) on UNICODE builds.
//--------------------------------------------------------------------------------------
HRESULT DXUTGetDXSDKMediaPathCch( WCHAR* 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,
L"Software\\Microsoft\\DirectX SDK",
0, KEY_READ, &hKey );
if( ERROR_SUCCESS != lResult )
return E_FAIL;
DWORD dwType;
DWORD dwSize = cchDest * sizeof(WCHAR);
lResult = RegQueryValueEx( hKey, L"DX9S4SDK 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 WCHAR* strMedia = L"\\Media\\";
if( lstrlen(strDest) + lstrlen(strMedia) < cchDest )
wcscat( strDest, strMedia );
else
return E_INVALIDARG;
return S_OK;
}
//--------------------------------------------------------------------------------------
// Tries to find the location of a SDK media file
// cchDest is the size in WCHARs of strDestPath. Be careful not to
// pass in sizeof(strDest) on UNICODE builds.
//--------------------------------------------------------------------------------------
HRESULT DXUTFindDXSDKMediaFileCch( WCHAR* strDestPath, int cchDest, LPCWSTR strFilename )
{
bool bFound;
WCHAR strSearchFor[MAX_PATH];
if( NULL==strFilename || strFilename[0] == 0 || NULL==strDestPath || cchDest < 10 )
return E_INVALIDARG;
// Get the DirectX SDK's media dir if the SDK is installed
WCHAR strMediaDir[MAX_PATH] = {0};
DXUTGetDXSDKMediaPathCch( strMediaDir, MAX_PATH );
// Get the exe name, and exe path
WCHAR strExePath[MAX_PATH] = {0};
WCHAR strExeName[MAX_PATH] = {0};
WCHAR* strLastSlash = NULL;
GetModuleFileName( NULL, strExePath, MAX_PATH );
strExePath[MAX_PATH-1]=0;
strLastSlash = wcsrchr( strExePath, TEXT('\\') );
if( strLastSlash )
{
lstrcpyn( strExeName, &strLastSlash[1], MAX_PATH );
// Chop the exe name from the exe path
*strLastSlash = 0;
// Chop the .exe from the exe name
strLastSlash = wcsrchr( strExeName, TEXT('.') );
if( strLastSlash )
*strLastSlash = 0;
}
// Typical directories:
// .\
// ..\
// ..\..\
// %EXE_DIR%\
// %EXE_DIR%\..\
// %EXE_DIR%\..\..\
// %EXE_DIR%\..\%EXE_NAME%
// %EXE_DIR%\..\..\%EXE_NAME%
// DXSDK media path
// Typical directory search
bFound = DXUTFindMediaSearchTypicalDirs( strDestPath, cchDest, strFilename, strExePath, strExeName, strMediaDir );
if( bFound )
return S_OK;
// Typical directory search again, but also look in a subdir called "\media\"
_snwprintf( strSearchFor, MAX_PATH, L"media\\%s", strFilename ); strSearchFor[MAX_PATH-1] = 0;
bFound = DXUTFindMediaSearchTypicalDirs( strDestPath, cchDest, strSearchFor, strExePath, strExeName, strMediaDir );
if( bFound )
return S_OK;
WCHAR strLeafName[MAX_PATH] = {0};
// Search all parent directories starting at .\ and using strFilename as the leaf name
wcsncpy( strLeafName, strFilename, MAX_PATH ); strLeafName[MAX_PATH-1] = 0;
bFound = DXUTFindMediaSearchParentDirs( strDestPath, cchDest, L".", strLeafName );
if( bFound )
return S_OK;
// Search all parent directories starting at the exe's dir and using strFilename as the leaf name
bFound = DXUTFindMediaSearchParentDirs( strDestPath, cchDest, strExePath, strLeafName );
if( bFound )
return S_OK;
// Search all parent directories starting at .\ and using "media\strFilename" as the leaf name
_snwprintf( strLeafName, MAX_PATH, L"media\\%s", strFilename ); strLeafName[MAX_PATH-1] = 0;
bFound = DXUTFindMediaSearchParentDirs( strDestPath, cchDest, L".", strLeafName );
if( bFound )
return S_OK;
// Search all parent directories starting at the exe's dir and using "media\strFilename" as the leaf name
bFound = DXUTFindMediaSearchParentDirs( strDestPath, cchDest, strExePath, strLeafName );
if( bFound )
return S_OK;
// On failure, return the file as the path but also return an error code
wcsncpy( strDestPath, strFilename, cchDest );
strDestPath[cchDest-1] = 0;
return DXUTERR_MEDIANOTFOUND;
}
//--------------------------------------------------------------------------------------
// Search a set of typical directories
//--------------------------------------------------------------------------------------
bool DXUTFindMediaSearchTypicalDirs( WCHAR* strSearchPath, int cchSearch, LPCWSTR strLeaf,
WCHAR* strExePath, WCHAR* strExeName, LPCWSTR strMediaDir )
{
// Typical directories:
// .\
// ..\
// ..\..\
// %EXE_DIR%\
// %EXE_DIR%\..\
// %EXE_DIR%\..\..\
// %EXE_DIR%\..\%EXE_NAME%
// %EXE_DIR%\..\..\%EXE_NAME%
// DXSDK media path
// Search in .\
wcsncpy( strSearchPath, strLeaf, cchSearch ); strSearchPath[cchSearch-1] = 0;
if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
return true;
// Search in ..\
_snwprintf( strSearchPath, cchSearch, L"..\\%s", strLeaf ); strSearchPath[cchSearch-1] = 0;
if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
return true;
// Search in ..\..\
_snwprintf( strSearchPath, cchSearch, L"..\\..\\%s", strLeaf ); strSearchPath[cchSearch-1] = 0;
if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -