最好不读注册表。

解决方案 »

  1.   

    Version Checking
    Applications sometimes need to know which version of Microsoft® DirectX® is currently available on the system. For example, if an older version of DirectX is on the system, your application may need to scale itself to the capabilities of that version or install the most recent version.There is no direct way to obtain the DirectX version number. However, each version has a characteristic set of objects and interfaces. Because any version of DirectX supports all previous versions, this set of interfaces and objects will be supported by the version in which they are introduced and all subsequent versions. Thus, the preferred way to determine whether your desired version is available is to test for its characteristic objects or interfaces. As long as those are present, your application will work normally even though you might be using a more recent version of DirectX.For example, suppose you need version 6.1 support. The Microsoft DirectMusic® object (CLSID_DirectMusic) was introduced in DirectX version 6.1. You can test for the presence of the DirectMusic object by attempting to create it with CoCreateInstance. If you are successful, you have version 6.1 or later, and you will be able to use all the DirectX 6.1 capabilities.Rather than provide a detailed list here of each version's characteristic interfaces and objects, you should refer to the DirectX Software Development kit's sample section. One of the samples is a function, GetDXVersion, that includes tests for all DirectX versions. GetDXVersion returns an integer that corresponds to the DirectX version that is present on the system. As long as this integer is greater than or equal to your desired version number, your application will run normally. You can find the sample code under your SDK root folder at \Samples\Multimedia\DXMisc\GetDXVer.Checking the Operating System Version
    In addition to determining the Microsoft® DirectX® version, applications may also need to know what operating system they are running on, and perhaps which Service Pack has been installed. The preferred way to check the operating system version is to use the Microsoft Windows® function, GetVersionEx. This function returns an OSVERSIONINFO structure that contains a variety of information including: Whether the system is Microsoft Windows NT®-based or Windows 98/Me/ME 
    The major and minor version numbers 
    The service pack number, for Windows NT-based systems 
    The general procedure is to determine the earliest version of the operating system that your application is compliant with. If that version or later is installed, you can safely install and run your application.Note  The operating system information returned by GetVersionEx should not be used to test for the presence or version number of DirectX. In particular, the fact that a system is Windows NT-based does not necessarily mean that DirectX is absent. The Windows 2000 operating system, for example, includes DirectX 7.0 or later. Use the procedures described in the previous section to determine whether DirectX is present and, if so, the version number.The following sample function illustrates how to use GetVersionEx to test the operating system version. If the installed version is identical to or more recent than the version specified in the parameter list, the function returns TRUE. You can then safely install and execute your application. Otherwise the function returns FALSE, indicating that your application will not run properly, if at all.#include <windows.h>
    #include <stdio.h>
    #include <tchar.h>BOOL bIsWindowsVersionOK(   DWORD dwWin9xMajor, DWORD dwWin9xMinor,
                                DWORD dwWinNTMajor, DWORD dwWinNTMinor, WORD wWinNTSPMajor )
    {
        OSVERSIONINFO           osvi;
        
        // Initialize the OSVERSIONINFO structure.
        ZeroMemory( &osvi, sizeof( osvi ) );
        osvi.dwOSVersionInfoSize = sizeof( osvi );
            
        GetVersionEx( &osvi );  // Assume this function succeeds.    // Split code paths for NT and Win9x    
        if( osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
        {
            // Check the major version.
            if( osvi.dwMajorVersion > dwWin9xMajor )
                return TRUE;
            else if( osvi.dwMajorVersion == dwWin9xMajor )
            {
                // Check the minor version.
                if( osvi.dwMinorVersion >= dwWin9xMinor )
                    return TRUE;
            }
        }
        else if( osvi.dwPlatformId == VER_PLATFORM_WIN32_NT )
        {
            // Check the major version.
            if( osvi.dwMajorVersion > dwWinNTMajor )
                return TRUE;
            else if( osvi.dwMajorVersion == dwWinNTMajor )
            {
                // Check the minor version.
                if( osvi.dwMinorVersion > dwWinNTMinor )
                    return TRUE;
                else if( osvi.dwMinorVersion == dwWinNTMinor )
                {
                    // Check the service pack.
                    DWORD dwServicePack = 0;                if( osvi.szCSDVersion )
                    {
                        _stscanf(   osvi.szCSDVersion,
                                    _T("Service Pack %d"),
                                    &dwServicePack );
                    }
                    return ( dwServicePack >= wWinNTSPMajor );
                }
            }
        }
        return FALSE;
    }
      

  2.   

    MS提供了Sample:
    DWORD GetDXVersion()
    {
        DIRECTDRAWCREATE     DirectDrawCreate   = NULL;
        DIRECTDRAWCREATEEX   DirectDrawCreateEx = NULL;
        DIRECTINPUTCREATE    DirectInputCreate  = NULL;
        HINSTANCE            hDDrawDLL          = NULL;
        HINSTANCE            hDInputDLL         = NULL;
        HINSTANCE            hD3D8DLL           = NULL;
        HINSTANCE            hDPNHPASTDLL       = NULL;
        LPDIRECTDRAW         pDDraw             = NULL;
        LPDIRECTDRAW2        pDDraw2            = NULL;
        LPDIRECTDRAWSURFACE  pSurf              = NULL;
        LPDIRECTDRAWSURFACE3 pSurf3             = NULL;
        LPDIRECTDRAWSURFACE4 pSurf4             = NULL;
        DWORD                dwDXVersion        = 0;
        HRESULT              hr;    // First see if DDRAW.DLL even exists.
        hDDrawDLL = LoadLibrary( "DDRAW.DLL" );
        if( hDDrawDLL == NULL )
        {
            dwDXVersion = 0;
            OutputDebugString( "Couldn't LoadLibrary DDraw\r\n" );
            return dwDXVersion;
        }    // See if we can create the DirectDraw object.
        DirectDrawCreate = (DIRECTDRAWCREATE)GetProcAddress( hDDrawDLL, "DirectDrawCreate" );
        if( DirectDrawCreate == NULL )
        {
            dwDXVersion = 0;
            FreeLibrary( hDDrawDLL );
            OutputDebugString( "Couldn't GetProcAddress DirectDrawCreate\r\n" );
            return dwDXVersion;
        }    hr = DirectDrawCreate( NULL, &pDDraw, NULL );
        if( FAILED(hr) )
        {
            dwDXVersion = 0;
            FreeLibrary( hDDrawDLL );
            OutputDebugString( "Couldn't create DDraw\r\n" );
            return dwDXVersion;
        }    // So DirectDraw exists.  We are at least DX1.
        dwDXVersion = 0x100;    // Let's see if IID_IDirectDraw2 exists.
        hr = pDDraw->QueryInterface( IID_IDirectDraw2, (VOID**)&pDDraw2 );
        if( FAILED(hr) )
        {
            // No IDirectDraw2 exists... must be DX1
            pDDraw->Release();
            FreeLibrary( hDDrawDLL );
            OutputDebugString( "Couldn't QI DDraw2\r\n" );
            return dwDXVersion;
        }    // IDirectDraw2 exists. We must be at least DX2
        pDDraw2->Release();
        dwDXVersion = 0x200;
      

  3.   

    续:
    //-------------------------------------------------------------------------
        // DirectX 3.0 Checks
    //-------------------------------------------------------------------------    // DirectInput was added for DX3
        hDInputDLL = LoadLibrary( "DINPUT.DLL" );
        if( hDInputDLL == NULL )
        {
            // No DInput... must not be DX3
            pDDraw->Release();
            FreeLibrary( hDDrawDLL );
            OutputDebugString( "Couldn't LoadLibrary DInput\r\n" );
            return dwDXVersion;
        }    DirectInputCreate = (DIRECTINPUTCREATE)GetProcAddress( hDInputDLL,
                                                            "DirectInputCreateA" );
        if( DirectInputCreate == NULL )
        {
            // No DInput... must be DX2
            FreeLibrary( hDInputDLL );
            pDDraw->Release();
            FreeLibrary( hDDrawDLL );
            OutputDebugString( "Couldn't GetProcAddress DInputCreate\r\n" );
            return dwDXVersion;
        }    // DirectInputCreate exists. We are at least DX3
        dwDXVersion = 0x300;
        FreeLibrary( hDInputDLL );    // Can do checks for 3a vs 3b here
    //-------------------------------------------------------------------------
        // DirectX 5.0 Checks
    //-------------------------------------------------------------------------    // We can tell if DX5 is present by checking for the existence of
        // IDirectDrawSurface3. First, we need a surface to QI off of.
        DDSURFACEDESC ddsd;
        ZeroMemory( &ddsd, sizeof(ddsd) );
        ddsd.dwSize         = sizeof(ddsd);
        ddsd.dwFlags        = DDSD_CAPS;
        ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;    hr = pDDraw->SetCooperativeLevel( NULL, DDSCL_NORMAL );
        if( FAILED(hr) )
        {
            // Failure. This means DDraw isn't properly installed.
            pDDraw->Release();
            FreeLibrary( hDDrawDLL );
            dwDXVersion = 0;
            OutputDebugString( "Couldn't Set coop level\r\n" );
            return dwDXVersion;
        }    hr = pDDraw->CreateSurface( &ddsd, &pSurf, NULL );
        if( FAILED(hr) )
        {
            // Failure. This means DDraw isn't properly installed.
            pDDraw->Release();
            FreeLibrary( hDDrawDLL );
            dwDXVersion = 0;
            OutputDebugString( "Couldn't CreateSurface\r\n" );
            return dwDXVersion;
        }    // Query for the IDirectDrawSurface3 interface
        if( FAILED( pSurf->QueryInterface( IID_IDirectDrawSurface3,
                                           (VOID**)&pSurf3 ) ) )
        {
            pSurf->Release();
            pDDraw->Release();
            FreeLibrary( hDDrawDLL );
            OutputDebugString( "Couldn't QI DDS3\r\n" );
            return dwDXVersion;
        }    // QI for IDirectDrawSurface3 succeeded. We must be at least DX5
        dwDXVersion = 0x500;
        pSurf3->Release();
    //-------------------------------------------------------------------------
        // DirectX 6.0 Checks
    //-------------------------------------------------------------------------    // The IDirectDrawSurface4 interface was introduced with DX 6.0
        if( FAILED( pSurf->QueryInterface( IID_IDirectDrawSurface4,
                                           (VOID**)&pSurf4 ) ) )
        {
            pSurf->Release();
            pDDraw->Release();
            FreeLibrary( hDDrawDLL );
            OutputDebugString( "Couldn't QI DDS4\r\n" );
            return dwDXVersion;
        }    // IDirectDrawSurface4 was create successfully. We must be at least DX6
        dwDXVersion = 0x600;
        pSurf4->Release();
        pSurf->Release();
        pDDraw->Release();
    //-------------------------------------------------------------------------
        // DirectX 6.1 Checks
    //-------------------------------------------------------------------------    // Check for DMusic, which was introduced with DX6.1
        LPDIRECTMUSIC pDMusic = NULL;
        CoInitialize( NULL );
        hr = CoCreateInstance( CLSID_DirectMusic, NULL, CLSCTX_INPROC_SERVER,
                               IID_IDirectMusic, (VOID**)&pDMusic );
        if( FAILED(hr) )
        {
            FreeLibrary( hDDrawDLL );
            OutputDebugString( "Couldn't create CLSID_DirectMusic\r\n" );
            return dwDXVersion;
        }    // DirectMusic was created successfully. We must be at least DX6.1
        dwDXVersion = 0x601;
        pDMusic->Release();
        CoUninitialize();
      

  4.   

    续:
    //-------------------------------------------------------------------------
        // DirectX 7.0 Checks
    //-------------------------------------------------------------------------    // Check for DirectX 7 by creating a DDraw7 object
        LPDIRECTDRAW7 pDD7;
        DirectDrawCreateEx = (DIRECTDRAWCREATEEX)GetProcAddress( hDDrawDLL,
                                                           "DirectDrawCreateEx" );
        if( NULL == DirectDrawCreateEx )
        {
            FreeLibrary( hDDrawDLL );
            OutputDebugString( "Couldn't GetProcAddress DirectDrawCreateEx\r\n" );
            return dwDXVersion;
        }    if( FAILED( DirectDrawCreateEx( NULL, (VOID**)&pDD7, IID_IDirectDraw7,
                                        NULL ) ) )
        {
            FreeLibrary( hDDrawDLL );
            OutputDebugString( "Couldn't DirectDrawCreateEx\r\n" );
            return dwDXVersion;
        }    // DDraw7 was created successfully. We must be at least DX7.0
        dwDXVersion = 0x700;
        pDD7->Release();
    //-------------------------------------------------------------------------
        // DirectX 8.0 Checks
    //-------------------------------------------------------------------------    // Simply see if D3D8.dll exists.
        hD3D8DLL = LoadLibrary( "D3D8.DLL" );
        if( hD3D8DLL == NULL )
        {
        FreeLibrary( hDDrawDLL );
            OutputDebugString( "Couldn't LoadLibrary D3D8.DLL\r\n" );
            return dwDXVersion;
        }    // D3D8.dll exists. We must be at least DX8.0
        dwDXVersion = 0x800;
    //-------------------------------------------------------------------------
        // DirectX 8.1 Checks
    //-------------------------------------------------------------------------    // Simply see if dpnhpast.dll exists.
        hDPNHPASTDLL = LoadLibrary( "dpnhpast.dll" );
        if( hDPNHPASTDLL == NULL )
        {
        FreeLibrary( hDPNHPASTDLL );
            OutputDebugString( "Couldn't LoadLibrary dpnhpast.dll\r\n" );
            return dwDXVersion;
        }    // dpnhpast.dll exists. We must be at least DX8.1
        dwDXVersion = 0x801;
    //-------------------------------------------------------------------------
        // End of checking for versions of DirectX 
    //-------------------------------------------------------------------------    // Close open libraries and return
        FreeLibrary( hDDrawDLL );
        FreeLibrary( hD3D8DLL );
        
        return dwDXVersion;
    }