dxutil.cpp
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:25k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. #ifndef STRICT
  2. #define STRICT
  3. #endif 
  4. #include <windows.h>
  5. #include <mmsystem.h>
  6. #include <tchar.h>
  7. #include <stdio.h> 
  8. #include <stdarg.h>
  9. #include "DXUtil.h"
  10. #ifdef UNICODE
  11.     typedef HINSTANCE (WINAPI* LPShellExecute)(HWND hwnd, LPCWSTR lpOperation, LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd);
  12. #else
  13.     typedef HINSTANCE (WINAPI* LPShellExecute)(HWND hwnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, INT nShowCmd);
  14. #endif
  15. #ifndef UNDER_CE
  16. HRESULT DXUtil_GetDXSDKMediaPathCch( TCHAR* strDest, int cchDest )
  17. {
  18.     if( strDest == NULL || cchDest < 1 )
  19.         return E_INVALIDARG;
  20.     lstrcpy( strDest, TEXT("") );
  21.     
  22.     HKEY  hKey;
  23.     LONG lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  24.                                 _T("Software\Microsoft\DirectX SDK"),
  25.                                 0, KEY_READ, &hKey );
  26.     if( ERROR_SUCCESS != lResult )
  27.         return E_FAIL;
  28.     DWORD dwType;
  29.     DWORD dwSize = cchDest * sizeof(TCHAR);
  30.     lResult = RegQueryValueEx( hKey, _T("DX9SDK Samples Path"), NULL,
  31.                               &dwType, (BYTE*)strDest, &dwSize );
  32.     strDest[cchDest-1] = 0; 
  33.     RegCloseKey( hKey );
  34.     if( ERROR_SUCCESS != lResult )
  35.         return E_FAIL;
  36.     const TCHAR* strMedia = _T("\Media\");
  37.     if( lstrlen(strDest) + lstrlen(strMedia) < cchDest )
  38.         _tcscat( strDest, strMedia );
  39.     else
  40.         return E_INVALIDARG;
  41.     return S_OK;
  42. }
  43. #endif 
  44. #ifndef UNDER_CE
  45. HRESULT DXUtil_FindMediaFileCch( TCHAR* strDestPath, int cchDest, TCHAR* strFilename )
  46. {
  47.     HRESULT hr;
  48.     HANDLE file;
  49.     TCHAR* strShortNameTmp = NULL;
  50.     TCHAR strShortName[MAX_PATH];
  51.     int cchPath;
  52.     if( NULL==strFilename || NULL==strDestPath || cchDest < 1 )
  53.         return E_INVALIDARG;
  54.     lstrcpy( strDestPath, TEXT("") );
  55.     lstrcpy( strShortName, TEXT("") );
  56.     
  57.     cchPath = GetFullPathName(strFilename, cchDest, strDestPath, &strShortNameTmp);
  58.     if ((cchPath == 0) || (cchDest <= cchPath))
  59.         return E_FAIL;
  60.     if( strShortNameTmp )
  61.         lstrcpyn( strShortName, strShortNameTmp, MAX_PATH );
  62.     
  63.     file = CreateFile( strDestPath, GENERIC_READ, FILE_SHARE_READ, NULL, 
  64.                        OPEN_EXISTING, 0, NULL );
  65.     if( INVALID_HANDLE_VALUE != file )
  66.     {
  67.         CloseHandle( file );
  68.         return S_OK;
  69.     }
  70.     
  71.     
  72.     file = CreateFile( strShortName, GENERIC_READ, FILE_SHARE_READ, NULL, 
  73.                        OPEN_EXISTING, 0, NULL );
  74.     if( INVALID_HANDLE_VALUE != file )
  75.     {
  76.         _tcsncpy( strDestPath, strShortName, cchDest );
  77.         strDestPath[cchDest-1] = 0; 
  78.         CloseHandle( file );
  79.         return S_OK;
  80.     }
  81.     
  82.     
  83.     if( FAILED( hr = DXUtil_GetDXSDKMediaPathCch( strDestPath, cchDest ) ) )
  84.         return hr;
  85.     if( lstrlen(strDestPath) + lstrlen(strShortName) < cchDest )
  86.         lstrcat( strDestPath, strShortName );
  87.     else
  88.         return E_INVALIDARG;
  89.     file = CreateFile( strDestPath, GENERIC_READ, FILE_SHARE_READ, NULL, 
  90.                        OPEN_EXISTING, 0, NULL );
  91.     if( INVALID_HANDLE_VALUE != file )
  92.     {
  93.         CloseHandle( file );
  94.         return S_OK;
  95.     }
  96.     
  97.     _tcsncpy( strDestPath, strFilename, cchDest );
  98.     strDestPath[cchDest-1] = 0; 
  99.     return HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND );
  100. }
  101. #endif 
  102. HRESULT DXUtil_ReadStringRegKeyCch( HKEY hKey, TCHAR* strRegName, TCHAR* strDest, 
  103.                                     DWORD cchDest, TCHAR* strDefault )
  104. {
  105.     DWORD dwType;
  106.     DWORD cbDest = cchDest * sizeof(TCHAR);
  107.     if( ERROR_SUCCESS != RegQueryValueEx( hKey, strRegName, 0, &dwType, 
  108.                                           (BYTE*)strDest, &cbDest ) )
  109.     {
  110.         _tcsncpy( strDest, strDefault, cchDest );
  111.         strDest[cchDest-1] = 0;
  112.         if( dwType != REG_SZ )
  113.             return E_FAIL;
  114.         return S_OK;
  115.     }
  116.     return E_FAIL;
  117. }
  118. HRESULT DXUtil_WriteStringRegKey( HKEY hKey, TCHAR* strRegName,
  119.                                   TCHAR* strValue )
  120. {
  121.     if( NULL == strValue )
  122.         return E_INVALIDARG;
  123.         
  124.     DWORD cbValue = ((DWORD)_tcslen(strValue)+1) * sizeof(TCHAR);
  125.     if( ERROR_SUCCESS != RegSetValueEx( hKey, strRegName, 0, REG_SZ, 
  126.                                         (BYTE*)strValue, cbValue ) )
  127.         return E_FAIL;
  128.     return S_OK;
  129. }
  130. HRESULT DXUtil_ReadIntRegKey( HKEY hKey, TCHAR* strRegName, DWORD* pdwDest, 
  131.                               DWORD dwDefault )
  132. {
  133.     DWORD dwType;
  134.     DWORD dwLength = sizeof(DWORD);
  135.     if( ERROR_SUCCESS != RegQueryValueEx( hKey, strRegName, 0, &dwType, 
  136.                                           (BYTE*)pdwDest, &dwLength ) )
  137.     {
  138.         *pdwDest = dwDefault;
  139.         if( dwType != REG_DWORD )
  140.             return E_FAIL;
  141.         return S_OK;
  142.     }
  143.     return E_FAIL;
  144. }
  145. HRESULT DXUtil_WriteIntRegKey( HKEY hKey, TCHAR* strRegName, DWORD dwValue )
  146. {
  147.     if( ERROR_SUCCESS != RegSetValueEx( hKey, strRegName, 0, REG_DWORD, 
  148.                                         (BYTE*)&dwValue, sizeof(DWORD) ) )
  149.         return E_FAIL;
  150.     return S_OK;
  151. }
  152. HRESULT DXUtil_ReadBoolRegKey( HKEY hKey, TCHAR* strRegName, BOOL* pbDest, 
  153.                               BOOL bDefault )
  154. {
  155.     DWORD dwType;
  156.     DWORD dwLength = sizeof(BOOL);
  157.     if( ERROR_SUCCESS != RegQueryValueEx( hKey, strRegName, 0, &dwType, 
  158.                                           (BYTE*)pbDest, &dwLength ) )
  159.     {
  160.         *pbDest = bDefault;
  161.         if( dwType != REG_DWORD )
  162.             return E_FAIL;
  163.         return S_OK;
  164.     }
  165.     return E_FAIL;
  166. }
  167. HRESULT DXUtil_WriteBoolRegKey( HKEY hKey, TCHAR* strRegName, BOOL bValue )
  168. {
  169.     if( ERROR_SUCCESS != RegSetValueEx( hKey, strRegName, 0, REG_DWORD, 
  170.                                         (BYTE*)&bValue, sizeof(BOOL) ) )
  171.         return E_FAIL;
  172.     return S_OK;
  173. }
  174. HRESULT DXUtil_ReadGuidRegKey( HKEY hKey, TCHAR* strRegName, GUID* pGuidDest, 
  175.                                GUID& guidDefault )
  176. {
  177.     DWORD dwType;
  178.     DWORD dwLength = sizeof(GUID);
  179.     if( ERROR_SUCCESS != RegQueryValueEx( hKey, strRegName, 0, &dwType, 
  180.                                           (LPBYTE) pGuidDest, &dwLength ) )
  181.     {
  182.         *pGuidDest = guidDefault;
  183.         if( dwType != REG_BINARY )
  184.             return E_FAIL;
  185.         return S_OK;
  186.     }
  187.     return E_FAIL;
  188. }
  189. HRESULT DXUtil_WriteGuidRegKey( HKEY hKey, TCHAR* strRegName, GUID guidValue )
  190. {
  191.     if( ERROR_SUCCESS != RegSetValueEx( hKey, strRegName, 0, REG_BINARY, 
  192.                                         (BYTE*)&guidValue, sizeof(GUID) ) )
  193.         return E_FAIL;
  194.     return S_OK;
  195. }
  196. FLOAT __stdcall DXUtil_Timer( TIMER_COMMAND command )
  197. {
  198.     static BOOL     m_bTimerInitialized = FALSE;
  199.     static BOOL     m_bUsingQPF         = FALSE;
  200.     static BOOL     m_bTimerStopped     = TRUE;
  201.     static LONGLONG m_llQPFTicksPerSec  = 0;
  202.     
  203.     if( FALSE == m_bTimerInitialized )
  204.     {
  205.         m_bTimerInitialized = TRUE;
  206.         
  207.         
  208.         LARGE_INTEGER qwTicksPerSec;
  209.         m_bUsingQPF = QueryPerformanceFrequency( &qwTicksPerSec );
  210.         if( m_bUsingQPF )
  211.             m_llQPFTicksPerSec = qwTicksPerSec.QuadPart;
  212.     }
  213.     if( m_bUsingQPF )
  214.     {
  215.         static LONGLONG m_llStopTime        = 0;
  216.         static LONGLONG m_llLastElapsedTime = 0;
  217.         static LONGLONG m_llBaseTime        = 0;
  218.         double fTime;
  219.         double fElapsedTime;
  220.         LARGE_INTEGER qwTime;
  221.         
  222.         
  223.         
  224.         if( m_llStopTime != 0 && command != TIMER_START && command != TIMER_GETABSOLUTETIME)
  225.             qwTime.QuadPart = m_llStopTime;
  226.         else
  227.             QueryPerformanceCounter( &qwTime );
  228.         
  229.         if( command == TIMER_GETELAPSEDTIME )
  230.         {
  231.             fElapsedTime = (double) ( qwTime.QuadPart - m_llLastElapsedTime ) / (double) m_llQPFTicksPerSec;
  232.             m_llLastElapsedTime = qwTime.QuadPart;
  233.             return (FLOAT) fElapsedTime;
  234.         }
  235.     
  236.         
  237.         if( command == TIMER_GETAPPTIME )
  238.         {
  239.             double fAppTime = (double) ( qwTime.QuadPart - m_llBaseTime ) / (double) m_llQPFTicksPerSec;
  240.             return (FLOAT) fAppTime;
  241.         }
  242.     
  243.         
  244.         if( command == TIMER_RESET )
  245.         {
  246.             m_llBaseTime        = qwTime.QuadPart;
  247.             m_llLastElapsedTime = qwTime.QuadPart;
  248.             m_llStopTime        = 0;
  249.             m_bTimerStopped     = FALSE;
  250.             return 0.0f;
  251.         }
  252.     
  253.         
  254.         if( command == TIMER_START )
  255.         {
  256.             if( m_bTimerStopped )
  257.                 m_llBaseTime += qwTime.QuadPart - m_llStopTime;
  258.             m_llStopTime = 0;
  259.             m_llLastElapsedTime = qwTime.QuadPart;
  260.             m_bTimerStopped = FALSE;
  261.             return 0.0f;
  262.         }
  263.     
  264.         
  265.         if( command == TIMER_STOP )
  266.         {
  267.             if( !m_bTimerStopped )
  268.             {
  269.                 m_llStopTime = qwTime.QuadPart;
  270.                 m_llLastElapsedTime = qwTime.QuadPart;
  271.                 m_bTimerStopped = TRUE;
  272.             }
  273.             return 0.0f;
  274.         }
  275.     
  276.         
  277.         if( command == TIMER_ADVANCE )
  278.         {
  279.             m_llStopTime += m_llQPFTicksPerSec/10;
  280.             return 0.0f;
  281.         }
  282.         if( command == TIMER_GETABSOLUTETIME )
  283.         {
  284.             fTime = qwTime.QuadPart / (double) m_llQPFTicksPerSec;
  285.             return (FLOAT) fTime;
  286.         }
  287.         return -1.0f; 
  288.     }
  289.     else
  290.     {
  291.         
  292.         static double m_fLastElapsedTime  = 0.0;
  293.         static double m_fBaseTime         = 0.0;
  294.         static double m_fStopTime         = 0.0;
  295.         double fTime;
  296.         double fElapsedTime;
  297.         
  298.         
  299.         
  300.         if( m_fStopTime != 0.0 && command != TIMER_START && command != TIMER_GETABSOLUTETIME)
  301.             fTime = m_fStopTime;
  302.         else
  303.             fTime = GETTIMESTAMP() * 0.001;
  304.     
  305.         
  306.         if( command == TIMER_GETELAPSEDTIME )
  307.         {   
  308.             fElapsedTime = (double) (fTime - m_fLastElapsedTime);
  309.             m_fLastElapsedTime = fTime;
  310.             return (FLOAT) fElapsedTime;
  311.         }
  312.     
  313.         
  314.         if( command == TIMER_GETAPPTIME )
  315.         {
  316.             return (FLOAT) (fTime - m_fBaseTime);
  317.         }
  318.     
  319.         
  320.         if( command == TIMER_RESET )
  321.         {
  322.             m_fBaseTime         = fTime;
  323.             m_fLastElapsedTime  = fTime;
  324.             m_fStopTime         = 0;
  325.             m_bTimerStopped     = FALSE;
  326.             return 0.0f;
  327.         }
  328.     
  329.         
  330.         if( command == TIMER_START )
  331.         {
  332.             if( m_bTimerStopped )
  333.                 m_fBaseTime += fTime - m_fStopTime;
  334.             m_fStopTime = 0.0f;
  335.             m_fLastElapsedTime  = fTime;
  336.             m_bTimerStopped = FALSE;
  337.             return 0.0f;
  338.         }
  339.     
  340.         
  341.         if( command == TIMER_STOP )
  342.         {
  343.             if( !m_bTimerStopped )
  344.             {
  345.                 m_fStopTime = fTime;
  346.                 m_fLastElapsedTime  = fTime;
  347.                 m_bTimerStopped = TRUE;
  348.             }
  349.             return 0.0f;
  350.         }
  351.     
  352.         
  353.         if( command == TIMER_ADVANCE )
  354.         {
  355.             m_fStopTime += 0.1f;
  356.             return 0.0f;
  357.         }
  358.         if( command == TIMER_GETABSOLUTETIME )
  359.         {
  360.             return (FLOAT) fTime;
  361.         }
  362.         return -1.0f; 
  363.     }
  364. }
  365. HRESULT DXUtil_ConvertAnsiStringToWideCch( WCHAR* wstrDestination, const CHAR* strSource, 
  366.                                      int cchDestChar )
  367. {
  368.     if( wstrDestination==NULL || strSource==NULL || cchDestChar < 1 )
  369.         return E_INVALIDARG;
  370.     int nResult = MultiByteToWideChar( CP_ACP, 0, strSource, -1, 
  371.                                        wstrDestination, cchDestChar );
  372.     wstrDestination[cchDestChar-1] = 0;
  373.     
  374.     if( nResult == 0 )
  375.         return E_FAIL;
  376.     return S_OK;
  377. }
  378. HRESULT DXUtil_ConvertWideStringToAnsiCch( CHAR* strDestination, const WCHAR* wstrSource, 
  379.                                      int cchDestChar )
  380. {
  381.     if( strDestination==NULL || wstrSource==NULL || cchDestChar < 1 )
  382.         return E_INVALIDARG;
  383.     int nResult = WideCharToMultiByte( CP_ACP, 0, wstrSource, -1, strDestination, 
  384.                                        cchDestChar*sizeof(CHAR), NULL, NULL );
  385.     strDestination[cchDestChar-1] = 0;
  386.     
  387.     if( nResult == 0 )
  388.         return E_FAIL;
  389.     return S_OK;
  390. }
  391. HRESULT DXUtil_ConvertGenericStringToAnsiCch( CHAR* strDestination, const TCHAR* tstrSource, 
  392.                                            int cchDestChar )
  393. {
  394.     if( strDestination==NULL || tstrSource==NULL || cchDestChar < 1 )
  395.         return E_INVALIDARG;
  396. #ifdef _UNICODE
  397.     return DXUtil_ConvertWideStringToAnsiCch( strDestination, tstrSource, cchDestChar );
  398. #else
  399.     strncpy( strDestination, tstrSource, cchDestChar );
  400.     strDestination[cchDestChar-1] = '';
  401.     return S_OK;
  402. #endif   
  403. }
  404. HRESULT DXUtil_ConvertGenericStringToWideCch( WCHAR* wstrDestination, const TCHAR* tstrSource, 
  405.                                            int cchDestChar )
  406. {
  407.     if( wstrDestination==NULL || tstrSource==NULL || cchDestChar < 1 )
  408.         return E_INVALIDARG;
  409. #ifdef _UNICODE
  410.     wcsncpy( wstrDestination, tstrSource, cchDestChar );
  411.     wstrDestination[cchDestChar-1] = L'';
  412.     return S_OK;
  413. #else
  414.     return DXUtil_ConvertAnsiStringToWideCch( wstrDestination, tstrSource, cchDestChar );
  415. #endif    
  416. }
  417. HRESULT DXUtil_ConvertAnsiStringToGenericCch( TCHAR* tstrDestination, const CHAR* strSource, 
  418.                                            int cchDestChar )
  419. {
  420.     if( tstrDestination==NULL || strSource==NULL || cchDestChar < 1 )
  421.         return E_INVALIDARG;
  422.         
  423. #ifdef _UNICODE
  424.     return DXUtil_ConvertAnsiStringToWideCch( tstrDestination, strSource, cchDestChar );
  425. #else
  426.     strncpy( tstrDestination, strSource, cchDestChar );
  427.     tstrDestination[cchDestChar-1] = '';
  428.     return S_OK;
  429. #endif    
  430. }
  431. HRESULT DXUtil_ConvertWideStringToGenericCch( TCHAR* tstrDestination, const WCHAR* wstrSource, 
  432.                                            int cchDestChar )
  433. {
  434.     if( tstrDestination==NULL || wstrSource==NULL || cchDestChar < 1 )
  435.         return E_INVALIDARG;
  436. #ifdef _UNICODE
  437.     wcsncpy( tstrDestination, wstrSource, cchDestChar );
  438.     tstrDestination[cchDestChar-1] = L'';    
  439.     return S_OK;
  440. #else
  441.     return DXUtil_ConvertWideStringToAnsiCch( tstrDestination, wstrSource, cchDestChar );
  442. #endif
  443. }
  444. VOID DXUtil_LaunchReadme( HWND hWnd, TCHAR* strLoc )
  445. {
  446. #ifdef UNDER_CE
  447.     
  448.     MessageBox( hWnd, TEXT("For operating instructions, please open the ")
  449.                       TEXT("readme.txt file included with the project."),
  450.                 TEXT("DirectX SDK Sample"), MB_ICONWARNING | MB_OK );
  451.     return;
  452. #else 
  453.     bool bSuccess = false;
  454.     bool bFound = false;
  455.     TCHAR strReadmePath[1024];
  456.     TCHAR strExeName[MAX_PATH];
  457.     TCHAR strExePath[MAX_PATH];
  458.     TCHAR strSamplePath[MAX_PATH];
  459.     TCHAR* strLastSlash = NULL;
  460.     lstrcpy( strReadmePath, TEXT("") );
  461.     lstrcpy( strExePath, TEXT("") );
  462.     lstrcpy( strExeName, TEXT("") );
  463.     lstrcpy( strSamplePath, TEXT("") );
  464.     
  465.     if( strLoc )
  466.     {
  467.         HKEY  hKey;
  468.         LONG lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  469.                                     _T("Software\Microsoft\DirectX SDK"),
  470.                                     0, KEY_READ, &hKey );
  471.         if( ERROR_SUCCESS == lResult )
  472.         {
  473.             DWORD dwType;
  474.             DWORD dwSize = MAX_PATH * sizeof(TCHAR);
  475.             lResult = RegQueryValueEx( hKey, _T("DX9SDK Samples Path"), NULL,
  476.                                       &dwType, (BYTE*)strSamplePath, &dwSize );
  477.             strSamplePath[MAX_PATH-1] = 0; 
  478.             
  479.             if( ERROR_SUCCESS == lResult )
  480.             {
  481.                 _sntprintf( strReadmePath, 1023, TEXT("%s\C++\%s\readme.txt"), 
  482.                             strSamplePath, strLoc );
  483.                 strReadmePath[1023] = 0;
  484.                 if( GetFileAttributes( strReadmePath ) != 0xFFFFFFFF )
  485.                     bFound = TRUE;
  486.             }
  487.         }
  488.         RegCloseKey( hKey );
  489.     }
  490.     
  491.     GetModuleFileName( NULL, strExePath, MAX_PATH );
  492.     strExePath[MAX_PATH-1]=0;
  493.     strLastSlash = _tcsrchr( strExePath, TEXT('\') );
  494.     if( strLastSlash )
  495.     {
  496.         _tcsncpy( strExeName, &strLastSlash[1], MAX_PATH );
  497.         strExeName[MAX_PATH-1]=0;
  498.         
  499.         *strLastSlash = 0;
  500.         
  501.         strLastSlash = _tcsrchr( strExeName, TEXT('.') );
  502.         if( strLastSlash )
  503.             *strLastSlash = 0;
  504.     }
  505.     if( !bFound )
  506.     {
  507.         
  508.         _tcscpy( strReadmePath, strExePath );
  509.         strLastSlash = _tcsrchr( strReadmePath, TEXT('\') );
  510.         if( strLastSlash )
  511.             *strLastSlash = 0;
  512.         lstrcat( strReadmePath, TEXT("\") );
  513.         lstrcat( strReadmePath, strExeName );
  514.         lstrcat( strReadmePath, TEXT("\readme.txt") );
  515.         if( GetFileAttributes( strReadmePath ) != 0xFFFFFFFF )
  516.             bFound = TRUE;
  517.     }
  518.     if( !bFound )
  519.     {
  520.         
  521.         _tcscpy( strReadmePath, strExePath );
  522.         lstrcat( strReadmePath, TEXT("\readme.txt") );
  523.         if( GetFileAttributes( strReadmePath ) != 0xFFFFFFFF )
  524.             bFound = TRUE;
  525.     }
  526.     if( !bFound )
  527.     {
  528.         
  529.         _tcscpy( strReadmePath, strExePath );
  530.         strLastSlash = _tcsrchr( strReadmePath, TEXT('\') );
  531.         if( strLastSlash )
  532.             *strLastSlash = 0;
  533.         lstrcat( strReadmePath, TEXT("\readme.txt") );
  534.         if( GetFileAttributes( strReadmePath ) != 0xFFFFFFFF )
  535.             bFound = TRUE;
  536.     }
  537.     if( !bFound )
  538.     {
  539.         
  540.         _tcscpy( strReadmePath, strExePath );
  541.         strLastSlash = _tcsrchr( strReadmePath, TEXT('\') );
  542.         if( strLastSlash )
  543.             *strLastSlash = 0;
  544.         strLastSlash = _tcsrchr( strReadmePath, TEXT('\') );
  545.         if( strLastSlash )
  546.             *strLastSlash = 0;
  547.         lstrcat( strReadmePath, TEXT("\readme.txt") );
  548.         if( GetFileAttributes( strReadmePath ) != 0xFFFFFFFF )
  549.             bFound = TRUE;
  550.     }
  551.     if( bFound )
  552.     {
  553.         
  554.         
  555.         LPShellExecute pShellExecute = NULL;
  556.         HINSTANCE hInstShell32 = LoadLibrary(TEXT("shell32.dll"));
  557.         if (hInstShell32 != NULL)
  558.         {
  559. #ifdef UNICODE
  560.             pShellExecute = (LPShellExecute)GetProcAddress(hInstShell32, _TWINCE("ShellExecuteW"));
  561. #else
  562.             pShellExecute = (LPShellExecute)GetProcAddress(hInstShell32, _TWINCE("ShellExecuteA"));
  563. #endif
  564.             if( pShellExecute != NULL )
  565.             {
  566.                 if( pShellExecute( hWnd, TEXT("open"), strReadmePath, NULL, NULL, SW_SHOW ) > (HINSTANCE) 32 )
  567.                     bSuccess = true;
  568.             }
  569.             FreeLibrary(hInstShell32);
  570.         }
  571.     }
  572.     if( !bSuccess )
  573.     {
  574.         
  575.         MessageBox( hWnd, TEXT("Could not find readme.txt"), 
  576.                     TEXT("DirectX SDK Sample"), MB_ICONWARNING | MB_OK );
  577.     }
  578. #endif 
  579. }
  580. VOID DXUtil_Trace( TCHAR* strMsg, ... )
  581. {
  582. #if defined(DEBUG) | defined(_DEBUG)
  583.     TCHAR strBuffer[512];
  584.     
  585.     va_list args;
  586.     va_start(args, strMsg);
  587.     _vsntprintf( strBuffer, 512, strMsg, args );
  588.     va_end(args);
  589.     OutputDebugString( strBuffer );
  590. #else
  591.     UNREFERENCED_PARAMETER(strMsg);
  592. #endif
  593. }
  594. HRESULT DXUtil_ConvertStringToGUID( const TCHAR* strSrc, GUID* pGuidDest )
  595. {
  596.     UINT aiTmp[10];
  597.     if( _stscanf( strSrc, TEXT("{%8X-%4X-%4X-%2X%2X-%2X%2X%2X%2X%2X%2X}"),
  598.                     &pGuidDest->Data1, 
  599.                     &aiTmp[0], &aiTmp[1], 
  600.                     &aiTmp[2], &aiTmp[3],
  601.                     &aiTmp[4], &aiTmp[5],
  602.                     &aiTmp[6], &aiTmp[7],
  603.                     &aiTmp[8], &aiTmp[9] ) != 11 )
  604.     {
  605.         ZeroMemory( pGuidDest, sizeof(GUID) );
  606.         return E_FAIL;
  607.     }
  608.     else
  609.     {
  610.         pGuidDest->Data2       = (USHORT) aiTmp[0];
  611.         pGuidDest->Data3       = (USHORT) aiTmp[1];
  612.         pGuidDest->Data4[0]    = (BYTE) aiTmp[2];
  613.         pGuidDest->Data4[1]    = (BYTE) aiTmp[3];
  614.         pGuidDest->Data4[2]    = (BYTE) aiTmp[4];
  615.         pGuidDest->Data4[3]    = (BYTE) aiTmp[5];
  616.         pGuidDest->Data4[4]    = (BYTE) aiTmp[6];
  617.         pGuidDest->Data4[5]    = (BYTE) aiTmp[7];
  618.         pGuidDest->Data4[6]    = (BYTE) aiTmp[8];
  619.         pGuidDest->Data4[7]    = (BYTE) aiTmp[9];
  620.         return S_OK;
  621.     }
  622. }
  623. HRESULT DXUtil_ConvertGUIDToStringCch( const GUID* pGuidSrc, TCHAR* strDest, int cchDestChar )
  624. {
  625.     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}"),
  626.                pGuidSrc->Data1, pGuidSrc->Data2, pGuidSrc->Data3,
  627.                pGuidSrc->Data4[0], pGuidSrc->Data4[1],
  628.                pGuidSrc->Data4[2], pGuidSrc->Data4[3],
  629.                pGuidSrc->Data4[4], pGuidSrc->Data4[5],
  630.                pGuidSrc->Data4[6], pGuidSrc->Data4[7] );
  631.     if( nResult < 0 )
  632.         return E_FAIL;
  633.     return S_OK;
  634. }
  635. CArrayList::CArrayList( ArrayListType Type, UINT BytesPerEntry )
  636. {
  637.     if( Type == AL_REFERENCE )
  638.         BytesPerEntry = sizeof(void*);
  639.     m_ArrayListType = Type;
  640.     m_pData = NULL;
  641.     m_BytesPerEntry = BytesPerEntry;
  642.     m_NumEntries = 0;
  643.     m_NumEntriesAllocated = 0;
  644. }
  645. CArrayList::~CArrayList( void )
  646. {
  647.     if( m_pData != NULL )
  648.         delete[] m_pData;
  649. }
  650. HRESULT CArrayList::Add( void* pEntry )
  651. {
  652.     if( m_BytesPerEntry == 0 )
  653.         return E_FAIL;
  654.     if( m_pData == NULL || m_NumEntries + 1 > m_NumEntriesAllocated )
  655.     {
  656.         void* pDataNew;
  657.         UINT NumEntriesAllocatedNew;
  658.         if( m_NumEntriesAllocated == 0 )
  659.             NumEntriesAllocatedNew = 16;
  660.         else
  661.             NumEntriesAllocatedNew = m_NumEntriesAllocated * 2;
  662.         pDataNew = new BYTE[NumEntriesAllocatedNew * m_BytesPerEntry];
  663.         if( pDataNew == NULL )
  664.             return E_OUTOFMEMORY;
  665.         if( m_pData != NULL )
  666.         {
  667.             CopyMemory( pDataNew, m_pData, m_NumEntries * m_BytesPerEntry );
  668.             delete[] m_pData;
  669.         }
  670.         m_pData = pDataNew;
  671.         m_NumEntriesAllocated = NumEntriesAllocatedNew;
  672.     }
  673.     if( m_ArrayListType == AL_VALUE )
  674.         CopyMemory( (BYTE*)m_pData + (m_NumEntries * m_BytesPerEntry), pEntry, m_BytesPerEntry );
  675.     else
  676.         *(((void**)m_pData) + m_NumEntries) = pEntry;
  677.     m_NumEntries++;
  678.     return S_OK;
  679. }
  680. void CArrayList::Remove( UINT Entry )
  681. {
  682.     
  683.     m_NumEntries--;
  684.     
  685.     BYTE* pData = (BYTE*)m_pData + (Entry * m_BytesPerEntry);
  686.     
  687.     MoveMemory( pData, pData + m_BytesPerEntry, ( m_NumEntries - Entry ) * m_BytesPerEntry );
  688. }
  689. void* CArrayList::GetPtr( UINT Entry )
  690. {
  691.     if( m_ArrayListType == AL_VALUE )
  692.         return (BYTE*)m_pData + (Entry * m_BytesPerEntry);
  693.     else
  694.         return *(((void**)m_pData) + Entry);
  695. }
  696. bool CArrayList::Contains( void* pEntryData )
  697. {
  698.     for( UINT iEntry = 0; iEntry < m_NumEntries; iEntry++ )
  699.     {
  700.         if( m_ArrayListType == AL_VALUE )
  701.         {
  702.             if( memcmp( GetPtr(iEntry), pEntryData, m_BytesPerEntry ) == 0 )
  703.                 return true;
  704.         }
  705.         else
  706.         {
  707.             if( GetPtr(iEntry) == pEntryData )
  708.                 return true;
  709.         }
  710.     }
  711.     return false;
  712. }
  713. HRESULT DXUtil_ConvertAnsiStringToWideCb( WCHAR* wstrDestination, const CHAR* strSource, int cbDestChar )
  714. {
  715.     return DXUtil_ConvertAnsiStringToWideCch( wstrDestination, strSource, cbDestChar / sizeof(WCHAR) );
  716. }
  717. HRESULT DXUtil_ConvertWideStringToAnsiCb( CHAR* strDestination, const WCHAR* wstrSource, int cbDestChar )
  718. {
  719.     return DXUtil_ConvertWideStringToAnsiCch( strDestination, wstrSource, cbDestChar / sizeof(CHAR) );
  720. }
  721. HRESULT DXUtil_ConvertGenericStringToAnsiCb( CHAR* strDestination, const TCHAR* tstrSource, int cbDestChar )
  722. {
  723.     return DXUtil_ConvertGenericStringToAnsiCch( strDestination, tstrSource, cbDestChar / sizeof(CHAR) );
  724. }
  725. HRESULT DXUtil_ConvertGenericStringToWideCb( WCHAR* wstrDestination, const TCHAR* tstrSource, int cbDestChar )
  726. {
  727.     return DXUtil_ConvertGenericStringToWideCch( wstrDestination, tstrSource, cbDestChar / sizeof(WCHAR) );
  728. }
  729. HRESULT DXUtil_ConvertAnsiStringToGenericCb( TCHAR* tstrDestination, const CHAR* strSource, int cbDestChar )
  730. {
  731.     return DXUtil_ConvertAnsiStringToGenericCch( tstrDestination, strSource, cbDestChar / sizeof(TCHAR) );
  732. }
  733. HRESULT DXUtil_ConvertWideStringToGenericCb( TCHAR* tstrDestination, const WCHAR* wstrSource, int cbDestChar )
  734. {
  735.     return DXUtil_ConvertWideStringToGenericCch( tstrDestination, wstrSource, cbDestChar / sizeof(TCHAR) );
  736. }
  737. HRESULT DXUtil_ReadStringRegKeyCb( HKEY hKey, TCHAR* strRegName, TCHAR* strDest, DWORD cbDest, TCHAR* strDefault )
  738. {
  739.     return DXUtil_ReadStringRegKeyCch( hKey, strRegName, strDest, cbDest / sizeof(TCHAR), strDefault );
  740. }
  741. HRESULT DXUtil_ConvertGUIDToStringCb( const GUID* pGuidSrc, TCHAR* strDest, int cbDestChar )
  742. {
  743.     return DXUtil_ConvertGUIDToStringCch( pGuidSrc, strDest, cbDestChar / sizeof(TCHAR) );
  744. }
  745. #ifndef UNDER_CE
  746. HRESULT DXUtil_GetDXSDKMediaPathCb( TCHAR* szDest, int cbDest )
  747. {
  748.     return DXUtil_GetDXSDKMediaPathCch( szDest, cbDest / sizeof(TCHAR) );
  749. }
  750. HRESULT DXUtil_FindMediaFileCb( TCHAR* szDestPath, int cbDest, TCHAR* strFilename )
  751. {
  752.     return DXUtil_FindMediaFileCch( szDestPath, cbDest / sizeof(TCHAR), strFilename );
  753. }
  754. #endif