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.

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