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.

880 lines
25 KiB

  1. /*****************************************************************************
  2. *
  3. * diquick.c
  4. *
  5. * DirectInput quick test
  6. *
  7. *****************************************************************************/
  8. #include "diquick.h"
  9. /*****************************************************************************
  10. *
  11. * GetCheckedRadioButton
  12. *
  13. * Return the ID of the one that is checked.
  14. *
  15. * If nothing is checked, we return idFirst.
  16. *
  17. *****************************************************************************/
  18. UINT EXTERNAL
  19. GetCheckedRadioButton(HWND hdlg, UINT idFirst, UINT idLast)
  20. {
  21. for (; idFirst < idLast; idLast--) {
  22. if (IsDlgButtonChecked(hdlg, idLast)) {
  23. return idLast;
  24. }
  25. }
  26. return idLast;
  27. }
  28. /*****************************************************************************
  29. *
  30. * MessageBoxV
  31. *
  32. * Format a message and display a message box.
  33. *
  34. *****************************************************************************/
  35. int __cdecl
  36. MessageBoxV(HWND hdlg, UINT ids, ...)
  37. {
  38. va_list ap;
  39. TCHAR tszStr[256] = {0};
  40. TCHAR tszBuf[1024] = {0};
  41. LoadString(g_hinst, ids, tszStr, cA(tszStr));
  42. va_start(ap, ids);
  43. #ifdef WIN95
  44. {
  45. char *psz = NULL;
  46. char szDfs[1024]={0};
  47. strcpy(szDfs,tszStr); // make a local copy of format string
  48. while (psz = strstr(szDfs,"%p")) // find each %p
  49. *(psz+1) = 'x'; // replace each %p with %x
  50. wvsprintf(tszBuf, szDfs, ap); // use the local format string
  51. }
  52. #else
  53. {
  54. wvsprintf(tszBuf, tszStr, ap);
  55. }
  56. #endif
  57. va_end(ap);
  58. return MessageBox(hdlg, tszBuf, TEXT("DirectInput QuickTest"), MB_OK);
  59. }
  60. /*****************************************************************************
  61. *
  62. * ThreadFailHres
  63. *
  64. * Tell the parent that a thread failed to start, and display
  65. * an error message with an HRESULT code.
  66. *
  67. *****************************************************************************/
  68. int EXTERNAL
  69. ThreadFailHres(HWND hdlg, UINT ids, HRESULT hres)
  70. {
  71. SendNotifyMessage(hdlg, WM_THREADSTARTED, 0, 0);
  72. SendNotifyMessage(hdlg, WM_CHILDEXIT, 0, 0);
  73. return MessageBoxV(hdlg, ids, hres);
  74. }
  75. /*****************************************************************************
  76. *
  77. * RecalcCursor
  78. *
  79. * If the cursor is over the window, force a new WM_SETCUSOR.
  80. *
  81. *****************************************************************************/
  82. void EXTERNAL
  83. RecalcCursor(HWND hdlg)
  84. {
  85. POINT pt;
  86. HWND hwnd;
  87. GetCursorPos(&pt);
  88. hwnd = WindowFromPoint(pt);
  89. if( (hwnd != NULL) && (hwnd == hdlg || IsChild(hdlg, hwnd)) ) {
  90. SetCursorPos(pt.x, pt.y);
  91. }
  92. }
  93. /*****************************************************************************
  94. *
  95. * ModalVtbl
  96. *
  97. * Things that tell you about the modal gizmo.
  98. *
  99. *****************************************************************************/
  100. typedef struct MODALVTBL {
  101. BOOL (WINAPI *IsDialogMessage)(HWND, LPMSG);
  102. BOOL (WINAPI *IsAlive)(HWND);
  103. void (INTERNAL *SendIdle)(HWND);
  104. } MODALVTBL, *PMODALVTBL;
  105. /*****************************************************************************
  106. *
  107. * ModalLoop
  108. *
  109. * Spin waiting for the dialog box to die.
  110. *
  111. * WEIRDNESS! We send the WM_SELFENTERIDLE message to the dialog box
  112. * rather than to the owner. This avoids inter-thread sendmessage goo.
  113. *
  114. * Don't re-post the quit message if we get one. The purpose of the
  115. * quit message is to break the modal loop.
  116. *
  117. *****************************************************************************/
  118. int EXTERNAL
  119. ModalLoop(HWND hwndOwner, HWND hdlg, PMODALVTBL pvtbl)
  120. {
  121. if (hdlg) {
  122. BOOL fSentIdle = 0;
  123. while (pvtbl->IsAlive(hdlg)) {
  124. MSG msg;
  125. if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
  126. fSentIdle = 0;
  127. if (msg.message == WM_QUIT) {
  128. break;
  129. }
  130. if (!pvtbl->IsDialogMessage(hdlg, &msg)) {
  131. TranslateMessage(&msg);
  132. DispatchMessage(&msg);
  133. }
  134. } else {
  135. if (fSentIdle) {
  136. WaitMessage();
  137. } else {
  138. fSentIdle = 1;
  139. pvtbl->SendIdle(hdlg);
  140. }
  141. }
  142. }
  143. if (IsWindow(hdlg)) {
  144. DestroyWindow(hdlg);
  145. }
  146. }
  147. SendNotifyMessage(hwndOwner, WM_CHILDEXIT, 0, 0);
  148. return 0;
  149. }
  150. /*****************************************************************************
  151. *
  152. * SendDlgIdle
  153. *
  154. * Send the fake idle message.
  155. *
  156. *****************************************************************************/
  157. void INTERNAL
  158. SendDlgIdle(HWND hdlg)
  159. {
  160. SendMessage(hdlg, WM_SELFENTERIDLE, MSGF_DIALOGBOX, (LPARAM)hdlg);
  161. }
  162. /*****************************************************************************
  163. *
  164. * SemimodalDialogBoxParam
  165. *
  166. * Create a non-modal dialog box, then spin waiting for it to die.
  167. *
  168. *****************************************************************************/
  169. #pragma BEGIN_CONST_DATA
  170. MODALVTBL c_dlgvtbl = {
  171. IsDialogMessage,
  172. IsWindow,
  173. SendDlgIdle,
  174. };
  175. #pragma END_CONST_DATA
  176. int EXTERNAL
  177. SemimodalDialogBoxParam(UINT idd, HWND hwndOwner, DLGPROC dp, LPARAM lp)
  178. {
  179. return ModalLoop(hwndOwner, CreateDialogParam(g_hinst,
  180. (LPVOID)(UINT_PTR)idd, hwndOwner, dp, lp), &c_dlgvtbl);
  181. }
  182. /*****************************************************************************
  183. *
  184. * IsPrshtMessage
  185. *
  186. *****************************************************************************/
  187. BOOL WINAPI
  188. IsPrshtMessage(HWND hdlg, LPMSG pmsg)
  189. {
  190. return PropSheet_IsDialogMessage(hdlg, pmsg);
  191. }
  192. /*****************************************************************************
  193. *
  194. * IsPrshtAlive
  195. *
  196. *****************************************************************************/
  197. BOOL WINAPI
  198. IsPrshtAlive(HWND hdlg)
  199. {
  200. return (BOOL)(INT_PTR)PropSheet_GetCurrentPageHwnd(hdlg);
  201. }
  202. /*****************************************************************************
  203. *
  204. * SendPrshtIdle
  205. *
  206. * Send the fake idle message.
  207. *
  208. *****************************************************************************/
  209. void INTERNAL
  210. SendPrshtIdle(HWND hdlg)
  211. {
  212. hdlg = PropSheet_GetCurrentPageHwnd(hdlg);
  213. SendDlgIdle(hdlg);
  214. }
  215. /*****************************************************************************
  216. *
  217. * SemimodalPropertySheet
  218. *
  219. * Create a non-modal property sheet, then spin waiting for it to die.
  220. *
  221. * We nuke the Cancel and Apply buttons, change OK to Close, and move
  222. * the button into the corner.
  223. *
  224. *****************************************************************************/
  225. #pragma BEGIN_CONST_DATA
  226. MODALVTBL c_pshvtbl = {
  227. IsPrshtMessage,
  228. IsPrshtAlive,
  229. SendPrshtIdle,
  230. };
  231. #pragma END_CONST_DATA
  232. int EXTERNAL
  233. SemimodalPropertySheet(HWND hwndOwner, LPPROPSHEETHEADER ppsh)
  234. {
  235. HWND hdlg = (HWND)PropertySheet(ppsh);
  236. if ( hdlg && hdlg != (HWND)-1 ) {
  237. RECT rcOk, rcCancel;
  238. HWND hwnd;
  239. PropSheet_CancelToClose(hdlg);
  240. /* Slide the Close button to where the Cancel button is */
  241. hwnd = GetDlgItem(hdlg, IDCANCEL);
  242. GetWindowRect(hwnd, &rcCancel);
  243. ShowWindow(hwnd, SW_HIDE);
  244. hwnd = GetDlgItem(hdlg, IDOK);
  245. GetWindowRect(hwnd, &rcOk);
  246. rcOk.left += rcCancel.right - rcOk.right;
  247. ScreenToClient(hdlg, (LPPOINT)&rcOk);
  248. SetWindowPos(hwnd, 0, rcOk.left, rcOk.top, 0, 0,
  249. SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
  250. return ModalLoop(hwndOwner, hdlg, &c_pshvtbl);
  251. } else {
  252. return -1;
  253. }
  254. }
  255. /*****************************************************************************
  256. *
  257. * CreateDI
  258. *
  259. * Create an IDirectInput interface in the appropriate manner.
  260. *
  261. *****************************************************************************/
  262. #pragma BEGIN_CONST_DATA
  263. /*
  264. * This table must be in sync with the CDIFL_* values.
  265. */
  266. const IID *c_rgiidDI[] = {
  267. &IID_IDirectInput8A, /* CDIFL_DI8 */
  268. &IID_IDirectInput8W, /* CDIFL_UNICODE | CDIFL_DI8 */
  269. };
  270. #pragma END_CONST_DATA
  271. STDMETHODIMP
  272. CreateDI(BOOL fOle, UINT flCreate, PV ppvOut)
  273. {
  274. HRESULT hres;
  275. if (fOle) {
  276. const IID *piid = c_rgiidDI[flCreate];
  277. hres = CoCreateInstance(&CLSID_DirectInput8, 0, CLSCTX_INPROC_SERVER,
  278. piid, ppvOut);
  279. if (SUCCEEDED(hres)) {
  280. LPDIRECTINPUT pdi = *(PPV)ppvOut;
  281. hres = pdi->lpVtbl->Initialize(pdi, g_hinst, g_dwDIVer);
  282. if (FAILED(hres)) {
  283. pdi->lpVtbl->Release(pdi);
  284. *(PPV)ppvOut = 0;
  285. }
  286. }
  287. } else { /* Create via DI */
  288. if (flCreate & CDIFL_UNICODE) {
  289. hres = DirectInput8Create(g_hinst, g_dwDIVer, &IID_IDirectInput8W, ppvOut, 0);
  290. } else {
  291. hres = DirectInput8Create(g_hinst, g_dwDIVer, &IID_IDirectInput8A, ppvOut, 0);
  292. }
  293. /*
  294. * If necessary, QI for the 2 interface.
  295. */
  296. if (flCreate & CDIFL_DI2) {
  297. LPDIRECTINPUT pdi = *(PPV)ppvOut;
  298. hres = pdi->lpVtbl->QueryInterface(pdi, c_rgiidDI[flCreate],
  299. ppvOut);
  300. pdi->lpVtbl->Release(pdi);
  301. }
  302. }
  303. return hres;
  304. }
  305. /*****************************************************************************
  306. *
  307. * GetDwordProperty
  308. *
  309. * Get a DWORD property from an IDirectInputDevice.
  310. *
  311. *****************************************************************************/
  312. STDMETHODIMP
  313. GetDwordProperty(IDirectInputDevice8 *pdid, PCGUID pguid, LPDWORD pdw)
  314. {
  315. HRESULT hres;
  316. DIPROPDWORD dipdw;
  317. dipdw.diph.dwSize = sizeof(DIPROPDWORD);
  318. dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
  319. dipdw.diph.dwObj = 0;
  320. dipdw.diph.dwHow = DIPH_DEVICE;
  321. hres = IDirectInputDevice8_GetProperty(pdid, pguid, &dipdw.diph);
  322. if (SUCCEEDED(hres)) {
  323. *pdw = dipdw.dwData;
  324. }
  325. return hres;
  326. }
  327. /*****************************************************************************
  328. *
  329. * SetDwordProperty
  330. *
  331. * Set a DWORD property into an IDirectInputDevice.
  332. *
  333. *****************************************************************************/
  334. STDMETHODIMP
  335. SetDwordProperty(IDirectInputDevice8 *pdid, PCGUID pguid, DWORD dw)
  336. {
  337. DIPROPDWORD dipdw;
  338. dipdw.diph.dwSize = sizeof(DIPROPDWORD);
  339. dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
  340. dipdw.diph.dwObj = 0;
  341. dipdw.diph.dwHow = DIPH_DEVICE;
  342. dipdw.dwData = dw;
  343. return IDirectInputDevice8_SetProperty(pdid, pguid, &dipdw.diph);
  344. }
  345. /*****************************************************************************
  346. *
  347. * ConvertString
  348. *
  349. * Convert a string from whatever character set it is in into
  350. * the preferred character set (ANSI or UNICODE, whichever we
  351. * were compiled with).
  352. *
  353. * This is used to convert strings received from DirectInput
  354. * into something we like.
  355. *
  356. *****************************************************************************/
  357. void EXTERNAL
  358. ConvertString(BOOL fWide, LPCVOID pvIn, LPTSTR ptszOut, UINT ctchOut)
  359. {
  360. if (fTchar(fWide)) {
  361. lstrcpyn(ptszOut, pvIn, ctchOut);
  362. } else {
  363. #ifdef UNICODE
  364. MultiByteToWideChar(CP_ACP, 0, pvIn, -1, ptszOut, ctchOut);
  365. #else
  366. WideCharToMultiByte(CP_ACP, 0, pvIn, -1, ptszOut, ctchOut, 0, 0);
  367. #endif
  368. }
  369. }
  370. /*****************************************************************************
  371. *
  372. * UnconvertString
  373. *
  374. * Convert a string from the preferred character set
  375. * (ANSI or UNICODE, whichever we were compiled with)
  376. * into the specified character set.
  377. *
  378. * This is used to convert strings generated from dialogs
  379. * into something that DirectInput will like.
  380. *
  381. *****************************************************************************/
  382. void EXTERNAL
  383. UnconvertString(BOOL fWide, LPCTSTR ptszIn, LPVOID pvOut, UINT ctchOut)
  384. {
  385. if (fTchar(fWide)) {
  386. lstrcpyn(pvOut, ptszIn, ctchOut);
  387. } else {
  388. #ifdef UNICODE
  389. WideCharToMultiByte(CP_ACP, 0, ptszIn, -1, pvOut, ctchOut, 0, 0);
  390. #else
  391. MultiByteToWideChar(CP_ACP, 0, ptszIn, -1, pvOut, ctchOut);
  392. #endif
  393. }
  394. }
  395. /*****************************************************************************
  396. *
  397. * ConvertDoi
  398. *
  399. * Convert the pvDoi into the local character set.
  400. *
  401. *****************************************************************************/
  402. void EXTERNAL
  403. ConvertDoi(PDEVDLGINFO pddi, LPDIDEVICEOBJECTINSTANCE pdoi, LPCVOID pvDoi)
  404. {
  405. if (IsUnicodeDidc(pddi->didcItf)) {
  406. LPCDIDEVICEOBJECTINSTANCEW pdoiW = pvDoi;
  407. ConvertString(TRUE,
  408. pdoiW->tszName, pdoi->tszName, cA(pdoi->tszName));
  409. pdoi->guidType = pdoiW->guidType;
  410. pdoi->dwOfs = pdoiW->dwOfs;
  411. pdoi->dwType = pdoiW->dwType;
  412. pdoi->dwFlags = pdoiW->dwFlags;
  413. pdoi->dwSize = sizeof(DIDEVICEOBJECTINSTANCE_DX3);
  414. pdoi->wReportId = pdoiW->wReportId;
  415. if (pdoiW->dwSize > cbX(DIDEVICEOBJECTINSTANCE_DX3W)) {
  416. pdoi->dwFFMaxForce = pdoiW->dwFFMaxForce;
  417. pdoi->dwFFForceResolution = pdoiW->dwFFForceResolution;
  418. pdoi->wCollectionNumber = pdoiW->wCollectionNumber;
  419. pdoi->wDesignatorIndex = pdoiW->wDesignatorIndex;
  420. pdoi->wUsagePage = pdoiW->wUsagePage;
  421. pdoi->wUsage = pdoiW->wUsage;
  422. pdoi->dwSize = sizeof(DIDEVICEOBJECTINSTANCE);
  423. }
  424. } else {
  425. LPCDIDEVICEOBJECTINSTANCEA pdoiA = pvDoi;
  426. ConvertString(FALSE,
  427. pdoiA->tszName, pdoi->tszName, cA(pdoi->tszName));
  428. pdoi->guidType = pdoiA->guidType;
  429. pdoi->dwOfs = pdoiA->dwOfs;
  430. pdoi->dwType = pdoiA->dwType;
  431. pdoi->dwFlags = pdoiA->dwFlags;
  432. pdoi->dwSize = sizeof(DIDEVICEOBJECTINSTANCE_DX3);
  433. pdoi->wReportId = pdoiA->wReportId;
  434. if (pdoiA->dwSize > cbX(DIDEVICEOBJECTINSTANCE_DX3A)) {
  435. pdoi->dwFFMaxForce = pdoiA->dwFFMaxForce;
  436. pdoi->dwFFForceResolution = pdoiA->dwFFForceResolution;
  437. pdoi->wCollectionNumber = pdoiA->wCollectionNumber;
  438. pdoi->wDesignatorIndex = pdoiA->wDesignatorIndex;
  439. pdoi->wUsagePage = pdoiA->wUsagePage;
  440. pdoi->wUsage = pdoiA->wUsage;
  441. pdoi->dwSize = sizeof(DIDEVICEOBJECTINSTANCE);
  442. }
  443. }
  444. }
  445. /*****************************************************************************
  446. *
  447. * GetObjectInfo
  448. *
  449. * Do a GetObjectInfo with character set conversion.
  450. *
  451. *****************************************************************************/
  452. HRESULT EXTERNAL
  453. GetObjectInfo(PDEVDLGINFO pddi, LPDIDEVICEOBJECTINSTANCE pdoi,
  454. DWORD dwObj, DWORD dwHow)
  455. {
  456. HRESULT hres;
  457. union {
  458. DIDEVICEOBJECTINSTANCEA doiA;
  459. DIDEVICEOBJECTINSTANCEW doiW;
  460. } u;
  461. if (IsUnicodeDidc(pddi->didcItf)) {
  462. if (g_dwDIVer > 0x0300) {
  463. u.doiW.dwSize = cbX(u.doiW);
  464. } else {
  465. u.doiW.dwSize = cbX(DIDEVICEOBJECTINSTANCE_DX3W);
  466. }
  467. } else {
  468. if (g_dwDIVer > 0x0300) {
  469. u.doiA.dwSize = cbX(u.doiA);
  470. } else {
  471. u.doiA.dwSize = cbX(DIDEVICEOBJECTINSTANCE_DX3A);
  472. }
  473. }
  474. hres = IDirectInputDevice8_GetObjectInfo(pddi->pdid, (PV)&u,
  475. dwObj, dwHow);
  476. if (SUCCEEDED(hres)) {
  477. ConvertDoi(pddi, pdoi, &u);
  478. hres = S_OK;
  479. }
  480. return hres;
  481. }
  482. /*****************************************************************************
  483. *
  484. * ConvertDdi
  485. *
  486. * Convert the pvDdi into the local character set.
  487. *
  488. *****************************************************************************/
  489. void EXTERNAL
  490. ConvertDdi(PDEVDLGINFO pddi, LPDIDEVICEINSTANCE pinst, LPCVOID pvDdi)
  491. {
  492. if (IsUnicodeDidc(pddi->didcItf)) {
  493. LPCDIDEVICEINSTANCEW pinstW = pvDdi;
  494. ConvertString(TRUE,
  495. pinstW->tszInstanceName,
  496. pinst->tszInstanceName, cA(pinst->tszInstanceName));
  497. ConvertString(TRUE,
  498. pinstW->tszProductName,
  499. pinst->tszProductName, cA(pinst->tszProductName));
  500. pinst->guidInstance = pinstW->guidInstance;
  501. pinst->guidProduct = pinstW->guidProduct;
  502. pinst->dwDevType = pinstW->dwDevType;
  503. pinst->dwSize = sizeof(DIDEVICEINSTANCE_DX3);
  504. if (pinstW->dwSize > cbX(DIDEVICEINSTANCE_DX3W)) {
  505. pinst->guidFFDriver = pinstW->guidFFDriver;
  506. pinst->wUsagePage = pinstW->wUsagePage;
  507. pinst->wUsage = pinstW->wUsage;
  508. pinst->dwSize = sizeof(DIDEVICEINSTANCE);
  509. }
  510. } else {
  511. LPCDIDEVICEINSTANCEA pinstA = pvDdi;
  512. ConvertString(FALSE,
  513. pinstA->tszInstanceName,
  514. pinst->tszInstanceName, cA(pinst->tszInstanceName));
  515. ConvertString(FALSE,
  516. pinstA->tszProductName,
  517. pinst->tszProductName, cA(pinst->tszProductName));
  518. pinst->guidInstance = pinstA->guidInstance;
  519. pinst->guidProduct = pinstA->guidProduct;
  520. pinst->dwDevType = pinstA->dwDevType;
  521. pinst->dwSize = sizeof(DIDEVICEINSTANCE_DX3);
  522. if (pinstA->dwSize > cbX(DIDEVICEINSTANCE_DX3A)) {
  523. pinst->guidFFDriver = pinstA->guidFFDriver;
  524. pinst->wUsagePage = pinstA->wUsagePage;
  525. pinst->wUsage = pinstA->wUsage;
  526. pinst->dwSize = sizeof(DIDEVICEINSTANCE);
  527. }
  528. }
  529. }
  530. /*****************************************************************************
  531. *
  532. * GetDeviceInfo
  533. *
  534. * Do a GetDeviceInfo with character set conversion.
  535. *
  536. *****************************************************************************/
  537. HRESULT EXTERNAL
  538. GetDeviceInfo(PDEVDLGINFO pddi, LPDIDEVICEINSTANCE pinst)
  539. {
  540. HRESULT hres;
  541. union {
  542. DIDEVICEINSTANCEA ddiA;
  543. DIDEVICEINSTANCEW ddiW;
  544. } u;
  545. if (IsUnicodeDidc(pddi->didcItf)) {
  546. if (g_dwDIVer > 0x0300) {
  547. u.ddiW.dwSize = cbX(u.ddiW);
  548. } else {
  549. u.ddiW.dwSize = cbX(DIDEVICEINSTANCE_DX3W);
  550. }
  551. } else {
  552. if (g_dwDIVer > 0x0300) {
  553. u.ddiA.dwSize = cbX(u.ddiA);
  554. } else {
  555. u.ddiA.dwSize = cbX(DIDEVICEINSTANCE_DX3A);
  556. }
  557. }
  558. hres = IDirectInputDevice8_GetDeviceInfo(pddi->pdid, (PV)&u);
  559. if (SUCCEEDED(hres)) {
  560. ConvertDdi(pddi, pinst, &u);
  561. hres = S_OK;
  562. }
  563. return hres;
  564. }
  565. /*****************************************************************************
  566. *
  567. * ConvertEffi
  568. *
  569. * Convert the pvEffi into the local character set.
  570. *
  571. *****************************************************************************/
  572. void EXTERNAL
  573. ConvertEffi(PDEVDLGINFO pddi, LPDIEFFECTINFO pei, LPCVOID pvEffi)
  574. {
  575. LPCDIEFFECTINFOW peiW = pvEffi;
  576. LPCDIEFFECTINFOA peiA = pvEffi;
  577. LPCVOID pvStr;
  578. if (IsUnicodeDidc(pddi->didcItf)) {
  579. pvStr = peiW->tszName;
  580. } else {
  581. pvStr = peiA->tszName;
  582. }
  583. ConvertString(IsUnicodeDidc(pddi->didcItf),
  584. pvStr, pei->tszName, cA(pei->tszName));
  585. pei->guid = peiA->guid;
  586. pei->dwEffType = peiA->dwEffType;
  587. pei->dwStaticParams = peiA->dwStaticParams;
  588. pei->dwDynamicParams= peiA->dwDynamicParams;
  589. }
  590. /*****************************************************************************
  591. *
  592. * GetEffectInfo
  593. *
  594. * Do a GetEffectInfo with character set conversion.
  595. *
  596. *****************************************************************************/
  597. HRESULT EXTERNAL
  598. GetEffectInfo(PDEVDLGINFO pddi, LPDIEFFECTINFO pei, REFGUID rguid)
  599. {
  600. HRESULT hres;
  601. union {
  602. DIEFFECTINFOA deiA;
  603. DIEFFECTINFOW deiW;
  604. } u;
  605. if (IsUnicodeDidc(pddi->didcItf)) {
  606. u.deiW.dwSize = cbX(u.deiW);
  607. } else {
  608. u.deiA.dwSize = cbX(u.deiA);
  609. }
  610. hres = IDirectInputDevice8_GetEffectInfo(pddi->pdid, (PV)&u, rguid);
  611. if (SUCCEEDED(hres)) {
  612. ConvertEffi(pddi, pei, &u);
  613. hres = S_OK;
  614. }
  615. return hres;
  616. }
  617. /*****************************************************************************
  618. *
  619. * StringFromGuid
  620. *
  621. *****************************************************************************/
  622. void EXTERNAL
  623. StringFromGuid(LPTSTR ptsz, REFGUID rclsid)
  624. {
  625. wsprintf(ptsz,
  626. TEXT("{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}"),
  627. rclsid->Data1, rclsid->Data2, rclsid->Data3,
  628. rclsid->Data4[0], rclsid->Data4[1],
  629. rclsid->Data4[2], rclsid->Data4[3],
  630. rclsid->Data4[4], rclsid->Data4[5],
  631. rclsid->Data4[6], rclsid->Data4[7]);
  632. }
  633. /*****************************************************************************
  634. *
  635. * MapGUID
  636. *
  637. * Convert a GUID to a string, using a friendly name if possible.
  638. *
  639. * ptszBuf must be large enough to hold a stringized GUID.
  640. *
  641. *****************************************************************************/
  642. #pragma BEGIN_CONST_DATA
  643. extern GUID GUID_HIDClass;
  644. GUID GUID_Null;
  645. GUIDMAP c_rggm[] = {
  646. { &GUID_XAxis, "GUID_XAxis", },
  647. { &GUID_YAxis, "GUID_YAxis", },
  648. { &GUID_ZAxis, "GUID_ZAxis", },
  649. { &GUID_RxAxis, "GUID_RxAxis", },
  650. { &GUID_RyAxis, "GUID_RyAxis", },
  651. { &GUID_RzAxis, "GUID_RzAxis", },
  652. { &GUID_Slider, "GUID_Slider", },
  653. { &GUID_Button, "GUID_Button", },
  654. { &GUID_Key, "GUID_Key", },
  655. { &GUID_POV, "GUID_POV", },
  656. { &GUID_Unknown, "GUID_Unknown", },
  657. { &GUID_SysMouse, "GUID_SysMouse" },
  658. { &GUID_SysKeyboard, "GUID_SysKeyboard" },
  659. { &GUID_Joystick, "GUID_Joystick", },
  660. { &GUID_Unknown, "GUID_Unknown", },
  661. { &GUID_ConstantForce,"GUID_ConstantForce", },
  662. { &GUID_RampForce, "GUID_RampForce", },
  663. { &GUID_Square, "GUID_Square", },
  664. { &GUID_Sine, "GUID_Sine", },
  665. { &GUID_Triangle, "GUID_Triangle", },
  666. { &GUID_SawtoothUp, "GUID_SawtoothUp", },
  667. { &GUID_SawtoothDown, "GUID_SawtoothDown", },
  668. { &GUID_Spring, "GUID_Spring", },
  669. { &GUID_Damper, "GUID_Damper", },
  670. { &GUID_Inertia, "GUID_Inertia", },
  671. { &GUID_Friction, "GUID_Friction", },
  672. { &GUID_CustomForce, "GUID_CustomForce", },
  673. { &GUID_Null, "GUID_NULL", },
  674. { &GUID_HIDClass, "GUID_HIDClass", },
  675. };
  676. LPCTSTR EXTERNAL
  677. MapGUID(REFGUID rguid, LPTSTR ptszBuf)
  678. {
  679. int igm;
  680. for (igm = 0; igm < cA(c_rggm); igm++) {
  681. if (IsEqualGUID(rguid, c_rggm[igm].rguid)) {
  682. return c_rggm[igm].ptsz;
  683. }
  684. }
  685. StringFromGuid(ptszBuf, rguid);
  686. return ptszBuf;
  687. }
  688. /*****************************************************************************
  689. *
  690. * ProbeDinputVersion
  691. *
  692. * Snoop around to determine what version of DirectInput is available.
  693. *
  694. *****************************************************************************/
  695. void INTERNAL
  696. ProbeDinputVersion(void)
  697. {
  698. IDirectInput *pdi;
  699. HRESULT hres;
  700. /*
  701. * For safety's sake, start with DirectX 3.0 and gradually
  702. * work upwards.
  703. */
  704. g_dwDIVer = DIRECTINPUT_VERSION;
  705. #if 0
  706. hres = DirectInput8Create(g_hinst, 0x0300, &IID_IDirectInput8, (PVOID)&pdi, 0);
  707. if (SUCCEEDED(hres)) {
  708. /*
  709. * Probe upward to see what version of DirectX is supported.
  710. */
  711. if (SUCCEEDED(IDirectInput_Initialize(pdi, g_hinst,
  712. DIRECTINPUT_VERSION))) {
  713. g_dwDIVer = DIRECTINPUT_VERSION;
  714. }
  715. IDirectInput_Release(pdi);
  716. }
  717. #endif
  718. }
  719. /*****************************************************************************
  720. *
  721. * Globals
  722. *
  723. *****************************************************************************/
  724. HINSTANCE g_hinst;
  725. HCURSOR g_hcurWait;
  726. HCURSOR g_hcurStarting;
  727. DWORD g_dwDIVer;
  728. #ifdef DEBUG
  729. TCHAR g_tszInvalid[128];
  730. #endif
  731. /*****************************************************************************
  732. *
  733. * Entry
  734. *
  735. *****************************************************************************/
  736. void __cdecl
  737. Entry(void)
  738. {
  739. g_hcurWait = LoadCursor(0, IDC_WAIT);
  740. g_hcurStarting = LoadCursor(0, IDC_APPSTARTING);
  741. g_hinst = GetModuleHandle(0);
  742. #ifdef DEBUG
  743. LoadString(g_hinst, IDS_INVALID, g_tszInvalid, cA(g_tszInvalid));
  744. #endif
  745. Checklist_Init();
  746. ProbeDinputVersion();
  747. if (SUCCEEDED(CoInitialize(0))) {
  748. DialogBox(g_hinst, MAKEINTRESOURCE(IDD_MAIN), 0, Diq_DlgProc);
  749. CoUninitialize();
  750. }
  751. Checklist_Term();
  752. ExitProcess(0);
  753. }