📄 sdkmisc.cpp
字号:
//--------------------------------------------------------------------------------------
// File: SDKmisc.cpp
//
// Various helper functionality that is shared between SDK samples
//
// Copyright (c) Microsoft Corporation. All rights reserved
//--------------------------------------------------------------------------------------
#include "dxut.h"
#include "SDKmisc.h"
#undef min // use __min instead
#undef max // use __max instead
//--------------------------------------------------------------------------------------
// Global/Static Members
//--------------------------------------------------------------------------------------
CDXUTResourceCache& WINAPI DXUTGetGlobalResourceCache()
{
// Using an accessor function gives control of the construction order
static CDXUTResourceCache cache;
return cache;
}
//--------------------------------------------------------------------------------------
// 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 WINAPI DXUTDisplaySwitchingToREFWarning( DXUTDeviceVersion ver )
{
if( DXUTGetShowMsgBoxOnError() )
{
DWORD dwSkipWarning = 0, dwRead = 0, dwWritten = 0;
HANDLE hFile = NULL;
// Read previous user settings
WCHAR strPath[MAX_PATH];
SHGetFolderPath( DXUTGetHWND(), CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, strPath );
StringCchCat( strPath, MAX_PATH, L"\\DXUT\\SkipRefWarning.dat" );
if( (hFile = CreateFile( strPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL )) != INVALID_HANDLE_VALUE )
{
ReadFile( hFile, &dwSkipWarning, sizeof(DWORD), &dwRead, NULL );
CloseHandle( hFile );
}
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[16]; 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 Shell Dlg 2",
{{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|WS_TABSTOP|BS_DEFPUSHBUTTON,0,80,39,50,14,IDYES},0xFFFF,0x0080,0,0,0}, // Yes button
{{WS_CHILD|WS_VISIBLE|WS_TABSTOP,0,133,39,50,14,IDNO},0xFFFF,0x0080,0,0,0}, // No button
{{WS_CHILD|WS_VISIBLE|WS_TABSTOP|BS_CHECKBOX,0,7,59,70,16,IDIGNORE},0xFFFF,0x0080,0,0,0}, // checkbox
};
int nResult = (int) DialogBoxIndirectParam( DXUTGetHINSTANCE(), (DLGTEMPLATE*)&dtp, DXUTGetHWND(), DisplaySwitchToREFWarningProc, (LPARAM) (ver==DXUT_D3D9_DEVICE) ? 9 : 10 );
if( (nResult & 0x80) == 0x80 ) // "Don't show again" checkbox was checked
{
// Save user settings
dwSkipWarning = 1;
SHGetFolderPath( DXUTGetHWND(), CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, strPath );
StringCchCat( strPath, MAX_PATH, L"\\DXUT" );
CreateDirectory( strPath, NULL );
StringCchCat( strPath, MAX_PATH, L"\\SkipRefWarning.dat" );
if( (hFile = CreateFile( strPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL )) != INVALID_HANDLE_VALUE )
{
WriteFile( hFile, &dwSkipWarning, sizeof(DWORD), &dwWritten, NULL );
CloseHandle( hFile );
}
}
// 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));
WCHAR sz[512]; StringCchPrintf( sz, 512, L"This program needs to use the Direct3D %d reference device. This device implements the entire Direct3D %d feature set, but runs very slowly. Do you wish to continue?", lParam, lParam );
SetDlgItemText( hDlg, 0x101, sz );
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;
}
//--------------------------------------------------------------------------------------
// Returns pointer to static media search buffer
//--------------------------------------------------------------------------------------
WCHAR* DXUTMediaSearchPath()
{
static WCHAR s_strMediaSearchPath[MAX_PATH] = {0};
return s_strMediaSearchPath;
}
//--------------------------------------------------------------------------------------
LPCWSTR WINAPI DXUTGetMediaSearchPath()
{
return DXUTMediaSearchPath();
}
//--------------------------------------------------------------------------------------
HRESULT WINAPI 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 WINAPI 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 );
strExePath[MAX_PATH-1]=0;
strLastSlash = wcsrchr( strExePath, TEXT('\\') );
if( strLastSlash )
{
StringCchCopy( strExeName, MAX_PATH, &strLastSlash[1] );
// 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%
// Typical directory search
bFound = DXUTFindMediaSearchTypicalDirs( strDestPath, cchDest, strFilename, strExePath, strExeName );
if( bFound )
return S_OK;
// Typical directory search again, but also look in a subdir called "\media\"
StringCchPrintf( strSearchFor, MAX_PATH, L"media\\%s", strFilename );
bFound = DXUTFindMediaSearchTypicalDirs( strDestPath, cchDest, strSearchFor, strExePath, strExeName );
if( bFound )
return S_OK;
WCHAR strLeafName[MAX_PATH] = {0};
// Search all parent directories starting at .\ and using strFilename as the leaf name
StringCchCopy( strLeafName, MAX_PATH, strFilename );
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
StringCchPrintf( strLeafName, MAX_PATH, L"media\\%s", strFilename );
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
StringCchCopy( strDestPath, cchDest, strFilename );
return DXUTERR_MEDIANOTFOUND;
}
//--------------------------------------------------------------------------------------
// Search a set of typical directories
//--------------------------------------------------------------------------------------
bool DXUTFindMediaSearchTypicalDirs( WCHAR* strSearchPath, int cchSearch, LPCWSTR strLeaf,
WCHAR* strExePath, WCHAR* strExeName )
{
// Typical directories:
// .\
// ..\
// ..\..\
// %EXE_DIR%\
// %EXE_DIR%\..\
// %EXE_DIR%\..\..\
// %EXE_DIR%\..\%EXE_NAME%
// %EXE_DIR%\..\..\%EXE_NAME%
// DXSDK media path
// Search in .\
StringCchCopy( strSearchPath, cchSearch, strLeaf );
if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
return true;
// Search in ..\
StringCchPrintf( strSearchPath, cchSearch, L"..\\%s", strLeaf );
if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
return true;
// Search in ..\..\
StringCchPrintf( strSearchPath, cchSearch, L"..\\..\\%s", strLeaf );
if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
return true;
// Search in ..\..\
StringCchPrintf( strSearchPath, cchSearch, L"..\\..\\%s", strLeaf );
if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
return true;
// Search in the %EXE_DIR%\
StringCchPrintf( strSearchPath, cchSearch, L"%s\\%s", strExePath, strLeaf );
if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
return true;
// Search in the %EXE_DIR%\..\
StringCchPrintf( strSearchPath, cchSearch, L"%s\\..\\%s", strExePath, strLeaf );
if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
return true;
// Search in the %EXE_DIR%\..\..\
StringCchPrintf( strSearchPath, cchSearch, L"%s\\..\\..\\%s", strExePath, strLeaf );
if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
return true;
// Search in "%EXE_DIR%\..\%EXE_NAME%\". This matches the DirectX SDK layout
StringCchPrintf( strSearchPath, cchSearch, L"%s\\..\\%s\\%s", strExePath, strExeName, strLeaf );
if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
return true;
// Search in "%EXE_DIR%\..\..\%EXE_NAME%\". This matches the DirectX SDK layout
StringCchPrintf( strSearchPath, cchSearch, L"%s\\..\\..\\%s\\%s", strExePath, strExeName, strLeaf );
if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
return true;
// Search in media search dir
WCHAR* s_strSearchPath = DXUTMediaSearchPath();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -