Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

645 lines
20 KiB

  1. //===========================================================================
  2. // DICPUTIL.CPP
  3. //
  4. // DirectInput CPL helper functions.
  5. //
  6. // Functions:
  7. // DIUtilGetJoystickTypeName()
  8. // DIUtilPollJoystick()
  9. //
  10. //===========================================================================
  11. //===========================================================================
  12. // (C) Copyright 1997 Microsoft Corp. All rights reserved.
  13. //
  14. // You have a royalty-free right to use, modify, reproduce and
  15. // distribute the Sample Files (and/or any modified version) in
  16. // any way you find useful, provided that you agree that
  17. // Microsoft has no warranty obligations or liability for any
  18. // Sample Application Files which are modified.
  19. //===========================================================================
  20. #include "cplsvr1.h"
  21. #include "dicputil.h"
  22. #include <shlwapi.h> // for Str... functions!
  23. #include <malloc.h> // for _alloca
  24. extern HWND ghDlg;
  25. extern CDIGameCntrlPropSheet_X *pdiCpl;
  26. extern HINSTANCE ghInst;
  27. extern CRITICAL_SECTION gcritsect;
  28. //===========================================================================
  29. // DIUtilPollJoystick
  30. //
  31. // Polls the joystick device and returns the device state.
  32. //
  33. // Parameters:
  34. // LPDIRECTINPUTDEVICE2 pdiDevice2 - ptr to device object
  35. // DIJOYSTATE *pdijs - ptr to store joystick state
  36. //
  37. // Returns: HRESULT
  38. //
  39. //===========================================================================
  40. HRESULT DIUtilPollJoystick(LPDIRECTINPUTDEVICE2 pdiDevice2, LPDIJOYSTATE pdijs)
  41. {
  42. // clear the pdijs memory
  43. // this way, if we fail, we return no data
  44. pdijs->lX = pdijs->lY = pdijs->lZ = pdijs->lRx = pdijs->lRy = pdijs->lRz = pdijs->rglSlider[0] = pdijs->rglSlider[1] = 0;
  45. // poll the joystick
  46. HRESULT hRes;
  47. if( SUCCEEDED(hRes = pdiDevice2->Poll()) )
  48. {
  49. static BOOL bFirstPoll = TRUE;
  50. // This is to disreguard the first poll!
  51. // DINPUT sends garbage the first poll.
  52. if( bFirstPoll )
  53. {
  54. pdiDevice2->GetDeviceState(sizeof(DIJOYSTATE), pdijs);
  55. bFirstPoll = FALSE;
  56. }
  57. // query the device state
  58. if( FAILED(hRes = pdiDevice2->GetDeviceState(sizeof(DIJOYSTATE), pdijs)) )
  59. {
  60. if( hRes == DIERR_INPUTLOST )
  61. {
  62. if( SUCCEEDED(hRes = pdiDevice2->Acquire()) )
  63. hRes = pdiDevice2->GetDeviceState(sizeof(DIJOYSTATE), pdijs);
  64. }
  65. }
  66. }
  67. // done
  68. return(hRes);
  69. } // *** end DIUtilPollJoystick()
  70. //===========================================================================
  71. // InitDInput
  72. //
  73. // Initializes DirectInput objects
  74. //
  75. // Parameters:
  76. // HWND hWnd - handle of caller's window
  77. // CDIGameCntrlPropSheet_X *pdiCpl - pointer to Game Controllers property
  78. // sheet object
  79. //
  80. // Returns: HRESULT
  81. //
  82. //===========================================================================
  83. HRESULT InitDInput(HWND hWnd, CDIGameCntrlPropSheet_X *pdiCpl)
  84. {
  85. HRESULT hRes = S_OK;
  86. LPDIRECTINPUTDEVICE2 pdiDevice2;
  87. LPDIRECTINPUTJOYCONFIG pdiJoyCfg;
  88. LPDIRECTINPUT pdi = 0;
  89. // protect ourselves from multithreading problems
  90. EnterCriticalSection(&gcritsect);
  91. // validate pdiCpl
  92. if( (IsBadReadPtr((void*)pdiCpl, sizeof(CDIGameCntrlPropSheet_X))) ||
  93. (IsBadWritePtr((void*)pdiCpl, sizeof(CDIGameCntrlPropSheet_X))) )
  94. {
  95. #ifdef _DEBUG
  96. OutputDebugString(TEXT("GCDEF.DLL: InitDInput() - bogus pointer\n"));
  97. #endif
  98. hRes = E_POINTER;
  99. goto exitinit;
  100. }
  101. // retrieve the current device object
  102. pdiCpl->GetDevice(&pdiDevice2);
  103. // retrieve the current joyconfig object
  104. pdiCpl->GetJoyConfig(&pdiJoyCfg);
  105. // have we already initialized DirectInput?
  106. if( (NULL == pdiDevice2) || (NULL == pdiJoyCfg) )
  107. {
  108. // no, create a base DirectInput object
  109. if( FAILED(hRes = DirectInputCreate(ghInst, DIRECTINPUT_VERSION, &pdi, NULL)) )
  110. {
  111. #ifdef _DEBUG
  112. OutputDebugString(TEXT("GCDEF.DLL: DirectInputCreate() failed\n"));
  113. #endif
  114. goto exitinit;
  115. }
  116. // have we already created a joyconfig object?
  117. if( NULL == pdiJoyCfg )
  118. {
  119. // no, create a joyconfig object
  120. if( SUCCEEDED(pdi->QueryInterface(IID_IDirectInputJoyConfig, (LPVOID*)&pdiJoyCfg)) )
  121. {
  122. if( SUCCEEDED(pdiJoyCfg->SetCooperativeLevel(hWnd, DISCL_EXCLUSIVE | DISCL_BACKGROUND)) )
  123. pdiCpl->SetJoyConfig(pdiJoyCfg);
  124. } else
  125. {
  126. #ifdef _DEBUG
  127. OutputDebugString(TEXT("GCDEF.DLL: Unable to create joyconfig\n"));
  128. #endif
  129. goto exitinit;
  130. }
  131. }
  132. // have we already created a device object?
  133. if( NULL == pdiDevice2 )
  134. {
  135. // no, create a device object
  136. if( NULL != pdiJoyCfg )
  137. {
  138. LPDIRECTINPUTDEVICE pdiDevTemp;
  139. LPDIJOYCONFIG_DX5 lpDIJoyConfig = (LPDIJOYCONFIG_DX5)_alloca(sizeof(DIJOYCONFIG_DX5));
  140. ASSERT (lpDIJoyConfig);
  141. // get the type name
  142. ZeroMemory(lpDIJoyConfig, sizeof(DIJOYCONFIG_DX5));
  143. // GetConfig will provide this information
  144. lpDIJoyConfig->dwSize = sizeof(DIJOYCONFIG_DX5);
  145. // Get the instance necessarey for CreateDevice
  146. if( SUCCEEDED(hRes = pdiJoyCfg->GetConfig(pdiCpl->GetID(), (LPDIJOYCONFIG)lpDIJoyConfig, DIJC_GUIDINSTANCE)) )
  147. {
  148. // Create the device
  149. if( SUCCEEDED(hRes = pdi->CreateDevice(lpDIJoyConfig->guidInstance, &pdiDevTemp, NULL)) )
  150. {
  151. // Query the device for the Device2 interface!
  152. if( SUCCEEDED(hRes = pdiDevTemp->QueryInterface(IID_IDirectInputDevice2, (LPVOID*)&pdiDevice2)) )
  153. {
  154. // release the temporary object
  155. pdiDevTemp->Release();
  156. // Set the DataFormat and CooperativeLevel!
  157. if( SUCCEEDED(hRes = pdiDevice2->SetDataFormat(&c_dfDIJoystick)) )
  158. hRes = pdiDevice2->SetCooperativeLevel(hWnd, DISCL_EXCLUSIVE | DISCL_BACKGROUND);
  159. }
  160. }
  161. }
  162. if( SUCCEEDED(hRes) )
  163. {
  164. // store the device object
  165. pdiCpl->SetDevice(pdiDevice2);
  166. } else
  167. {
  168. goto exitinit;
  169. }
  170. } else goto exitinit;
  171. }
  172. } else {
  173. goto exitinit;
  174. }
  175. // if everything is Zero, either you've never enumerated or the enumeration is suspectable
  176. if( (pdiCpl->GetStateFlags()->nButtons == 0) &&
  177. (pdiCpl->GetStateFlags()->nAxis == 0) &&
  178. (pdiCpl->GetStateFlags()->nPOVs == 0) )
  179. {
  180. EnumDeviceObjects(pdiDevice2, pdiCpl->GetStateFlags());
  181. /*
  182. if (FAILED(pdiDevice2->EnumObjects((LPDIENUMDEVICEOBJECTSCALLBACK)DIEnumDeviceObjectsProc, (LPVOID *)pdiCpl->GetStateFlags(), DIDFT_ALL)))
  183. {
  184. #ifdef _DEBUG
  185. OutputDebugString(TEXT("GCDEF.DLL: TEST.CPP: WM_INIT: EnumObjects FAILED!\n"));
  186. #endif
  187. }
  188. */
  189. }
  190. exitinit:
  191. // release the base DirectInput object
  192. if( pdi ) {
  193. pdi->Release();
  194. }
  195. // we're done
  196. LeaveCriticalSection(&gcritsect);
  197. return(hRes);
  198. } //*** end InitDInput()
  199. void OnHelp(LPARAM lParam)
  200. {
  201. assert ( lParam );
  202. short nSize = STR_LEN_32;
  203. // point to help file
  204. LPTSTR pszHelpFileName = (LPTSTR) _alloca(sizeof(TCHAR[STR_LEN_32]));
  205. assert (pszHelpFileName);
  206. // returns help file name and size of string
  207. GetHelpFileName(pszHelpFileName, &nSize);
  208. if( ((LPHELPINFO)lParam)->iContextType == HELPINFO_WINDOW )
  209. WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle, pszHelpFileName, (UINT)HELP_WM_HELP, (ULONG_PTR)gaHelpIDs);
  210. }
  211. BOOL GetHelpFileName(TCHAR *lpszHelpFileName, short* nSize)
  212. {
  213. if( LoadString(ghInst, IDS_HELPFILENAME, lpszHelpFileName, *nSize) )
  214. return(S_OK);
  215. else
  216. return(E_FAIL);
  217. }
  218. ////////////////////////////////////////////////////////////////////////////////////////
  219. // OnContextMenu(WPARAM wParam)
  220. ////////////////////////////////////////////////////////////////////////////////////////
  221. void OnContextMenu(WPARAM wParam)
  222. {
  223. short nSize = STR_LEN_32;
  224. // point to help file
  225. LPTSTR pszHelpFileName = (LPTSTR) _alloca(sizeof(TCHAR[STR_LEN_32]));
  226. assert (pszHelpFileName);
  227. // returns help file name and size of string
  228. GetHelpFileName(pszHelpFileName, &nSize);
  229. WinHelp((HWND)wParam, pszHelpFileName, HELP_CONTEXTMENU, (ULONG_PTR)gaHelpIDs);
  230. }
  231. // Instead of enumerating via EnumObjects
  232. void EnumDeviceObjects(LPDIRECTINPUTDEVICE2 pdiDevice2, STATEFLAGS *pStateFlags)
  233. {
  234. LPDIDEVICEOBJECTINSTANCE_DX3 pDevObjInst = (LPDIDEVICEOBJECTINSTANCE_DX3) _alloca(sizeof(DIDEVICEOBJECTINSTANCE_DX3));
  235. assert (pDevObjInst);
  236. pDevObjInst->dwSize = sizeof(DIDEVICEOBJECTINSTANCE_DX3);
  237. const DWORD dwOffsetArray[] = {DIJOFS_X, DIJOFS_Y, DIJOFS_Z, DIJOFS_RX, DIJOFS_RY, DIJOFS_RZ, DIJOFS_SLIDER(0), DIJOFS_SLIDER(1)};
  238. // -1 is for 0 based dwOffsetArray!
  239. BYTE n = MAX_AXIS;
  240. do
  241. {
  242. if( SUCCEEDED(pdiDevice2->GetObjectInfo((LPDIDEVICEOBJECTINSTANCE)pDevObjInst, dwOffsetArray[--n], DIPH_BYOFFSET)) )
  243. pStateFlags->nAxis |= (HAS_X<<n);
  244. } while( n );
  245. n = MAX_BUTTONS;
  246. do
  247. {
  248. if( SUCCEEDED(pdiDevice2->GetObjectInfo((LPDIDEVICEOBJECTINSTANCE)pDevObjInst, DIJOFS_BUTTON(--n), DIPH_BYOFFSET)) )
  249. pStateFlags->nButtons |= (HAS_BUTTON1<<n);
  250. } while( n );
  251. n = MAX_POVS;
  252. do
  253. {
  254. if( SUCCEEDED(pdiDevice2->GetObjectInfo((LPDIDEVICEOBJECTINSTANCE)pDevObjInst, DIJOFS_POV(--n), DIPH_BYOFFSET)) )
  255. pStateFlags->nPOVs |= (HAS_POV1<<n);
  256. } while( n );
  257. }
  258. #define GETRANGE( n ) \
  259. pDIPropCal->lMin = lpMyRanges->jpMin.dw##n##; \
  260. pDIPropCal->lCenter = lpMyRanges->jpCenter.dw##n##; \
  261. pDIPropCal->lMax = lpMyRanges->jpMax.dw##n##; \
  262. void SetMyRanges(LPDIRECTINPUTDEVICE2 lpdiDevice2, LPMYJOYRANGE lpMyRanges, BYTE nAxis)
  263. {
  264. LPDIPROPCAL pDIPropCal = (LPDIPROPCAL)_alloca(sizeof(DIPROPCAL));
  265. assert (pDIPropCal);
  266. pDIPropCal->diph.dwSize = sizeof(DIPROPCAL);
  267. pDIPropCal->diph.dwHeaderSize = sizeof(DIPROPHEADER);
  268. pDIPropCal->diph.dwHow = DIPH_BYOFFSET;
  269. const DWORD dwOffsetArray[] = {DIJOFS_X, DIJOFS_Y, DIJOFS_Z, DIJOFS_RX, DIJOFS_RY, DIJOFS_RZ, DIJOFS_SLIDER(0), DIJOFS_SLIDER(1)};
  270. BYTE n = 0;
  271. // You have to start with a "while" here because Reset to Default may not have Any Axis!!!
  272. while( nAxis )
  273. {
  274. if( nAxis & HAS_X )
  275. {
  276. GETRANGE(X);
  277. } else if( nAxis & HAS_Y )
  278. {
  279. GETRANGE(Y);
  280. n = 1;
  281. } else if( nAxis & HAS_Z )
  282. {
  283. GETRANGE(Z)
  284. n = 2;
  285. } else if( nAxis & HAS_RX )
  286. {
  287. GETRANGE(Rx);
  288. n = 3;
  289. } else if( nAxis & HAS_RY )
  290. {
  291. GETRANGE(Ry);
  292. n = 4;
  293. } else if( nAxis & HAS_RZ )
  294. {
  295. GETRANGE(Rz);
  296. n = 5;
  297. } else if( nAxis & HAS_SLIDER0 )
  298. {
  299. GETRANGE(S0);
  300. n = 6;
  301. } else if( nAxis & HAS_SLIDER1 )
  302. {
  303. GETRANGE(S1);
  304. n = 7;
  305. }
  306. pDIPropCal->diph.dwObj = dwOffsetArray[n];
  307. VERIFY(SUCCEEDED(lpdiDevice2->SetProperty(DIPROP_CALIBRATION, &pDIPropCal->diph)));
  308. nAxis &= ~HAS_X<<n;
  309. }
  310. }
  311. // Removed 'till we calibrate POVs again!
  312. void SetMyPOVRanges(LPDIRECTINPUTDEVICE2 pdiDevice2)
  313. {
  314. DIPROPCALPOV *pDIPropCal = new (DIPROPCALPOV);
  315. assert (pDIPropCal);
  316. ZeroMemory(pDIPropCal, sizeof(*pDIPropCal));
  317. pDIPropCal->diph.dwSize = sizeof(*pDIPropCal);
  318. pDIPropCal->diph.dwHeaderSize = sizeof(DIPROPHEADER);
  319. pDIPropCal->diph.dwHow = DIPH_BYID;
  320. pDIPropCal->diph.dwObj = DIDFT_POV;
  321. memcpy( pDIPropCal->lMin, myPOV[POV_MIN], sizeof(pDIPropCal->lMin) );
  322. memcpy( pDIPropCal->lMax, myPOV[POV_MAX], sizeof(pDIPropCal->lMax) );
  323. if( FAILED(pdiDevice2->SetProperty(DIPROP_CALIBRATION, &pDIPropCal->diph)) )
  324. {
  325. #if (defined(_DEBUG) || defined(DEBUG))
  326. OutputDebugString(TEXT("GCDEF.DLL: SetMyRanges: SetProperty failed to set POV!\n"));
  327. #endif
  328. }
  329. if( pDIPropCal ) {
  330. delete (pDIPropCal);
  331. }
  332. }
  333. void SetTitle( HWND hDlg )
  334. {
  335. // Set the title bar!
  336. LPDIRECTINPUTDEVICE2 pdiDevice2;
  337. pdiCpl->GetDevice(&pdiDevice2);
  338. DIPROPSTRING *pDIPropStr = new (DIPROPSTRING);
  339. ASSERT (pDIPropStr);
  340. ZeroMemory(pDIPropStr, sizeof(DIPROPSTRING));
  341. pDIPropStr->diph.dwSize = sizeof(DIPROPSTRING);
  342. pDIPropStr->diph.dwHeaderSize = sizeof(DIPROPHEADER);
  343. pDIPropStr->diph.dwHow = DIPH_DEVICE;
  344. if( SUCCEEDED(pdiDevice2->GetProperty(DIPROP_INSTANCENAME, &pDIPropStr->diph)) )
  345. {
  346. TCHAR tszFormat[STR_LEN_64];
  347. #ifndef _UNICODE
  348. CHAR szOut[STR_LEN_128];
  349. #endif
  350. LPWSTR lpwszTitle = new (WCHAR[STR_LEN_128]);
  351. ASSERT (lpwszTitle);
  352. // Shorten length, provide elipse,
  353. if( wcslen(pDIPropStr->wsz) > 32 )
  354. {
  355. pDIPropStr->wsz[30] = pDIPropStr->wsz[31] = pDIPropStr->wsz[32] = L'.';
  356. pDIPropStr->wsz[33] = L'\0';
  357. }
  358. LoadString(ghInst, IDS_SHEETCAPTION, tszFormat, sizeof(tszFormat)/sizeof(tszFormat[0]));
  359. #ifdef _UNICODE
  360. wsprintfW(lpwszTitle, tszFormat, pDIPropStr->wsz);
  361. #else
  362. USES_CONVERSION;
  363. wsprintfA(szOut, tszFormat, W2A(pDIPropStr->wsz));
  364. StrCpyW(lpwszTitle, A2W(szOut));
  365. #endif
  366. //SetWindowText(GetParent(hDlg),
  367. ::SendMessage(GetParent(hDlg), WM_SETTEXT, 0, (LPARAM)(LPCTSTR)
  368. #ifdef _UNICODE
  369. lpwszTitle);
  370. #else
  371. W2A(lpwszTitle));
  372. #endif
  373. if( lpwszTitle )
  374. delete[] (lpwszTitle);
  375. }
  376. #ifdef _DEBUG
  377. else OutputDebugString(TEXT("GCDEF.DLL: DICPUTIL.CPP: SetTitle: GetProperty Failed!\n"));
  378. #endif
  379. if( pDIPropStr )
  380. delete (pDIPropStr);
  381. }
  382. BOOL Error(HWND hWnd, short nTitleID, short nMsgID)
  383. {
  384. LPTSTR lptTitle = new TCHAR[STR_LEN_64];
  385. ASSERT (lptTitle);
  386. BOOL bRet = FALSE;
  387. if( LoadString(ghInst, nTitleID, lptTitle, STR_LEN_64) )
  388. {
  389. LPTSTR lptMsg = (LPTSTR)_alloca(sizeof(TCHAR[STR_LEN_128]));
  390. ASSERT (lptMsg);
  391. if( LoadString(ghInst, nMsgID, lptMsg, STR_LEN_128) )
  392. {
  393. MessageBox(hWnd, lptMsg, lptTitle, MB_ICONHAND | MB_OK);
  394. bRet = TRUE;
  395. }
  396. }
  397. if( lptTitle )
  398. delete[] (lptTitle);
  399. return(bRet);
  400. }
  401. void CenterDialog(HWND hWnd)
  402. {
  403. RECT rc;
  404. HWND hParentWnd = GetParent(hWnd);
  405. GetWindowRect(hParentWnd, &rc);
  406. // Centre the Dialog!
  407. SetWindowPos(hParentWnd, NULL,
  408. (GetSystemMetrics(SM_CXSCREEN) - (rc.right-rc.left))>>1,
  409. (GetSystemMetrics(SM_CYSCREEN) - (rc.bottom-rc.top))>>1,
  410. NULL, NULL, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW);
  411. }
  412. #define SETRANGE( n ) \
  413. lpMyRanges->jpMin.dw##n## = pDIPropRange->lMin; \
  414. lpMyRanges->jpCenter.dw##n## = pDIPropRange->lCenter; \
  415. lpMyRanges->jpMax.dw##n## = pDIPropRange->lMax; \
  416. //===========================================================================
  417. // BOOL GetMyRanges( LPMYJOYRANGE lpMyRanges, LPDIRECTINPUTDEVICE2 pdiDevice2, BYTE nAxis)
  418. //
  419. // Parameters:
  420. // LPMYJOYRANGE lpMyRanges - Structure to fill with ranges
  421. // LPDIRECTINPUTDEVICE2 pdiDevice2 - Device in which axis ranges are requested
  422. // BYTE nAxis - Bit mask of axis ranges to retrieve
  423. //
  424. // Returns: FALSE if failed
  425. //
  426. //===========================================================================
  427. void GetMyRanges(LPDIRECTINPUTDEVICE2 lpdiDevice2, LPMYJOYRANGE lpMyRanges, BYTE nAxis)
  428. {
  429. // Use DIPROPCAL to retrieve Range Information
  430. // Don't use DIPROPRANGE, as it doesn't have Center!
  431. LPDIPROPCAL pDIPropRange = (LPDIPROPCAL)_alloca(sizeof(DIPROPCAL));
  432. assert(pDIPropRange);
  433. pDIPropRange->diph.dwSize = sizeof(DIPROPCAL);
  434. pDIPropRange->diph.dwHeaderSize = sizeof(DIPROPHEADER);
  435. pDIPropRange->diph.dwHow = DIPH_BYOFFSET;
  436. const DWORD dwOffsetArray[] = {DIJOFS_X, DIJOFS_Y, DIJOFS_Z, DIJOFS_RX, DIJOFS_RY, DIJOFS_RZ, DIJOFS_SLIDER(0), DIJOFS_SLIDER(1)};
  437. BYTE nIndex = 0;
  438. // Zero out the buffer members and the index!
  439. pDIPropRange->lMin = pDIPropRange->lCenter = pDIPropRange->lMax = 0;
  440. // You don't have to start with "while" here because Reset to Default does not call this function!!1
  441. do
  442. {
  443. if( nAxis & HAS_X )
  444. {
  445. pDIPropRange->diph.dwObj = dwOffsetArray[nIndex = 0];
  446. if( SUCCEEDED(lpdiDevice2->GetProperty(DIPROP_CALIBRATION, &pDIPropRange->diph)) )
  447. {
  448. SETRANGE(X);
  449. }
  450. } else if( nAxis & HAS_Y )
  451. {
  452. pDIPropRange->diph.dwObj = dwOffsetArray[nIndex = 1];
  453. if( SUCCEEDED(lpdiDevice2->GetProperty(DIPROP_CALIBRATION, &pDIPropRange->diph)) )
  454. {
  455. SETRANGE(Y);
  456. }
  457. } else if( nAxis & HAS_Z )
  458. {
  459. pDIPropRange->diph.dwObj = dwOffsetArray[nIndex = 2];
  460. if( SUCCEEDED(lpdiDevice2->GetProperty(DIPROP_CALIBRATION, &pDIPropRange->diph)) )
  461. {
  462. SETRANGE(Z);
  463. }
  464. } else if( nAxis & HAS_RX )
  465. {
  466. pDIPropRange->diph.dwObj = dwOffsetArray[nIndex = 3];
  467. if( SUCCEEDED(lpdiDevice2->GetProperty(DIPROP_CALIBRATION, &pDIPropRange->diph)) )
  468. {
  469. SETRANGE(Rx);
  470. }
  471. } else if( nAxis & HAS_RY )
  472. {
  473. pDIPropRange->diph.dwObj = dwOffsetArray[nIndex = 4];
  474. if( SUCCEEDED(lpdiDevice2->GetProperty(DIPROP_CALIBRATION, &pDIPropRange->diph)) )
  475. {
  476. SETRANGE(Ry);
  477. }
  478. } else if( nAxis & HAS_RZ )
  479. {
  480. pDIPropRange->diph.dwObj = dwOffsetArray[nIndex = 5];
  481. if( SUCCEEDED(lpdiDevice2->GetProperty(DIPROP_CALIBRATION, &pDIPropRange->diph)) )
  482. {
  483. SETRANGE(Rz);
  484. }
  485. } else if( nAxis & HAS_SLIDER0 )
  486. {
  487. pDIPropRange->diph.dwObj = dwOffsetArray[nIndex = 6];
  488. if( SUCCEEDED(lpdiDevice2->GetProperty(DIPROP_CALIBRATION, &pDIPropRange->diph)) )
  489. {
  490. SETRANGE(S0);
  491. }
  492. } else if( nAxis & HAS_SLIDER1 )
  493. {
  494. pDIPropRange->diph.dwObj = dwOffsetArray[nIndex = 7];
  495. if( SUCCEEDED(lpdiDevice2->GetProperty(DIPROP_CALIBRATION, &pDIPropRange->diph)) )
  496. {
  497. SETRANGE(S1);
  498. }
  499. } else {
  500. break;
  501. }
  502. } while( nAxis &= ~HAS_X<<nIndex );
  503. }
  504. void PostDlgItemEnableWindow(HWND hDlg, USHORT nItem, BOOL bEnabled)
  505. {
  506. HWND hCtrl = GetDlgItem(hDlg, nItem);
  507. if( hCtrl )
  508. PostEnableWindow(hCtrl, bEnabled);
  509. }
  510. void PostEnableWindow(HWND hCtrl, BOOL bEnabled)
  511. {
  512. DWORD dwStyle = GetWindowLong(hCtrl, GWL_STYLE);
  513. // No point Redrawing the Window if there's no change!
  514. if( bEnabled )
  515. {
  516. if( dwStyle & WS_DISABLED )
  517. dwStyle &= ~WS_DISABLED;
  518. else return;
  519. } else
  520. {
  521. if( !(dwStyle & WS_DISABLED) )
  522. dwStyle |= WS_DISABLED;
  523. else return;
  524. }
  525. SetWindowLongPtr(hCtrl, GWL_STYLE, (LONG_PTR)dwStyle);
  526. RedrawWindow(hCtrl, NULL, NULL, RDW_INTERNALPAINT | RDW_INVALIDATE);
  527. }
  528. void CopyRange( LPJOYRANGE lpjr, LPMYJOYRANGE lpmyjr )
  529. {
  530. memcpy( &lpjr->jpMin, &lpmyjr->jpMin, sizeof(JOYPOS) );
  531. memcpy( &lpjr->jpCenter, &lpmyjr->jpCenter, sizeof(JOYPOS) );
  532. memcpy( &lpjr->jpMax, &lpmyjr->jpMax, sizeof(JOYPOS) );
  533. }