/***************************************************************************** * * diqdev.c * * The dialog box that asks what to do with the DirectInput device. * *****************************************************************************/ #include "diquick.h" /***************************************************************************** * * Property sheet goo * *****************************************************************************/ #pragma BEGIN_CONST_DATA #define MAKE_PSP(idd, dlgproc) { \ cbX(PROPSHEETPAGE), /* dwSize */ \ PSP_DEFAULT, /* dwFlags */ \ 0, /* hInstance */ \ MAKEINTRESOURCE(idd), /* pszTemplate */ \ 0, /* hIcon */ \ 0, /* pszTitle */ \ dlgproc, /* pfnDlgProc */ \ idd == IDD_ENUMEFF, /* lParam */ \ 0, /* pfnCallback */ \ 0, /* pcRefParent */ \ } \ PROPSHEETPAGE c_rgpsp[] = { EACH_PROPSHEET(MAKE_PSP) }; #undef MAKE_PSP RIID c_rgriid[] = { &IID_IDirectInputDevice8A, &IID_IDirectInputDevice8W, }; #pragma END_CONST_DATA /***************************************************************************** * * Dev_DoPropertySheet * *****************************************************************************/ BOOL INTERNAL Dev_DoPropertySheet(PDEVDLGINFO pddi) { PROPSHEETPAGE rgpsp[cA(c_rgpsp)]; PROPSHEETHEADER psh; int ipsp; psh.dwSize = cbX(psh); psh.dwFlags = PSH_PROPSHEETPAGE | PSH_MODELESS | PSH_NOAPPLYNOW; psh.hwndParent = 0; /* pddi->hdlgOwner */ psh.pszCaption = pddi->ptszDesc; psh.nPages = 0; psh.nStartPage = 0; psh.ppsp = rgpsp; /* * The lParam of the structure is nonzero iff the page should * be shown only if the DX 5 interface is being used. */ for (ipsp = 0; ipsp < cA(c_rgpsp); ipsp++) { if (fLimpFF(c_rgpsp[ipsp].lParam, pddi->pdid)) { rgpsp[psh.nPages] = c_rgpsp[ipsp]; rgpsp[psh.nPages].hInstance = g_hinst; rgpsp[psh.nPages].lParam = (LPARAM)pddi; psh.nPages++; } } return SemimodalPropertySheet(pddi->hdlgOwner, &psh); } /***************************************************************************** * * Dev_DoDevice * *****************************************************************************/ HRESULT INTERNAL Dev_DoDevice(PDEVDLGINFO pddi, LPDIRECTINPUTA pdia) { HRESULT hres; UINT idsError; if (pdia) { /* * To create an uninitialized device, we CoCreateInstance it * and "forget" to call Initialize(). */ if (IsEqualGUID(pddi->pguidInstance, &GUID_Uninit)) { REFIID riid = IsUnicodeDidc(pddi->didcItf) ? &IID_IDirectInputDevice8W : &IID_IDirectInputDevice8A; hres = CoCreateInstance(&CLSID_DirectInputDevice8, 0, CLSCTX_INPROC_SERVER, riid, (PV)&pddi->pdid); } else { hres = IDirectInput_CreateDevice(pdia, pddi->pguidInstance, (PV)&pddi->pdid, 0); } /* * If we need to change character set, then do so in-place. */ if (SUCCEEDED(hres) && pddi->flCreate != (BOOL)pddi->didcItf) { IDirectInputDevice8 *pdid; hres = IDirectInputDevice8_QueryInterface(pddi->pdid, c_rgriid[pddi->didcItf], (PV)&pdid); IDirectInputDevice8_Release(pddi->pdid); pddi->pdid = pdid; if (IsFFDidc(pddi->didcItf)) { pddi->pdid = (PV)pdid; } else { pddi->pdid = 0; } } } else { hres = E_FAIL; } SendNotifyMessage(pddi->hdlgOwner, WM_THREADSTARTED, 0, 0); if (SUCCEEDED(hres)) { idsError = Dev_DoPropertySheet(pddi) ? IDS_ERR_CREATEDEV : 0; pddi->pdid->lpVtbl->Release(pddi->pdid); } else { idsError = IDS_ERR_CREATEDEV; } if (idsError) { MessageBoxV(pddi->hdlgOwner, idsError); SendNotifyMessage(pddi->hdlgOwner, WM_CHILDEXIT, 0, 0); } return hres; } /***************************************************************************** * * Dev_ThreadStart * * Runs on the new thread. Creates the object and spins the dialog * box to control it. * *****************************************************************************/ DWORD WINAPI Dev_ThreadStart(PDEVDLGINFO pddi) { HRESULT hres; LPDIRECTINPUTA pdia; hres = CoInitialize(0); if (SUCCEEDED(hres)) { hres = CreateDI(pddi->fOle, pddi->flCreate, (PPV)&pdia); if (SUCCEEDED(hres)) { hres = Dev_DoDevice(pddi, pdia); pdia->lpVtbl->Release(pdia); } else { ThreadFailHres(pddi->hdlgOwner, IDS_ERR_CREATEOBJ, hres); } CoUninitialize(); } else { ThreadFailHres(pddi->hdlgOwner, IDS_ERR_COINIT, hres); } LocalFree(pddi); return 0; } /***************************************************************************** * * Dev_Create * * Spin a thread to create a DirectInput device interface. * *****************************************************************************/ INT_PTR EXTERNAL Dev_Create(HWND hdlg, BOOL fOle, UINT flCreate, const GUID *pguidInstance, LPCTSTR ptszDesc, UINT didcItf) { PDEVDLGINFO pddi = LocalAlloc(LPTR, cbX(DEVDLGINFO)); if (pddi) { DWORD id; HANDLE h; pddi->hdlgOwner = hdlg ; pddi->fOle = fOle ; pddi->flCreate = flCreate ; pddi->pguidInstance = pguidInstance; pddi->ptszDesc = ptszDesc ; pddi->didcItf = didcItf ; h = CreateThread(0, 0, Dev_ThreadStart, pddi, 0, &id); if (h) { } else { if (pddi->pvtbl) { pddi->pvtbl->Destroy(pddi); } LocalFree(pddi); pddi = 0; } } return (INT_PTR)pddi; }