home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / directx / viewer / getdxver.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-15  |  8.0 KB  |  306 lines

  1. /**************************************************************************
  2.  
  3.     GetDXVer.cpp
  4.  
  5.     Demonstrates how applications can detect what version of DirectX
  6.     is installed.
  7.  
  8.  **************************************************************************/
  9. /**************************************************************************
  10.  
  11.     (C) Copyright 1995-1997 Microsoft Corp.  All rights reserved.
  12.  
  13.     You have a royalty-free right to use, modify, reproduce and
  14.     distribute the Sample Files (and/or any modified version) in
  15.     any way you find useful, provided that you agree that
  16.     Microsoft has no warranty obligations or liability for any
  17.     Sample Application Files which are modified.
  18.  
  19.  **************************************************************************/
  20.  
  21. #include <windows.h>
  22. #include <windowsx.h>
  23. #include <ddraw.h>
  24. #include <dinput.h>
  25. #include <d3drm.h>
  26. #include "viewer.h"
  27.  
  28. /****************************************************************************
  29.  *
  30.  *      GetDXVersion
  31.  *
  32.  *  This function returns two arguments:
  33.  *    dwDXVersion:
  34.  *        0        No DirectX installed
  35.  *        0x100   DirectX version 1 installed
  36.  *        0x200   DirectX 2 installed
  37.  *        0x300   DirectX 3 installed
  38.  *        0x500   At least DirectX 5 installed.
  39.  *        0x501   At least DirectX 5a installed.
  40.  *    dwDXPlatform:
  41.  *        0                                Unknown (This is a failure case. Should never happen)
  42.  *        VER_PLATFORM_WIN32_WINDOWS        Windows 9X platform
  43.  *        VER_PLATFORM_WIN32_NT        Windows NT platform
  44.  *
  45.  ****************************************************************************/
  46.  
  47. typedef HRESULT (WINAPI *DIRECTDRAWCREATE)(GUID *, LPDIRECTDRAW *, IUnknown *);
  48. typedef HRESULT (WINAPI *DIRECTINPUTCREATE)(HINSTANCE, DWORD, LPDIRECTINPUT *, IUnknown *);
  49.  
  50. void WINAPI GetDXVersion(LPDWORD pdwDXVersion, LPDWORD pdwDXPlatform)
  51. {
  52.     HRESULT            hr;
  53.     HINSTANCE            DDHinst = 0;
  54.     HINSTANCE            DIHinst = 0;
  55.     LPDIRECTDRAW        pDDraw = 0;
  56.     LPDIRECTDRAW2        pDDraw2 = 0;
  57.     DIRECTDRAWCREATE        DirectDrawCreate = 0;
  58.     DIRECTINPUTCREATE        DirectInputCreate = 0;
  59.     OSVERSIONINFO        osVer;
  60.     LPDIRECTDRAWSURFACE        pSurf = 0;
  61.     LPDIRECTDRAWSURFACE3    pSurf3 = 0;
  62.  
  63.     /*
  64.      * First get the windows platform
  65.      */
  66.     osVer.dwOSVersionInfoSize = sizeof(osVer);
  67.     if (!GetVersionEx(&osVer))
  68.     {
  69.     *pdwDXVersion = 0;
  70.     *pdwDXPlatform = 0;
  71.     return;
  72.     }
  73.  
  74.     if (osVer.dwPlatformId == VER_PLATFORM_WIN32_NT)
  75.     {
  76.     *pdwDXPlatform = VER_PLATFORM_WIN32_NT;
  77.     /*
  78.      * NT is easy... NT 4.0 is DX2, 4.0 SP3 is DX3, 5.0 is DX5
  79.      * and no DX on earlier versions.
  80.      */
  81.     if (osVer.dwMajorVersion < 4)
  82.     {
  83.         *pdwDXPlatform = 0;    //No DX on NT3.51 or earlier
  84.         return;
  85.     }
  86.     if (osVer.dwMajorVersion == 4)
  87.     {
  88.         /*
  89.          * NT4 up to SP2 is DX2, and SP3 onwards is DX3, so we are at least DX2
  90.          */
  91.         *pdwDXVersion = 0x200;
  92.  
  93.             /*
  94.              * We're not supposed to be able to tell which SP we're on, so check for dinput
  95.              */
  96.             DIHinst = LoadLibrary("DINPUT.DLL");
  97.             if (DIHinst == 0) 
  98.             {
  99.                 /*
  100.                  * No DInput... must be DX2 on NT 4 pre-SP3
  101.                  */
  102.                 OutputDebugString("Couldn't LoadLibrary DInput\r\n");
  103.             return;
  104.             }
  105.  
  106.             DirectInputCreate = (DIRECTINPUTCREATE)
  107.                                     GetProcAddress(DIHinst, "DirectInputCreateA");
  108.             FreeLibrary(DIHinst);
  109.  
  110.             if (DirectInputCreate == 0) 
  111.             {
  112.                 /*
  113.                  * No DInput... must be pre-SP3 DX2
  114.                  */
  115.                 OutputDebugString("Couldn't GetProcAddress DInputCreate\r\n");
  116.             return;
  117.             }
  118.  
  119.         /*
  120.          * It must be NT4, DX2
  121.          */
  122.         *pdwDXVersion = 0x300; //DX3 on NT4 SP3 or higher
  123.         return;
  124.     }
  125.     /*
  126.      * Else it's NT5 or higher, and it's DX5a or higher:
  127.      */
  128.     *pdwDXVersion = 0x501; //DX5a on NT5
  129.     return;
  130.     }
  131.  
  132.     /*
  133.      * Not NT... must be Win9x
  134.      */
  135.     *pdwDXPlatform = VER_PLATFORM_WIN32_WINDOWS;
  136.  
  137.     /*
  138.      * If we are on Memphis or higher, then we are at least DX5a
  139.      */
  140.     if ( (osVer.dwBuildNumber & 0xffff) > 1353) //Check for higher than developer release
  141.     {
  142.     *pdwDXVersion = 0x501; //DX5a on Memphis or higher
  143.     return;
  144.     }
  145.  
  146.     /*
  147.      * Now we know we are in Windows 9x (or maybe 3.1), so anything's possible.
  148.      * First see if DDRAW.DLL even exists.
  149.      */
  150.     DDHinst = LoadLibrary("DDRAW.DLL");
  151.     if (DDHinst == 0) 
  152.     {
  153.     *pdwDXVersion = 0;
  154.     *pdwDXPlatform = 0;
  155.     FreeLibrary(DDHinst);
  156.     return;
  157.     }
  158.  
  159.     /*
  160.      *  See if we can create the DirectDraw object.
  161.      */
  162.     DirectDrawCreate = (DIRECTDRAWCREATE)
  163.                             GetProcAddress(DDHinst, "DirectDrawCreate");
  164.     if (DirectDrawCreate == 0) 
  165.     {
  166.     *pdwDXVersion = 0;
  167.     *pdwDXPlatform = 0;
  168.     FreeLibrary(DDHinst);
  169.         OutputDebugString("Couldn't LoadLibrary DDraw\r\n");
  170.     return;
  171.     }
  172.  
  173.     hr = DirectDrawCreate(NULL, &pDDraw, NULL);
  174.     if (FAILED(hr)) 
  175.     {
  176.     *pdwDXVersion = 0;
  177.     *pdwDXPlatform = 0;
  178.     FreeLibrary(DDHinst);
  179.         OutputDebugString("Couldn't create DDraw\r\n");
  180.     return;
  181.     }
  182.  
  183.     /*
  184.      *  So DirectDraw exists.  We are at least DX1.
  185.      */
  186.     *pdwDXVersion = 0x100;
  187.  
  188.     /*
  189.      *  Let's see if IID_IDirectDraw2 exists.
  190.      */
  191.     hr = pDDraw->QueryInterface(IID_IDirectDraw2, (LPVOID *)&pDDraw2);
  192.     if (FAILED(hr)) 
  193.     {
  194.     /*
  195.      * No IDirectDraw2 exists... must be DX1
  196.      */
  197.     pDDraw->Release();
  198.     FreeLibrary(DDHinst);
  199.         OutputDebugString("Couldn't QI DDraw2\r\n");
  200.     return;
  201.     }
  202.     /*
  203.      * IDirectDraw2 exists. We must be at least DX2
  204.      */
  205.     pDDraw2->Release();
  206.     *pdwDXVersion = 0x200;
  207.  
  208.     /*
  209.      *  See if we can create the DirectInput object.
  210.      */
  211.     DIHinst = LoadLibrary("DINPUT.DLL");
  212.     if (DIHinst == 0) 
  213.     {
  214.         /*
  215.          * No DInput... must be DX2
  216.          */
  217.         OutputDebugString("Couldn't LoadLibrary DInput\r\n");
  218.     pDDraw->Release();
  219.     FreeLibrary(DDHinst);
  220.     return;
  221.     }
  222.  
  223.     DirectInputCreate = (DIRECTINPUTCREATE)
  224.                             GetProcAddress(DIHinst, "DirectInputCreateA");
  225.     FreeLibrary(DIHinst);
  226.  
  227.     if (DirectInputCreate == 0) 
  228.     {
  229.         /*
  230.          * No DInput... must be DX2
  231.          */
  232.     FreeLibrary(DDHinst);
  233.     pDDraw->Release();
  234.         OutputDebugString("Couldn't GetProcAddress DInputCreate\r\n");
  235.     return;
  236.     }
  237.  
  238.     /*
  239.      * DirectInputCreate exists. That's enough to tell us that we are at least DX3
  240.      */
  241.     *pdwDXVersion = 0x300;
  242.  
  243.     /*
  244.      * Checks for 3a vs 3b?
  245.      */
  246.  
  247.     /*
  248.      * We can tell if DX5 is present by checking for the existence of IDirectDrawSurface3.
  249.      * First we need a surface to QI off of.
  250.      */
  251.     DDSURFACEDESC desc;
  252.  
  253.     ZeroMemory(&desc, sizeof(desc));
  254.     desc.dwSize = sizeof(desc);
  255.     desc.dwFlags = DDSD_CAPS;
  256.     desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
  257.  
  258.     hr = pDDraw->SetCooperativeLevel(NULL,DDSCL_NORMAL);
  259.     if (FAILED(hr)) 
  260.     {
  261.     /*
  262.      * Failure. This means DDraw isn't properly installed.
  263.      */
  264.     pDDraw->Release();
  265.     FreeLibrary(DDHinst);
  266.     *pdwDXVersion = 0;
  267.         OutputDebugString("Couldn't Set coop level\r\n");
  268.     return;
  269.     }
  270.  
  271.     hr = pDDraw->CreateSurface(&desc, &pSurf, NULL);
  272.     if (FAILED(hr)) 
  273.     {
  274.     /*
  275.      * Failure. This means DDraw isn't properly installed.
  276.      */
  277.     pDDraw->Release();
  278.     FreeLibrary(DDHinst);
  279.     *pdwDXVersion = 0;
  280.         OutputDebugString("Couldn't CreateSurface\r\n");
  281.     return;
  282.     }
  283.  
  284.     /*
  285.      * Try for the IDirectDrawSurface3 interface. If it works, we're on DX5 at least
  286.      */
  287.     if ( FAILED(pSurf->QueryInterface(IID_IDirectDrawSurface3,(LPVOID*)&pSurf3)) )
  288.     {
  289.         pDDraw->Release();
  290.         FreeLibrary(DDHinst);
  291.  
  292.         return;
  293.     }
  294.  
  295.     /*
  296.      * QI for IDirectDrawSurface3 succeeded. We must be at least DX5
  297.      */
  298.     *pdwDXVersion = 0x500;
  299.  
  300.     pSurf->Release();
  301.     pDDraw->Release();
  302.     FreeLibrary(DDHinst);
  303.  
  304.     return;
  305. }
  306.