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