GETDXVER.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:8k
源码类别:

Windows编程

开发平台:

Visual C++

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