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.

226 lines
6.5 KiB

  1. /*****************************************************************************
  2. *
  3. * diqdev.c
  4. *
  5. * The dialog box that asks what to do with the DirectInput device.
  6. *
  7. *****************************************************************************/
  8. #include "diquick.h"
  9. /*****************************************************************************
  10. *
  11. * Property sheet goo
  12. *
  13. *****************************************************************************/
  14. #pragma BEGIN_CONST_DATA
  15. #define MAKE_PSP(idd, dlgproc) { \
  16. cbX(PROPSHEETPAGE), /* dwSize */ \
  17. PSP_DEFAULT, /* dwFlags */ \
  18. 0, /* hInstance */ \
  19. MAKEINTRESOURCE(idd), /* pszTemplate */ \
  20. 0, /* hIcon */ \
  21. 0, /* pszTitle */ \
  22. dlgproc, /* pfnDlgProc */ \
  23. idd == IDD_ENUMEFF, /* lParam */ \
  24. 0, /* pfnCallback */ \
  25. 0, /* pcRefParent */ \
  26. } \
  27. PROPSHEETPAGE c_rgpsp[] = {
  28. EACH_PROPSHEET(MAKE_PSP)
  29. };
  30. #undef MAKE_PSP
  31. RIID c_rgriid[] = {
  32. &IID_IDirectInputDevice8A,
  33. &IID_IDirectInputDevice8W,
  34. };
  35. #pragma END_CONST_DATA
  36. /*****************************************************************************
  37. *
  38. * Dev_DoPropertySheet
  39. *
  40. *****************************************************************************/
  41. BOOL INTERNAL
  42. Dev_DoPropertySheet(PDEVDLGINFO pddi)
  43. {
  44. PROPSHEETPAGE rgpsp[cA(c_rgpsp)];
  45. PROPSHEETHEADER psh;
  46. int ipsp;
  47. psh.dwSize = cbX(psh);
  48. psh.dwFlags = PSH_PROPSHEETPAGE | PSH_MODELESS | PSH_NOAPPLYNOW;
  49. psh.hwndParent = 0; /* pddi->hdlgOwner */
  50. psh.pszCaption = pddi->ptszDesc;
  51. psh.nPages = 0;
  52. psh.nStartPage = 0;
  53. psh.ppsp = rgpsp;
  54. /*
  55. * The lParam of the structure is nonzero iff the page should
  56. * be shown only if the DX 5 interface is being used.
  57. */
  58. for (ipsp = 0; ipsp < cA(c_rgpsp); ipsp++) {
  59. if (fLimpFF(c_rgpsp[ipsp].lParam, pddi->pdid)) {
  60. rgpsp[psh.nPages] = c_rgpsp[ipsp];
  61. rgpsp[psh.nPages].hInstance = g_hinst;
  62. rgpsp[psh.nPages].lParam = (LPARAM)pddi;
  63. psh.nPages++;
  64. }
  65. }
  66. return SemimodalPropertySheet(pddi->hdlgOwner, &psh);
  67. }
  68. /*****************************************************************************
  69. *
  70. * Dev_DoDevice
  71. *
  72. *****************************************************************************/
  73. HRESULT INTERNAL
  74. Dev_DoDevice(PDEVDLGINFO pddi, LPDIRECTINPUTA pdia)
  75. {
  76. HRESULT hres;
  77. UINT idsError;
  78. if (pdia) {
  79. /*
  80. * To create an uninitialized device, we CoCreateInstance it
  81. * and "forget" to call Initialize().
  82. */
  83. if (IsEqualGUID(pddi->pguidInstance, &GUID_Uninit)) {
  84. REFIID riid = IsUnicodeDidc(pddi->didcItf)
  85. ? &IID_IDirectInputDevice8W
  86. : &IID_IDirectInputDevice8A;
  87. hres = CoCreateInstance(&CLSID_DirectInputDevice8, 0,
  88. CLSCTX_INPROC_SERVER,
  89. riid, (PV)&pddi->pdid);
  90. } else {
  91. hres = IDirectInput_CreateDevice(pdia, pddi->pguidInstance,
  92. (PV)&pddi->pdid, 0);
  93. }
  94. /*
  95. * If we need to change character set, then do so in-place.
  96. */
  97. if (SUCCEEDED(hres) && pddi->flCreate != (BOOL)pddi->didcItf) {
  98. IDirectInputDevice8 *pdid;
  99. hres = IDirectInputDevice8_QueryInterface(pddi->pdid,
  100. c_rgriid[pddi->didcItf],
  101. (PV)&pdid);
  102. IDirectInputDevice8_Release(pddi->pdid);
  103. pddi->pdid = pdid;
  104. if (IsFFDidc(pddi->didcItf)) {
  105. pddi->pdid = (PV)pdid;
  106. } else {
  107. pddi->pdid = 0;
  108. }
  109. }
  110. } else {
  111. hres = E_FAIL;
  112. }
  113. SendNotifyMessage(pddi->hdlgOwner, WM_THREADSTARTED, 0, 0);
  114. if (SUCCEEDED(hres)) {
  115. idsError = Dev_DoPropertySheet(pddi) ? IDS_ERR_CREATEDEV : 0;
  116. pddi->pdid->lpVtbl->Release(pddi->pdid);
  117. } else {
  118. idsError = IDS_ERR_CREATEDEV;
  119. }
  120. if (idsError) {
  121. MessageBoxV(pddi->hdlgOwner, idsError);
  122. SendNotifyMessage(pddi->hdlgOwner, WM_CHILDEXIT, 0, 0);
  123. }
  124. return hres;
  125. }
  126. /*****************************************************************************
  127. *
  128. * Dev_ThreadStart
  129. *
  130. * Runs on the new thread. Creates the object and spins the dialog
  131. * box to control it.
  132. *
  133. *****************************************************************************/
  134. DWORD WINAPI
  135. Dev_ThreadStart(PDEVDLGINFO pddi)
  136. {
  137. HRESULT hres;
  138. LPDIRECTINPUTA pdia;
  139. hres = CoInitialize(0);
  140. if (SUCCEEDED(hres)) {
  141. hres = CreateDI(pddi->fOle, pddi->flCreate, (PPV)&pdia);
  142. if (SUCCEEDED(hres)) {
  143. hres = Dev_DoDevice(pddi, pdia);
  144. pdia->lpVtbl->Release(pdia);
  145. } else {
  146. ThreadFailHres(pddi->hdlgOwner, IDS_ERR_CREATEOBJ, hres);
  147. }
  148. CoUninitialize();
  149. } else {
  150. ThreadFailHres(pddi->hdlgOwner, IDS_ERR_COINIT, hres);
  151. }
  152. LocalFree(pddi);
  153. return 0;
  154. }
  155. /*****************************************************************************
  156. *
  157. * Dev_Create
  158. *
  159. * Spin a thread to create a DirectInput device interface.
  160. *
  161. *****************************************************************************/
  162. INT_PTR EXTERNAL
  163. Dev_Create(HWND hdlg, BOOL fOle, UINT flCreate,
  164. const GUID *pguidInstance, LPCTSTR ptszDesc, UINT didcItf)
  165. {
  166. PDEVDLGINFO pddi = LocalAlloc(LPTR, cbX(DEVDLGINFO));
  167. if (pddi) {
  168. DWORD id;
  169. HANDLE h;
  170. pddi->hdlgOwner = hdlg ;
  171. pddi->fOle = fOle ;
  172. pddi->flCreate = flCreate ;
  173. pddi->pguidInstance = pguidInstance;
  174. pddi->ptszDesc = ptszDesc ;
  175. pddi->didcItf = didcItf ;
  176. h = CreateThread(0, 0, Dev_ThreadStart, pddi, 0, &id);
  177. if (h) {
  178. } else {
  179. if (pddi->pvtbl) {
  180. pddi->pvtbl->Destroy(pddi);
  181. }
  182. LocalFree(pddi);
  183. pddi = 0;
  184. }
  185. }
  186. return (INT_PTR)pddi;
  187. }