0001:
0002:
0003:
0004:
0005:
0006:
0007: #define STRICT
0008: #include <basetsd.h>
0009: #include <tchar.h>
0010: #include <stdio.h>
0011: #include "DIUtil.h"
0012: #include "DXUtil.h"
0013:
0014:
0015:
0016:
0017:
0018:
0019:
0020:
0021:
0022: CInputDeviceManager::CInputDeviceManager()
0023: {
0024: HRESULT hr = CoInitialize(NULL);
0025: m_bCleanupCOM = SUCCEEDED(hr);
0026:
0027: m_dwNumDevices = 0;
0028: m_dwMaxDevices = 10;
0029: m_pDI = NULL;
0030:
0031:
0032: m_pDevices = (DeviceInfo*) malloc( m_dwMaxDevices*sizeof(DeviceInfo) );
0033: if( m_pDevices )
0034: ZeroMemory( m_pDevices, m_dwMaxDevices*sizeof(DeviceInfo) );
0035: }
0036:
0037:
0038:
0039:
0040:
0041:
0042:
0043:
0044: CInputDeviceManager::~CInputDeviceManager()
0045: {
0046: if( m_pDevices )
0047: {
0048:
0049: for( DWORD i=0; i<m_dwNumDevices; i++ )
0050: {
0051: if( m_pDevices[i].pdidDevice )
0052: m_pDevices[i].pdidDevice->Unacquire();
0053:
0054: SAFE_RELEASE( m_pDevices[i].pdidDevice );
0055: }
0056:
0057: free( m_pDevices );
0058: }
0059:
0060:
0061: SAFE_RELEASE( m_pDI );
0062:
0063: if( m_bCleanupCOM )
0064: CoUninitialize();
0065: }
0066:
0067:
0068:
0069:
0070:
0071:
0072:
0073:
0074: HRESULT CInputDeviceManager::GetDevices( DeviceInfo** ppDeviceInfo,
0075: DWORD* pdwCount )
0076: {
0077: if( NULL==ppDeviceInfo || NULL==pdwCount )
0078: return E_INVALIDARG;
0079:
0080: (*ppDeviceInfo) = m_pDevices;
0081: (*pdwCount) = m_dwNumDevices;
0082:
0083: return S_OK;
0084: }
0085:
0086:
0087:
0088:
0089:
0090:
0091:
0092:
0093: HRESULT CInputDeviceManager::AddDevice( const DIDEVICEINSTANCE* pdidi,
0094: const LPDIRECTINPUTDEVICE8 pdidDevice )
0095: {
0096: HRESULT hr;
0097:
0098:
0099: if( NULL == pdidDevice )
0100: return E_INVALIDARG;
0101:
0102: pdidDevice->Unacquire();
0103:
0104:
0105: hr = pdidDevice->SetCooperativeLevel( m_hWnd, DISCL_NONEXCLUSIVE|DISCL_FOREGROUND );
0106: if( FAILED(hr) )
0107: return hr;
0108:
0109:
0110: if( m_dwNumDevices >= m_dwMaxDevices )
0111: {
0112:
0113: DWORD dwNewMax = m_dwMaxDevices + 10;
0114: DeviceInfo* pNewDevices = (DeviceInfo*) realloc( m_pDevices, sizeof(DeviceInfo) * dwNewMax );
0115:
0116:
0117: if( NULL == pNewDevices )
0118: return E_OUTOFMEMORY;
0119:
0120:
0121: ZeroMemory( pNewDevices + m_dwMaxDevices, sizeof(DeviceInfo) * (dwNewMax - m_dwMaxDevices) );
0122:
0123:
0124: m_pDevices = pNewDevices;
0125: m_dwMaxDevices = dwNewMax;
0126: }
0127:
0128:
0129:
0130:
0131: m_pDevices[m_dwNumDevices].pdidDevice = pdidDevice;
0132:
0133:
0134:
0135: if( m_AddDeviceCallback )
0136: {
0137: hr = m_AddDeviceCallback( &m_pDevices[m_dwNumDevices], pdidi, m_AddDeviceCallbackParam );
0138: if( FAILED(hr) )
0139: return hr;
0140: }
0141:
0142:
0143: hr = m_pDevices[m_dwNumDevices].pdidDevice->BuildActionMap( &m_diaf, m_strUserName, 0 );
0144: if( FAILED(hr) )
0145: return hr;
0146:
0147:
0148: hr = m_pDevices[m_dwNumDevices].pdidDevice->SetActionMap( &m_diaf, m_strUserName, 0 );
0149: if( FAILED(hr) )
0150: return hr;
0151:
0152:
0153: m_pDevices[m_dwNumDevices].pdidDevice->AddRef();
0154: m_dwNumDevices++;
0155:
0156:
0157: return S_OK;
0158: }
0159:
0160:
0161:
0162:
0163:
0164:
0165:
0166:
0167:
0168: BOOL CALLBACK EnumSuitableDevicesCB( LPCDIDEVICEINSTANCE pdidi,
0169: LPDIRECTINPUTDEVICE8 pdidDevice,
0170: DWORD dwFlags, DWORD dwDeviceRemaining,
0171: VOID* pContext )
0172: {
0173: UNREFERENCED_PARAMETER( dwFlags );
0174: UNREFERENCED_PARAMETER( dwDeviceRemaining );
0175:
0176:
0177: ((CInputDeviceManager*)pContext)->AddDevice( pdidi, pdidDevice );
0178:
0179:
0180: return DIENUM_CONTINUE;
0181: }
0182:
0183:
0184:
0185:
0186:
0187:
0188:
0189:
0190:
0191: HRESULT CInputDeviceManager::SetActionFormat( DIACTIONFORMAT& diaf, BOOL bReenumerate )
0192: {
0193: HRESULT hr = S_OK;
0194:
0195:
0196: m_diaf = diaf;
0197:
0198:
0199:
0200:
0201: if( bReenumerate )
0202: {
0203:
0204: for( DWORD i=0; i<m_dwNumDevices; i++ )
0205: {
0206: if( m_pDevices[i].pdidDevice )
0207: m_pDevices[i].pdidDevice->Unacquire();
0208:
0209: SAFE_RELEASE( m_pDevices[i].pdidDevice );
0210: }
0211: m_dwNumDevices = 0;
0212:
0213:
0214: hr = m_pDI->EnumDevicesBySemantics( m_strUserName, &m_diaf,
0215: EnumSuitableDevicesCB, this, 0L );
0216: if( FAILED(hr) )
0217: return hr;
0218: }
0219: else
0220: {
0221:
0222: UnacquireDevices();
0223:
0224:
0225: for( DWORD i=0; i<m_dwNumDevices; i++ )
0226: {
0227: hr = m_pDevices[i].pdidDevice->BuildActionMap( &m_diaf, m_strUserName, 0 );
0228: if( FAILED(hr) )
0229: return hr;
0230:
0231: hr = m_pDevices[i].pdidDevice->SetActionMap( &m_diaf, m_strUserName, 0 );
0232: if( FAILED(hr) )
0233: return hr;
0234: }
0235: }
0236:
0237: return S_OK;
0238: }
0239:
0240:
0241:
0242:
0243:
0244:
0245:
0246:
0247: HRESULT CInputDeviceManager::Create( HWND hWnd, TCHAR* strUserName,
0248: DIACTIONFORMAT& diaf,
0249: LPDIMANAGERCALLBACK AddDeviceCallback,
0250: LPVOID pCallbackParam )
0251: {
0252: HRESULT hr;
0253:
0254:
0255: m_hWnd = hWnd;
0256: m_strUserName = strUserName;
0257: m_AddDeviceCallback = AddDeviceCallback;
0258: m_AddDeviceCallbackParam = pCallbackParam;
0259:
0260:
0261: hr = DirectInput8Create( GetModuleHandle(NULL), DIRECTINPUT_VERSION,
0262: IID_IDirectInput8, (VOID**)&m_pDI, NULL );
0263: if( FAILED(hr) )
0264: return hr;
0265:
0266: hr = SetActionFormat( diaf, TRUE );
0267: if( FAILED(hr) )
0268: return hr;
0269:
0270: return S_OK;
0271: }
0272:
0273:
0274:
0275:
0276:
0277:
0278:
0279:
0280: HRESULT CInputDeviceManager::ConfigureDevices( HWND hWnd, IUnknown* pSurface,
0281: VOID* ConfigureDevicesCB,
0282: DWORD dwFlags, LPVOID pvCBParam )
0283: {
0284: HRESULT hr;
0285:
0286:
0287: DICOLORSET dics;
0288: ZeroMemory(&dics, sizeof(DICOLORSET));
0289: dics.dwSize = sizeof(DICOLORSET);
0290:
0291:
0292: DICONFIGUREDEVICESPARAMS dicdp;
0293: ZeroMemory(&dicdp, sizeof(dicdp));
0294: dicdp.dwSize = sizeof(dicdp);
0295: dicdp.dwcFormats = 1;
0296: dicdp.lprgFormats = &m_diaf;
0297: dicdp.hwnd = hWnd;
0298: dicdp.lpUnkDDSTarget = pSurface;
0299:
0300: if( m_strUserName )
0301: {
0302: dicdp.dwcUsers = 1;
0303: dicdp.lptszUserNames = m_strUserName;
0304: }
0305:
0306:
0307: UnacquireDevices();
0308:
0309: hr = m_pDI->ConfigureDevices( (LPDICONFIGUREDEVICESCALLBACK)ConfigureDevicesCB,
0310: &dicdp, dwFlags, pvCBParam );
0311: if( FAILED(hr) )
0312: return hr;
0313:
0314: if( dwFlags & DICD_EDIT )
0315: {
0316:
0317: hr = SetActionFormat( m_diaf, TRUE );
0318: if( FAILED(hr) )
0319: return hr;
0320: }
0321:
0322: return S_OK;
0323: }
0324:
0325:
0326:
0327:
0328:
0329:
0330:
0331: VOID CInputDeviceManager::UnacquireDevices()
0332: {
0333: for( DWORD i=0; i<m_dwNumDevices; i++ )
0334: m_pDevices[i].pdidDevice->Unacquire();
0335: }
0336:
0337:
0338:
0339:
0340:
0341:
0342:
0343:
0344: VOID CInputDeviceManager::SetFocus( HWND hWnd )
0345: {
0346: m_hWnd = hWnd;
0347:
0348: UnacquireDevices();
0349:
0350: for( DWORD i=0; i<m_dwNumDevices; i++ )
0351: {
0352:
0353: m_pDevices[i].pdidDevice->SetCooperativeLevel( m_hWnd,
0354: DISCL_NONEXCLUSIVE|DISCL_FOREGROUND );
0355: }
0356: }
0357:
0358:
0359: