home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / DirectX SDK / DXSDK / bin / DXUtils / AppWizard / DXAppwiz.awx / TEMPLATE / DIUTIL.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  2001-10-25  |  10.6 KB  |  345 lines

  1. //-----------------------------------------------------------------------------
  2. // File: DIUtil.cpp
  3. //
  4. // Desc: DirectInput framework class using semantic mapping.  Feel free to use 
  5. //       this class as a starting point for adding extra functionality.
  6. //-----------------------------------------------------------------------------
  7. #define STRICT
  8. $$IF(DINPUT)
  9. #define DIRECTINPUT_VERSION 0x0800
  10. $$ENDIF
  11. $$IF(DLG)
  12. #include "stdafx.h"
  13. $$ENDIF
  14. #include <basetsd.h>
  15. #include <tchar.h>
  16. #include <stdio.h>
  17. #include "DIUtil.h"
  18. #include "DXUtil.h"
  19.  
  20.  
  21.  
  22.  
  23.  
  24. //-----------------------------------------------------------------------------
  25. // Name: CInputDeviceManager()
  26. // Desc: Constructor 
  27. //-----------------------------------------------------------------------------
  28. CInputDeviceManager::CInputDeviceManager()
  29. {
  30.     HRESULT hr = CoInitialize(NULL);
  31.     m_bCleanupCOM = SUCCEEDED(hr);
  32.  
  33.     m_dwNumDevices = 0;
  34.     m_dwMaxDevices = 10;
  35.     m_pDI          = NULL;
  36.  
  37.     // Allocate DeviceInfo structs
  38.     m_pDevices = NULL;
  39.     m_pDevices = (DeviceInfo*) realloc( m_pDevices, m_dwMaxDevices*sizeof(DeviceInfo) );
  40.     ZeroMemory( m_pDevices, m_dwMaxDevices*sizeof(DeviceInfo) );
  41. }
  42.  
  43.  
  44.  
  45.  
  46. //-----------------------------------------------------------------------------
  47. // Name: ~CInputDeviceManager()
  48. // Desc: Destructor
  49. //-----------------------------------------------------------------------------
  50. CInputDeviceManager::~CInputDeviceManager()
  51. {
  52.     if( m_pDevices )
  53.     {
  54.         // Release() all devices
  55.         for( DWORD i=0; i<m_dwNumDevices; i++ )
  56.         {
  57.             m_pDevices[i].pdidDevice->Unacquire();
  58.             m_pDevices[i].pdidDevice->Release();
  59.             m_pDevices[i].pdidDevice = NULL;
  60.         }
  61.  
  62.         free( m_pDevices );
  63.     }
  64.  
  65.     // Release() base object
  66.     SAFE_RELEASE( m_pDI );
  67.  
  68.     if( m_bCleanupCOM )
  69.         CoUninitialize();
  70. }
  71.  
  72.  
  73.  
  74.  
  75. //-----------------------------------------------------------------------------
  76. // Name: GetDevices()
  77. // Desc: Get the DeviceInfo array and number of devices
  78. //-----------------------------------------------------------------------------
  79. HRESULT CInputDeviceManager::GetDevices( DeviceInfo** ppDeviceInfo, 
  80.                                          DWORD* pdwCount )
  81. {
  82.     if( NULL==ppDeviceInfo || NULL==pdwCount )
  83.         return E_INVALIDARG;
  84.  
  85.     (*ppDeviceInfo) = m_pDevices;
  86.     (*pdwCount) = m_dwNumDevices;
  87.  
  88.     return S_OK;
  89. }
  90.  
  91.  
  92.  
  93.  
  94. //-----------------------------------------------------------------------------
  95. // Name: AddDevice()
  96. // Desc: Add the provided device to the list and perform initialization
  97. //-----------------------------------------------------------------------------
  98. HRESULT CInputDeviceManager::AddDevice( const DIDEVICEINSTANCE* pdidi, 
  99.                                         const LPDIRECTINPUTDEVICE8 pdidDevice )
  100. {
  101.     HRESULT hr;
  102.     DWORD   dwDeviceType = pdidi->dwDevType;
  103.  
  104.     pdidDevice->Unacquire();
  105.  
  106.     // Set the device's coop level
  107.     hr = pdidDevice->SetCooperativeLevel( m_hWnd, DISCL_NONEXCLUSIVE|DISCL_FOREGROUND );
  108.     if( FAILED(hr) )
  109.         return hr;
  110.  
  111.     // Add new DeviceInfo struct to list, and resize array if needed
  112.     m_dwNumDevices++;
  113.     if( m_dwNumDevices > m_dwMaxDevices )
  114.     {
  115.         m_dwMaxDevices += 10;
  116.         m_pDevices = (DeviceInfo*) realloc( m_pDevices, m_dwMaxDevices*sizeof(DeviceInfo) );
  117.         ZeroMemory( m_pDevices + m_dwMaxDevices - 10, 10*sizeof(DeviceInfo) );
  118.     }
  119.  
  120.     DWORD dwCurrentDevice = m_dwNumDevices-1;
  121.     m_pDevices[dwCurrentDevice].pdidDevice = pdidDevice;
  122.     m_pDevices[dwCurrentDevice].pdidDevice->AddRef();
  123.  
  124.     // Callback into the app so it can adjust the device and set
  125.     // the m_pDevices[dwCurrentDevice].pParam field with a device state struct
  126.     if( m_AddDeviceCallback )
  127.     {
  128.         hr = m_AddDeviceCallback( &m_pDevices[dwCurrentDevice], pdidi, m_AddDeviceCallbackParam ); 
  129.         if( FAILED(hr) )    
  130.             return hr;
  131.     }
  132.  
  133.     // Build the action map
  134.     hr = m_pDevices[dwCurrentDevice].pdidDevice->BuildActionMap( &m_diaf, m_strUserName, 0 );
  135.     if( FAILED(hr) )
  136.         return hr;
  137.  
  138.     // Set the action map for the current device
  139.     hr = m_pDevices[dwCurrentDevice].pdidDevice->SetActionMap( &m_diaf, m_strUserName, 0 );
  140.     if( FAILED(hr) )
  141.         return hr;
  142.  
  143.     // Continue enumerating suitable devices
  144.     return S_OK;
  145. }
  146.  
  147.  
  148.  
  149.  
  150. //-----------------------------------------------------------------------------
  151. // Name: EnumSuitableDevicesCB()
  152. // Desc: Callback function for device enumeration. Adds all devices which
  153. //       met the search criteria
  154. //-----------------------------------------------------------------------------
  155. BOOL CALLBACK EnumSuitableDevicesCB( LPCDIDEVICEINSTANCE pdidi, 
  156.                                      LPDIRECTINPUTDEVICE8 pdidDevice, 
  157.                                      DWORD dwFlags, DWORD dwDeviceRemaining,
  158.                                      VOID* pContext )
  159. {
  160.     // Add the device to the device manager's internal list
  161.     ((CInputDeviceManager*)pContext)->AddDevice( pdidi, pdidDevice );
  162.  
  163.     // Continue enumerating suitable devices
  164.     return DIENUM_CONTINUE;
  165. }
  166.  
  167.  
  168.  
  169.  
  170. //-----------------------------------------------------------------------------
  171. // Name: SetActionFormat()
  172. // Desc: Set the action format to the provided DIACTIONFORMAT structure, and
  173. //       destroy and recreate device list if flagged
  174. //-----------------------------------------------------------------------------
  175. HRESULT CInputDeviceManager::SetActionFormat( DIACTIONFORMAT& diaf, BOOL bReenumerate )
  176. {
  177.     HRESULT hr = S_OK;
  178.  
  179.     // Store the new action format
  180.     m_diaf = diaf;
  181.  
  182.     // Only destroy and re-enumerate devices if the caller explicitly wants to. The 
  183.     // device list may be used within a loop, and kicking off an enumeration while 
  184.     // the device array is in use would cause problems.
  185.     if( bReenumerate )
  186.     {
  187.         // Cleanup any previously enumerated devices
  188.         for( DWORD i=0; i<m_dwNumDevices; i++ )
  189.         {
  190.             m_pDevices[i].pdidDevice->Unacquire();
  191.             m_pDevices[i].pdidDevice->Release();
  192.             m_pDevices[i].pdidDevice = NULL;
  193.         }
  194.         m_dwNumDevices = 0;
  195.  
  196.         // Enumerate suitable DirectInput devices
  197.         hr = m_pDI->EnumDevicesBySemantics( m_strUserName, &m_diaf, 
  198.                                             EnumSuitableDevicesCB, this, 0L );
  199.         if( FAILED(hr) )
  200.             return hr;
  201.     }
  202.     else // Just apply the new maps.
  203.     {
  204.         // Devices must be unacquired to have a new action map set.
  205.         UnacquireDevices();
  206.  
  207.         // Apply the new action map to the current devices.
  208.         for( DWORD i=0; i<m_dwNumDevices; i++ )
  209.         {
  210.             hr = m_pDevices[i].pdidDevice->BuildActionMap( &m_diaf, m_strUserName, 0 );
  211.             if( FAILED(hr) )
  212.                 return hr;
  213.  
  214.             hr = m_pDevices[i].pdidDevice->SetActionMap( &m_diaf, m_strUserName, 0 );
  215.             if( FAILED(hr) )
  216.                 return hr;
  217.         }
  218.     }
  219.  
  220.     if( FAILED(hr) )
  221.         return hr;
  222.  
  223.     return S_OK;
  224. }
  225.  
  226.  
  227.  
  228.  
  229. //-----------------------------------------------------------------------------
  230. // Name: Create()
  231. // Desc: Create DirectInput object and perform initialization
  232. //-----------------------------------------------------------------------------
  233. HRESULT CInputDeviceManager::Create( HWND hWnd, TCHAR* strUserName, 
  234.                                      DIACTIONFORMAT& diaf,
  235.                                      LPDIMANAGERCALLBACK AddDeviceCallback, 
  236.                                      LPVOID pCallbackParam )
  237. {
  238.     HRESULT hr;
  239.  
  240.     // Store data
  241.     m_hWnd        = hWnd;
  242.     m_strUserName = strUserName;
  243.     m_AddDeviceCallback = AddDeviceCallback;
  244.     m_AddDeviceCallbackParam = pCallbackParam;
  245.     
  246.     // Create the base DirectInput object
  247.     hr = DirectInput8Create( GetModuleHandle(NULL), DIRECTINPUT_VERSION, 
  248.                               IID_IDirectInput8, (VOID**)&m_pDI, NULL );
  249.     if( FAILED(hr) )
  250.         return hr;
  251.  
  252.     hr = SetActionFormat( diaf, TRUE );
  253.     if( FAILED(hr) )
  254.         return hr;
  255.  
  256.     return S_OK;
  257. }
  258.  
  259.  
  260.  
  261.  
  262. //-----------------------------------------------------------------------------
  263. // Name: ConfigureDevices()
  264. // Desc: Pause input and display the device configuration UI
  265. //-----------------------------------------------------------------------------
  266. HRESULT CInputDeviceManager::ConfigureDevices( HWND hWnd, IUnknown* pSurface,
  267.                                                VOID* ConfigureDevicesCB,
  268.                                                DWORD dwFlags, LPVOID pvCBParam )
  269. {
  270.     HRESULT hr;
  271.  
  272.     // Initialize all the colors here
  273.     DICOLORSET dics;
  274.     ZeroMemory(&dics, sizeof(DICOLORSET));
  275.     dics.dwSize = sizeof(DICOLORSET);
  276.  
  277.     // Fill in all the params
  278.     DICONFIGUREDEVICESPARAMS dicdp;
  279.     ZeroMemory(&dicdp, sizeof(dicdp));
  280.     dicdp.dwSize = sizeof(dicdp);
  281.     dicdp.dwcFormats     = 1;
  282.     dicdp.lprgFormats    = &m_diaf;
  283.     dicdp.hwnd           = hWnd;
  284.     dicdp.lpUnkDDSTarget = pSurface;
  285.  
  286.     if( m_strUserName )
  287.     {
  288.         dicdp.dwcUsers       = 1;
  289.         dicdp.lptszUserNames = m_strUserName;
  290.     }
  291.  
  292.     // Unacquire the devices so that mouse doesn't control the game while in control panel
  293.     UnacquireDevices();
  294.  
  295.     hr = m_pDI->ConfigureDevices( (LPDICONFIGUREDEVICESCALLBACK)ConfigureDevicesCB, 
  296.                                   &dicdp, dwFlags, pvCBParam );
  297.     if( FAILED(hr) )
  298.         return hr;
  299.  
  300.     if( dwFlags & DICD_EDIT )
  301.     {
  302.         // Re-set up the devices
  303.         hr = SetActionFormat( m_diaf, TRUE );
  304.         if( FAILED(hr) )
  305.             return hr;
  306.     }
  307.  
  308.     return S_OK;
  309. }
  310.  
  311.  
  312.  
  313. //-----------------------------------------------------------------------------
  314. // Name: UnacquireDevices()
  315. // Desc: Unacquire all devices in the member list
  316. //-----------------------------------------------------------------------------
  317. VOID CInputDeviceManager::UnacquireDevices()
  318. {
  319.     for( DWORD i=0; i<m_dwNumDevices; i++ )
  320.         m_pDevices[i].pdidDevice->Unacquire();
  321. }
  322.  
  323.  
  324.  
  325.  
  326. //-----------------------------------------------------------------------------
  327. // Name: SetFocus()
  328. // Desc: Sets the DirectInput focus to a new HWND
  329. //-----------------------------------------------------------------------------
  330. VOID CInputDeviceManager::SetFocus( HWND hWnd ) 
  331. {
  332.     m_hWnd = hWnd;
  333.  
  334.     UnacquireDevices();
  335.  
  336.     for( DWORD i=0; i<m_dwNumDevices; i++ )
  337.     {
  338.         // Set the device's coop level
  339.         m_pDevices[i].pdidDevice->SetCooperativeLevel( m_hWnd, 
  340.                                         DISCL_NONEXCLUSIVE|DISCL_FOREGROUND );
  341.     }
  342. }
  343.  
  344.  
  345.