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_IDirectInputA, /* */
  268. &IID_IDirectInputW, /* CDIFL_UNICODE */
  269. &IID_IDirectInput2A, /* CDIFL_DI2 */
  270. &IID_IDirectInput2W, /* CDIFL_UNICODE | CDIFL_DI2 */
  271. };
  272. #pragma END_CONST_DATA
  273. STDMETHODIMP
  274. CreateDI(BOOL fOle, UINT flCreate, PV ppvOut)
  275. {
  276. HRESULT hres;
  277. if (fOle) {
  278. const IID *piid = c_rgiidDI[flCreate];
  279. hres = CoCreateInstance(&CLSID_DirectInput, 0, CLSCTX_INPROC_SERVER,
  280. piid, ppvOut);
  281. if (SUCCEEDED(hres)) {
  282. LPDIRECTINPUT pdi = *(PPV)ppvOut;
  283. hres = pdi->lpVtbl->Initialize(pdi, g_hinst, g_dwDIVer);
  284. if (FAILED(hres)) {
  285. pdi->lpVtbl->Release(pdi);
  286. *(PPV)ppvOut = 0;
  287. }
  288. }
  289. } else { /* Create via DI */
  290. if (flCreate & CDIFL_UNICODE) {
  291. hres = DirectInputCreateW(g_hinst, g_dwDIVer, ppvOut, 0);
  292. } else {
  293. hres = DirectInputCreateA(g_hinst, g_dwDIVer, ppvOut, 0);
  294. }
  295. /*
  296. * If necessary, QI for the 2 interface.
  297. */
  298. if (flCreate & CDIFL_DI2) {
  299. LPDIRECTINPUT pdi = *(PPV)ppvOut;
  300. hres = pdi->lpVtbl->QueryInterface(pdi, c_rgiidDI[flCreate],
  301. ppvOut);
  302. pdi->lpVtbl->Release(pdi);
  303. }
  304. }
  305. return hres;
  306. }
  307. /*****************************************************************************
  308. *
  309. * GetDwordProperty
  310. *
  311. * Get a DWORD property from an IDirectInputDevice.
  312. *
  313. *****************************************************************************/
  314. STDMETHODIMP
  315. GetDwordProperty(IDirectInputDevice *pdid, PCGUID pguid, LPDWORD pdw)
  316. {
  317. HRESULT hres;
  318. DIPROPDWORD dipdw;
  319. dipdw.diph.dwSize = sizeof(DIPROPDWORD);
  320. dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
  321. dipdw.diph.dwObj = 0;
  322. dipdw.diph.dwHow = DIPH_DEVICE;
  323. hres = IDirectInputDevice_GetProperty(pdid, pguid, &dipdw.diph);
  324. if (SUCCEEDED(hres)) {
  325. *pdw = dipdw.dwData;
  326. }
  327. return hres;
  328. }
  329. /*****************************************************************************
  330. *
  331. * SetDwordProperty
  332. *
  333. * Set a DWORD property into an IDirectInputDevice.
  334. *
  335. *****************************************************************************/
  336. STDMETHODIMP
  337. SetDwordProperty(IDirectInputDevice *pdid, PCGUID pguid, DWORD dw)
  338. {
  339. DIPROPDWORD dipdw;
  340. dipdw.diph.dwSize = sizeof(DIPROPDWORD);
  341. dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
  342. dipdw.diph.dwObj = 0;
  343. dipdw.diph.dwHow = DIPH_DEVICE;
  344. dipdw.dwData = dw;
  345. return IDirectInputDevice_SetProperty(pdid, pguid, &dipdw.diph);
  346. }
  347. /*****************************************************************************
  348. *
  349. * ConvertString
  350. *
  351. * Convert a string from whatever character set it is in into
  352. * the preferred character set (ANSI or UNICODE, whichever we
  353. * were compiled with).
  354. *
  355. * This is used to convert strings received from DirectInput
  356. * into something we like.
  357. *
  358. *****************************************************************************/
  359. void EXTERNAL
  360. ConvertString(BOOL fWide, LPCVOID pvIn, LPTSTR ptszOut, UINT ctchOut)
  361. {
  362. if (fTchar(fWide)) {
  363. lstrcpyn(ptszOut, pvIn, ctchOut);
  364. } else {
  365. #ifdef UNICODE
  366. MultiByteToWideChar(CP_ACP, 0, pvIn, -1, ptszOut, ctchOut);
  367. #else
  368. WideCharToMultiByte(CP_ACP, 0, pvIn, -1, ptszOut, ctchOut, 0, 0);
  369. #endif
  370. }
  371. }
  372. /*****************************************************************************
  373. *
  374. * UnconvertString
  375. *
  376. * Convert a string from the preferred character set
  377. * (ANSI or UNICODE, whichever we were compiled with)
  378. * into the specified character set.
  379. *
  380. * This is used to convert strings generated from dialogs
  381. * into something that DirectInput will like.
  382. *
  383. *****************************************************************************/
  384. void EXTERNAL
  385. UnconvertString(BOOL fWide, LPCTSTR ptszIn, LPVOID pvOut, UINT ctchOut)
  386. {
  387. if (fTchar(fWide)) {
  388. lstrcpyn(pvOut, ptszIn, ctchOut);
  389. } else {
  390. #ifdef UNICODE
  391. WideCharToMultiByte(CP_ACP, 0, ptszIn, -1, pvOut, ctchOut, 0, 0);
  392. #else
  393. MultiByteToWideChar(CP_ACP, 0, ptszIn, -1, pvOut, ctchOut);
  394. #endif
  395. }
  396. }
  397. /*****************************************************************************
  398. *
  399. * ConvertDoi
  400. *
  401. * Convert the pvDoi into the local character set.
  402. *
  403. *****************************************************************************/
  404. void EXTERNAL
  405. ConvertDoi(PDEVDLGINFO pddi, LPDIDEVICEOBJECTINSTANCE pdoi, LPCVOID pvDoi)
  406. {
  407. if (IsUnicodeDidc(pddi->didcItf)) {
  408. LPCDIDEVICEOBJECTINSTANCEW pdoiW = pvDoi;
  409. ConvertString(TRUE,
  410. pdoiW->tszName, pdoi->tszName, cA(pdoi->tszName));
  411. pdoi->guidType = pdoiW->guidType;
  412. pdoi->dwOfs = pdoiW->dwOfs;
  413. pdoi->dwType = pdoiW->dwType;
  414. pdoi->dwFlags = pdoiW->dwFlags;
  415. pdoi->dwSize = sizeof(DIDEVICEOBJECTINSTANCE_DX3);
  416. pdoi->wReportId = pdoiW->wReportId;
  417. if (pdoiW->dwSize > cbX(DIDEVICEOBJECTINSTANCE_DX3W)) {
  418. pdoi->dwFFMaxForce = pdoiW->dwFFMaxForce;
  419. pdoi->dwFFForceResolution = pdoiW->dwFFForceResolution;
  420. pdoi->wCollectionNumber = pdoiW->wCollectionNumber;
  421. pdoi->wDesignatorIndex = pdoiW->wDesignatorIndex;
  422. pdoi->wUsagePage = pdoiW->wUsagePage;
  423. pdoi->wUsage = pdoiW->wUsage;
  424. pdoi->dwSize = sizeof(DIDEVICEOBJECTINSTANCE);
  425. }
  426. } else {
  427. LPCDIDEVICEOBJECTINSTANCEA pdoiA = pvDoi;
  428. ConvertString(FALSE,
  429. pdoiA->tszName, pdoi->tszName, cA(pdoi->tszName));
  430. pdoi->guidType = pdoiA->guidType;
  431. pdoi->dwOfs = pdoiA->dwOfs;
  432. pdoi->dwType = pdoiA->dwType;
  433. pdoi->dwFlags = pdoiA->dwFlags;
  434. pdoi->dwSize = sizeof(DIDEVICEOBJECTINSTANCE_DX3);
  435. pdoi->wReportId = pdoiA->wReportId;
  436. if (pdoiA->dwSize > cbX(DIDEVICEOBJECTINSTANCE_DX3A)) {
  437. pdoi->dwFFMaxForce = pdoiA->dwFFMaxForce;
  438. pdoi->dwFFForceResolution = pdoiA->dwFFForceResolution;
  439. pdoi->wCollectionNumber = pdoiA->wCollectionNumber;
  440. pdoi->wDesignatorIndex = pdoiA->wDesignatorIndex;
  441. pdoi->wUsagePage = pdoiA->wUsagePage;
  442. pdoi->wUsage = pdoiA->wUsage;
  443. pdoi->dwSize = sizeof(DIDEVICEOBJECTINSTANCE);
  444. }
  445. }
  446. }
  447. /*****************************************************************************
  448. *
  449. * GetObjectInfo
  450. *
  451. * Do a GetObjectInfo with character set conversion.
  452. *
  453. *****************************************************************************/
  454. HRESULT EXTERNAL
  455. GetObjectInfo(PDEVDLGINFO pddi, LPDIDEVICEOBJECTINSTANCE pdoi,
  456. DWORD dwObj, DWORD dwHow)
  457. {
  458. HRESULT hres;
  459. union {
  460. DIDEVICEOBJECTINSTANCEA doiA;
  461. DIDEVICEOBJECTINSTANCEW doiW;
  462. } u;
  463. if (IsUnicodeDidc(pddi->didcItf)) {
  464. if (g_dwDIVer > 0x0300) {
  465. u.doiW.dwSize = cbX(u.doiW);
  466. } else {
  467. u.doiW.dwSize = cbX(DIDEVICEOBJECTINSTANCE_DX3W);
  468. }
  469. } else {
  470. if (g_dwDIVer > 0x0300) {
  471. u.doiA.dwSize = cbX(u.doiA);
  472. } else {
  473. u.doiA.dwSize = cbX(DIDEVICEOBJECTINSTANCE_DX3A);
  474. }
  475. }
  476. hres = IDirectInputDevice_GetObjectInfo(pddi->pdid, (PV)&u,
  477. dwObj, dwHow);
  478. if (SUCCEEDED(hres)) {
  479. ConvertDoi(pddi, pdoi, &u);
  480. hres = S_OK;
  481. }
  482. return hres;
  483. }
  484. /*****************************************************************************
  485. *
  486. * ConvertDdi
  487. *
  488. * Convert the pvDdi into the local character set.
  489. *
  490. *****************************************************************************/
  491. void EXTERNAL
  492. ConvertDdi(PDEVDLGINFO pddi, LPDIDEVICEINSTANCE pinst, LPCVOID pvDdi)
  493. {
  494. if (IsUnicodeDidc(pddi->didcItf)) {
  495. LPCDIDEVICEINSTANCEW pinstW = pvDdi;
  496. ConvertString(TRUE,
  497. pinstW->tszInstanceName,
  498. pinst->tszInstanceName, cA(pinst->tszInstanceName));
  499. ConvertString(TRUE,
  500. pinstW->tszProductName,
  501. pinst->tszProductName, cA(pinst->tszProductName));
  502. pinst->guidInstance = pinstW->guidInstance;
  503. pinst->guidProduct = pinstW->guidProduct;
  504. pinst->dwDevType = pinstW->dwDevType;
  505. pinst->dwSize = sizeof(DIDEVICEINSTANCE_DX3);
  506. if (pinstW->dwSize > cbX(DIDEVICEINSTANCE_DX3W)) {
  507. pinst->guidFFDriver = pinstW->guidFFDriver;
  508. pinst->wUsagePage = pinstW->wUsagePage;
  509. pinst->wUsage = pinstW->wUsage;
  510. pinst->dwSize = sizeof(DIDEVICEINSTANCE);
  511. }
  512. } else {
  513. LPCDIDEVICEINSTANCEA pinstA = pvDdi;
  514. ConvertString(FALSE,
  515. pinstA->tszInstanceName,
  516. pinst->tszInstanceName, cA(pinst->tszInstanceName));
  517. ConvertString(FALSE,
  518. pinstA->tszProductName,
  519. pinst->tszProductName, cA(pinst->tszProductName));
  520. pinst->guidInstance = pinstA->guidInstance;
  521. pinst->guidProduct = pinstA->guidProduct;
  522. pinst->dwDevType = pinstA->dwDevType;
  523. pinst->dwSize = sizeof(DIDEVICEINSTANCE_DX3);
  524. if (pinstA->dwSize > cbX(DIDEVICEINSTANCE_DX3A)) {
  525. pinst->guidFFDriver = pinstA->guidFFDriver;
  526. pinst->wUsagePage = pinstA->wUsagePage;
  527. pinst->wUsage = pinstA->wUsage;
  528. pinst->dwSize = sizeof(DIDEVICEINSTANCE);
  529. }
  530. }
  531. }
  532. /*****************************************************************************
  533. *
  534. * GetDeviceInfo
  535. *
  536. * Do a GetDeviceInfo with character set conversion.
  537. *
  538. *****************************************************************************/
  539. HRESULT EXTERNAL
  540. GetDeviceInfo(PDEVDLGINFO pddi, LPDIDEVICEINSTANCE pinst)
  541. {
  542. HRESULT hres;
  543. union {
  544. DIDEVICEINSTANCEA ddiA;
  545. DIDEVICEINSTANCEW ddiW;
  546. } u;
  547. if (IsUnicodeDidc(pddi->didcItf)) {
  548. if (g_dwDIVer > 0x0300) {
  549. u.ddiW.dwSize = cbX(u.ddiW);
  550. } else {
  551. u.ddiW.dwSize = cbX(DIDEVICEINSTANCE_DX3W);
  552. }
  553. } else {
  554. if (g_dwDIVer > 0x0300) {
  555. u.ddiA.dwSize = cbX(u.ddiA);
  556. } else {
  557. u.ddiA.dwSize = cbX(DIDEVICEINSTANCE_DX3A);
  558. }
  559. }
  560. hres = IDirectInputDevice_GetDeviceInfo(pddi->pdid, (PV)&u);
  561. if (SUCCEEDED(hres)) {
  562. ConvertDdi(pddi, pinst, &u);
  563. hres = S_OK;
  564. }
  565. return hres;
  566. }
  567. /*****************************************************************************
  568. *
  569. * ConvertEffi
  570. *
  571. * Convert the pvEffi into the local character set.
  572. *
  573. *****************************************************************************/
  574. void EXTERNAL
  575. ConvertEffi(PDEVDLGINFO pddi, LPDIEFFECTINFO pei, LPCVOID pvEffi)
  576. {
  577. LPCDIEFFECTINFOW peiW = pvEffi;
  578. LPCDIEFFECTINFOA peiA = pvEffi;
  579. LPCVOID pvStr;
  580. if (IsUnicodeDidc(pddi->didcItf)) {
  581. pvStr = peiW->tszName;
  582. } else {
  583. pvStr = peiA->tszName;
  584. }
  585. ConvertString(IsUnicodeDidc(pddi->didcItf),
  586. pvStr, pei->tszName, cA(pei->tszName));
  587. pei->guid = peiA->guid;
  588. pei->dwEffType = peiA->dwEffType;
  589. pei->dwStaticParams = peiA->dwStaticParams;
  590. pei->dwDynamicParams= peiA->dwDynamicParams;
  591. }
  592. /*****************************************************************************
  593. *
  594. * GetEffectInfo
  595. *
  596. * Do a GetEffectInfo with character set conversion.
  597. *
  598. *****************************************************************************/
  599. HRESULT EXTERNAL
  600. GetEffectInfo(PDEVDLGINFO pddi, LPDIEFFECTINFO pei, REFGUID rguid)
  601. {
  602. HRESULT hres;
  603. union {
  604. DIEFFECTINFOA deiA;
  605. DIEFFECTINFOW deiW;
  606. } u;
  607. if (IsUnicodeDidc(pddi->didcItf)) {
  608. u.deiW.dwSize = cbX(u.deiW);
  609. } else {
  610. u.deiA.dwSize = cbX(u.deiA);
  611. }
  612. hres = IDirectInputDevice2_GetEffectInfo(pddi->pdid2, (PV)&u, rguid);
  613. if (SUCCEEDED(hres)) {
  614. ConvertEffi(pddi, pei, &u);
  615. hres = S_OK;
  616. }
  617. return hres;
  618. }
  619. /*****************************************************************************
  620. *
  621. * StringFromGuid
  622. *
  623. *****************************************************************************/
  624. void EXTERNAL
  625. StringFromGuid(LPTSTR ptsz, REFGUID rclsid)
  626. {
  627. wsprintf(ptsz,
  628. TEXT("{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}"),
  629. rclsid->Data1, rclsid->Data2, rclsid->Data3,
  630. rclsid->Data4[0], rclsid->Data4[1],
  631. rclsid->Data4[2], rclsid->Data4[3],
  632. rclsid->Data4[4], rclsid->Data4[5],
  633. rclsid->Data4[6], rclsid->Data4[7]);
  634. }
  635. /*****************************************************************************
  636. *
  637. * MapGUID
  638. *
  639. * Convert a GUID to a string, using a friendly name if possible.
  640. *
  641. * ptszBuf must be large enough to hold a stringized GUID.
  642. *
  643. *****************************************************************************/
  644. #pragma BEGIN_CONST_DATA
  645. extern GUID GUID_HIDClass;
  646. GUID GUID_Null;
  647. GUIDMAP c_rggm[] = {
  648. { &GUID_XAxis, "GUID_XAxis", },
  649. { &GUID_YAxis, "GUID_YAxis", },
  650. { &GUID_ZAxis, "GUID_ZAxis", },
  651. { &GUID_RxAxis, "GUID_RxAxis", },
  652. { &GUID_RyAxis, "GUID_RyAxis", },
  653. { &GUID_RzAxis, "GUID_RzAxis", },
  654. { &GUID_Slider, "GUID_Slider", },
  655. { &GUID_Button, "GUID_Button", },
  656. { &GUID_Key, "GUID_Key", },
  657. { &GUID_POV, "GUID_POV", },
  658. { &GUID_Unknown, "GUID_Unknown", },
  659. { &GUID_SysMouse, "GUID_SysMouse" },
  660. { &GUID_SysKeyboard, "GUID_SysKeyboard" },
  661. { &GUID_Joystick, "GUID_Joystick", },
  662. { &GUID_Unknown, "GUID_Unknown", },
  663. { &GUID_ConstantForce,"GUID_ConstantForce", },
  664. { &GUID_RampForce, "GUID_RampForce", },
  665. { &GUID_Square, "GUID_Square", },
  666. { &GUID_Sine, "GUID_Sine", },
  667. { &GUID_Triangle, "GUID_Triangle", },
  668. { &GUID_SawtoothUp, "GUID_SawtoothUp", },
  669. { &GUID_SawtoothDown, "GUID_SawtoothDown", },
  670. { &GUID_Spring, "GUID_Spring", },
  671. { &GUID_Damper, "GUID_Damper", },
  672. { &GUID_Inertia, "GUID_Inertia", },
  673. { &GUID_Friction, "GUID_Friction", },
  674. { &GUID_CustomForce, "GUID_CustomForce", },
  675. { &GUID_Null, "GUID_NULL", },
  676. { &GUID_HIDClass, "GUID_HIDClass", },
  677. };
  678. LPCTSTR EXTERNAL
  679. MapGUID(REFGUID rguid, LPTSTR ptszBuf)
  680. {
  681. int igm;
  682. for (igm = 0; igm < cA(c_rggm); igm++) {
  683. if (IsEqualGUID(rguid, c_rggm[igm].rguid)) {
  684. return c_rggm[igm].ptsz;
  685. }
  686. }
  687. StringFromGuid(ptszBuf, rguid);
  688. return ptszBuf;
  689. }
  690. /*****************************************************************************
  691. *
  692. * ProbeDinputVersion
  693. *
  694. * Snoop around to determine what version of DirectInput is available.
  695. *
  696. *****************************************************************************/
  697. void INTERNAL
  698. ProbeDinputVersion(void)
  699. {
  700. IDirectInput *pdi;
  701. HRESULT hres;
  702. /*
  703. * For safety's sake, start with DirectX 3.0 and gradually
  704. * work upwards.
  705. */
  706. g_dwDIVer = 0x0300;
  707. hres = DirectInputCreate(g_hinst, 0x0300, (PVOID)&pdi, 0);
  708. if (SUCCEEDED(hres)) {
  709. /*
  710. * Probe upward to see what version of DirectX is supported.
  711. */
  712. if (SUCCEEDED(IDirectInput_Initialize(pdi, g_hinst,
  713. DIRECTINPUT_VERSION))) {
  714. g_dwDIVer = DIRECTINPUT_VERSION;
  715. }
  716. IDirectInput_Release(pdi);
  717. }
  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. }