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.

507 lines
14 KiB

  1. /*****************************************************************************
  2. *
  3. * diqmain.c
  4. *
  5. * The main dialog box.
  6. *
  7. *****************************************************************************/
  8. #include "diquick.h"
  9. GUID GUID_Uninit = { 1 };
  10. DWORD g_dwEnumType;
  11. DWORD g_dwEnumFlags;
  12. /*****************************************************************************
  13. *
  14. * Dialog instance data
  15. *
  16. * Instance data for main dialog box.
  17. *
  18. *****************************************************************************/
  19. typedef struct MAINDLGINFO {
  20. HWND hwndDevices; /* Devices combo box */
  21. UINT cBusy; /* Number of threads starting */
  22. UINT cDevs; /* Number of devices created */
  23. IDirectInput *pdi; /* Cached interface */
  24. BOOL fW; /* Is pdi a pdiW? (else, pdiA) */
  25. DARY daryDevs; /* Device info lives here */
  26. } MAINDLGINFO, *PMAINDLGINFO;
  27. /*****************************************************************************
  28. *
  29. * Diq_DeviceEnumProc
  30. *
  31. * Device enumeration procedure which is called one for each device.
  32. *
  33. * Add the item to our dialog instance data and to the combo box.
  34. *
  35. *****************************************************************************/
  36. BOOL INTERNAL
  37. Diq_DeviceEnumProc(PCV pvDi, LPVOID pv)
  38. {
  39. PMAINDLGINFO pmdi = pv;
  40. DIDEVICEINSTANCE didi;
  41. TCHAR tsz[1024];
  42. int ich;
  43. if (pmdi->fW) {
  44. LPCDIDEVICEINSTANCEW pdiW = pvDi;
  45. didi.guidInstance = pdiW->guidInstance;
  46. didi.guidProduct = pdiW->guidProduct;
  47. didi.dwDevType = pdiW->dwDevType;
  48. ConvertString(pmdi->fW, pdiW->tszProductName,
  49. didi.tszProductName,
  50. cA(didi.tszProductName));
  51. ConvertString(pmdi->fW, pdiW->tszInstanceName,
  52. didi.tszInstanceName,
  53. cA(didi.tszInstanceName));
  54. } else {
  55. LPCDIDEVICEINSTANCEA pdiA = pvDi;
  56. didi.guidInstance = pdiA->guidInstance;
  57. didi.guidProduct = pdiA->guidProduct;
  58. didi.dwDevType = pdiA->dwDevType;
  59. ConvertString(pmdi->fW, pdiA->tszProductName,
  60. didi.tszProductName,
  61. cA(didi.tszProductName));
  62. ConvertString(pmdi->fW, pdiA->tszInstanceName,
  63. didi.tszInstanceName,
  64. cA(didi.tszInstanceName));
  65. }
  66. ich = wsprintf(tsz, TEXT("%s (%s)"),
  67. didi.tszInstanceName,
  68. didi.tszProductName);
  69. if (didi.dwDevType & DIDEVTYPE_HID) {
  70. LoadString(g_hinst, IDS_SPACEPARENHID, &tsz[ich], 10);
  71. }
  72. ComboBox_AddString(pmdi->hwndDevices, tsz);
  73. Dary_Append(&pmdi->daryDevs, &didi);
  74. return DIENUM_CONTINUE;
  75. }
  76. /*****************************************************************************
  77. *
  78. * Diq_EnumDevices
  79. *
  80. * Rebuild the list of enumerated devices. Try to preserve the
  81. * current selection index.
  82. *
  83. *****************************************************************************/
  84. void INTERNAL
  85. Diq_EnumDevices(PMAINDLGINFO pmdi)
  86. {
  87. HRESULT hres;
  88. int iSel = ComboBox_GetCurSel(pmdi->hwndDevices);
  89. HCURSOR hcurPrev = GetCursor();
  90. SetCursor(LoadCursor(NULL, IDC_WAIT));
  91. Dary_Term(&pmdi->daryDevs);
  92. ZeroX(pmdi->daryDevs);
  93. ComboBox_ResetContent(pmdi->hwndDevices);
  94. #if defined(_DEBUG) || defined(DEBUG)
  95. {
  96. /*
  97. * Create the intentionally invalid device.
  98. */
  99. DIDEVICEINSTANCE didi;
  100. ComboBox_AddString(pmdi->hwndDevices, g_tszInvalid);
  101. ZeroX(didi);
  102. Dary_Append(&pmdi->daryDevs, &didi);
  103. ComboBox_AddString(pmdi->hwndDevices, "<uninit>");
  104. ZeroX(didi);
  105. didi.guidInstance = GUID_Uninit;
  106. lstrcpyn(didi.tszInstanceName, "<uninit instance>",
  107. cA(didi.tszInstanceName));
  108. Dary_Append(&pmdi->daryDevs, &didi);
  109. }
  110. #endif
  111. pmdi->fW = 1;
  112. hres = DirectInput8Create(g_hinst, g_dwDIVer, &IID_IDirectInput8W, (PVOID)&pmdi->pdi, 0);
  113. /* For each object, add it to the menu */
  114. if (SUCCEEDED(hres)) {
  115. IDirectInput_EnumDevices(pmdi->pdi, g_dwEnumType, Diq_DeviceEnumProc,
  116. pmdi, g_dwEnumFlags);
  117. IDirectInput_Release(pmdi->pdi);
  118. pmdi->pdi = 0;
  119. }
  120. ComboBox_SetCurSel(pmdi->hwndDevices, max(iSel, 0));
  121. SetCursor(hcurPrev);
  122. }
  123. /*****************************************************************************
  124. *
  125. * Diq_OnInitDialog
  126. *
  127. * Populate the combo box with the list of devices.
  128. *
  129. *****************************************************************************/
  130. BOOL INTERNAL
  131. Diq_OnInitDialog(HWND hdlg)
  132. {
  133. PMAINDLGINFO pmdi;
  134. Diq_HackPropertySheets(hdlg);
  135. pmdi = LocalAlloc(LPTR, cbX(MAINDLGINFO));
  136. if ( !pmdi ) {
  137. return 0;
  138. }
  139. SetDialogPtr(hdlg, pmdi);
  140. pmdi->hwndDevices = GetDlgItem(hdlg, IDC_MAIN_DEVICES);
  141. Diq_EnumDevices(pmdi);
  142. CheckRadioButton(hdlg, IDC_MAIN_OLE, IDC_MAIN_DI, IDC_MAIN_DI);
  143. CheckRadioButton(hdlg, IDC_MAIN_DIA, IDC_MAIN_DIW, IDC_MAIN_DIW);
  144. CheckRadioButton(hdlg, IDC_MAIN_DIDA, IDC_MAIN_ITFMAC, IDC_MAIN_DIDW);
  145. if (g_dwDIVer <= 0x0300) {
  146. //EnableWindow(GetDlgItem(hdlg, IDC_MAIN_DID2A), FALSE);
  147. //EnableWindow(GetDlgItem(hdlg, IDC_MAIN_DID2W), FALSE);
  148. EnableWindow(GetDlgItem(hdlg, IDC_MAIN_DIDJC), FALSE);
  149. }
  150. return 1;
  151. }
  152. /*****************************************************************************
  153. *
  154. * Diq_OnDestroy
  155. *
  156. * Clean up.
  157. *
  158. *****************************************************************************/
  159. BOOL INTERNAL
  160. Diq_OnDestroy(PMAINDLGINFO pmdi, HWND hdlg)
  161. {
  162. if (pmdi) {
  163. Dary_Term(&pmdi->daryDevs);
  164. LocalFree(pmdi);
  165. }
  166. return 1;
  167. }
  168. /*****************************************************************************
  169. *
  170. * Diq_RecalcClose
  171. *
  172. * Enable or disable the SC_CLOSE option accordingly.
  173. *
  174. *****************************************************************************/
  175. void INTERNAL
  176. Diq_RecalcClose(PMAINDLGINFO pmdi, HWND hdlg)
  177. {
  178. EnableMenuItem(GetSystemMenu(hdlg, 0), SC_CLOSE,
  179. MF_BYCOMMAND |
  180. (pmdi->cDevs ? MF_DISABLED | MF_GRAYED : MF_ENABLED));
  181. }
  182. /*****************************************************************************
  183. *
  184. * Diq_OnGetStatus
  185. *
  186. * Somebody asked for the status of the device.
  187. *
  188. *****************************************************************************/
  189. BOOL INTERNAL
  190. Diq_OnGetStatus(HWND hdlg)
  191. {
  192. PMAINDLGINFO pmdi = GetDialogPtr(hdlg);
  193. int iSel = ComboBox_GetCurSel(pmdi->hwndDevices);
  194. if ((UINT)iSel < (UINT)pmdi->daryDevs.cx) {
  195. LPDIRECTINPUTA pdia;
  196. HRESULT hres;
  197. UINT didc;
  198. int ids;
  199. didc = GetCheckedRadioButton(hdlg,
  200. IDC_MAIN_ITF, IDC_MAIN_ITFMAC) - IDC_MAIN_ITF;
  201. hres = CreateDI(IsDlgButtonChecked(hdlg, IDC_MAIN_OLE),
  202. IsUnicodeDidc(didc),
  203. (PPV)&pdia);
  204. if (SUCCEEDED(hres)) {
  205. LPDIDEVICEINSTANCE pdidi;
  206. pdidi = Dary_GetPtr(&pmdi->daryDevs, iSel, DIDEVICEINSTANCE);
  207. hres = IDirectInput_GetDeviceStatus(pdia,
  208. &pdidi->guidInstance);
  209. switch (hres) {
  210. case DI_OK: ids = IDS_GETSTAT_OK; break;
  211. case DI_NOTATTACHED: ids = IDS_GETSTAT_NOTATTACHED; break;
  212. default: ids = IDS_GETSTAT_ERROR; break;
  213. }
  214. } else {
  215. ids = IDS_GETSTAT_ERROR;
  216. }
  217. MessageBoxV(hdlg, ids, hres);
  218. }
  219. return 1;
  220. }
  221. /*****************************************************************************
  222. *
  223. * Diq_OnCreateObject
  224. *
  225. * Somebody asked us to create an object. Party!
  226. *
  227. *****************************************************************************/
  228. BOOL INTERNAL
  229. Diq_OnCreateObject(HWND hdlg)
  230. {
  231. PMAINDLGINFO pmdi = GetDialogPtr(hdlg);
  232. int iSel = ComboBox_GetCurSel(pmdi->hwndDevices);
  233. //#ifdef DEBUG
  234. if (IsDlgButtonChecked(hdlg, IDC_MAIN_DIDJC)) {
  235. if (Cpl_Create(hdlg,
  236. IsDlgButtonChecked(hdlg, IDC_MAIN_OLE),
  237. IsDlgButtonChecked(hdlg, IDC_MAIN_DIW))) {
  238. pmdi->cBusy++;
  239. pmdi->cDevs++;
  240. RecalcCursor(hdlg);
  241. Diq_RecalcClose(pmdi, hdlg);
  242. }
  243. } else
  244. //#endif
  245. if ((UINT)iSel < (UINT)pmdi->daryDevs.cx) {
  246. UINT didc;
  247. LPDIDEVICEINSTANCE pdidi;
  248. didc = GetCheckedRadioButton(hdlg,
  249. IDC_MAIN_ITF, IDC_MAIN_ITFMAC) - IDC_MAIN_ITF;
  250. pdidi = Dary_GetPtr(&pmdi->daryDevs, iSel, DIDEVICEINSTANCE);
  251. if (Dev_Create(hdlg,
  252. IsDlgButtonChecked(hdlg, IDC_MAIN_OLE),
  253. IsUnicodeDidc(didc),
  254. &pdidi->guidInstance,
  255. pdidi->tszInstanceName,
  256. didc)) {
  257. pmdi->cBusy++;
  258. pmdi->cDevs++;
  259. RecalcCursor(hdlg);
  260. Diq_RecalcClose(pmdi, hdlg);
  261. }
  262. }
  263. return 1;
  264. }
  265. /*****************************************************************************
  266. *
  267. * Diq_OnFindDevice
  268. *
  269. * Display the "FindDevice" dialog.
  270. *
  271. *****************************************************************************/
  272. BOOL INTERNAL
  273. Diq_OnFindDevice(HWND hdlg)
  274. {
  275. PMAINDLGINFO pmdi = GetDialogPtr(hdlg);
  276. UINT didc;
  277. didc = GetCheckedRadioButton(hdlg,
  278. IDC_MAIN_ITF, IDC_MAIN_ITFMAC) - IDC_MAIN_ITF;
  279. if (Find_Create(hdlg,
  280. IsDlgButtonChecked(hdlg, IDC_MAIN_OLE),
  281. IsDlgButtonChecked(hdlg, IDC_MAIN_DIW))) {
  282. pmdi->cBusy++;
  283. pmdi->cDevs++;
  284. RecalcCursor(hdlg);
  285. Diq_RecalcClose(pmdi, hdlg);
  286. }
  287. return 1;
  288. }
  289. /*****************************************************************************
  290. *
  291. * Diq_OnControlPanel
  292. *
  293. * Run the DirectInput control panel using the indicated interface.
  294. *
  295. *****************************************************************************/
  296. BOOL INTERNAL
  297. Diq_OnControlPanel(HWND hdlg)
  298. {
  299. HRESULT hres;
  300. LPDIRECTINPUTA pdia;
  301. hres = CreateDI(IsDlgButtonChecked(hdlg, IDC_MAIN_OLE),
  302. IsDlgButtonChecked(hdlg, IDC_MAIN_DIW),
  303. (PPV)&pdia);
  304. if (SUCCEEDED(hres)) {
  305. hres = pdia->lpVtbl->RunControlPanel(pdia, hdlg, 0);
  306. if (SUCCEEDED(hres)) {
  307. } else {
  308. MessageBoxV(hdlg, IDS_ERR_RUNCPL, hres);
  309. }
  310. pdia->lpVtbl->Release(pdia);
  311. } else {
  312. MessageBoxV(hdlg, IDS_ERR_CREATEOBJ, hres);
  313. }
  314. return 1;
  315. }
  316. /*****************************************************************************
  317. *
  318. * Diq_OnRefresh
  319. *
  320. * Refresh the device list.
  321. *
  322. *****************************************************************************/
  323. BOOL INTERNAL
  324. Diq_OnRefresh(HWND hdlg)
  325. {
  326. if (DialogBox(g_hinst, MAKEINTRESOURCE(IDD_ENUMDEV),
  327. hdlg, DEnum_DlgProc) > 0) {
  328. PMAINDLGINFO pmdi = GetDialogPtr(hdlg);
  329. Diq_EnumDevices(pmdi);
  330. }
  331. return TRUE;
  332. }
  333. /*****************************************************************************
  334. *
  335. * Diq_OnCommand
  336. *
  337. *****************************************************************************/
  338. BOOL INLINE
  339. Diq_OnCommand(HWND hdlg, int id, UINT cmd)
  340. {
  341. switch (id) {
  342. case IDC_MAIN_GETSTAT:return Diq_OnGetStatus(hdlg);
  343. case IDC_MAIN_CREATE: return Diq_OnCreateObject(hdlg);
  344. case IDC_MAIN_CPL: return Diq_OnControlPanel(hdlg);
  345. case IDC_MAIN_FIND: return Diq_OnFindDevice(hdlg);
  346. case IDC_MAIN_REFRESH:return Diq_OnRefresh(hdlg);
  347. }
  348. return 0;
  349. }
  350. /*****************************************************************************
  351. *
  352. * Diq_OnChildExit
  353. *
  354. * A client device has exited. Decrement the dev count.
  355. *
  356. *****************************************************************************/
  357. BOOL INTERNAL
  358. Diq_OnChildExit(PMAINDLGINFO pmdi, HWND hdlg)
  359. {
  360. if (pmdi) {
  361. pmdi->cDevs--;
  362. if (pmdi->cDevs == 0) {
  363. Diq_RecalcClose(pmdi, hdlg);
  364. }
  365. }
  366. return 1;
  367. }
  368. /*****************************************************************************
  369. *
  370. * Diq_OnThreadStarted
  371. *
  372. * A worker thread has finished starting. Decrement our busy count.
  373. *
  374. *****************************************************************************/
  375. BOOL INTERNAL
  376. Diq_OnThreadStarted(PMAINDLGINFO pmdi, HWND hdlg)
  377. {
  378. if (pmdi) {
  379. pmdi->cBusy--;
  380. if (pmdi->cBusy == 0) { /* Set the cursor back if it's us */
  381. RecalcCursor(hdlg);
  382. }
  383. }
  384. return 1;
  385. }
  386. /*****************************************************************************
  387. *
  388. * Diq_OnSetCursor
  389. *
  390. * Set the cursor to match our pending thread create count.
  391. *
  392. *****************************************************************************/
  393. BOOL INTERNAL
  394. Diq_OnSetCursor(PMAINDLGINFO pmdi, HWND hdlg, WPARAM wp, LPARAM lp)
  395. {
  396. if (LOWORD(lp) == HTCLIENT && pmdi->cBusy) {
  397. SetCursor(g_hcurStarting);
  398. return SetDlgMsgResult(hdlg, WM_SETCURSOR, 1);
  399. } else {
  400. return 0;
  401. }
  402. }
  403. /*****************************************************************************
  404. *
  405. * Diq_DlgProc
  406. *
  407. *****************************************************************************/
  408. INT_PTR CALLBACK
  409. Diq_DlgProc(HWND hdlg, UINT wm, WPARAM wp, LPARAM lp)
  410. {
  411. PMAINDLGINFO pmdi = GetDialogPtr(hdlg);
  412. switch (wm) {
  413. case WM_INITDIALOG: return Diq_OnInitDialog(hdlg);
  414. case WM_DESTROY: return Diq_OnDestroy(pmdi, hdlg);
  415. case WM_CLOSE: EndDialog(hdlg, 0); break;
  416. case WM_COMMAND:
  417. return Diq_OnCommand(hdlg,
  418. (int)GET_WM_COMMAND_ID(wp, lp),
  419. (UINT)GET_WM_COMMAND_CMD(wp, lp));
  420. case WM_SETCURSOR:
  421. return Diq_OnSetCursor(pmdi, hdlg, wp, lp);
  422. case WM_THREADSTARTED:
  423. return Diq_OnThreadStarted(pmdi, hdlg);
  424. case WM_CHILDEXIT:
  425. return Diq_OnChildExit(pmdi, hdlg);
  426. }
  427. return 0;
  428. }