windows-nt/Source/XPSP1/NT/multimedia/directx/dinput/dx8/diquick/diqmain.c
2020-09-26 16:20:57 +08:00

508 lines
14 KiB
C

/*****************************************************************************
*
* diqmain.c
*
* The main dialog box.
*
*****************************************************************************/
#include "diquick.h"
GUID GUID_Uninit = { 1 };
DWORD g_dwEnumType;
DWORD g_dwEnumFlags;
/*****************************************************************************
*
* Dialog instance data
*
* Instance data for main dialog box.
*
*****************************************************************************/
typedef struct MAINDLGINFO {
HWND hwndDevices; /* Devices combo box */
UINT cBusy; /* Number of threads starting */
UINT cDevs; /* Number of devices created */
IDirectInput *pdi; /* Cached interface */
BOOL fW; /* Is pdi a pdiW? (else, pdiA) */
DARY daryDevs; /* Device info lives here */
} MAINDLGINFO, *PMAINDLGINFO;
/*****************************************************************************
*
* Diq_DeviceEnumProc
*
* Device enumeration procedure which is called one for each device.
*
* Add the item to our dialog instance data and to the combo box.
*
*****************************************************************************/
BOOL INTERNAL
Diq_DeviceEnumProc(PCV pvDi, LPVOID pv)
{
PMAINDLGINFO pmdi = pv;
DIDEVICEINSTANCE didi;
TCHAR tsz[1024];
int ich;
if (pmdi->fW) {
LPCDIDEVICEINSTANCEW pdiW = pvDi;
didi.guidInstance = pdiW->guidInstance;
didi.guidProduct = pdiW->guidProduct;
didi.dwDevType = pdiW->dwDevType;
ConvertString(pmdi->fW, pdiW->tszProductName,
didi.tszProductName,
cA(didi.tszProductName));
ConvertString(pmdi->fW, pdiW->tszInstanceName,
didi.tszInstanceName,
cA(didi.tszInstanceName));
} else {
LPCDIDEVICEINSTANCEA pdiA = pvDi;
didi.guidInstance = pdiA->guidInstance;
didi.guidProduct = pdiA->guidProduct;
didi.dwDevType = pdiA->dwDevType;
ConvertString(pmdi->fW, pdiA->tszProductName,
didi.tszProductName,
cA(didi.tszProductName));
ConvertString(pmdi->fW, pdiA->tszInstanceName,
didi.tszInstanceName,
cA(didi.tszInstanceName));
}
ich = wsprintf(tsz, TEXT("%s (%s)"),
didi.tszInstanceName,
didi.tszProductName);
if (didi.dwDevType & DIDEVTYPE_HID) {
LoadString(g_hinst, IDS_SPACEPARENHID, &tsz[ich], 10);
}
ComboBox_AddString(pmdi->hwndDevices, tsz);
Dary_Append(&pmdi->daryDevs, &didi);
return DIENUM_CONTINUE;
}
/*****************************************************************************
*
* Diq_EnumDevices
*
* Rebuild the list of enumerated devices. Try to preserve the
* current selection index.
*
*****************************************************************************/
void INTERNAL
Diq_EnumDevices(PMAINDLGINFO pmdi)
{
HRESULT hres;
int iSel = ComboBox_GetCurSel(pmdi->hwndDevices);
HCURSOR hcurPrev = GetCursor();
SetCursor(LoadCursor(NULL, IDC_WAIT));
Dary_Term(&pmdi->daryDevs);
ZeroX(pmdi->daryDevs);
ComboBox_ResetContent(pmdi->hwndDevices);
#if defined(_DEBUG) || defined(DEBUG)
{
/*
* Create the intentionally invalid device.
*/
DIDEVICEINSTANCE didi;
ComboBox_AddString(pmdi->hwndDevices, g_tszInvalid);
ZeroX(didi);
Dary_Append(&pmdi->daryDevs, &didi);
ComboBox_AddString(pmdi->hwndDevices, "<uninit>");
ZeroX(didi);
didi.guidInstance = GUID_Uninit;
lstrcpyn(didi.tszInstanceName, "<uninit instance>",
cA(didi.tszInstanceName));
Dary_Append(&pmdi->daryDevs, &didi);
}
#endif
pmdi->fW = 1;
hres = DirectInput8Create(g_hinst, g_dwDIVer, &IID_IDirectInput8W, (PVOID)&pmdi->pdi, 0);
/* For each object, add it to the menu */
if (SUCCEEDED(hres)) {
IDirectInput_EnumDevices(pmdi->pdi, g_dwEnumType, Diq_DeviceEnumProc,
pmdi, g_dwEnumFlags);
IDirectInput_Release(pmdi->pdi);
pmdi->pdi = 0;
}
ComboBox_SetCurSel(pmdi->hwndDevices, max(iSel, 0));
SetCursor(hcurPrev);
}
/*****************************************************************************
*
* Diq_OnInitDialog
*
* Populate the combo box with the list of devices.
*
*****************************************************************************/
BOOL INTERNAL
Diq_OnInitDialog(HWND hdlg)
{
PMAINDLGINFO pmdi;
Diq_HackPropertySheets(hdlg);
pmdi = LocalAlloc(LPTR, cbX(MAINDLGINFO));
if ( !pmdi ) {
return 0;
}
SetDialogPtr(hdlg, pmdi);
pmdi->hwndDevices = GetDlgItem(hdlg, IDC_MAIN_DEVICES);
Diq_EnumDevices(pmdi);
CheckRadioButton(hdlg, IDC_MAIN_OLE, IDC_MAIN_DI, IDC_MAIN_DI);
CheckRadioButton(hdlg, IDC_MAIN_DIA, IDC_MAIN_DIW, IDC_MAIN_DIW);
CheckRadioButton(hdlg, IDC_MAIN_DIDA, IDC_MAIN_ITFMAC, IDC_MAIN_DIDW);
if (g_dwDIVer <= 0x0300) {
//EnableWindow(GetDlgItem(hdlg, IDC_MAIN_DID2A), FALSE);
//EnableWindow(GetDlgItem(hdlg, IDC_MAIN_DID2W), FALSE);
EnableWindow(GetDlgItem(hdlg, IDC_MAIN_DIDJC), FALSE);
}
return 1;
}
/*****************************************************************************
*
* Diq_OnDestroy
*
* Clean up.
*
*****************************************************************************/
BOOL INTERNAL
Diq_OnDestroy(PMAINDLGINFO pmdi, HWND hdlg)
{
if (pmdi) {
Dary_Term(&pmdi->daryDevs);
LocalFree(pmdi);
}
return 1;
}
/*****************************************************************************
*
* Diq_RecalcClose
*
* Enable or disable the SC_CLOSE option accordingly.
*
*****************************************************************************/
void INTERNAL
Diq_RecalcClose(PMAINDLGINFO pmdi, HWND hdlg)
{
EnableMenuItem(GetSystemMenu(hdlg, 0), SC_CLOSE,
MF_BYCOMMAND |
(pmdi->cDevs ? MF_DISABLED | MF_GRAYED : MF_ENABLED));
}
/*****************************************************************************
*
* Diq_OnGetStatus
*
* Somebody asked for the status of the device.
*
*****************************************************************************/
BOOL INTERNAL
Diq_OnGetStatus(HWND hdlg)
{
PMAINDLGINFO pmdi = GetDialogPtr(hdlg);
int iSel = ComboBox_GetCurSel(pmdi->hwndDevices);
if ((UINT)iSel < (UINT)pmdi->daryDevs.cx) {
LPDIRECTINPUTA pdia;
HRESULT hres;
UINT didc;
int ids;
didc = GetCheckedRadioButton(hdlg,
IDC_MAIN_ITF, IDC_MAIN_ITFMAC) - IDC_MAIN_ITF;
hres = CreateDI(IsDlgButtonChecked(hdlg, IDC_MAIN_OLE),
IsUnicodeDidc(didc),
(PPV)&pdia);
if (SUCCEEDED(hres)) {
LPDIDEVICEINSTANCE pdidi;
pdidi = Dary_GetPtr(&pmdi->daryDevs, iSel, DIDEVICEINSTANCE);
hres = IDirectInput_GetDeviceStatus(pdia,
&pdidi->guidInstance);
switch (hres) {
case DI_OK: ids = IDS_GETSTAT_OK; break;
case DI_NOTATTACHED: ids = IDS_GETSTAT_NOTATTACHED; break;
default: ids = IDS_GETSTAT_ERROR; break;
}
} else {
ids = IDS_GETSTAT_ERROR;
}
MessageBoxV(hdlg, ids, hres);
}
return 1;
}
/*****************************************************************************
*
* Diq_OnCreateObject
*
* Somebody asked us to create an object. Party!
*
*****************************************************************************/
BOOL INTERNAL
Diq_OnCreateObject(HWND hdlg)
{
PMAINDLGINFO pmdi = GetDialogPtr(hdlg);
int iSel = ComboBox_GetCurSel(pmdi->hwndDevices);
//#ifdef DEBUG
if (IsDlgButtonChecked(hdlg, IDC_MAIN_DIDJC)) {
if (Cpl_Create(hdlg,
IsDlgButtonChecked(hdlg, IDC_MAIN_OLE),
IsDlgButtonChecked(hdlg, IDC_MAIN_DIW))) {
pmdi->cBusy++;
pmdi->cDevs++;
RecalcCursor(hdlg);
Diq_RecalcClose(pmdi, hdlg);
}
} else
//#endif
if ((UINT)iSel < (UINT)pmdi->daryDevs.cx) {
UINT didc;
LPDIDEVICEINSTANCE pdidi;
didc = GetCheckedRadioButton(hdlg,
IDC_MAIN_ITF, IDC_MAIN_ITFMAC) - IDC_MAIN_ITF;
pdidi = Dary_GetPtr(&pmdi->daryDevs, iSel, DIDEVICEINSTANCE);
if (Dev_Create(hdlg,
IsDlgButtonChecked(hdlg, IDC_MAIN_OLE),
IsUnicodeDidc(didc),
&pdidi->guidInstance,
pdidi->tszInstanceName,
didc)) {
pmdi->cBusy++;
pmdi->cDevs++;
RecalcCursor(hdlg);
Diq_RecalcClose(pmdi, hdlg);
}
}
return 1;
}
/*****************************************************************************
*
* Diq_OnFindDevice
*
* Display the "FindDevice" dialog.
*
*****************************************************************************/
BOOL INTERNAL
Diq_OnFindDevice(HWND hdlg)
{
PMAINDLGINFO pmdi = GetDialogPtr(hdlg);
UINT didc;
didc = GetCheckedRadioButton(hdlg,
IDC_MAIN_ITF, IDC_MAIN_ITFMAC) - IDC_MAIN_ITF;
if (Find_Create(hdlg,
IsDlgButtonChecked(hdlg, IDC_MAIN_OLE),
IsDlgButtonChecked(hdlg, IDC_MAIN_DIW))) {
pmdi->cBusy++;
pmdi->cDevs++;
RecalcCursor(hdlg);
Diq_RecalcClose(pmdi, hdlg);
}
return 1;
}
/*****************************************************************************
*
* Diq_OnControlPanel
*
* Run the DirectInput control panel using the indicated interface.
*
*****************************************************************************/
BOOL INTERNAL
Diq_OnControlPanel(HWND hdlg)
{
HRESULT hres;
LPDIRECTINPUTA pdia;
hres = CreateDI(IsDlgButtonChecked(hdlg, IDC_MAIN_OLE),
IsDlgButtonChecked(hdlg, IDC_MAIN_DIW),
(PPV)&pdia);
if (SUCCEEDED(hres)) {
hres = pdia->lpVtbl->RunControlPanel(pdia, hdlg, 0);
if (SUCCEEDED(hres)) {
} else {
MessageBoxV(hdlg, IDS_ERR_RUNCPL, hres);
}
pdia->lpVtbl->Release(pdia);
} else {
MessageBoxV(hdlg, IDS_ERR_CREATEOBJ, hres);
}
return 1;
}
/*****************************************************************************
*
* Diq_OnRefresh
*
* Refresh the device list.
*
*****************************************************************************/
BOOL INTERNAL
Diq_OnRefresh(HWND hdlg)
{
if (DialogBox(g_hinst, MAKEINTRESOURCE(IDD_ENUMDEV),
hdlg, DEnum_DlgProc) > 0) {
PMAINDLGINFO pmdi = GetDialogPtr(hdlg);
Diq_EnumDevices(pmdi);
}
return TRUE;
}
/*****************************************************************************
*
* Diq_OnCommand
*
*****************************************************************************/
BOOL INLINE
Diq_OnCommand(HWND hdlg, int id, UINT cmd)
{
switch (id) {
case IDC_MAIN_GETSTAT:return Diq_OnGetStatus(hdlg);
case IDC_MAIN_CREATE: return Diq_OnCreateObject(hdlg);
case IDC_MAIN_CPL: return Diq_OnControlPanel(hdlg);
case IDC_MAIN_FIND: return Diq_OnFindDevice(hdlg);
case IDC_MAIN_REFRESH:return Diq_OnRefresh(hdlg);
}
return 0;
}
/*****************************************************************************
*
* Diq_OnChildExit
*
* A client device has exited. Decrement the dev count.
*
*****************************************************************************/
BOOL INTERNAL
Diq_OnChildExit(PMAINDLGINFO pmdi, HWND hdlg)
{
if (pmdi) {
pmdi->cDevs--;
if (pmdi->cDevs == 0) {
Diq_RecalcClose(pmdi, hdlg);
}
}
return 1;
}
/*****************************************************************************
*
* Diq_OnThreadStarted
*
* A worker thread has finished starting. Decrement our busy count.
*
*****************************************************************************/
BOOL INTERNAL
Diq_OnThreadStarted(PMAINDLGINFO pmdi, HWND hdlg)
{
if (pmdi) {
pmdi->cBusy--;
if (pmdi->cBusy == 0) { /* Set the cursor back if it's us */
RecalcCursor(hdlg);
}
}
return 1;
}
/*****************************************************************************
*
* Diq_OnSetCursor
*
* Set the cursor to match our pending thread create count.
*
*****************************************************************************/
BOOL INTERNAL
Diq_OnSetCursor(PMAINDLGINFO pmdi, HWND hdlg, WPARAM wp, LPARAM lp)
{
if (LOWORD(lp) == HTCLIENT && pmdi->cBusy) {
SetCursor(g_hcurStarting);
return SetDlgMsgResult(hdlg, WM_SETCURSOR, 1);
} else {
return 0;
}
}
/*****************************************************************************
*
* Diq_DlgProc
*
*****************************************************************************/
INT_PTR CALLBACK
Diq_DlgProc(HWND hdlg, UINT wm, WPARAM wp, LPARAM lp)
{
PMAINDLGINFO pmdi = GetDialogPtr(hdlg);
switch (wm) {
case WM_INITDIALOG: return Diq_OnInitDialog(hdlg);
case WM_DESTROY: return Diq_OnDestroy(pmdi, hdlg);
case WM_CLOSE: EndDialog(hdlg, 0); break;
case WM_COMMAND:
return Diq_OnCommand(hdlg,
(int)GET_WM_COMMAND_ID(wp, lp),
(UINT)GET_WM_COMMAND_CMD(wp, lp));
case WM_SETCURSOR:
return Diq_OnSetCursor(pmdi, hdlg, wp, lp);
case WM_THREADSTARTED:
return Diq_OnThreadStarted(pmdi, hdlg);
case WM_CHILDEXIT:
return Diq_OnChildExit(pmdi, hdlg);
}
return 0;
}