?? dxutmisc.cpp
字號:
//--------------------------------------------------------------------------------------
// File: DXUTMisc.cpp
//
// Shortcut macros and functions for using DX objects
//
// Copyright (c) Microsoft Corporation. All rights reserved
//--------------------------------------------------------------------------------------
#include "dxstdafx.h"
#define DXUT_GAMEPAD_TRIGGER_THRESHOLD 30
#define DXUT_INPUT_DEADZONE ( 0.24f * FLOAT(0x7FFF) ) // Default to 24% of the +/- 32767 range. This is a reasonable default value but can be altered if needed.
#undef min // use __min instead
#undef max // use __max instead
//--------------------------------------------------------------------------------------
// 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 );
bool DXUTFindMediaSearchParentDirs( WCHAR* strSearchPath, int cchSearch, WCHAR* strStartAt, WCHAR* strLeafName );
INT_PTR CALLBACK DisplaySwitchToREFWarningProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
//--------------------------------------------------------------------------------------
// Shared code for samples to ask user if they want to use a REF device or quit
//--------------------------------------------------------------------------------------
void DXUTDisplaySwitchingToREFWarning()
{
if( DXUTGetShowMsgBoxOnError() )
{
// Open the appropriate registry key
DWORD dwSkipWarning = 0;
HKEY hKey;
LONG lResult = RegOpenKeyEx( HKEY_CURRENT_USER, L"Software\\Microsoft\\DirectX 9.0 SDK", 0, KEY_READ, &hKey );
if( ERROR_SUCCESS == lResult )
{
DWORD dwType;
DWORD dwSize = sizeof(DWORD);
lResult = RegQueryValueEx( hKey, L"Skip Warning On REF", NULL, &dwType, (BYTE*)&dwSkipWarning, &dwSize );
RegCloseKey( hKey );
}
if( dwSkipWarning == 0 )
{
// Compact code to create a custom dialog box without using a template in a resource file.
// If this dialog were in a .rc file, this would be a lot simpler but every sample calling this function would
// need a copy of the dialog in its own .rc file. Also MessageBox API could be used here instead, but
// the MessageBox API is simpler to call but it can't provide a "Don't show again" checkbox
typedef struct { DLGITEMTEMPLATE a; WORD b; WORD c; WORD d; WORD e; WORD f; } DXUT_DLG_ITEM;
typedef struct { DLGTEMPLATE a; WORD b; WORD c; WCHAR d[2]; WORD e; WCHAR f[14]; DXUT_DLG_ITEM i1; DXUT_DLG_ITEM i2; DXUT_DLG_ITEM i3; DXUT_DLG_ITEM i4; DXUT_DLG_ITEM i5; } DXUT_DLG_DATA;
DXUT_DLG_DATA dtp =
{
{WS_CAPTION|WS_POPUP|WS_VISIBLE|WS_SYSMENU|DS_ABSALIGN|DS_3DLOOK|DS_SETFONT|DS_MODALFRAME|DS_CENTER,0,5,0,0,269,82},0,0,L" ",8,L"MS Sans Serif",
{{WS_CHILD|WS_VISIBLE|SS_ICON|SS_CENTERIMAGE,0,7,7,24,24,0x100},0xFFFF,0x0082,0,0,0}, // icon
{{WS_CHILD|WS_VISIBLE,0,40,7,230,25,0x101},0xFFFF,0x0082,0,0,0}, // static text
{{WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON,0,80,39,50,14,IDYES},0xFFFF,0x0080,0,0,0}, // Yes button
{{WS_CHILD|WS_VISIBLE,0,133,39,50,14,IDNO},0xFFFF,0x0080,0,0,0}, // No button
{{WS_CHILD|WS_VISIBLE|BS_CHECKBOX,0,7,59,70,16,IDIGNORE},0xFFFF,0x0080,0,0,0}, // checkbox
};
int nResult = (int) DialogBoxIndirect( DXUTGetHINSTANCE(), (DLGTEMPLATE*)&dtp, DXUTGetHWND(), DisplaySwitchToREFWarningProc );
if( (nResult & 0x80) == 0x80 ) // "Don't show again" checkbox was checked
{
lResult = RegOpenKeyEx( HKEY_CURRENT_USER, L"Software\\Microsoft\\DirectX 9.0 SDK", 0, KEY_WRITE, &hKey );
if( ERROR_SUCCESS == lResult )
{
dwSkipWarning = 1;
RegSetValueEx( hKey, L"Skip Warning On REF", 0, REG_DWORD, (BYTE*)&dwSkipWarning, sizeof(DWORD) );
RegCloseKey( hKey );
}
}
// User choose not to continue
if( (nResult & 0x0F) == IDNO )
DXUTShutdown(1);
}
}
}
//--------------------------------------------------------------------------------------
// MsgProc for DXUTDisplaySwitchingToREFWarning() dialog box
//--------------------------------------------------------------------------------------
INT_PTR CALLBACK DisplaySwitchToREFWarningProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
// Easier to set text here than in the DLGITEMTEMPLATE
SetWindowText( hDlg, DXUTGetWindowTitle() );
SendMessage( GetDlgItem(hDlg, 0x100), STM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadIcon(0, IDI_QUESTION));
SetDlgItemText( hDlg, 0x101, L"Switching to the Direct3D reference rasterizer, a software device\nthat implements the entire Direct3D feature set, but runs very slowly.\nDo you wish to continue?" );
SetDlgItemText( hDlg, IDYES, L"&Yes" );
SetDlgItemText( hDlg, IDNO, L"&No" );
SetDlgItemText( hDlg, IDIGNORE, L"&Don't show again" );
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDIGNORE: CheckDlgButton( hDlg, IDIGNORE, (IsDlgButtonChecked( hDlg, IDIGNORE ) == BST_CHECKED) ? BST_UNCHECKED : BST_CHECKED ); EnableWindow( GetDlgItem( hDlg, IDNO ), (IsDlgButtonChecked( hDlg, IDIGNORE ) != BST_CHECKED) ); break;
case IDNO: EndDialog(hDlg, (IsDlgButtonChecked( hDlg, IDIGNORE ) == BST_CHECKED) ? IDNO|0x80 : IDNO|0x00 ); return TRUE;
case IDCANCEL:
case IDYES: EndDialog(hDlg, (IsDlgButtonChecked( hDlg, IDIGNORE ) == BST_CHECKED) ? IDYES|0x80 : IDYES|0x00 ); return TRUE;
}
break;
}
return FALSE;
}
//--------------------------------------------------------------------------------------
CDXUTTimer::CDXUTTimer()
{
m_bTimerStopped = true;
m_llQPFTicksPerSec = 0;
m_llStopTime = 0;
m_llLastElapsedTime = 0;
m_llBaseTime = 0;
// Use QueryPerformanceFrequency to get the frequency of the counter
LARGE_INTEGER qwTicksPerSec;
QueryPerformanceFrequency( &qwTicksPerSec );
m_llQPFTicksPerSec = qwTicksPerSec.QuadPart;
}
//--------------------------------------------------------------------------------------
void CDXUTTimer::Reset()
{
LARGE_INTEGER qwTime = GetAdjustedCurrentTime();
m_llBaseTime = qwTime.QuadPart;
m_llLastElapsedTime = qwTime.QuadPart;
m_llStopTime = 0;
m_bTimerStopped = FALSE;
}
//--------------------------------------------------------------------------------------
void CDXUTTimer::Start()
{
// Get the current time
LARGE_INTEGER qwTime;
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_bTimerStopped )
{
LARGE_INTEGER qwTime;
QueryPerformanceCounter( &qwTime );
m_llStopTime = qwTime.QuadPart;
m_llLastElapsedTime = qwTime.QuadPart;
m_bTimerStopped = TRUE;
}
}
//--------------------------------------------------------------------------------------
void CDXUTTimer::Advance()
{
m_llStopTime += m_llQPFTicksPerSec/10;
}
//--------------------------------------------------------------------------------------
double CDXUTTimer::GetAbsoluteTime()
{
LARGE_INTEGER qwTime;
QueryPerformanceCounter( &qwTime );
double fTime = qwTime.QuadPart / (double) m_llQPFTicksPerSec;
return fTime;
}
//--------------------------------------------------------------------------------------
double CDXUTTimer::GetTime()
{
LARGE_INTEGER qwTime = GetAdjustedCurrentTime();
double fAppTime = (double) ( qwTime.QuadPart - m_llBaseTime ) / (double) m_llQPFTicksPerSec;
return fAppTime;
}
//--------------------------------------------------------------------------------------
void CDXUTTimer::GetTimeValues( double* pfTime, double* pfAbsoluteTime, float* pfElapsedTime )
{
assert( pfTime && pfAbsoluteTime && pfElapsedTime );
LARGE_INTEGER qwTime = GetAdjustedCurrentTime();
float fElapsedTime = (float) ((double) ( qwTime.QuadPart - m_llLastElapsedTime ) / (double) m_llQPFTicksPerSec);
m_llLastElapsedTime = qwTime.QuadPart;
// Clamp the timer to non-negative values to ensure the timer is accurate.
// fElapsedTime can be outside this range if processor goes into a
// power save mode or we somehow get shuffled to another processor.
// However, the main thread should call SetThreadAffinityMask to ensure that
// we don't get shuffled to another processor. Other worker threads should NOT call
// SetThreadAffinityMask, but use a shared copy of the timer data gathered from
// the main thread.
if( fElapsedTime < 0.0f )
fElapsedTime = 0.0f;
*pfAbsoluteTime = qwTime.QuadPart / (double) m_llQPFTicksPerSec;
*pfTime = ( qwTime.QuadPart - m_llBaseTime ) / (double) m_llQPFTicksPerSec;
*pfElapsedTime = fElapsedTime;
}
//--------------------------------------------------------------------------------------
double CDXUTTimer::GetElapsedTime()
{
LARGE_INTEGER qwTime = GetAdjustedCurrentTime();
double fElapsedTime = (double) ( qwTime.QuadPart - m_llLastElapsedTime ) / (double) m_llQPFTicksPerSec;
m_llLastElapsedTime = qwTime.QuadPart;
// See the explanation about clamping in CDXUTTimer::GetTimeValues()
if( fElapsedTime < 0.0f )
fElapsedTime = 0.0f;
return fElapsedTime;
}
//--------------------------------------------------------------------------------------
// If stopped, returns time when stopped otherwise returns current time
//--------------------------------------------------------------------------------------
LARGE_INTEGER CDXUTTimer::GetAdjustedCurrentTime()
{
LARGE_INTEGER qwTime;
if( m_llStopTime != 0 )
qwTime.QuadPart = m_llStopTime;
else
QueryPerformanceCounter( &qwTime );
return qwTime;
}
//--------------------------------------------------------------------------------------
bool CDXUTTimer::IsStopped()
{
return m_bTimerStopped;
}
//--------------------------------------------------------------------------------------
// Returns pointer to static media search buffer
//--------------------------------------------------------------------------------------
WCHAR* DXUTMediaSearchPath()
{
static WCHAR s_strMediaSearchPath[MAX_PATH] = {0};
return s_strMediaSearchPath;
}
//--------------------------------------------------------------------------------------
LPCWSTR DXUTGetMediaSearchPath()
{
return DXUTMediaSearchPath();
}
//--------------------------------------------------------------------------------------
HRESULT DXUTSetMediaSearchPath( LPCWSTR strPath )
{
HRESULT hr;
WCHAR* s_strSearchPath = DXUTMediaSearchPath();
hr = StringCchCopy( s_strSearchPath, MAX_PATH, strPath );
if( SUCCEEDED(hr) )
{
// append slash if needed
size_t ch;
hr = StringCchLength( s_strSearchPath, MAX_PATH, &ch );
if( SUCCEEDED(hr) && s_strSearchPath[ch-1] != L'\\')
{
hr = StringCchCat( s_strSearchPath, MAX_PATH, L"\\" );
}
}
return hr;
}
//--------------------------------------------------------------------------------------
// 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 exe name, and exe path
WCHAR strExePath[MAX_PATH] = {0};
WCHAR strExeName[MAX_PATH] = {0};
WCHAR* strLastSlash = NULL;
GetModuleFileName( NULL, strExePath, MAX_PATH );
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -